manifold:client 0.1.0
Contract reference · Payloads · contract.json (crates/manifold-wasm-abi/wit/contract.json)
Status: legacy contract 0.1: linked by the mod’s [caps] until migration steps M2 and M3 move its interfaces into the contract packages.
client-plugin WIT world — DISJOINT from manifold:game.
SECURITY BOUNDARY: this world is the fail-closed surface for untrusted, client-only wasm plugins. It deliberately names NO server-side interface (no asset-source, no resource-bundle, no persistent-storage, no game ui, no plugin, no logging). A guest compiled against this world literally cannot name or call any capability absent from this file. The separation is structural, not just policy.
| Interface | Kind |
|---|---|
action | import |
client-clock | import |
client-state-read | import |
draw | export |
hud-catalog | import |
hud-layout | import |
hud-reskin | import |
Interface action
import · since 0.1.0
One-way command submission. The host validates the postcard PluginCommand against the plugin’s declared allowlist before applying it. Returns true if the command was accepted and enqueued, false if rejected.
Functions
submit-command
submit-command: func(command: list<u8>) -> bool
command: schema payloadplugin-command.
Interface client-clock
import · since 0.1.0
Minimal clock always linked by the host (no capability gate required). All other imports are gated by declared capability at load time.
Functions
now-millis
now-millis: func() -> u64
Interface client-state-read
import · since 0.1.0
Read-only window into curated client state. Returns postcard-encoded ReadValue bytes, or none if the value-id was not granted to this plugin in its declared capability set.
Functions
read-value
read-value: func(value-id: u32) -> option<list<u8>>
result: schema payloadread-value.
Interface draw
export · since 0.1.0
Guest-exported lifecycle interface. The host calls these to drive the client-plugin frame loop and interaction handling.
Functions
build
build: func(overlay-id: u64) -> result<list<u8>, plugin-error>
Called each frame (or on dirty) for the given overlay-id. Returns a postcard-encoded UiStateMap built from curated reads.
result: schema payloadui-state-map.
handle-interaction
handle-interaction: func(overlay-id: u64, event: list<u8>) -> result<option<list<u8>>, plugin-error>
Called when the player interacts with this plugin’s overlay. event is a postcard-encoded UiEvent. On success, optionally returns a postcard-encoded PluginCommand to submit via the action interface.
event: schema payloadui-event.result: schema payloadplugin-command.
plugin-manifest
plugin-manifest: func() -> list<u8>
Called once at load. Returns postcard-encoded PluginUiRegistration describing the overlays, value-id reads, and command types this plugin declares. The host uses this to gate the capability surface.
result: schema payloadplugin-ui-registration.
Types
plugin-error (record)
Error returned when a draw or interaction call fails gracefully.
| Field | Type | About |
|---|---|---|
message | string |
Interface hud-catalog
import · since 0.1.0
C2b-a: Static catalog of hookable HUD layers + their policies. Linked when EITHER HudReskin or HudLayout capability is declared. Returns only manifest config (layer keys + HookPolicy) — no player state, no resolved values. A plugin with neither HUD cap has a world byte-identical to a C2a plugin and cannot name this interface.
Functions
enumerate-hookable-layers
enumerate-hookable-layers: func() -> list<u8>
Returns postcard-encoded Vec<(SmolStr, HookPolicy)>: layer key + policy pairs for every hookable HUD layer in declaration order.
result: schema payloadhud-layer-policies.
Interface hud-layout
import · since 0.1.0
C2b-a: Submit move/hide transforms for built-in HUD layers. Linked iff caps.hud_layout.
Functions
apply-layout
apply-layout: func(ops: list<u8>) -> u32
Replaces this plugin’s entire layout set. Returns accepted transform count. Same fail-soft rejection semantics as apply-reskin.
ops: schema payloadlayout-transforms.
Interface hud-reskin
import · since 0.1.0
C2b-a: Submit reskin (theme-token override) transforms for built-in HUD layers. Linked iff caps.hud_reskin. Cannot name Move or explicit Hide — those require hud-layout. A reskin transform CAN still conceal via alpha-0/color-match/ font-0; concealment-resistance is the per-layer HookPolicy’s job, not this capability split.
Functions
apply-reskin
apply-reskin: func(transforms: list<u8>) -> u32
Replaces this plugin’s entire reskin set. Returns accepted transform count. Entries that violate the target layer’s HookPolicy, target unknown layers, or exceed structural caps are dropped and logged host-side; the rest are stored. A wholly-rejected submission does not quarantine the plugin.
transforms: schema payloadreskin-transforms.
World client-plugin
Client-plugin world: the complete, bounded capability surface for untrusted client-only wasm plugins. Nothing outside this world is reachable.
C2b-a HUD interfaces are linked per-cap (fail-closed, same pattern as client-state-read / action): hud-catalog — iff (caps.hud_reskin || caps.hud_layout) hud-reskin — iff caps.hud_reskin hud-layout — iff caps.hud_layout A plugin declaring neither HUD cap has a world byte-identical to a C2a plugin.
Imports:
manifold:client/action@0.1.0manifold:client/client-clock@0.1.0manifold:client/client-state-read@0.1.0manifold:client/hud-catalog@0.1.0manifold:client/hud-layout@0.1.0manifold:client/hud-reskin@0.1.0
Exports:
manifold:client/draw@0.1.0