Where things go
The frozen engine, the wire, and the one home every new thing has.
The engine, rows and kinds, prefabs and scene files, and the wire between the engine and a game are finished. Everything a game adds goes into one of the homes below and changes none of them.
The engine is frozen
Nothing in engine/ is edited, for a feature, a game or a test. The engine names nothing outside itself: no game, kind, field, plugin or addon. A feature that was fully built as a plugin or an addon and could not work there, because every way left would send a seat data it must not have, goes to Patchwork as an issue on its GitHub repo.
The wire
- scenemanager is in every game: many truths, a seat on one of them at a time, and the seat moved between them. Its plugin is the one plugin that connects a page to its scene.
- A transport carries packets and messages between two ends and knows nothing about scenes or seats. loopback joins a page and its server in one process, with a simulated bad network when given one; socket is a WebSocket between two processes. A new way to travel, WebRTC for example, is a new transport addon.
- Nothing else carries a packet.
Row or local
For anything a game holds, ask whether every seat has to agree on it or only this page feels it.
- A row holds what every seat must agree on and the server decides: positions, health, ammo, score, who hit whom. The thing a seat plays as is that seat's own
playerrow. Every seat is sent everyplayerrow; a field only its own seat may read is listed insecurity. - Local state is what only this page needs: the camera, screen shake, a menu cursor, a HUD flash, the volume or rebound keys. It never goes up the wire and no rule reads it. It lives in the actor or plugin that draws it, or in the store when it must outlive a scene. The feedback for the seat's own press is read off its own
playerrow. - What another seat does is read off rows, since only the server knows it happened.
The pages
| Page | What it runs |
|---|---|
index.html | The truth in this tab over a loopback, stepped by the page's clock, with no prediction and no lag. |
client.html | One seat on <game>.server.ts over a socket. Every scene a seat plays in sets world.predict, so the page runs it ahead of the server. |
dev.html | The game's own testbed: any readout, any number of seats, any scene entered and any value overridden in its own copy before the boot. |
index.html and client.html are the same in every game except the files they import. A cpu driver, a network panel or a readout goes in dev.html.
Every new thing has one home
Ask in this order. The first yes is the home.
- A value (a number, colour, size, rate, list or starting setting). If it changes while the game runs, its starting value is a field of its kind's prefab in the scene file. If it never changes, it is the kind's definition, its entry in a data file the scene names. A scene's own few numbers are fields of its
world. A level or other large data is a file of its own in the game'sassets/. A plugin's fixed numbers areworld.<plugin>. Where a seat starts is astartactor, oneactorsentry per slot. - A value only the page uses (volume, brightness, a theme, rebound keys): a key of the store.
- One game's rule, or how one of its things is drawn: an actor in that game's folder,
<kind>.sim.tsfor the rule and<kind>.client.tsfor the drawing. Something used by one game only, shared by several of its kinds, or a system of that game's (its level, its HUD): a plugin or addon of the game's own, ingames/<game>/plugins/<name>/orgames/<game>/addons/<name>/. - Used by a second game, and living in the world or the browser (rows, the step, drawing, input, camera, sound, UI): a top-level plugin in
plugins/, moved up from the game that had it. - Used by a second game, and holding a truth (seats, connections, sockets, files, timers, more than one truth, what a packet carries): a top-level addon in
addons/.
Who uses a thing decides whether it is top-level, not whether it could be described without naming a game.
What each home may do
| Home | May do |
|---|---|
| Scene file | Holds data. Every number a game has is in it or in a data file it names. |
| Files | Every file a game uses is an entry in its scene's asset catalogue, or named by one, and is read through the loader only. |
| Store | Belongs to the page. The server never reads it, writes it or is sent it. |
| Actor | Reads changing values off its row and fixed ones off its definition and world, and writes no number of its own. Anything it remembers between steps is a field on its row. Its rules run in before, tick, after and its acts. It uses plugins and never imports another actor. A new system is a new kind. |
| Plugin | Names no game or game kind (a game's own plugin may name that game's kinds). Has a row only when its server half has changing state. A plugin it is built on is handed to it, never imported. It never imports from games/. |
| Mod | How one plugin gives another what it knows: plugin a writes <a>.<p>.ts, and a scene switches it on with world.<p>.mods. |
| Input | player binds a seat with bind, straight to keys, or control, to named actions a player may rebind. |
| Ledger | A row that only appends events for the page to play or draw once. |
| Addon | Takes a truth, runs where the truth is, and knows no game or kind (a game's own addon may know that game's). It never imports from games/. |
| Page | Mounts things. No rule, number, readout, listener or scene name. dev.html is the exception. |
Names
- A file in a game folder is named after a kind, a scene or the game. The browser loads a row's actor by its kind's name, so a file with any other name is never loaded.
assets/holds the game's data files and art, and beside them the scripts they are made from.- A kind is never named after its game, a scene or a plugin.
- A test sits beside the file it tests and is named after it.
When something is missing
Build it in its home: in the game that needs it, set from the scene file and tested. It moves to plugins/ or addons/ when a second game needs it. A plugin does not get a setting only one game would set; that setting is the game's actor.
The work, page by page
| Page | The work |
|---|---|
| Starting a game | A new game, from yarn new-game to the first thing of its own playing. |
| Designing a kind | A thing with rules, and things acting on each other. |
| Designing a seat | The player row is the thing the seat plays as, never a row it spawns. |
| Input and seats | How a player controls the game: seats, starts, presses and ledgers. |
| Building a controls screen | The screen where a player sees and rebinds the controls. |
| Building a level | The place a game is played in. |
| Bringing in art | Pictures, sheets, models and files into a game and drawn. |
| Writing the look | How a game looks, in 2D or 3D. |
| Scene flow | More than one scene: titles, menus, levels and game over. |
| Building a cutscene intro | An intro that films the entry scene's own kinds, then lands on the title. |
| Session flow | The loop around play: a menu, a choice, joining, respawn, results and a fresh round. |
| Building the HUD | What is drawn over the game. |
| Sound | Sound and music. |
| Tuning feel | Movement, physics, cameras, and the numbers that make them feel right. |
| 3D physics | box3d, box3dvehicle, walker, hitscan3d, volley3d, flight3d, ragdoll3d, interact and cover3d, and which mods make a thing solid, stood on or hit in each. |
| Smooth gameplay | Drawing between steps, a teleport, and anything that slides, streaks, judders or pops on screen. |
| Building a plugin | A plugin, an addon or a mod, top-level or a game's own. |
| Proving a game | Tests, bots, the simulator, replay, and playing it. |
| Porting a game | A game that exists elsewhere, brought into Patchwork. |
| Auditing a game | A game checked against every rule on this page and moved into its homes. |
| Going multiplayer | Playing with other people over a network. |
| Persisting players | Who a player is, and what is kept for them. |
| Shipping a game | Getting a game to people, and keeping its repo alongside Patchwork. |