The boundary today
Every limit below is a limit of the engine as it stands, not of your approach. Each is cheap to hit and expensive to discover halfway through a build, so each one also says what does work instead — and, where something is planned, points at the one place promises live: the roadmap.
Hosting
Section titled “Hosting”No dedicated server
Section titled “No dedicated server”Hosting means running the game as the host. The session ends when you leave, so you cannot start one on a machine and leave it running.
Instead: host from the game, with --become-host. Your configuration survives: an
instance is described by config/server.toml, and a dedicated server changes which
process reads that file, not the file — see Configuration.
Dedicated servers are committed → Roadmap.
The mod surface
Section titled “The mod surface”No shooting, and no hitting a player with a ray
Section titled “No shooting, and no hitting a player with a ray”spatial::raycast deliberately excludes character bodies. Rays see map geometry and
the collision proxies of archetypes flagged interact or contact — never a player.
There is also no health anywhere in the engine.
So: no hitscan weapons, no melee that resolves against a player, no deathmatch.
Instead: a ray toward a player’s position tells you whether the map occludes them
— enough for line of sight, hide-and-seek and vision cones; the watchman reference
mod is built on exactly that. And a shape probe is not a ray: spatial::intersections
reports every participant the probe touches, by session id — presence in a volume,
not a hit point.
Proximity, not player-to-player touch
Section titled “Proximity, not player-to-player touch”Contact events fire for archetypes you flagged, and tell you which participant touched one of them. There is no player-to-player contact event, because neither party is a flagged entity.
Instead: ask spatial::intersections with a probe around a point — every
participant it catches comes back by session id, which is what a tag zone needs. For
distances, the bundled freeroam gamemode publishes a player-positions fact over the
signal bus, and the watchman reference mod ranges on exactly that.
Elimination has no spectator
Section titled “Elimination has no spectator”There is one camera and it is a child of the body, so a player without a body sees black rather than the world. A gamemode that spawned the body may despawn it — nothing stops you leaving a player with nothing to look through.
Instead: “eliminated” has to mean moved. Teleport them to a pen, a balcony, a jail. It plays better anyway, because they can watch and heckle.
UI is one line of text
Section titled “UI is one line of text”The whole client-side presentation surface is ui::set-overlay-text. No panels, no
images, no layout, no input widgets.
Instead: a scoreboard is a formatted string. A real UI surface is intended → Roadmap.
No items, no attachments
Section titled “No items, no attachments”There is no inventory, no held item, and no way to attach one entity to another.
Instead: a “carried” object is one you move to follow its owner each tick.
Nothing a mod writes survives the session
Section titled “Nothing a mod writes survives the session”There is no storage of any kind. When the session ends, everything your mod knew is gone — scores, unlocks, who built what, where they left it.
Instead: there is no workaround. A mod cannot reach a file or a network, so nothing can be smuggled out. Build things that are true for one session. Persistence is intended, and its shape is stated once, on the roadmap.
No personas
Section titled “No personas”A player, their account and their body are currently one and the same thing. One account, one character, one body, always — so no character selection, no alt characters, and no permadeath that costs a character rather than an account.
The contract already carries the split: a mod can ask a player for its profile — the server-local persona — today, and the answer is none for everyone, so a mod written now keys correctly when personas arrive.
Instead: treat the player as the character. It is the only shape available. Personas are intended → Roadmap.
Sound is one-shots only
Section titled “Sound is one-shots only”You can ship a sound and play it at a volume you choose, and every listener hears it the same wherever they stand → Sound.
What does not exist is sound that has a place: a source anchored to an entity, audible by distance, still playing when someone joins halfway through. Nor looping or continuous sound of any kind, nor voice from a mod.
Instead: one-shots keyed to things that happen. A press, an impact, a pickup.
No timers, no scheduling, no randomness
Section titled “No timers, no scheduling, no randomness”Your tick receives a delta, and every hook’s context carries two tick numbers:
raised-at, the tick the event happened on, and now, the tick the handler runs on.
That is the whole time surface — you cannot ask for the wall clock, ask to be called
back later, or get a random number from the host.
Instead: accumulate the delta yourself for anything time-based, and count in
ticks where ordering matters — raised-at is the tick, so two events sort without
any clock. For randomness, seed a generator inside your own mod; just be aware that
nothing makes it agree with any other peer.
The map answers one question
Section titled “The map answers one question”You can ask a loaded map for its spawn points. That is the whole surface.
There are no zones, no lookup of entities the map declares by name, no surface tags on a raycast hit, no navmesh or pathfinding, no reading or overriding gravity, fog or sky.
Instead: put your own geometry in the world as archetypes and use contact events and spatial queries against those.
The structural hooks are declared, and unfired
Section titled “The structural hooks are declared, and unfired”The contract declares a set of structural hooks — an entity spawned, a map loaded, a body requested — each answering allow or deny. They are declared so a mod can already export them, and unfired: the mechanism that orders mods and acts on the verdicts does not exist yet, so today a mod observes other mods and does not take part in their decisions.
Instead: cooperate by convention over signals and requests, and accept that the mod that owns a behaviour has the last word on it. Composition hooks are intended → Roadmap.
You cannot ask whether a handle is still good
Section titled “You cannot ask whether a handle is still good”There is no way to test an entity handle for validity. A handle to something despawned fails when you use it.
Instead: give your entities ids with set-id and fetch them with by-id each
time, rather than holding a handle across ticks.
Cross-mod reach is identity and bytes, not handles
Section titled “Cross-mod reach is identity and bytes, not handles”You cannot get a handle to another mod’s entity. find and by-id are scoped to your
own ids, a ray that hits a foreign entity reports geometry without a handle, and an
intersections probe names a foreign entity by its full id — still no handle. Mods
cooperate by exchanging payloads over signals and
requests.
This one is a deliberate boundary rather than a gap, and it is not going to be lifted: a handle is permission to mutate.
What this leaves
Section titled “What this leaves”More than it sounds: race and parkour courses, king-of-the-hill, tag and infection, hide-and-seek with real occlusion, red-light/green-light, floor-is-lava, puzzle rooms, trigger-driven traps — anything built from moving props, per-player text and the keys you bind.
The common shape is: watch positions, move things, recolour things, tell people what happened.