Skip to content
Docs
Get started

Create your first game

Scaffold a game, understand how it runs, and play it in a test room.

This guide shows how a disko game works, using the project you created in Install, and plays it in a private test room.

The template

The template is a small team game: players pick Red or Blue in a Menu, move their disc with the arrow keys or WASD, and kick with Space. A HUD shows the score and the clock.

text

How a game runs

A game is not a loop you write yourself. disko runs your code at specific moments, and your code reacts.

When a room loads your game, your top-level code runs once. This is where you set things up: build the Menu, declare which actions players can use, and register handlers with game.on(...) for the moments you care about.

When a match starts, a fresh physical world is created: discs, walls, goals. Players who join the match get something to control. While the match runs, disko moves everything forward 60 times a second and calls your handlers when something happens, such as a disc crossing a goal line.

When the match stops, the world is thrown away. The Menu stays, ready for the next match.

When the game loads, its top-level code runs once and the game is Ready, showing its Menu. Starting a match creates the world and the game is Running; stopping it discards the world and returns to Ready.

So there are two kinds of state in a game. Things that should survive between matches, like the Menu or the team each player picked, live in top-level variables. Things that belong to one match, like discs, are created when it starts and forgotten when it stops.

A minimal game

The smallest useful game has a Menu with a Start button, and a disc for each player in the match.

The Menu and the Start button

The Menu is what players see before and between matches. You describe it with ui functions: here, a line of text and a button.

A button doesn't run code in the browser. When someone presses it, the player's browser sends a request to the game, and your ui-request handler decides what to do. That's how a game stays in charge of its own rules: a request can be refused.

src/main.ts

request.player.play() puts the player who pressed Start into the match, and game.start() begins it.

Discs for the players in the match

Players come and go. Rather than tracking that yourself, react to two events: player-enter when someone joins the running match, and player-exit when they leave it. Create a disc on enter and remove it on exit.

src/main.ts

When the match stops, the world and every disc in it are gone, so the map of discs is simply cleared.

Creating a disc

A disc is a round physical body. world.createDisc places one in the world, setAppearance colors it, and player.control connects it to that player's keyboard.

Kicking is an action. An action schema lists the actions a player can use; here, a single Kick that disko's physics already knows how to perform.

src/players.ts

Play it

sh

This starts a private test room and opens it in your browser. Leave it running: every time you save, the game reloads.

Next

When you're happy with your game, publish a release so any room can load it, or host a room of your own.