Real-time simulation
A step beyond replicated state: a physics simulation the platform runs deterministically in a Worker, so a fast-twitch game stays in sync without you writing netcode. It rides the same connection as the rest of TipTap.net — rooms, state, turns and chat behave identically whether or not you use it.
| tier | what you write | where it stands |
|---|---|---|
| Modules | A fixed menu of four platform-authored simulations. You pick one and configure it; the physics, the tick and the netcode are ours. | Shippable today. Declarable in Creator Studio, refereed by the relay, and the tier every simulation game here runs on. |
| Creator logic | A simulation you write. One TypeScript file, compiled server-side to WebAssembly and checked for determinism rather than trusted to be deterministic. | Preview — in Labs. It compiles, gates and runs, but you cannot publish a game on it yet. Read about it. |
Which should you build on now? Modules. If the genre you want is on the menu below, take it. If it is not, the honest answer is that this platform cannot host your game yet — creator logic is where that changes, and it is worth reading, not worth blocking on.
Four modules ship, and a game declares exactly one. arena2d — top-down 60 Hz, circular bodies, walls, projectiles, resources and respawns, for arenas and shooters. turnphysics — one actor at a time simulated to rest, for pool, golf and artillery; no prediction, which makes it the most forgiving of a bad connection. platformer2d — tilemaps, gravity, one-ways, coyote time, wall jump, and kinematic moving platforms a rider inherits correctly inside prediction. racer — vehicle bodies, a tire model, spline tracks, checkpoints and laps, with correction smoothing tuned so a contested overtake does not spin the car, and the only module that will drive its own empty seats.
Turn it on in Creator Studio under Advanced → Multiplayer SDK. Declaring an unknown or unbuilt name is refused by name and tells you what you may declare instead.
There is no 3D. arena3d is named in the spec as the flagship first-person module and it is not built; declaring it is refused. Neither physics (general rigid bodies) nor fighter exists either. If you were asked for a 3D shooter, you cannot build one here — say so rather than shipping a 2D game that pretends.
Two more limits worth knowing. Play again currently reloads the game document — a simulation session cannot span two matches. And sim.query resolves on the host and travels, so it is authoritative but not free; poll it at a rate you have measured and pass { timeoutMs } rather than relying on the five-second default.
A room’s seats are its ceiling, not its attendance. Every module lays out one body per seat, so two people matched into an eight-seat room get eight bodies and nobody is driving six of them — a row of parked cars on a racing grid.
racer can fill them: config.botSeats is a bitmask of the seats the module drives with its own autopilot, and config.botStartTick holds them until your countdown is over. Build the mask from net.peerAtSeat(i) === null immediately before sim.define. The other three modules have no autopilot.
A dev session never gets a simulation. A room opened against a dev-session grant is served at relay tier deliberately, whatever the game declares — so TipTap.sim is injected, every call queues, and each settles as simulation unavailable about fifteen seconds later. The same is true of a file you open yourself. Expected, not broken — worth knowing before an evening on the wrong theory.
What follows is the shape the tier has. Nothing in the game document simulates anything — the simulation is WebAssembly in a Worker the platform owns, and the game supplies geometry once and intent every frame. Design it gently or the netcode gets blamed for the design: slow time-to-kill, generous hitboxes, a small map, short rounds.

