server-api
Functions
Section titled “Functions”| Function | Summary |
|---|---|
init |
|
on-player-join |
|
on-player-leave |
|
handle-rpc |
|
update |
Fixed-rate server tick. |
on-interact |
A player used (pressed interact on) one of this mod’s interactable entities. |
on-signal |
A signal arrived on a channel this mod subscribed to. source is the emitting mod’s addon id, stamped by the host — unforgeable, so policy (“only the gamemode commands me”, “facts only from the protocol owner”) is one comparison. |
on-contact |
Physical touch on one of this mod’s contact entities (archetypes declaring contact = true), for entities this mod named via identify — target is that id in the mod’s own scope. |
init: async func();Undocumented in the WIT.
on-player-join
Section titled “on-player-join”on-player-join: async func(player-id: string);Undocumented in the WIT.
on-player-leave
Section titled “on-player-leave”on-player-leave: async func(player-id: string);Undocumented in the WIT.
handle-rpc
Section titled “handle-rpc”handle-rpc: async func(player-id: string, method: string, args: list<u8>) -> result<list<u8>, string>;Undocumented in the WIT.
update
Section titled “update”update: async func(dt: f32);Fixed-rate server tick. The server realm has no render frames (a headless server
renders nothing), so periodic mod logic runs on a fixed cadence, not per frame.
dt is the seconds since the previous update, so motion stays rate-independent.
The host dispatches this to every loaded server-mod and does NOT wait for it: a
slow update is skipped until it finishes, and never stalls the simulation.
on-interact
Section titled “on-interact”on-interact: async func(player-id: string, target: string, hit-point: vec3, distance: f32);A player used (pressed interact on) one of this mod’s interactable entities.
The host raycasts authoritatively from the player’s body and routes the hit
to the archetype owner’s mod — only archetypes declaring interact = true
arrive here, and only for entities this mod named via identify. target
is that id in the mod’s own scope, so it feeds straight into entity.find.
hit-point is where the use-ray struck, in world space — on a multi-part
entity it tells WHICH part was pressed; distance is from the presser’s
body to that point, the same measure the host’s reach limit enforces.
on-signal
Section titled “on-signal”on-signal: async func(channel: string, source: string, payload: list<u8>);A signal arrived on a channel this mod subscribed to. source
is the emitting mod’s addon id, stamped by the host — unforgeable, so
policy (“only the gamemode commands me”, “facts only from the protocol
owner”) is one comparison. The payload carries everything the handler
needs: a signal does not synchronize with the emitter’s queued entity
verbs, so “hear signal, then read the world” is an anti-pattern.
on-contact
Section titled “on-contact”on-contact: async func(target: string, other: contact-party, point: vec3, edge: contact-edge);Physical touch on one of this mod’s contact entities (archetypes declaring
contact = true), for entities this mod named via identify —
target is that id in the mod’s own scope. When both parties are contact
entities, each owner hears about its own. point is where the touch sits
in world space (on ended — where the other party separated to).
record vec3 { x: f32, y: f32, z: f32,}Defined locally: this wit-parser rejects cross-interface use (same reason
map-api carries its own copy).
contact-party
Section titled “contact-party”variant contact-party { player(string), entity(string), map-geometry,}What physically touched one of this mod’s contact entities — instance-exact, so “react only to THIS player / THAT balloon” is one comparison in the handler.
contact-edge
Section titled “contact-edge”enum contact-edge { started, ended }Which side of a touch interval this event marks. Only the edges cross the boundary — never per-frame contact data; a mod that needs “while touching” holds the interval between the two.