Build a Multiplayer Game with Twilio Sync: Part 1
Time to read: 10 minutes
This blog post is the first part of a two-part tutorial where you will learn how to create a multiplayer Tic Tac Toe game with the Twilio Sync Javascript SDK.
Tic Tac Toe is a two-player game played on a 3x3 grid. The objective of the game is to be the first player to get three of their symbols (either X or O) in a row, either horizontally, vertically, or diagonally.
In the first part, you will learn how to create your own Tic Tac Toe game, including creating a game’s user interface, adding the controls, and implementing the game logic. Additionally, you will also learn how to add an AI player to make the game more challenging and engaging.
In the second part of the series, you will take your game to the next level by adding multiplayer functionality with the help of Twilio Sync Javascript SDK. So stay tuned for the second part, where you will learn how to leverage Twilio Sync to add real-time multiplayer functionality to the game!
Twilio Sync Javascript SDK is a software development kit that allows you to add real-time data synchronization functionality to your web and mobile applications.
By the end of this part, you will have a game that looks like the following:
Tutorial Requirements
To follow this tutorial you will need the following:
- A free Twilio account
- A basic understanding of how to use Twilio and Javascript;
- Node.js v12+, NPM, and Git installed;
Creating the Game UI
In this section, you will create the project directory where you will store your project files and create the game UI.
Open a terminal window and navigate to a suitable location for your project. Run the following commands to create the project directory and navigate into it:
Create a subdirectory named public where you will store this project’s static files and navigate into it:
Create a file named index.html inside the public subdirectory and add the following code to it:
The code uses the link
tag to include Bootstrap CSS and styles.css files in the head
section, and the script
tag to include Bootstrap JS, index.js, and game.js files. Index.js will contain the game controls while game.js will contain the game logic.
Furthermore, the background color of the body
section is set to dark purple.
Add the following code in the body
section above the script
tags:
The code creates a toolbar for the game with player names, scores, and symbols for X and O and a Start button.
When the game begins, the human player's name is set to "You," and the AI player's name is set to "Player 2."
Add the following code below the game’s toolbar–the code you just added above–and above the script
tags:
Here, the code creates a 3x3 grid to represent a Tic Tac Toe game board using div
elements. The grid is organized into rows and columns, with each column containing a cell. The grid is enclosed within a card element that has a lighter purple background color.
Add the following code below the game board:
The code creates a modal dialog box to be displayed at the end of the game with the title "Game over", a body for displaying the game status, and a footer with a Close button.
Save your index.html file. Then, create a file named styles.css inside your public directory and add the following code to it:
This code defines the visual styles for the Tic Tac Toe game, which include the Start button appearance, board width, and margin, cell height, and background color, symbols used in the game, and animation effects when a cell is clicked or hovered over. Additionally, it sets the background color of the game's modal window.
Save styles.css and then open the index.html file in your preferred browser and your game UI should similar to the following:
Creating the game controls
In this section, you will set a sign for both the human and AI player and implement the game controls. These controls will allow you to start a game and make a move on the board.
Create a file named index.js and add the following code to it:
The code sets up variables for the Start button, game cells, and player name elements.
The Start button initiates the game, the game cells make up the Tic Tac Toe grid, and the player name elements indicate which symbol the human player is using.
Add the following code variables to the bottom of your index.js file:
Here the code initializes new variables to help manage the game:
player
for the human playerAI
for the AI playercurrentPlayer
to keep track of whose turn it isaddedListenersToCells
to check if the cells have been assigned event listenersisGameOver
to determine if the game has ended.
Add the following code to the bottom of your index.js file:
This code defines a function named indicatePlayerSign()
that is used to set the player name elements on the game board and indicate which sign the human player is using.
It sets the text content of the corresponding player name element to You
based on the player variable.
Finally, the code calls this function to set the player name at the beginning of the game.
Add the following code below the indicatePlayerSign()
function call:
The addListenersToCells()
function defined above adds event listeners to all cells in the game board to allow player interaction via clicking and hovering.
The function iterates through each cell using a for loop and attaches two event listeners to each cell: mouseover
and mouseout
.
These event listeners will only run if it’s the human player’s turn to play, the game is not over, and the cell is empty.
The mouseover
event listener adds a pulsating effect to the cell, while the mouseout
removes it.
Add the following highlighted code inside the addListenersToCells()
function, below the mouseout
event listener:
Here the code adds a click
event listener to all cells on the board to detect when a human player clicks a cell.
It checks if it is the human player’s turn, if the game is not over yet, and if the cell is empty. If all conditions are met, it disables the cell, removes the pulsating effect, and calls the markCell()
function with the cell element as an argument.
Add the following code below the addListenersToCells()
function:
The code defines a function named markCell
that takes one argument, cell
.
This function updates the game board by marking the cell that was passed as an argument with the current player's symbol and visually representing that symbol on the cell using a span
element with a class name based on the player's symbol.
Next, add the following below all the existing code in index.js:
Here the code adds a click
event listener to the Start button and defines a function named startGame()
that will be called when this button is clicked.
The startGame()
function initializes the game by setting isGameOver
to false and calling the addListenersToCells()
function to attach event listeners to the cells if they are not attached already. Additionally, it disables the Start button to prevent the player from starting a new game before finishing the current one.
Go back to the browser tab where you opened the index.html file, and refresh the page. Once the page refreshes click on the Start to start a new game and then interact with the cells on the board:
Adding the game logic
In this section, you will start working on the game logic and integrating the AI player. The code you will implement here will handle various tasks such as storing the conditions for winning the game, keeping track of whose turn it is, switching between player turns, and allowing the AI player to make a move.
Create a file named game.js inside the public directory, and add the following code to it:
The code initializes several variables that will be used in the Tic Tac Toe game. These include xSign
and OSign
for displaying the X and O symbols, txtPlayerOScore
and txtPlayerXScore
for displaying the players' scores, modalGameOver
for displaying the game over modal, and txtGameStatus
for displaying the game status. Additionally, playerOScore
and playerXScore
are used for keeping track of the players' scores.
Add the following variables below the playerXScore
variable at the bottom of the file:
The code above defines two variables related to the game's winning combinations:winningCombos
and gameWinningCombo
.
The winningCombos
variable is an array of arrays representing the possible winning combinations.
The gameWinningCombo
variable is an empty array that will store the winning combination when a player wins.
Add the following code below the gameWinningCombo
variable:
The code above defines two functions : switchPlayer()
and indicatePlayerTurn()
The switchPlayer()
function swaps the current player with the other player after every move and calls indicatePlayerTurn()
to show whose turn it is.
The indicatePlayerTurn()
function adds a blink effect to the current player's symbol and removes it from the other player's symbol to visually indicate the player's turn.
Add the following code below the indicatePlayerTurn()
function:
Here, the code defines a function named AIPlayer()
that represents the behavior of the AI player in the game.
This function selects a random empty cell on the game board, disables it to prevent further selection, and marks it with the symbol of the AI player using the markCell()
function.
Go back to the index.js file and add the following highlighted code to the bottom of the markCell()
function (located around line 46):
The code you added to the markCell()
function, first, calls the switchPlayer()
function to switch to the next player.
Then, it checks if the current player is the AI player. If so, the function sets a timeout to delay the AI player's turn by 1 second.
In the same file, add the following highlighted code to the bottom of the Start button click event listener (located around line 60):
Here, you added a code to the Start button click event listener that calls the indicatePlayerTurn()
function to indicate whose turn it is to play right after the game starts.
Save all of your working files. Then, go back to the browser tab where you opened the index.html file, and refresh the page. Once the page refreshes click on the Start to start a new game, notice the player’s turn indicator is now functional, then click on any random cell and also notice how now there is an AI player as well.
Building the end game logic
In this section, you will create several functions in the game.js that will work together to determine when the game is over, who the winner is, and how to reset the board for a new game.
Go back to your game.js file and add the following code to the bottom of this file:
This code defines a function named checkWin()
, which checks whether any of the predefined winning combinations have been achieved by the current player.
If there is a winning combination the gameWinningCombo
variable is assigned that winning combination and the function returns true
. Otherwise, the function returns false
.
Add the following code below the checkWin()
function:
Here the code defines a function named checkTie()
, which determines if the game has ended in a tie by checking if all the cells on the board have been marked with either X or O.
Add the following code below the checkTie()
function:
The code above defines a function named checkGameStatus()
, which is responsible for checking the current game status and determining the appropriate action to take.
First, it checks if the current player has won the game by calling the checkWin()
function. If checkWin()
returns true, the game is over and a function named gameOver()
is called with the argument win
.
If the game is not won, it checks if the game is tied by calling the checkTie()
function. If checkTie()
returns true, the game is over and a function named gameOver()
is called with the argument 'tie'.
If neither of the above conditions is met, the function switches to the next player by calling the switchPlayer()
function. Additionally, if the current player is the AI player, the function sets a timeout to delay the AI player's turn by 1 second.
Add the following gameOver()
function below the checkGameStatus()
function:
The gameOver()
function defined above is called when the game is over. It takes a parameter gameOutcome
which is either win
or tie
meaning that the game ended in a win or tie.
if the game ended in a win, the function checks which player won the game and updates their score. Then, it displays the updated scores on the web page by setting the innerText
properties of the txtPlayerOScore
and txtPlayerXScore
HTML elements.
Next, it calls a function named showGameOverModal()
, created in the next step, and passes the gameOutcome
as an argument, enables the Start button, and sets isGameOver
to true.
Add the following code below the gameOver()
function:
The code above defines a function named showGameOverModal()
, which is responsible for showing a modal dialog box when the game is over. This function takes in a parameter named gameOutcome
with either a win
or tie
value.
If the game ends in a win, the function sets the text of the txtGameStatus
element to indicate the winner, and if the game ends in a tie, it sets the text to show that it ended in a tie.
To display the modal, the function creates and calls an instance of the Modal class from the Bootstrap library after a brief delay.
Add the following code below the showGameOverModal()
function:
The code above defines a function named reset()
that prepares the game board for a new game.
This function first, ensures that all cells on the game board are cleared of any markings or other modifications and that they are clickable again.
Next, it clears the value stored on the gameWinningCombo
variable and calls the switchPlayer()
function to ensure that the player who made the final move in the previous game isn’t the one who makes the first move in the next game.
Save and close game.js.
Go back to the index.js file and replace all the code below the line cell.appendChild(sign)
inside the markCell()
function (around line 51) with the following highlighted line of code:
Here you replaced the previous code with a checkGameStatus()
function call. Now every time a player makes a move on the board this function will be called to check if the game has ended and if not switch to another player.
Go to the Start button click event listener and replace the indicatePlayerTurn()
function call (around line 57) with the following highlighted code:
When a game starts, the code added checks if it is the AI player’s turn to play, and if that is the case, the code sets a timeout to delay the AI player's turn by 1 second.
Go to the startGame()
function and add the following highlighted code to the bottom of this function (located around line 64):
With the code added, when the startGame()
function is triggered the code calls the reset()
function to prepare the board for a new game.
Save and close index.js.
Go back to the browser tab where you opened the index.html file, and refresh the page. Once the page refreshes click on the Start to start a new game, and notice that now when a player achieves a winning combination the game ends, the game over modal appears and the Start button is enabled.
Conclusion
In this part of a two-part tutorial, you learned how to build a tic tac toe game from scratch using HTML, CSS, and Javascript. First, you created the game’s user interface and added controls for player interaction. Then, you implemented game logic to track player turns, enable the AI player to make moves, and check for game ending conditions.
The code for this part of the tutorial is available in the following repository https://github.com/CSFM93/twilio-multiplayer-game-part1.
Now it's time to begin to the second part of this project: adding multiplayer functionality with Twilio Sync.
Carlos Mucuho is a Mozambican geologist turned developer who enjoys using programming to bring ideas into reality. https://twitter.com/CarlosMucuho
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.