How to make a game
How to make an XP
What to press, in the order you will want to press it: lay the world out of pieces, turn the things in it into blueprints, give the blueprints rules, write a script when a rule will not do, and play it. The showcase walks real games built exactly this way, and the sidebar goes deeper on every room this page walks through.
What an XP is
An XP is one document: the world, the things in it, their rules, their scripts, who the player is and what ends the game — all of it in one file the runtime reads. There is no build step and no server of yours behind it. Copy the file and you have copied the game; send a link and somebody is playing it.
That is the fact everything else in this guide leans on. Every panel in the editor is a view of some part of that document, and nothing you can click produces a document the runtime would refuse — anything that would be refused is refused at the click instead, with the reason next to it.
How it works
One document
The world, the things, their rules and scripts, the player, what wins — one file is the whole game.
The editor edits it
Every panel is a view of one part of the file. Try plays a snapshot over the editor, solo and free.
The runtime plays it
The same component everywhere: the editor’s Try, the public link, a match.
A match is a room
Everybody who joins runs the same rules from the same inputs — no server of yours anywhere.
The last box explains most of the design decisions you will meet in these docs: because every client runs the same document from the same inputs, everything in it has to be deterministic. That is why scripts have world.random() instead of Math.random, why movement is computed from the shared clock rather than accumulated, and why a script's cut-off is counted in operations rather than milliseconds — two machines must always agree on what just happened.
The window
The editor is panels in a frame — drag them, split them, stack them into tabs. The layout saves itself and comes back. Everything is optional except the viewport, which is the work. The window page takes each panel apart; the short version:
| Viewport | The level. Drag to draw, right-drag to pan. |
| Scene | Things by name, architecture folded by model, the marks, the player. |
| Models | The catalogue, searchable. Click to pick, drag to place. |
| Tools | What a drag does, the working height, the turn, and whether there is ground. |
| Rules | A blueprint's triggers, as rows. |
| Scripts | JavaScript, by name, and which blueprints run it. |
| Document | The counts, the capabilities, and what the level would be refused for. |
Keep Document open while you work. It is the only panel that tells you things you cannot see by looking — whether the claims and the marks line up, and what would stop the level opening if it were reloaded right now.
The tools
| Select | Click a thing to find out what it is. Never builds. |
| Place | One piece where you let go, then hands you back to Select. |
| Draw | Paints while the button is down. |
| Erase | Takes away what a drag crosses. |
| Line | Two corners, a straight run. |
| Fill | Two corners, filled. |
| Room | Two corners, four walls and no ceiling. |
Select is the default, because the first thing anybody does with a level they already have is click something to find out what it is. Place hands you back to Select holding the piece it just laid — the next thing you do after putting a crate somewhere is nudge it, turn it, or look at it, none of which Place can do. The keys, the working plane and the handles are on the tools page.
Building
Lay a floor: pick a floor tile in Models, choose Fill, drag a rectangle. Height is the working level (Q and W) — except when the pointer is over something, in which case the piece goes on top of what you are pointing at. The slider answers for the empty parts of the world; the geometry answers everywhere else.
Walls: a wall is four wide, four high, one deep. R turns it. Line runs one along an edge; Room gives you four from two corners.
A door is a gap in a wall run. Collision is cell-shaped and a cell is a metre, so a 1.6-metre doorway straddles two cells, fills neither, and rasterises solid. Leave a piece out instead.
Put one thing somewhere exact: drag it out of Models into the viewport. It lands where you let go — on a floor, against a wall, or on the working plane — already selected, with the handles on it. Placements are not on a grid: a crate can sit at 2.3, a wall can stand at an angle. What stays cell-shaped is collision, so a wall at 2.5 is solid where it looks solid to within half a metre.
Two kinds of thing
A placement is architecture: walls, floors, stairs. It rasterises into cells once, when the level opens, and never moves. It has no name, no properties, no rules — which is why a room of four thousand pieces costs the same to walk around as a room of four.
An entity is a thing: a crate, a pickup, a target, a door. It has its own collision box exactly where the model is, it can hold properties, it can have rules, and it can stop existing. Entities come from blueprints — a kind of thing, named, with a model and optional properties and rules. Every crate made from the crate blueprint gets the same rules, which is what makes forty of them one edit.
Rule of thumb: if it needs a name or a rule, it is an entity. If a placed piece turns out to need behaviour, select it and press make it a blueprint — it becomes an entity in its place, and the placement is consumed rather than left behind.
Rules
A rule is three things: on (the event), an optional when (one property against one number), and do (a list of verbs). The vocabulary is closed — that is why it fits on a panel rather than needing a language, and why there is nothing you can write that fails while somebody is playing. The whole vocabulary is on the rules page; the recipe that teaches the shape of every rule is a crate that breaks:
Give the blueprint an hp property, add a rule on damaged when hp <= 0, and make the verbs spawn (the pieces left behind), score, then despawn. Order matters: anything after despawn is writing to a corpse, so the rule stops there.
One thing telling another is emit and emitted: a bell that emits "ring" when pressed, a gate that listens for it and opens, lights that listen for the same name and come on. Every listener hears it — the bell does not name the gate, so a third thing that reacts is a new rule and no edit to the bell.
Scripts
For behaviour a rule cannot express: JavaScript, in a sandbox, with three hooks — onSpawn, onTick(dt) and onTrigger(event, other). In scope: self, world, getEntityByName and log. Nothing else is — no fetch, no Date, no Math.random — so a level somebody else wrote is a level you can open. The script API page lists everything a script can reach.
The platform that makes a level three-dimensional is four lines, and the shape of it is worth learning once: position is a function of the world clock rather than an accumulator, so two browsers that have been running for different lengths of time still draw it in the same place.
function onTick(dt) {
self.y = 3 + Math.sin(world.time * 0.8) * 2
}When to reach for one:anything that is "when X happens, do Y" is a rule — it fires immediately and shows as rows a panel can explain. A script is for computing a position, a distance, an angle, a cadence — or remembering something between frames. Properties are the memory: self.set('toB', 1) is visible in the inspector and saves with the document; a module-level variable would be neither.
Physics
Every thing answers two opposite questions, and the controls sit together because the questions do. Collides as is: does this stop other things. Physics is: does this get stopped. On, the thing becomes a body — it falls, lands, bounces off walls, and walking into it pushes it, with no rule and no script anywhere. All four combinations are useful: a coin you walk straight through that still falls to the floor is walk-through with physics on.
A push is not a hit, and the difference is most of how this feels. Walking into something moves it along in front of you at your pace and it stops when you stop — nothing is stored, so a touch cannot send it across the level. To make it roll on by itself you have to hit it: a dash, or a kick from a script.
gravity | A multiple of the world’s. 0 floats where you leave it; below zero rises, which is a balloon. |
bounce | How much speed comes back off a surface. 0 stops dead. |
mass | Divides every push. 1 is a football; 20 barely notices you. |
friction | How fast a roll dies on the ground. The one you will actually reach for. |
drag | The same, in the air. |
roll | Degrees it turns per cell travelled, so a ball does not look like it is skating. |
The player
Absent means the built-in dummy, and that is the common case — most levels want a person in them, not a paragraph about what a person is. Set a body to be something else: a kart, a bird, a tank. What somebody is holding is a blueprint on a socket, and what makes it a weapon is its properties — damage and range, read when the trigger is pulled. A blueprint with neither is just something you are carrying.
Give the body an ammoproperty and rounds are counted; leave it off and they are not. Ammo lives on the player rather than the gun, because an ammo box hands it to whoever walked in. Spawns and goals, the peep body, the level's own keys and a worked gun are on the player page.
Mode, marks, camera
Three things are true of the level rather than of whatever is selected. Mode is the preset — freestyle, deathmatch, football, parkour, shooter — plus what ends it. A preset the world cannot back up is greyed out with the reason beside it: football needs a goal at each end, parkour a start and a finish. Sides is who is against whom, a separate question — a deathmatch can be every player for themselves or two sides of four.
Marksare the facts about a level: where a side spawns, where red scores, where a run starts and finishes. They matter more than they look, because the document's claims are checked against them — a level saying "match" with fewer than two spawns is refused on load, by name. So a level can be perfect and still refuse to open, and the Document panel is where it tells you why.
Camera is where the world is watched from, and it is an input mode as much as a view — keys are read against wherever the camera calls forward. Follow is behind the body; side-on is a platformer; fixed is nailed to one spot, and left without angles it watches the player.
Trying it
Play takes a snapshot and opens it over the editor — no save, no session, no room. It is the one screen where looking at the thing costs nothing, and there is a phone-shaped toggle for how it feels under a thumb.
The Logkeeps everything the level said this run: a pickup collected, a script's log, a rule that refused. It collects whether or not the panel is open, so opening it shows what already happened rather than starting from the moment you wondered. A turret that quietly does nothing is the failure it exists to prevent.
Things that will catch you
| A flush target is unhittable | Architecture rasterises into the cells it mostly covers, so a target mounted flat against its own stand is swallowed by the stand’s cells — every shot lands on the post. Give it clearance. |
| A door is a gap | The same cell approximation from the other side: a modelled doorway rasterises shut. Leave a piece out of the wall run. |
| Distinct models are the cost | The renderer pays per distinct model, not per piece — four thousand walls of one kind are cheaper than forty of a hundred kinds. The Scene panel warns past a dozen. |
| Unnamed means unaddressable | A rule or a script can only find an entity by name. The Document panel counts the nameless. |
| A buried body never moves | A body standing inside something cannot move at all, and nothing says why. Its footprint is around its middle — if its bottom is under the floor, move it up, not down. |
Stuck on something this page does not answer? The showcase takes real games apart rule by rule — the shooter is the place to start.