Worlds and callbacks
A world names the host imports and guest exports of a component. Included worlds are expanded below. Each imported interface documents its own grants.
extension
Experimental developer contract; no WASI or ambient operating-system access.
Imports
- cinnabar:world-draw/drawing@0.2.0
- cinnabar:world-draw/masks@0.2.0
- cinnabar:world-draw/assets@0.2.0
- cinnabar:extension/terrain@0.1.0
- cinnabar:extension/player-state@0.1.0
- cinnabar:session/items@0.1.0
- cinnabar:extension/inventory@0.1.0
- cinnabar:extension/item-use@0.1.0
- cinnabar:extension/camera@0.1.0
- cinnabar:extension/hud@0.1.0
- cinnabar:extension/clock@0.1.0
- cinnabar:extension/facts@0.1.0
- cinnabar:extension/gameplay@0.1.0
- cinnabar:extension/render@0.1.0
- cinnabar:extension/presentation@0.1.0
- cinnabar:extension/panel@0.1.0
- cinnabar:extension/input@0.1.0
- cinnabar:extension/touch@0.1.0
- cinnabar:extension/environment@0.1.0
- cinnabar:extension/events@0.1.0
- cinnabar:extension/settings@0.1.0
- cinnabar:extension/budget@0.1.0
- cinnabar:extension/permissions@0.1.0
Exports
init
init: func();
Creates the initial retained UI state.
frame
frame: func();
Runs a frame transaction with frozen input, session and clock observations. The host may suspend it without refilling fuel; time only schedules work. Output publishes after successful post-return. Late input actions are dropped. Instances exporting decision handlers keep synchronous frame execution.
filtered-player-mod
Explicit opt-in player-mod world for generic action filtering. Existing player-mod components remain supported and do not claim filter ownership.
Imports
- cinnabar:server-experience/ui@1.5.0
- cinnabar:extension/screen@0.1.0
- cinnabar:session/items@0.1.0
- cinnabar:session/recipes@0.1.0
- cinnabar:world-draw/drawing@0.2.0
- cinnabar:world-draw/masks@0.2.0
- cinnabar:world-draw/assets@0.2.0
- cinnabar:extension/terrain@0.1.0
- cinnabar:extension/player-state@0.1.0
- cinnabar:extension/inventory@0.1.0
- cinnabar:extension/item-use@0.1.0
- cinnabar:extension/camera@0.1.0
- cinnabar:extension/hud@0.1.0
- cinnabar:extension/clock@0.1.0
- cinnabar:extension/facts@0.1.0
- cinnabar:extension/gameplay@0.1.0
- cinnabar:extension/render@0.1.0
- cinnabar:extension/presentation@0.1.0
- cinnabar:extension/panel@0.1.0
- cinnabar:extension/input@0.1.0
- cinnabar:extension/touch@0.1.0
- cinnabar:extension/environment@0.1.0
- cinnabar:extension/events@0.1.0
- cinnabar:extension/settings@0.1.0
- cinnabar:extension/budget@0.1.0
- cinnabar:extension/permissions@0.1.0
- cinnabar:extension/action-filter@0.1.0
data-source
What a data-changed reports as changed. Closed: changing it would refuse every built
data-changed, so a new kind of change arrives as a new optional export instead.
enum data-source {
items,
recipes,
}
| Member | Type | Description |
|---|---|---|
items | ||
recipes |
Exports
filter-actions
filter-actions: func(frame: action-frame) -> action-verdict;
Optional and explicitly exported by filtering modules; requires controls authority. The earliest active exporting module is the sole owner. Runs after ordinary frame callbacks, before gameplay, with independent ACTION_FILTER_FUEL from mod-api and no host-import calls. Called for transitions and every frame with a retained hold. No callback is needed for an idle physical hold. Suppressing a release retains its hold. Suppressing its following press joins that hold; accepting that press completes the outstanding release before a fresh press. Suppressing a fresh press blocks its gesture until release. Rejected repeats leave the existing hold intact. Native never creates a press without an observed source. Traps or invalid verdicts quarantine the module and complete retained releases; owner loss and input-authority interruptions do the same. Suppressed physical holds stay suppressed until release. No duration or filtering policy is imposed by the host.
Types: action-frame, action-verdict.
screen-changed
screen-changed: func(layout: option<screen-layout>);
A container screen opened, closed (none) or was laid out anew.
Types: screen-layout.
action
action: func(id: string, collection-index: option<u32>);
A primary press on an overlay or view control mapped to a declared action; the index is the control’s row in its nearest collection.
secondary-action
secondary-action: func(id: string, collection-index: option<u32>);
A secondary press (a right click) on a control that maps button.menu_secondary_select
to a declared action.
scrolled
scrolled: func(delta: f64, x: f64, y: f64, modifiers: modifiers);
The wheel turned delta notches (one per detent; a pixel-precise wheel reports its
pixels / 16) with the pointer at x, y in GUI units, over the overlay’s drawn area or
the view, with modifiers held. Positive scrolls down, towards the end.
Types: modifiers.
text-changed
text-changed: func(control: string, text: string);
The text of the edit box named control, a declared action, changed.
key
key: func(id: string, hovered: option<stack>, row: option<tuple<string, u32>>);
A declared key was pressed while a container screen or the view was up and no edit box
had focus. hovered is the vanilla slot’s stack under the pointer; row is the
collection name and index of the mod’s control under the pointer, overlay or view, by
the rule action uses (its nearest collection).
Types: stack.
data-changed
data-changed: func(sources: list<data-source>);
The listed session sources changed revision, each listed once. It gets the load fuel
budget, as does init of a component that exports it.
Types: data-source.
view-closed
view-closed: func();
The host closed the view (Escape, or the container closing), not the mod.
init
init: func();
Creates the initial retained UI state.
frame
frame: func();
Runs a frame transaction with frozen input, session and clock observations. The host may suspend it without refilling fuel; time only schedules work. Output publishes after successful post-return. Late input actions are dropped. Instances exporting decision handlers keep synchronous frame execution.
handled-player-mod
A personal component with the action filter, every event handler, and ordinary frame and
UI callbacks. A component needing fewer composes its own world from player-mod or
filtered-player-mod and the handler worlds it implements.
Imports
- cinnabar:server-experience/ui@1.5.0
- cinnabar:extension/screen@0.1.0
- cinnabar:session/items@0.1.0
- cinnabar:session/recipes@0.1.0
- cinnabar:world-draw/drawing@0.2.0
- cinnabar:world-draw/masks@0.2.0
- cinnabar:world-draw/assets@0.2.0
- cinnabar:extension/terrain@0.1.0
- cinnabar:extension/player-state@0.1.0
- cinnabar:extension/inventory@0.1.0
- cinnabar:extension/item-use@0.1.0
- cinnabar:extension/camera@0.1.0
- cinnabar:extension/hud@0.1.0
- cinnabar:extension/clock@0.1.0
- cinnabar:extension/facts@0.1.0
- cinnabar:extension/gameplay@0.1.0
- cinnabar:extension/render@0.1.0
- cinnabar:extension/presentation@0.1.0
- cinnabar:extension/panel@0.1.0
- cinnabar:extension/input@0.1.0
- cinnabar:extension/touch@0.1.0
- cinnabar:extension/environment@0.1.0
- cinnabar:extension/events@0.1.0
- cinnabar:extension/settings@0.1.0
- cinnabar:extension/budget@0.1.0
- cinnabar:extension/permissions@0.1.0
- cinnabar:extension/action-filter@0.1.0
- cinnabar:extension/sound-handling@0.1.0
- cinnabar:extension/teleport-handling@0.1.0
data-source
What a data-changed reports as changed. Closed: changing it would refuse every built
data-changed, so a new kind of change arrives as a new optional export instead.
enum data-source {
items,
recipes,
}
| Member | Type | Description |
|---|---|---|
items | ||
recipes |
Exports
filter-actions
filter-actions: func(frame: action-frame) -> action-verdict;
Optional and explicitly exported by filtering modules; requires controls authority. The earliest active exporting module is the sole owner. Runs after ordinary frame callbacks, before gameplay, with independent ACTION_FILTER_FUEL from mod-api and no host-import calls. Called for transitions and every frame with a retained hold. No callback is needed for an idle physical hold. Suppressing a release retains its hold. Suppressing its following press joins that hold; accepting that press completes the outstanding release before a fresh press. Suppressing a fresh press blocks its gesture until release. Rejected repeats leave the existing hold intact. Native never creates a press without an observed source. Traps or invalid verdicts quarantine the module and complete retained releases; owner loss and input-authority interruptions do the same. Suppressed physical holds stay suppressed until release. No duration or filtering policy is imposed by the host.
Types: action-frame, action-verdict.
screen-changed
screen-changed: func(layout: option<screen-layout>);
A container screen opened, closed (none) or was laid out anew.
Types: screen-layout.
action
action: func(id: string, collection-index: option<u32>);
A primary press on an overlay or view control mapped to a declared action; the index is the control’s row in its nearest collection.
secondary-action
secondary-action: func(id: string, collection-index: option<u32>);
A secondary press (a right click) on a control that maps button.menu_secondary_select
to a declared action.
scrolled
scrolled: func(delta: f64, x: f64, y: f64, modifiers: modifiers);
The wheel turned delta notches (one per detent; a pixel-precise wheel reports its
pixels / 16) with the pointer at x, y in GUI units, over the overlay’s drawn area or
the view, with modifiers held. Positive scrolls down, towards the end.
Types: modifiers.
text-changed
text-changed: func(control: string, text: string);
The text of the edit box named control, a declared action, changed.
key
key: func(id: string, hovered: option<stack>, row: option<tuple<string, u32>>);
A declared key was pressed while a container screen or the view was up and no edit box
had focus. hovered is the vanilla slot’s stack under the pointer; row is the
collection name and index of the mod’s control under the pointer, overlay or view, by
the rule action uses (its nearest collection).
Types: stack.
data-changed
data-changed: func(sources: list<data-source>);
The listed session sources changed revision, each listed once. It gets the load fuel
budget, as does init of a component that exports it.
Types: data-source.
view-closed
view-closed: func();
The host closed the view (Escape, or the container closing), not the mod.
init
init: func();
Creates the initial retained UI state.
frame
frame: func();
Runs a frame transaction with frozen input, session and clock observations. The host may suspend it without refilling fuel; time only schedules work. Output publishes after successful post-return. Late input actions are dropped. Instances exporting decision handlers keep synchronous frame execution.
handle-sound
handle-sound: func(ctx: sound-context) -> sound-context;
One call per new playback request, at most 256 per audio frame; excess and oversized requests play unhandled. Approved starts waiting for decoding are not offered again. Playing voices are not retroactively stopped; managed loops are offered again when they next need a start.
Types: sound-context.
handle-teleport
handle-teleport: func(ctx: teleport-context) -> teleport-context;
One call per committed local-player MovePlayer with a finite rotation, before it applies.
The server’s rotation is reported as sent, even outside -90..90 pitch. Returning the
incoming rotation is always valid; a replacement must be finite with pitch in -90..90.
Types: teleport-context.
packet-mod
A trusted mod that relays every session packet. It needs the packets grant; WASI preview 2
is linked only with the wasi grant, without files, environment, arguments or network.
Imports
Exports
start
start: func(identity: session-identity, client-data: string, startup: list<u8>) -> result<list<session-pack>, string>;
Begins a session: the upstream identity, the login client data as the session’s Connect sent it (JSON), and the server’s startup packets through StartGame as one batch body. Returns the resource packs the mod adds.
Types: session-identity, session-pack.
on-batch
on-batch: func(direction: direction, batch: list<u8>) -> result<option<list<u8>>, string>;
Handles one relayed batch: none forwards it unchanged; some replaces it, and an empty body drops it.
Types: direction.
tick
tick: func() -> result<outbound, string>;
Runs timed work about once per client tick (50 ms) and returns packets to send now.
Types: outbound.
stop
stop: func();
Ends the session.
player-mod
extension plus screens beside the container screens, the session’s read-only items and
recipes, declared keys and event callbacks. A mod package (mod.toml) targets this world.
Every event export is optional: the host type-checks each one a component exports, refusing
one of another signature, and never calls one it lacks. New events arrive as new exports, so
a built component keeps working. init and frame stay required.
Imports
- cinnabar:server-experience/ui@1.5.0
- cinnabar:extension/screen@0.1.0
- cinnabar:session/items@0.1.0
- cinnabar:session/recipes@0.1.0
- cinnabar:world-draw/drawing@0.2.0
- cinnabar:world-draw/masks@0.2.0
- cinnabar:world-draw/assets@0.2.0
- cinnabar:extension/terrain@0.1.0
- cinnabar:extension/player-state@0.1.0
- cinnabar:extension/inventory@0.1.0
- cinnabar:extension/item-use@0.1.0
- cinnabar:extension/camera@0.1.0
- cinnabar:extension/hud@0.1.0
- cinnabar:extension/clock@0.1.0
- cinnabar:extension/facts@0.1.0
- cinnabar:extension/gameplay@0.1.0
- cinnabar:extension/render@0.1.0
- cinnabar:extension/presentation@0.1.0
- cinnabar:extension/panel@0.1.0
- cinnabar:extension/input@0.1.0
- cinnabar:extension/touch@0.1.0
- cinnabar:extension/environment@0.1.0
- cinnabar:extension/events@0.1.0
- cinnabar:extension/settings@0.1.0
- cinnabar:extension/budget@0.1.0
- cinnabar:extension/permissions@0.1.0
data-source
What a data-changed reports as changed. Closed: changing it would refuse every built
data-changed, so a new kind of change arrives as a new optional export instead.
enum data-source {
items,
recipes,
}
| Member | Type | Description |
|---|---|---|
items | ||
recipes |
Exports
screen-changed
screen-changed: func(layout: option<screen-layout>);
A container screen opened, closed (none) or was laid out anew.
Types: screen-layout.
action
action: func(id: string, collection-index: option<u32>);
A primary press on an overlay or view control mapped to a declared action; the index is the control’s row in its nearest collection.
secondary-action
secondary-action: func(id: string, collection-index: option<u32>);
A secondary press (a right click) on a control that maps button.menu_secondary_select
to a declared action.
scrolled
scrolled: func(delta: f64, x: f64, y: f64, modifiers: modifiers);
The wheel turned delta notches (one per detent; a pixel-precise wheel reports its
pixels / 16) with the pointer at x, y in GUI units, over the overlay’s drawn area or
the view, with modifiers held. Positive scrolls down, towards the end.
Types: modifiers.
text-changed
text-changed: func(control: string, text: string);
The text of the edit box named control, a declared action, changed.
key
key: func(id: string, hovered: option<stack>, row: option<tuple<string, u32>>);
A declared key was pressed while a container screen or the view was up and no edit box
had focus. hovered is the vanilla slot’s stack under the pointer; row is the
collection name and index of the mod’s control under the pointer, overlay or view, by
the rule action uses (its nearest collection).
Types: stack.
data-changed
data-changed: func(sources: list<data-source>);
The listed session sources changed revision, each listed once. It gets the load fuel
budget, as does init of a component that exports it.
Types: data-source.
view-closed
view-closed: func();
The host closed the view (Escape, or the container closing), not the mod.
init
init: func();
Creates the initial retained UI state.
frame
frame: func();
Runs a frame transaction with frozen input, session and clock observations. The host may suspend it without refilling fuel; time only schedules work. Output publishes after successful post-return. Late input actions are dropped. Instances exporting decision handlers keep synchronous frame execution.
server-bundle
Server-scoped component; optional grants return denial through these imports. A component built against an earlier 1.x (imports at that version, exporting only the callbacks it had) still runs.
Imports
- cinnabar:server-experience/ui@1.5.0
- cinnabar:server-experience/input@1.5.0
- cinnabar:server-experience/messaging@1.5.0
- cinnabar:server-experience/scene@1.5.0
- cinnabar:server-experience/media@1.5.0
- cinnabar:session/items@0.1.0
- cinnabar:world-draw/drawing@0.2.0
- cinnabar:world-draw/masks@0.2.0
- cinnabar:extension/gameplay@0.1.0
- cinnabar:extension/render@0.1.0
- cinnabar:extension/environment@0.1.0
- cinnabar:world-draw/assets@0.2.0
Exports
init
init: func();
Initializes this instance after its signed bundle and capabilities have been admitted.
frame
frame: func();
Runs when the host admits a presentation frame; older components may omit it.
dispatch
dispatch: func(channel: string, record-json: list<u8>);
A typed message or host-owned input edge; no raw packet or keyboard data.
action
action: func(id: string, collection-index: option<u32>);
A declared action fired from a modal screen control while the modal has focus; the index is the control’s row in its nearest collection.
epoch
epoch: func();
The logical world epoch changed (a world notice or dimension change); the runtime and its state live on.
modal-resized
modal-resized: func(size: gui-size);
The open modal was first drawn, or its size changed (a window resize or a GUI scale
change); size is what ui.modal-size now returns.
Types: gui-size.
text-changed
text-changed: func(control: string, text: string);
The text of the modal’s edit box whose text_box_name is control changed while the
modal had focus; control is a declared action. Text ends editing like vanilla’s
text_edit_box: Enter or Escape deselects the box, and Escape closes the modal only
when no box was selected.
secondary-action
secondary-action: func(id: string, collection-index: option<u32>);
A secondary press (a right click) on a modal screen control that maps
button.menu_secondary_select to a declared action fired, while the modal has focus; the
index is the control’s row in its nearest collection. action stays the primary press.
scroll-changed
scroll-changed: func(view: string, range: scroll-range);
The open modal’s scroll view whose scroll_view_name is view, a declared action, now
shows range: it scrolled, or its viewport or content changed length. Changes coalesce,
so this is the latest range, not each step of a scroll.
Types: scroll-range.
shift-changed
shift-changed: func(held: bool);
Shift was pressed or released while the modal had focus, or the modal gained or lost
focus with Shift held: held is whether it is held now. A screen can show what it shows
on Shift, as Java screens’ hasShiftDown does.
sound-handler
The optional event handlers. Each receives a context of the event’s facts and changeable values and returns it; the host applies only the changeable values. Handlers run in load order, each receiving the previous handler’s changes. They cannot call host imports and each call has full callback fuel within a shared per-event allowance; handlers without a full allowance are skipped. Denial and absence pass the event through unchanged. Traps and invalid values quarantine the component and keep the context it received. A component exporting a handler world must implement every handler in it; include only the handlers a component uses.
Imports
Exports
handle-sound
handle-sound: func(ctx: sound-context) -> sound-context;
One call per new playback request, at most 256 per audio frame; excess and oversized requests play unhandled. Approved starts waiting for decoding are not offered again. Playing voices are not retroactively stopped; managed loops are offered again when they next need a start.
Types: sound-context.
teleport-handler
See sound-handler for the shared handler contract.
Imports
Exports
handle-teleport
handle-teleport: func(ctx: teleport-context) -> teleport-context;
One call per committed local-player MovePlayer with a finite rotation, before it applies.
The server’s rotation is reported as sent, even outside -90..90 pitch. Returning the
incoming rotation is always valid; a replacement must be finite with pitch in -90..90.
Types: teleport-context.