This tutorial is derived from the official Boardgame.io Tutorial. It uses Webpack as an alternative to using React or Parcel.
Tutorial
This tutorial walks through implementing a simple game of Tic-Tac-Toe.
Setup
We’re going to use node.js modules with our web client, so we’ll need to use some kind of build system to compile our code for the browser. In this version of the tutorial, we will use Webpack to package the javascript code our web client needs into a single file dist/main.js
Let’s create a new Node project from the command line:
mkdir bgio-tutorial
cd bgio-tutorial
npm init -yes
We’re going to add boardgame.io and Webpack modules to help us build our app:
npm install boardgame.io
npm install --save-dev webpack webpack-cli
Now, let’s create a basic HTML page that will load our app:
index.html:
<!DOCTYPE html>
<html>
<head>
<title>boardgame.io Tutorial</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app"></div>
<script src="./dist/main.js"></script>
</body>
</html>
Next, create a basic http-server to share our html and javascript files:
server.js:
const PORT = 3004;
const fs = require('fs');
http = require('http');
http.createServer(function (req, res)
{
console.log(`Request for url:${req.url}`);
if (req.url == '/')
req.url = '/index.html';
fs.readFile(__dirname + req.url, function (err,data) {
if (err) {
res.writeHead(404);
res.end(JSON.stringify(err));
return;
}
res.setHeader('Cache-Control', 'no-store');
if (req.url.endsWith('.js'))
res.setHeader('Content-Type', 'text/javascript');
res.writeHead(200);
res.end(data);
});
}).listen(PORT);
console.log(`Server started on port ${PORT}`);
Create a src
folder to hold our game files:
mkdir src
Our completed project directory will look like this:
bgio-tutorial/
├── dist
│ └── main.js
├── index.html
├── node_modules/
├── package-lock.json
├── package.json
├── server.js
└── src/
├── App.js
└── Game.js
Defining a Game
We define a game by creating an object whose contents tell boardgame.io how your game works. More or less everything is optional, so we can start simple and gradually add complexity. To start, we’ll add a setup
function, which will set the initial value of the game state G
, and a moves
object containing the moves that make up the game.
A move function receives the game state G
and updates it to the desired new state. It also receives ctx
, an object managed by boardgame.io that contains metadata like turn
and currentPlayer
. After G
and ctx
, moves can receive arbitrary arguments that you pass in when making the move.
In Tic-Tac-Toe, we only have one type of move and we will name it clickCell
. It will take the ID of the cell that was clicked and update that cell with the ID of the player who clicked it.
Let’s put this together in src/Game.js
to start defining our game:
src/Game.js:
export const TicTacToe = {
setup: () => ({ cells: Array(9).fill(null) }),
moves: {
clickCell: (G, ctx, id) => {
G.cells[id] = ctx.currentPlayer;
},
},
};
NOTE: The setup
function will receive ctx
as its first argument. This is useful if you need to customize the initial state based on some field in ctx
— the number of players, for example — but we don’t need that for Tic-Tac-Toe.
Creating a Client
We’ll start by creating a class to manage our web app’s logic in src/App.js
.
In the class’s constructor we’ll create a boardgame.io client and call its start method to run it.
src/App.js:
import { Client } from 'boardgame.io/client';
import { TicTacToe } from './Game';
class TicTacToeClient {
constructor() {
this.client = Client({ game: TicTacToe });
this.client.start();
}
}
const app = new TicTacToeClient();
Let’s also add two scripts to package.json
to make serving the web app simpler:
package.json:
{
"scripts": {
"webpack": "webpack-cli --mode=development src/App.js",
"start": "node server.js"
}
}
Pack our classes and packages for distribution to client browsers:
npm run webpack
Open port 3004 on your firewall if necessary. On my CentOS 8 server I run:
sudo firewall-cmd --zone dmz --add-port 3004/tcp
sudo firewall-cmd --zone dmz --add-port 3004/tcp --permanent
You can now serve the app from the command line by running:
npm start
You should now be able to view the site in your browser. If you started the server on the same machine, just browse: http://localhost:3004
Although we haven’t built any UI yet, boardgame.io renders a Debug Panel. This panel means we can already play our Tic-Tac-Toe game!
You can make a move by clicking on clickCell
on the Debug Panel, entering a number between 0 and 8, and pressing Enter. The current player will make a move on the chosen cell. The number you enter is the id
passed to the clickCell
function as the first argument after G
and ctx
. Notice how the cells
array on the Debug Panel updates as you make moves. You can end the turn by clicking endTurn
and pressing Enter. The next call to clickCell
will result in a “1” in the chosen cell instead of a “0”.
Note: You can turn off the Debug Panel by passing debug: false
in the Client
config.
Next Steps
This is the end of the WebPack-specific content of the tutorial. You can now complete the "Plain JS" version of the official tutorial continuing from the Game Improvements section.