Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

Exports

init

init: func();

Creates the initial retained UI state.

frame

frame: func();

Bounded frame callback used to measure the spike’s crossing cost.

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

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,
}
MemberTypeDescription
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 fuel 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();

Bounded frame callback used to measure the spike’s crossing cost.

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

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,
}
MemberTypeDescription
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();

Bounded frame callback used to measure the spike’s crossing cost.

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

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: 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.