@gameable/wasm-host
Classes
abstract GuestLoop
The game module: one fixed step is one guest tick.
A step runs GuestLoop.beginStep, GuestLoop.readInput, GuestLoop.beforeEncode, then reads contacts, drains events, reads GuestLoop.readPlayers, encodes, steps and applies. The first failure latches: a trapped guest is not retried, the frame it returned is not applied, and GuestLoop.onDead runs once.
Example
ts
class MyLoop extends GuestLoop<HeadlessEngine, ServerAdapter> {
protected initGuest(ctx: HostContext): void { this.sandbox.init(config); }
protected beginStep(): void { this.adapter.beginTick(); }
protected readInput(): void { aliasInputState(input, this.args.inputState); }
protected entityOfBody(body: number): number { return this.adapter.world.entityOfBody(body); }
protected onDead(error: Error | null): void { console.error(error); }
}Type Parameters
| Type Parameter | Default type |
|---|---|
E extends LoopEngine | - |
A extends LoopAdapter | - |
S extends Sandbox | null | Sandbox |
Implements
Constructors
Constructor
ts
new GuestLoop<E, A, S>(
engine,
sandbox,
adapter,
options
): GuestLoop<E, A, S>;Parameters
| Parameter | Type | Description |
|---|---|---|
engine | E | The booted engine, page or headless. |
sandbox | S | The guest, or null for a loop that runs none. |
adapter | A | Where the guest's output is applied. |
options | GuestLoopOptions | Capacity and module order. |
Returns
GuestLoop<E, A, S>
Properties
adapter
ts
protected readonly adapter: A;Where the guest's output is applied.
args
ts
protected readonly args: EncodeArgs;The encoder's arguments, one object rewritten every tick.
bodies
ts
protected readonly bodies: BodyRows;Post-step body rows, reused; grows by doubling when the world does.
dead
ts
protected dead: boolean = false;True once the guest has died; latches.
elapsed
ts
protected elapsed: number = 0;Simulated seconds ticked so far.
encoder
ts
protected readonly encoder: InputEncoder;The frame-input builder; reuses one record.
engine
ts
protected readonly engine: E;The booted engine, page or headless.
frame
ts
protected frame: number = 0;Fixed steps ticked so far.
id
ts
readonly id: "game" = 'game';The module id; the slot it fills is registered under the same one.
Implementation of
order
ts
readonly order: number;The module order.
Implementation of
physics
ts
protected physics: PhysicsService | null = null;The physics service, looked up in init; null without one.
sandbox
ts
protected readonly sandbox: S;The guest, or null for a loop that runs none.
Methods
beforeEncode()?
ts
protected optional beforeEncode(): void;Queue anything else onto adapter.events before they are drained.
Returns
void
beginStep()
ts
abstract protected beginStep(): void;Open the step on the adapter (beginFixedStep, beginTick).
Returns
void
dispose()
ts
dispose(): void;Unsubscribe, shut the guest down (when there is one) and dispose the adapter.
Returns
void
Implementation of
entityOfBody()
ts
abstract protected entityOfBody(body): number;Parameters
| Parameter | Type | Description |
|---|---|---|
body | number | A body id from a contact. |
Returns
number
The entity it drives.
fixedUpdate()
ts
fixedUpdate(dt): void;Tick the guest once and apply what it sent.
Parameters
| Parameter | Type | Description |
|---|---|---|
dt | number | The fixed step, in seconds. |
Returns
void
Implementation of
init()
ts
init(ctx): void;Look physics up, subscribe to physics:stepped, then the subclass's own set-up.
Parameters
| Parameter | Type | Description |
|---|---|---|
ctx | HostContext | The engine context. |
Returns
void
Implementation of
initGuest()
ts
abstract protected initGuest(ctx): void;The subclass's part of init: its own services, and sandbox.init.
Parameters
| Parameter | Type | Description |
|---|---|---|
ctx | HostContext | The engine context. |
Returns
void
onDead()
ts
abstract protected onDead(error): void;Report the guest's death. Runs once.
Parameters
| Parameter | Type | Description |
|---|---|---|
error | Error | null | Why the sandbox died. |
Returns
void
readInput()
ts
abstract protected readInput(): void;Fill this.args.inputState with this step's input.
Returns
void
readPlayers()
ts
protected readPlayers(): readonly PlayerInput[];This step's frame-input.players. Read once per step, after GuestLoop.readInput; must not allocate.
Returns
readonly PlayerInput[]
Every player in the room, ascending by id. Empty by default: a page is one player, and its input is frame-input.input.
runSeed()
ts
protected static runSeed(seed): bigint;Parameters
| Parameter | Type | Description |
|---|---|---|
seed | number | bigint | undefined | The caller's seed, if any. |
Returns
bigint
The run seed game.init takes; 0x5eed1234 when none was given.
step()
ts
protected step(input): FrameOutput | null;Run one step of the guest. Defaults to sandbox.tick, and to nothing without a sandbox.
Parameters
| Parameter | Type | Description |
|---|---|---|
input | HostFrameInput | This step's encoded frame-input. |
Returns
FrameOutput | null
The frame to apply, or null for nothing to apply (the dead check and applyOutput are skipped).
Interfaces
AdapterCall
One recorded EngineAdapter call.
Properties
args
ts
args: readonly unknown[];Arguments, by reference — they may be pooled and reused by the guest.
method
ts
method: AdapterMethod;Method name.
DirectSandboxOptions
Run the game's TypeScript directly, in the host realm.
Properties
game
ts
game: GameDefinition;The game's defineGame result.
host
ts
host: HostApi;Host services the guest imports.
mode
ts
mode: "direct";DomHudOptions
Options accepted by createDomHud.
Properties
className?
ts
optional className?: string;Class name given to the root element. Defaults to aos-hud.
container?
ts
optional container?: HudElement;Where the overlay is appended. Defaults to document.body.
document?
ts
optional document?: HudDocument;Document used to create elements. Defaults to the global document.
EncodeArgs
Everything an encoder needs for one fixed step.
Properties
bodies
ts
bodies: Float32Array;Packed body rows, stride 15, sorted ascending by body id.
Handed to the guest as a view of this very buffer, so the caller may grow it whenever it likes — the encoder notices the new identity and drops the views it memoised over the old one.
bodyCount
ts
bodyCount: number;Live body count; bodies may be longer.
contacts?
ts
optional contacts?: readonly Contact[];Reported contacts.
dt
ts
dt: number;Fixed timestep in seconds.
elapsed
ts
elapsed: number;Simulated seconds since init.
events?
ts
optional events?: readonly GameEvent[];Host-side events since the previous tick.
frame
ts
frame: number;Fixed-step counter.
inputState
ts
inputState: InputSnapshot;Host input state.
players?
ts
optional players?: readonly PlayerInput[];Every player's input in a room, ascending by id. Absent or empty for one player.
EngineAdapter
Everything the host can be asked to do, one method per command.
Extended by
Properties
appliesLocal
ts
readonly appliesLocal: boolean;True when frame-output.local-commands are applied here, after commands: the page's own adapter and the authority's server adapter. A replica's adapter says false; the replicator never forwards them.
Methods
addBody()
ts
addBody(args): void;Create a rigid body or character controller.
Parameters
| Parameter | Type |
|---|---|
args | AddBodyCmd |
Returns
void
applyImpulse()
ts
applyImpulse(
body,
impulse,
atPoint
): void;Apply a one-shot impulse.
Parameters
| Parameter | Type |
|---|---|
body | number |
impulse | Vec3 |
atPoint | Vec3 | undefined |
Returns
void
applyTransforms()
ts
applyTransforms(transforms, count): void;Apply packed entity transforms.
Parameters
| Parameter | Type | Description |
|---|---|---|
transforms | Float32Array | Stride 12: entity, flags, position, rotation, scale. |
count | number | Number of rows. The buffer may be longer. |
Returns
void
conversation()
ts
conversation(command): void;Forward structural controls to an optional conversation module.
Parameters
| Parameter | Type |
|---|---|
command | ConversationCmd |
Returns
void
despawn()
ts
despawn(entity): void;Destroy an entity and everything attached to it.
Parameters
| Parameter | Type |
|---|---|
entity | number |
Returns
void
exchange()
ts
exchange(command): void;Trade between two players' documents. The command is pooled: read it, never keep it.
Parameters
| Parameter | Type |
|---|---|
command | ExchangeCmd |
Returns
void
loadAsset()
ts
loadAsset(asset, priority): void;Start loading an asset.
Parameters
| Parameter | Type |
|---|---|
asset | number |
priority | number |
Returns
void
localScope()?
ts
optional localScope(on): void;Optional: told when applyOutput starts (true) and ends (false) applying frame-output.local-commands. The server adapter uses it to keep what a local command does out of the replicated world record.
Parameters
| Parameter | Type |
|---|---|
on | boolean |
Returns
void
lookAt()
ts
lookAt(
entity,
target,
weight
): void;Aim a character's head and eyes.
Parameters
| Parameter | Type |
|---|---|
entity | number |
target | Vec3 | undefined |
weight | number |
Returns
void
moveCharacter()
ts
moveCharacter(
body,
desiredVelocity,
jump,
crouch,
maxSlopeDeg
): void;Drive a character body for one step.
Parameters
| Parameter | Type |
|---|---|
body | number |
desiredVelocity | Vec3 |
jump | boolean |
crouch | boolean |
maxSlopeDeg | number |
Returns
void
playSound()
ts
playSound(
sound,
asset,
entity,
position,
volume,
pitch,
looping,
bus
): void;Start a sound.
Parameters
| Parameter | Type |
|---|---|
sound | number |
asset | number |
entity | number | undefined |
position | Vec3 | undefined |
volume | number |
pitch | number |
looping | boolean |
bus | AudioBus |
Returns
void
removeBody()
ts
removeBody(body): void;Destroy a body.
Parameters
| Parameter | Type |
|---|---|
body | number |
Returns
void
saveGameData()
ts
saveGameData(data): void;Persist the room's game-wide document (JSON).
Parameters
| Parameter | Type |
|---|---|
data | string |
Returns
void
savePlayerData()
ts
savePlayerData(player, data): void;Persist one player's document (JSON).
Parameters
| Parameter | Type |
|---|---|
player | number |
data | string |
Returns
void
say()
ts
say(
entity,
text,
audio,
visemes
): void;Speak a line.
Parameters
| Parameter | Type |
|---|---|
entity | number |
text | string |
audio | number | undefined |
visemes | string | undefined |
Returns
void
send()
ts
send(
to,
name,
payload,
reliable
): void;Send a game message; to undefined is every player (or the authority, from a client).
Parameters
| Parameter | Type |
|---|---|
to | number | undefined |
name | string |
payload | string |
reliable | boolean |
Returns
void
setAnim()
ts
setAnim(
entity,
clip,
looping,
speed,
fadeMs,
weight
): void;Play or cross-fade an animation clip.
Parameters
| Parameter | Type |
|---|---|
entity | number |
clip | string |
looping | boolean |
speed | number |
fadeMs | number |
weight | number |
Returns
void
setAsset()
ts
setAsset(entity, asset): void;Attach or detach a renderable.
Parameters
| Parameter | Type |
|---|---|
entity | number |
asset | number | undefined |
Returns
void
setBodyEnabled()
ts
setBodyEnabled(body, enabled): void;Enable or disable a body in the broad phase.
Parameters
| Parameter | Type |
|---|---|
body | number |
enabled | boolean |
Returns
void
setBodyTransform()
ts
setBodyTransform(
body,
position,
rotation,
teleport
): void;Move a body directly.
Parameters
| Parameter | Type |
|---|---|
body | number |
position | Vec3 |
rotation | Quat |
teleport | boolean |
Returns
void
setBodyVelocity()
ts
setBodyVelocity(
body,
linear,
angular
): void;Overwrite a body's velocities; undefined leaves one untouched.
Parameters
| Parameter | Type |
|---|---|
body | number |
linear | Vec3 | undefined |
angular | Vec3 | undefined |
Returns
void
setCamera()
ts
setCamera(camera): void;Apply the camera the guest asked for.
Parameters
| Parameter | Type |
|---|---|
camera | CameraState |
Returns
void
setCharacterState()
ts
setCharacterState(
entity,
state,
velocity,
grounded
): void;Drive a character's locomotion state machine.
Parameters
| Parameter | Type |
|---|---|
entity | number |
state | string |
velocity | Vec3 |
grounded | boolean |
Returns
void
setClipWeights()
ts
setClipWeights(
entity,
clips,
weights,
timeScale
): void;Set explicit per-clip weights.
Parameters
| Parameter | Type |
|---|---|
entity | number |
clips | readonly string[] |
weights | ArrayLike<number> |
timeScale | number |
Returns
void
setExpression()
ts
setExpression(
entity,
space,
weights
): void;Set facial expression coefficients.
Parameters
| Parameter | Type |
|---|---|
entity | number |
space | ExpressionSpace |
weights | ArrayLike<number> |
Returns
void
setHud()
ts
setHud(json): void;Apply the HUD model, or leave the previous one when undefined.
Parameters
| Parameter | Type |
|---|---|
json | string | undefined |
Returns
void
setListener()
ts
setListener(
position,
rotation,
velocity
): void;Place the audio listener.
Parameters
| Parameter | Type |
|---|---|
position | Vec3 |
rotation | Quat |
velocity | Vec3 |
Returns
void
setMaterialParam()
ts
setMaterialParam(
entity,
name,
value
): void;Set one material uniform.
Parameters
| Parameter | Type |
|---|---|
entity | number |
name | string |
value | MaterialValue |
Returns
void
setParent()
ts
setParent(
entity,
parent,
keepWorldTransform
): void;Reparent an entity.
Parameters
| Parameter | Type |
|---|---|
entity | number |
parent | number | undefined |
keepWorldTransform | boolean |
Returns
void
setPlayerCamera()
ts
setPlayerCamera(player, camera): void;The camera one player renders from.
Parameters
| Parameter | Type |
|---|---|
player | number |
camera | CameraState |
Returns
void
setPlayerEntity()
ts
setPlayerEntity(player, entity): void;Which entity a player controls (0 for none). The authority keeps the mapping for relevancy and each player's "your entity"; a page ignores it.
Parameters
| Parameter | Type |
|---|---|
player | number |
entity | number |
Returns
void
setPlayerHud()
ts
setPlayerHud(player, hud): void;One player's HUD model as JSON.
Parameters
| Parameter | Type |
|---|---|
player | number |
hud | string |
Returns
void
setPointerLock()
ts
setPointerLock(locked): void;Request or release pointer lock.
Parameters
| Parameter | Type |
|---|---|
locked | boolean |
Returns
void
setTimeScale()
ts
setTimeScale(scale): void;Scale simulated time.
Parameters
| Parameter | Type |
|---|---|
scale | number |
Returns
void
spawn()
ts
spawn(
entity,
asset,
position,
rotation,
scale,
flags
): void;Create an entity in the scene.
Parameters
| Parameter | Type |
|---|---|
entity | number |
asset | number | undefined |
position | Vec3 |
rotation | Quat |
scale | Vec3 |
flags | { name?: string; parent?: number; visible: boolean; } |
flags.name? | string |
flags.parent? | number |
flags.visible | boolean |
Returns
void
spawnCharacter()
ts
spawnCharacter(
entity,
bundle,
position,
rotation
): void;Instantiate a splat character bundle.
Parameters
| Parameter | Type |
|---|---|
entity | number |
bundle | number |
position | Vec3 |
rotation | Quat |
Returns
void
stopSound()
ts
stopSound(sound, fadeMs): void;Stop a playing sound.
Parameters
| Parameter | Type |
|---|---|
sound | number |
fadeMs | number |
Returns
void
EngineAdapterHandle
The engine-backed adapter, plus the hooks the host loop drives.
Extends
Properties
appliesLocal
ts
readonly appliesLocal: boolean;True when frame-output.local-commands are applied here, after commands: the page's own adapter and the authority's server adapter. A replica's adapter says false; the replicator never forwards them.
Inherited from
events
ts
readonly events: GameEvent[];Host-side occurrences since the loop last drained them.
hud
ts
readonly hud: HudRenderer | null;The HUD renderer, or null when hud: false.
hudModel
ts
readonly hudModel: unknown;The HUD model currently on screen, whether or not a renderer is attached.
transforms
ts
readonly transforms: TransformStore;Previous/current transforms, slot 0 being the camera.
Methods
addBody()
ts
addBody(args): void;Create a rigid body or character controller.
Parameters
| Parameter | Type |
|---|---|
args | AddBodyCmd |
Returns
void
Inherited from
animationOf()
ts
animationOf(entity): CharacterAnimationState | null;What the guest last asked an entity's animation to do.
Parameters
| Parameter | Type | Description |
|---|---|---|
entity | number | The entity. |
Returns
CharacterAnimationState | null
The recorded intent, or null when the entity has never been the subject of a spawn-character, set-anim or set-character-state.
applyBodyRows()
ts
applyBodyRows(rows, count): void;Write post-step body rows straight onto the entities they drive.
The host half of "physics owns body transforms": the physics module hands these rows over the moment it has stepped, and each one becomes the driven entity's current position and rotation in the transform store. The entity's scale is left alone — a body has none, and the guest's is the only opinion there is.
Nothing crosses the wasm boundary here. The guest still receives the same rows as frame-input.bodies on its next tick and still keeps Transform and Velocity up to date for gameplay; it simply no longer has to send twelve floats per body back for the host to apply a second time.
Parameters
| Parameter | Type | Description |
|---|---|---|
rows | Float32Array | Stride-15 rows, as PhysicsWorld.readBodies writes them. |
count | number | Rows to read; rows may be longer. |
Returns
void
Nothing.
applyImpulse()
ts
applyImpulse(
body,
impulse,
atPoint
): void;Apply a one-shot impulse.
Parameters
| Parameter | Type |
|---|---|
body | number |
impulse | Vec3 |
atPoint | Vec3 | undefined |
Returns
void
Inherited from
applyTransforms()
ts
applyTransforms(transforms, count): void;Apply packed entity transforms.
Parameters
| Parameter | Type | Description |
|---|---|---|
transforms | Float32Array | Stride 12: entity, flags, position, rotation, scale. |
count | number | Number of rows. The buffer may be longer. |
Returns
void
Inherited from
beginFixedStep()
ts
beginFixedStep(): void;Roll current transforms into previous ones.
Call once per fixed step, before applying that step's output.
Returns
void
Nothing.
conversation()
ts
conversation(command): void;Forward structural controls to an optional conversation module.
Parameters
| Parameter | Type |
|---|---|
command | ConversationCmd |
Returns
void
Inherited from
despawn()
ts
despawn(entity): void;Destroy an entity and everything attached to it.
Parameters
| Parameter | Type |
|---|---|
entity | number |
Returns
void
Inherited from
dispose()
ts
dispose(): void;Release the HUD and every object this adapter put in the scene.
Returns
void
entityOfBody()
ts
entityOfBody(body): number;The entity a body id drives.
Parameters
| Parameter | Type | Description |
|---|---|---|
body | number | Body id minted by the guest. |
Returns
number
The entity, or 0 when the body is unknown.
exchange()
ts
exchange(command): void;Trade between two players' documents. The command is pooled: read it, never keep it.
Parameters
| Parameter | Type |
|---|---|
command | ExchangeCmd |
Returns
void
Inherited from
interpolate()
ts
interpolate(alpha): void;Write the blend of the previous and current transforms onto the scene.
Parameters
| Parameter | Type | Description |
|---|---|---|
alpha | number | Interpolation factor in [0, 1), from the engine loop. |
Returns
void
Nothing.
loadAsset()
ts
loadAsset(asset, priority): void;Start loading an asset.
Parameters
| Parameter | Type |
|---|---|
asset | number |
priority | number |
Returns
void
Inherited from
localScope()?
ts
optional localScope(on): void;Optional: told when applyOutput starts (true) and ends (false) applying frame-output.local-commands. The server adapter uses it to keep what a local command does out of the replicated world record.
Parameters
| Parameter | Type |
|---|---|
on | boolean |
Returns
void
Inherited from
lookAt()
ts
lookAt(
entity,
target,
weight
): void;Aim a character's head and eyes.
Parameters
| Parameter | Type |
|---|---|
entity | number |
target | Vec3 | undefined |
weight | number |
Returns
void
Inherited from
moveCharacter()
ts
moveCharacter(
body,
desiredVelocity,
jump,
crouch,
maxSlopeDeg
): void;Drive a character body for one step.
Parameters
| Parameter | Type |
|---|---|
body | number |
desiredVelocity | Vec3 |
jump | boolean |
crouch | boolean |
maxSlopeDeg | number |
Returns
void
Inherited from
playSound()
ts
playSound(
sound,
asset,
entity,
position,
volume,
pitch,
looping,
bus
): void;Start a sound.
Parameters
| Parameter | Type |
|---|---|
sound | number |
asset | number |
entity | number | undefined |
position | Vec3 | undefined |
volume | number |
pitch | number |
looping | boolean |
bus | AudioBus |
Returns
void
Inherited from
removeBody()
ts
removeBody(body): void;Destroy a body.
Parameters
| Parameter | Type |
|---|---|
body | number |
Returns
void
Inherited from
saveGameData()
ts
saveGameData(data): void;Persist the room's game-wide document (JSON).
Parameters
| Parameter | Type |
|---|---|
data | string |
Returns
void
Inherited from
savePlayerData()
ts
savePlayerData(player, data): void;Persist one player's document (JSON).
Parameters
| Parameter | Type |
|---|---|
player | number |
data | string |
Returns
void
Inherited from
say()
ts
say(
entity,
text,
audio,
visemes
): void;Speak a line.
Parameters
| Parameter | Type |
|---|---|
entity | number |
text | string |
audio | number | undefined |
visemes | string | undefined |
Returns
void
Inherited from
send()
ts
send(
to,
name,
payload,
reliable
): void;Send a game message; to undefined is every player (or the authority, from a client).
Parameters
| Parameter | Type |
|---|---|
to | number | undefined |
name | string |
payload | string |
reliable | boolean |
Returns
void
Inherited from
setAnim()
ts
setAnim(
entity,
clip,
looping,
speed,
fadeMs,
weight
): void;Play or cross-fade an animation clip.
Parameters
| Parameter | Type |
|---|---|
entity | number |
clip | string |
looping | boolean |
speed | number |
fadeMs | number |
weight | number |
Returns
void
Inherited from
setAsset()
ts
setAsset(entity, asset): void;Attach or detach a renderable.
Parameters
| Parameter | Type |
|---|---|
entity | number |
asset | number | undefined |
Returns
void
Inherited from
setBodyEnabled()
ts
setBodyEnabled(body, enabled): void;Enable or disable a body in the broad phase.
Parameters
| Parameter | Type |
|---|---|
body | number |
enabled | boolean |
Returns
void
Inherited from
setBodyTransform()
ts
setBodyTransform(
body,
position,
rotation,
teleport
): void;Move a body directly.
Parameters
| Parameter | Type |
|---|---|
body | number |
position | Vec3 |
rotation | Quat |
teleport | boolean |
Returns
void
Inherited from
EngineAdapter.setBodyTransform
setBodyVelocity()
ts
setBodyVelocity(
body,
linear,
angular
): void;Overwrite a body's velocities; undefined leaves one untouched.
Parameters
| Parameter | Type |
|---|---|
body | number |
linear | Vec3 | undefined |
angular | Vec3 | undefined |
Returns
void
Inherited from
setCamera()
ts
setCamera(camera): void;Apply the camera the guest asked for.
Parameters
| Parameter | Type |
|---|---|
camera | CameraState |
Returns
void
Inherited from
setCharacterState()
ts
setCharacterState(
entity,
state,
velocity,
grounded
): void;Drive a character's locomotion state machine.
Parameters
| Parameter | Type |
|---|---|
entity | number |
state | string |
velocity | Vec3 |
grounded | boolean |
Returns
void
Inherited from
EngineAdapter.setCharacterState
setClipWeights()
ts
setClipWeights(
entity,
clips,
weights,
timeScale
): void;Set explicit per-clip weights.
Parameters
| Parameter | Type |
|---|---|
entity | number |
clips | readonly string[] |
weights | ArrayLike<number> |
timeScale | number |
Returns
void
Inherited from
setExpression()
ts
setExpression(
entity,
space,
weights
): void;Set facial expression coefficients.
Parameters
| Parameter | Type |
|---|---|
entity | number |
space | ExpressionSpace |
weights | ArrayLike<number> |
Returns
void
Inherited from
setHud()
ts
setHud(json): void;Apply the HUD model, or leave the previous one when undefined.
Parameters
| Parameter | Type |
|---|---|
json | string | undefined |
Returns
void
Inherited from
setListener()
ts
setListener(
position,
rotation,
velocity
): void;Place the audio listener.
Parameters
| Parameter | Type |
|---|---|
position | Vec3 |
rotation | Quat |
velocity | Vec3 |
Returns
void
Inherited from
setMaterialParam()
ts
setMaterialParam(
entity,
name,
value
): void;Set one material uniform.
Parameters
| Parameter | Type |
|---|---|
entity | number |
name | string |
value | MaterialValue |
Returns
void
Inherited from
EngineAdapter.setMaterialParam
setParent()
ts
setParent(
entity,
parent,
keepWorldTransform
): void;Reparent an entity.
Parameters
| Parameter | Type |
|---|---|
entity | number |
parent | number | undefined |
keepWorldTransform | boolean |
Returns
void
Inherited from
setPlayerCamera()
ts
setPlayerCamera(player, camera): void;The camera one player renders from.
Parameters
| Parameter | Type |
|---|---|
player | number |
camera | CameraState |
Returns
void
Inherited from
setPlayerEntity()
ts
setPlayerEntity(player, entity): void;Which entity a player controls (0 for none). The authority keeps the mapping for relevancy and each player's "your entity"; a page ignores it.
Parameters
| Parameter | Type |
|---|---|
player | number |
entity | number |
Returns
void
Inherited from
setPlayerHud()
ts
setPlayerHud(player, hud): void;One player's HUD model as JSON.
Parameters
| Parameter | Type |
|---|---|
player | number |
hud | string |
Returns
void
Inherited from
setPointerLock()
ts
setPointerLock(locked): void;Request or release pointer lock.
Parameters
| Parameter | Type |
|---|---|
locked | boolean |
Returns
void
Inherited from
setTimeScale()
ts
setTimeScale(scale): void;Scale simulated time.
Parameters
| Parameter | Type |
|---|---|
scale | number |
Returns
void
Inherited from
setTransformFromHost()
ts
setTransformFromHost(
entity,
flags,
position,
rotation,
scale
): void;Write one transform the host, not the guest, authored: a multiplayer client's replicated row from the authority.
Only the lanes flags names are written (TRANSFORM_FLAGS.POSITION, ROTATION, SCALE); the others keep their current values. TELEPORT snaps instead of interpolating, and VISIBLE shows an entity that was hidden at spawn. Unlike applyTransforms, a rotation written here is not guest intent, so it never outranks a later physics row. An unknown entity is ignored.
Parameters
| Parameter | Type | Description |
|---|---|---|
entity | number | The entity. |
flags | number | TRANSFORM_FLAGS bits; the multiplayer RowFlag bits are the same values. |
position | ArrayLike<number> | Position xyz, read when POSITION is set. |
rotation | ArrayLike<number> | Quaternion xyzw, read when ROTATION is set. |
scale | ArrayLike<number> | Scale xyz, read when SCALE is set. |
Returns
void
Nothing.
spawn()
ts
spawn(
entity,
asset,
position,
rotation,
scale,
flags
): void;Create an entity in the scene.
Parameters
| Parameter | Type |
|---|---|
entity | number |
asset | number | undefined |
position | Vec3 |
rotation | Quat |
scale | Vec3 |
flags | { name?: string; parent?: number; visible: boolean; } |
flags.name? | string |
flags.parent? | number |
flags.visible | boolean |
Returns
void
Inherited from
spawnCharacter()
ts
spawnCharacter(
entity,
bundle,
position,
rotation
): void;Instantiate a splat character bundle.
Parameters
| Parameter | Type |
|---|---|
entity | number |
bundle | number |
position | Vec3 |
rotation | Quat |
Returns
void
Inherited from
stopSound()
ts
stopSound(sound, fadeMs): void;Stop a playing sound.
Parameters
| Parameter | Type |
|---|---|
sound | number |
fadeMs | number |
Returns
void
Inherited from
update()
ts
update(dt, alpha): void;One rendered frame's worth of adapter work: interpolate, then the character bridge's animators and rigs.
The two are separate because interpolation is pure transform maths and characters are not: a rig runs a compute pass and wants wall-clock seconds, not an interpolation factor.
Parameters
| Parameter | Type | Description |
|---|---|---|
dt | number | Clamped wall-clock seconds since the previous frame. |
alpha | number | Interpolation factor in [0, 1), from the engine loop. |
Returns
void
Nothing.
EngineAdapterOptions
Options accepted by createEngineAdapter; localPlayer and send are on the base.
Extends
PlayerCommandOptions
Properties
capacity?
ts
optional capacity?: number;Entity slots reserved up front. Defaults to 512.
characters?
ts
optional characters?: CharacterBridge;Renders the spawn-character family for real.
Build one with createCharacterBridge from gameable/host/characters — the optional module, so a game with no characters never downloads the rig stack. Leave it out and the six character commands are recorded on EngineAdapterHandle.animationOf and warn once, which is what shipped before this existed.
conversation?
ts
optional conversation?: (command) => void;Optional structural interview command sink. No integration is loaded by default.
Forward structural controls to an optional conversation module.
Parameters
| Parameter | Type |
|---|---|
command | ConversationCmd |
Returns
void
hud?
ts
optional hud?: false | HudRenderer;HUD renderer. Defaults to createDomHud over document.body; pass your own to restyle it, or false to render no HUD at all and read adapter.hudModel yourself.
hudContainer?
ts
optional hudContainer?: HudElement;Container for the default HUD. Defaults to document.body.
localPlayer?
ts
optional localPlayer?: number;The player this page shows. Defaults to 0, the single-player player.
Inherited from
ts
PlayerCommandOptions.localPlayermaxBodies?
ts
optional maxBodies?: number;Body-id slots reserved for the body-to-entity table. Defaults to 4096.
The table is a Uint32Array indexed by body id, so EngineAdapterHandle.entityOfBody is an array read rather than a Map lookup — it runs once per contact and once per raycast hit. Guest body ids are minted in order and never reused, so a long session walks past any fixed ceiling; the table doubles when it has to and warns once, naming this option.
modules?
ts
optional modules?: readonly EngineModule[];The module instances handed to createEngine.
Services are normally reached through engine.get(id), but the audio decoder is only on the module object: decodeAsset, which turns a play-sound asset handle into an AudioBuffer, and the optional decodedAsset, which answers synchronously for a buffer that is already decoded and so lets a sound start on the frame it was asked for. Pass the same array you passed to createEngine and both are found automatically.
placeholders?
ts
optional placeholders?: "bodies" | "always" | "never";When to draw a placeholder mesh in place of a real asset.
bodies(the default) — an entity with no renderable gets a mesh the shape and size of its physics body, and a spawn whose asset is unknown or not yet resident gets a unit box until the bytes arrive.always— additionally, an entity with neither an asset nor a body gets a unit box. The right choice for a sketch, where nothing has an asset yet and an empty scene is indistinguishable from a broken one.never— draw only what the manifest provides. The right choice once the game has real content, because then a missing mesh is a bug and should look like one.
send?
ts
optional send?: (to, name, payload, reliable) => void;Where the guest's send commands go: the client transport. Without one they are dropped. Called during applyOutput; copy what you keep.
Parameters
| Parameter | Type | Description |
|---|---|---|
to | number | undefined | The addressee, or undefined for the authority / everyone. |
name | string | Message name. |
payload | string | JSON payload. |
reliable | boolean | Whether it must arrive. |
Returns
void
Inherited from
ts
PlayerCommandOptions.sendwarn?
ts
optional warn?: (message) => void;Where warnings go. Defaults to console.warn, once per distinct message.
Parameters
| Parameter | Type | Description |
|---|---|---|
message | string | What went wrong. |
Returns
void
GameSlot
A registered place in the module order, filled in once the engine exists.
Properties
module
ts
readonly module: EngineModule;Register this with createEngine({ modules }).
Methods
attach()
ts
attach(loop, ctx): Promise<void>;Bind the real loop and initialise it.
Parameters
| Parameter | Type | Description |
|---|---|---|
loop | EngineModule | The module from createHostLoop. |
ctx | HostContext | The engine context, normally engine.ctx. |
Returns
Promise<void>
Resolves once the loop's own init has run.
GuestLoopOptions
Options every loop takes.
Example
ts
const options: GuestLoopOptions = { maxBodies: 2048, order: -50 };Properties
maxBodies?
ts
optional maxBodies?: number;Body rows the input encoder reserves before it grows. Defaults to 1024.
order?
ts
optional order?: number;Module order. Defaults to -50: after input, before physics.
GuestNamespace
The game namespace the component exports.
Methods
init()
ts
init(config): void;Parameters
| Parameter | Type |
|---|---|
config | HostGameConfig |
Returns
void
restore()
ts
restore(state): void;Parameters
| Parameter | Type |
|---|---|
state | Uint8Array |
Returns
void
shutdown()
ts
shutdown(): void;Returns
void
snapshot()
ts
snapshot(): Uint8Array;Returns
Uint8Array
tick()
ts
tick(input): FrameOutput;Parameters
| Parameter | Type |
|---|---|
input | HostFrameInput |
Returns
HostBindings
The gameable:engine half of a jco import object.
Properties
gameable:engine/assets
ts
gameable:engine/assets: object;describe
ts
describe: (id) => AssetDesc | undefined;Parameters
| Parameter | Type |
|---|---|
id | number |
Returns
AssetDesc | undefined
resolveId
ts
resolveId: (name) => number | undefined;Parameters
| Parameter | Type |
|---|---|
name | string |
Returns
number | undefined
gameable:engine/env
ts
gameable:engine/env: object;log
ts
log: (level, msg) => void;Parameters
| Parameter | Type |
|---|---|
level | string |
msg | string |
Returns
void
nowMs
ts
nowMs: () => number;Returns
number
seed
ts
seed: () => bigint;Returns
bigint
gameable:engine/physics-query
ts
gameable:engine/physics-query: object;overlapSphere
ts
overlapSphere: (center, radius, filter, maxResults) => OverlapHit[];Parameters
| Parameter | Type |
|---|---|
center | Vec3 |
radius | number |
filter | QueryFilter |
maxResults | number |
Returns
raycast
ts
raycast: (origin, direction, maxDistance, filter) => RayHit | undefined;Parameters
| Parameter | Type |
|---|---|
origin | Vec3 |
direction | Vec3 |
maxDistance | number |
filter | QueryFilter |
Returns
RayHit | undefined
raycastBatch
ts
raycastBatch: (rays) => (RayHit | undefined)[];Parameters
| Parameter | Type |
|---|---|
rays | RayQuery[] |
Returns
(RayHit | undefined)[]
HostLoopOptions
Options accepted by createHostLoop.
Properties
devMode?
ts
optional devMode?: boolean;Value of game-config.dev-mode. Defaults to true.
init?
ts
optional init?: boolean;Call sandbox.init during module init. Defaults to true.
maxBodies?
ts
optional maxBodies?: number;Body rows the input encoder reserves. Defaults to 1024.
onDead?
ts
optional onDead?: (error) => void;Shown when the guest dies. Defaults to a red overlay on document.body.
Parameters
| Parameter | Type | Description |
|---|---|---|
error | Error | null | Why the sandbox died. |
Returns
void
options?
ts
optional options?: string;Extra options string handed to game.init.
order?
ts
optional order?: number;Module order. Defaults to -50: after input, before physics.
That is what removes a fixed step of input latency — see createHostLoop. Moving it after physics puts the latency back.
seed?
ts
optional seed?: number | bigint;Deterministic run seed handed to game.init. Defaults to 0x5eed1234.
Fix it and a run replays; vary it and each run differs.
HudDocument
The slice of Document the renderer uses.
Methods
createElement()
ts
createElement(tag): HudElement;Create an element.
Parameters
| Parameter | Type | Description |
|---|---|---|
tag | string | Tag name, always 'div' here. |
Returns
The new element.
HudElement
The slice of HTMLElement the renderer uses.
Properties
className
ts
className: string;Class name, set once per element at creation.
style
ts
readonly style: object;Inline style, written through setProperty so a fake needs one method.
setProperty()
ts
setProperty(name, value): void;Parameters
| Parameter | Type |
|---|---|
name | string |
value | string |
Returns
void
textContent
ts
textContent: string | null;Text content; the renderer only ever writes it.
Methods
append()
ts
append(...nodes): void;Append children.
The parameter is unknown rather than HudElement on purpose: the real HTMLElement.append takes (string | Node)[], and only a parameter type that a Node is assignable to makes a real element satisfy this interface under method bivariance.
Parameters
| Parameter | Type | Description |
|---|---|---|
...nodes | unknown[] | Children to append; always HudElements here. |
Returns
void
remove()
ts
remove(): void;Detach from the parent, if any.
Returns
void
HudModel
The HUD model the default renderer understands.
Properties
bars?
ts
optional bars?: Record<string, {
max: number;
value: number;
}>;Label to { value, max } meters, drawn bottom-left in declaration order.
crosshair?
ts
optional crosshair?: boolean;Draw the centre crosshair.
message?
ts
optional message?: string;A single centred line, for "You win" and friends. Empty or absent hides it.
text?
ts
optional text?: Record<string, string | number>;Label to value rows, drawn top-left in declaration order.
HudRenderer
What createDomHud returns, and what the adapter drives.
Properties
element
ts
readonly element: HudElement;The overlay root, for tests and for callers that want to restyle it.
model
ts
readonly model: HudModel | null;The model currently on screen, or null before the first payload.
Methods
clear()
ts
clear(): void;Hide everything and forget the model.
Returns
void
dispose()
ts
dispose(): void;Detach the overlay from its container.
Returns
void
set()
ts
set(json): boolean;Apply one frame-output.hud value.
Parameters
| Parameter | Type | Description |
|---|---|---|
json | string | undefined | The JSON the guest sent, or undefined when nothing changed. |
Returns
boolean
True when the DOM was touched.
InputEncoder
A reusable frame-input builder.
Methods
encode()
ts
encode(args): HostFrameInput;Build the next frame input. The returned object is reused.
Parameters
| Parameter | Type |
|---|---|
args | EncodeArgs |
Returns
InputSnapshot
The shape the engine's input module hands over each frame.
Properties
down
ts
down: Uint32Array;Keys held, KEY_WORDS words. Aliased into the frame input, not copied: the array must stay alive and must not be recycled mid-tick.
focused
ts
focused: boolean;gamepads?
ts
optional gamepads?: readonly GamepadState[];mods
ts
mods: InputMods;mouse
ts
mouse: MouseState;pressed
ts
pressed: Uint32Array;Keys that went down this step, aliased like InputSnapshot.down.
released
ts
released: Uint32Array;Keys that came up this step, aliased like InputSnapshot.down.
LoopAdapter
What a loop needs of its adapter beyond the EngineAdapter commands.
Example
ts
const adapter: LoopAdapter = createServerAdapter(engine.modules.get('physics'));Extends
Properties
appliesLocal
ts
readonly appliesLocal: boolean;True when frame-output.local-commands are applied here, after commands: the page's own adapter and the authority's server adapter. A replica's adapter says false; the replicator never forwards them.
Inherited from
events
ts
readonly events: GameEvent[];The host event queue; drained into each tick's frame-input.events.
Methods
addBody()
ts
addBody(args): void;Create a rigid body or character controller.
Parameters
| Parameter | Type |
|---|---|
args | AddBodyCmd |
Returns
void
Inherited from
applyBodyRows()
ts
applyBodyRows(rows, count): void;Write the post-step body rows onto the entities they drive.
Parameters
| Parameter | Type |
|---|---|
rows | Float32Array |
count | number |
Returns
void
applyImpulse()
ts
applyImpulse(
body,
impulse,
atPoint
): void;Apply a one-shot impulse.
Parameters
| Parameter | Type |
|---|---|
body | number |
impulse | Vec3 |
atPoint | Vec3 | undefined |
Returns
void
Inherited from
applyTransforms()
ts
applyTransforms(transforms, count): void;Apply packed entity transforms.
Parameters
| Parameter | Type | Description |
|---|---|---|
transforms | Float32Array | Stride 12: entity, flags, position, rotation, scale. |
count | number | Number of rows. The buffer may be longer. |
Returns
void
Inherited from
conversation()
ts
conversation(command): void;Forward structural controls to an optional conversation module.
Parameters
| Parameter | Type |
|---|---|
command | ConversationCmd |
Returns
void
Inherited from
despawn()
ts
despawn(entity): void;Destroy an entity and everything attached to it.
Parameters
| Parameter | Type |
|---|---|
entity | number |
Returns
void
Inherited from
dispose()
ts
dispose(): void;Release the adapter.
Returns
void
exchange()
ts
exchange(command): void;Trade between two players' documents. The command is pooled: read it, never keep it.
Parameters
| Parameter | Type |
|---|---|
command | ExchangeCmd |
Returns
void
Inherited from
loadAsset()
ts
loadAsset(asset, priority): void;Start loading an asset.
Parameters
| Parameter | Type |
|---|---|
asset | number |
priority | number |
Returns
void
Inherited from
localScope()?
ts
optional localScope(on): void;Optional: told when applyOutput starts (true) and ends (false) applying frame-output.local-commands. The server adapter uses it to keep what a local command does out of the replicated world record.
Parameters
| Parameter | Type |
|---|---|
on | boolean |
Returns
void
Inherited from
lookAt()
ts
lookAt(
entity,
target,
weight
): void;Aim a character's head and eyes.
Parameters
| Parameter | Type |
|---|---|
entity | number |
target | Vec3 | undefined |
weight | number |
Returns
void
Inherited from
moveCharacter()
ts
moveCharacter(
body,
desiredVelocity,
jump,
crouch,
maxSlopeDeg
): void;Drive a character body for one step.
Parameters
| Parameter | Type |
|---|---|
body | number |
desiredVelocity | Vec3 |
jump | boolean |
crouch | boolean |
maxSlopeDeg | number |
Returns
void
Inherited from
playSound()
ts
playSound(
sound,
asset,
entity,
position,
volume,
pitch,
looping,
bus
): void;Start a sound.
Parameters
| Parameter | Type |
|---|---|
sound | number |
asset | number |
entity | number | undefined |
position | Vec3 | undefined |
volume | number |
pitch | number |
looping | boolean |
bus | AudioBus |
Returns
void
Inherited from
removeBody()
ts
removeBody(body): void;Destroy a body.
Parameters
| Parameter | Type |
|---|---|
body | number |
Returns
void
Inherited from
saveGameData()
ts
saveGameData(data): void;Persist the room's game-wide document (JSON).
Parameters
| Parameter | Type |
|---|---|
data | string |
Returns
void
Inherited from
savePlayerData()
ts
savePlayerData(player, data): void;Persist one player's document (JSON).
Parameters
| Parameter | Type |
|---|---|
player | number |
data | string |
Returns
void
Inherited from
say()
ts
say(
entity,
text,
audio,
visemes
): void;Speak a line.
Parameters
| Parameter | Type |
|---|---|
entity | number |
text | string |
audio | number | undefined |
visemes | string | undefined |
Returns
void
Inherited from
send()
ts
send(
to,
name,
payload,
reliable
): void;Send a game message; to undefined is every player (or the authority, from a client).
Parameters
| Parameter | Type |
|---|---|
to | number | undefined |
name | string |
payload | string |
reliable | boolean |
Returns
void
Inherited from
setAnim()
ts
setAnim(
entity,
clip,
looping,
speed,
fadeMs,
weight
): void;Play or cross-fade an animation clip.
Parameters
| Parameter | Type |
|---|---|
entity | number |
clip | string |
looping | boolean |
speed | number |
fadeMs | number |
weight | number |
Returns
void
Inherited from
setAsset()
ts
setAsset(entity, asset): void;Attach or detach a renderable.
Parameters
| Parameter | Type |
|---|---|
entity | number |
asset | number | undefined |
Returns
void
Inherited from
setBodyEnabled()
ts
setBodyEnabled(body, enabled): void;Enable or disable a body in the broad phase.
Parameters
| Parameter | Type |
|---|---|
body | number |
enabled | boolean |
Returns
void
Inherited from
setBodyTransform()
ts
setBodyTransform(
body,
position,
rotation,
teleport
): void;Move a body directly.
Parameters
| Parameter | Type |
|---|---|
body | number |
position | Vec3 |
rotation | Quat |
teleport | boolean |
Returns
void
Inherited from
EngineAdapter.setBodyTransform
setBodyVelocity()
ts
setBodyVelocity(
body,
linear,
angular
): void;Overwrite a body's velocities; undefined leaves one untouched.
Parameters
| Parameter | Type |
|---|---|
body | number |
linear | Vec3 | undefined |
angular | Vec3 | undefined |
Returns
void
Inherited from
setCamera()
ts
setCamera(camera): void;Apply the camera the guest asked for.
Parameters
| Parameter | Type |
|---|---|
camera | CameraState |
Returns
void
Inherited from
setCharacterState()
ts
setCharacterState(
entity,
state,
velocity,
grounded
): void;Drive a character's locomotion state machine.
Parameters
| Parameter | Type |
|---|---|
entity | number |
state | string |
velocity | Vec3 |
grounded | boolean |
Returns
void
Inherited from
EngineAdapter.setCharacterState
setClipWeights()
ts
setClipWeights(
entity,
clips,
weights,
timeScale
): void;Set explicit per-clip weights.
Parameters
| Parameter | Type |
|---|---|
entity | number |
clips | readonly string[] |
weights | ArrayLike<number> |
timeScale | number |
Returns
void
Inherited from
setExpression()
ts
setExpression(
entity,
space,
weights
): void;Set facial expression coefficients.
Parameters
| Parameter | Type |
|---|---|
entity | number |
space | ExpressionSpace |
weights | ArrayLike<number> |
Returns
void
Inherited from
setHud()
ts
setHud(json): void;Apply the HUD model, or leave the previous one when undefined.
Parameters
| Parameter | Type |
|---|---|
json | string | undefined |
Returns
void
Inherited from
setListener()
ts
setListener(
position,
rotation,
velocity
): void;Place the audio listener.
Parameters
| Parameter | Type |
|---|---|
position | Vec3 |
rotation | Quat |
velocity | Vec3 |
Returns
void
Inherited from
setMaterialParam()
ts
setMaterialParam(
entity,
name,
value
): void;Set one material uniform.
Parameters
| Parameter | Type |
|---|---|
entity | number |
name | string |
value | MaterialValue |
Returns
void
Inherited from
EngineAdapter.setMaterialParam
setParent()
ts
setParent(
entity,
parent,
keepWorldTransform
): void;Reparent an entity.
Parameters
| Parameter | Type |
|---|---|
entity | number |
parent | number | undefined |
keepWorldTransform | boolean |
Returns
void
Inherited from
setPlayerCamera()
ts
setPlayerCamera(player, camera): void;The camera one player renders from.
Parameters
| Parameter | Type |
|---|---|
player | number |
camera | CameraState |
Returns
void
Inherited from
setPlayerEntity()
ts
setPlayerEntity(player, entity): void;Which entity a player controls (0 for none). The authority keeps the mapping for relevancy and each player's "your entity"; a page ignores it.
Parameters
| Parameter | Type |
|---|---|
player | number |
entity | number |
Returns
void
Inherited from
setPlayerHud()
ts
setPlayerHud(player, hud): void;One player's HUD model as JSON.
Parameters
| Parameter | Type |
|---|---|
player | number |
hud | string |
Returns
void
Inherited from
setPointerLock()
ts
setPointerLock(locked): void;Request or release pointer lock.
Parameters
| Parameter | Type |
|---|---|
locked | boolean |
Returns
void
Inherited from
setTimeScale()
ts
setTimeScale(scale): void;Scale simulated time.
Parameters
| Parameter | Type |
|---|---|
scale | number |
Returns
void
Inherited from
spawn()
ts
spawn(
entity,
asset,
position,
rotation,
scale,
flags
): void;Create an entity in the scene.
Parameters
| Parameter | Type |
|---|---|
entity | number |
asset | number | undefined |
position | Vec3 |
rotation | Quat |
scale | Vec3 |
flags | { name?: string; parent?: number; visible: boolean; } |
flags.name? | string |
flags.parent? | number |
flags.visible | boolean |
Returns
void
Inherited from
spawnCharacter()
ts
spawnCharacter(
entity,
bundle,
position,
rotation
): void;Instantiate a splat character bundle.
Parameters
| Parameter | Type |
|---|---|
entity | number |
bundle | number |
position | Vec3 |
rotation | Quat |
Returns
void
Inherited from
stopSound()
ts
stopSound(sound, fadeMs): void;Stop a playing sound.
Parameters
| Parameter | Type |
|---|---|
sound | number |
fadeMs | number |
Returns
void
Inherited from
LoopEngine
The two parts of an engine a loop uses: the module registry and the event bus.
Both the page's Engine and a HeadlessEngine have them.
Example
ts
const engine: LoopEngine = await createHeadlessEngine({ manifest, modules });Properties
events
ts
readonly events: Events<EngineEventMap>;Where physics:stepped is announced.
modules
ts
readonly modules: ModuleRegistry;Where the physics service is looked up.
MinimalWasiOptions
Options for minimalWasi.
Properties
monotonicNs?
ts
optional monotonicNs?: () => bigint;Monotonic nanoseconds. Default: performance.now().
Returns
bigint
stderr?
ts
optional stderr?: StderrSink;Where the guest's stderr goes. Default: console.error.
NullAdapter
An adapter that records instead of rendering.
Extends
Properties
appliesLocal
ts
appliesLocal: boolean;Whether applyOutput applies localCommands here. True unless the options say otherwise.
Overrides
calls
ts
readonly calls: AdapterCall[];Every call, in order.
lastTransformCount
ts
readonly lastTransformCount: number;Rows handed to the most recent applyTransforms.
Methods
addBody()
ts
addBody(args): void;Create a rigid body or character controller.
Parameters
| Parameter | Type |
|---|---|
args | AddBodyCmd |
Returns
void
Inherited from
applyImpulse()
ts
applyImpulse(
body,
impulse,
atPoint
): void;Apply a one-shot impulse.
Parameters
| Parameter | Type |
|---|---|
body | number |
impulse | Vec3 |
atPoint | Vec3 | undefined |
Returns
void
Inherited from
applyTransforms()
ts
applyTransforms(transforms, count): void;Apply packed entity transforms.
Parameters
| Parameter | Type | Description |
|---|---|---|
transforms | Float32Array | Stride 12: entity, flags, position, rotation, scale. |
count | number | Number of rows. The buffer may be longer. |
Returns
void
Inherited from
by()
ts
by(method): AdapterCall[];Calls with a given method name.
Parameters
| Parameter | Type |
|---|---|
method | AdapterMethod |
Returns
conversation()
ts
conversation(command): void;Forward structural controls to an optional conversation module.
Parameters
| Parameter | Type |
|---|---|
command | ConversationCmd |
Returns
void
Inherited from
despawn()
ts
despawn(entity): void;Destroy an entity and everything attached to it.
Parameters
| Parameter | Type |
|---|---|
entity | number |
Returns
void
Inherited from
exchange()
ts
exchange(command): void;Trade between two players' documents. The command is pooled: read it, never keep it.
Parameters
| Parameter | Type |
|---|---|
command | ExchangeCmd |
Returns
void
Inherited from
loadAsset()
ts
loadAsset(asset, priority): void;Start loading an asset.
Parameters
| Parameter | Type |
|---|---|
asset | number |
priority | number |
Returns
void
Inherited from
localScope()?
ts
optional localScope(on): void;Optional: told when applyOutput starts (true) and ends (false) applying frame-output.local-commands. The server adapter uses it to keep what a local command does out of the replicated world record.
Parameters
| Parameter | Type |
|---|---|
on | boolean |
Returns
void
Inherited from
lookAt()
ts
lookAt(
entity,
target,
weight
): void;Aim a character's head and eyes.
Parameters
| Parameter | Type |
|---|---|
entity | number |
target | Vec3 | undefined |
weight | number |
Returns
void
Inherited from
moveCharacter()
ts
moveCharacter(
body,
desiredVelocity,
jump,
crouch,
maxSlopeDeg
): void;Drive a character body for one step.
Parameters
| Parameter | Type |
|---|---|
body | number |
desiredVelocity | Vec3 |
jump | boolean |
crouch | boolean |
maxSlopeDeg | number |
Returns
void
Inherited from
playSound()
ts
playSound(
sound,
asset,
entity,
position,
volume,
pitch,
looping,
bus
): void;Start a sound.
Parameters
| Parameter | Type |
|---|---|
sound | number |
asset | number |
entity | number | undefined |
position | Vec3 | undefined |
volume | number |
pitch | number |
looping | boolean |
bus | AudioBus |
Returns
void
Inherited from
removeBody()
ts
removeBody(body): void;Destroy a body.
Parameters
| Parameter | Type |
|---|---|
body | number |
Returns
void
Inherited from
reset()
ts
reset(): void;Forget every recorded call.
Returns
void
saveGameData()
ts
saveGameData(data): void;Persist the room's game-wide document (JSON).
Parameters
| Parameter | Type |
|---|---|
data | string |
Returns
void
Inherited from
savePlayerData()
ts
savePlayerData(player, data): void;Persist one player's document (JSON).
Parameters
| Parameter | Type |
|---|---|
player | number |
data | string |
Returns
void
Inherited from
say()
ts
say(
entity,
text,
audio,
visemes
): void;Speak a line.
Parameters
| Parameter | Type |
|---|---|
entity | number |
text | string |
audio | number | undefined |
visemes | string | undefined |
Returns
void
Inherited from
send()
ts
send(
to,
name,
payload,
reliable
): void;Send a game message; to undefined is every player (or the authority, from a client).
Parameters
| Parameter | Type |
|---|---|
to | number | undefined |
name | string |
payload | string |
reliable | boolean |
Returns
void
Inherited from
setAnim()
ts
setAnim(
entity,
clip,
looping,
speed,
fadeMs,
weight
): void;Play or cross-fade an animation clip.
Parameters
| Parameter | Type |
|---|---|
entity | number |
clip | string |
looping | boolean |
speed | number |
fadeMs | number |
weight | number |
Returns
void
Inherited from
setAsset()
ts
setAsset(entity, asset): void;Attach or detach a renderable.
Parameters
| Parameter | Type |
|---|---|
entity | number |
asset | number | undefined |
Returns
void
Inherited from
setBodyEnabled()
ts
setBodyEnabled(body, enabled): void;Enable or disable a body in the broad phase.
Parameters
| Parameter | Type |
|---|---|
body | number |
enabled | boolean |
Returns
void
Inherited from
setBodyTransform()
ts
setBodyTransform(
body,
position,
rotation,
teleport
): void;Move a body directly.
Parameters
| Parameter | Type |
|---|---|
body | number |
position | Vec3 |
rotation | Quat |
teleport | boolean |
Returns
void
Inherited from
EngineAdapter.setBodyTransform
setBodyVelocity()
ts
setBodyVelocity(
body,
linear,
angular
): void;Overwrite a body's velocities; undefined leaves one untouched.
Parameters
| Parameter | Type |
|---|---|
body | number |
linear | Vec3 | undefined |
angular | Vec3 | undefined |
Returns
void
Inherited from
setCamera()
ts
setCamera(camera): void;Apply the camera the guest asked for.
Parameters
| Parameter | Type |
|---|---|
camera | CameraState |
Returns
void
Inherited from
setCharacterState()
ts
setCharacterState(
entity,
state,
velocity,
grounded
): void;Drive a character's locomotion state machine.
Parameters
| Parameter | Type |
|---|---|
entity | number |
state | string |
velocity | Vec3 |
grounded | boolean |
Returns
void
Inherited from
EngineAdapter.setCharacterState
setClipWeights()
ts
setClipWeights(
entity,
clips,
weights,
timeScale
): void;Set explicit per-clip weights.
Parameters
| Parameter | Type |
|---|---|
entity | number |
clips | readonly string[] |
weights | ArrayLike<number> |
timeScale | number |
Returns
void
Inherited from
setExpression()
ts
setExpression(
entity,
space,
weights
): void;Set facial expression coefficients.
Parameters
| Parameter | Type |
|---|---|
entity | number |
space | ExpressionSpace |
weights | ArrayLike<number> |
Returns
void
Inherited from
setHud()
ts
setHud(json): void;Apply the HUD model, or leave the previous one when undefined.
Parameters
| Parameter | Type |
|---|---|
json | string | undefined |
Returns
void
Inherited from
setListener()
ts
setListener(
position,
rotation,
velocity
): void;Place the audio listener.
Parameters
| Parameter | Type |
|---|---|
position | Vec3 |
rotation | Quat |
velocity | Vec3 |
Returns
void
Inherited from
setMaterialParam()
ts
setMaterialParam(
entity,
name,
value
): void;Set one material uniform.
Parameters
| Parameter | Type |
|---|---|
entity | number |
name | string |
value | MaterialValue |
Returns
void
Inherited from
EngineAdapter.setMaterialParam
setParent()
ts
setParent(
entity,
parent,
keepWorldTransform
): void;Reparent an entity.
Parameters
| Parameter | Type |
|---|---|
entity | number |
parent | number | undefined |
keepWorldTransform | boolean |
Returns
void
Inherited from
setPlayerCamera()
ts
setPlayerCamera(player, camera): void;The camera one player renders from.
Parameters
| Parameter | Type |
|---|---|
player | number |
camera | CameraState |
Returns
void
Inherited from
setPlayerEntity()
ts
setPlayerEntity(player, entity): void;Which entity a player controls (0 for none). The authority keeps the mapping for relevancy and each player's "your entity"; a page ignores it.
Parameters
| Parameter | Type |
|---|---|
player | number |
entity | number |
Returns
void
Inherited from
setPlayerHud()
ts
setPlayerHud(player, hud): void;One player's HUD model as JSON.
Parameters
| Parameter | Type |
|---|---|
player | number |
hud | string |
Returns
void
Inherited from
setPointerLock()
ts
setPointerLock(locked): void;Request or release pointer lock.
Parameters
| Parameter | Type |
|---|---|
locked | boolean |
Returns
void
Inherited from
setTimeScale()
ts
setTimeScale(scale): void;Scale simulated time.
Parameters
| Parameter | Type |
|---|---|
scale | number |
Returns
void
Inherited from
spawn()
ts
spawn(
entity,
asset,
position,
rotation,
scale,
flags
): void;Create an entity in the scene.
Parameters
| Parameter | Type |
|---|---|
entity | number |
asset | number | undefined |
position | Vec3 |
rotation | Quat |
scale | Vec3 |
flags | { name?: string; parent?: number; visible: boolean; } |
flags.name? | string |
flags.parent? | number |
flags.visible | boolean |
Returns
void
Inherited from
spawnCharacter()
ts
spawnCharacter(
entity,
bundle,
position,
rotation
): void;Instantiate a splat character bundle.
Parameters
| Parameter | Type |
|---|---|
entity | number |
bundle | number |
position | Vec3 |
rotation | Quat |
Returns
void
Inherited from
stopSound()
ts
stopSound(sound, fadeMs): void;Stop a playing sound.
Parameters
| Parameter | Type |
|---|---|
sound | number |
fadeMs | number |
Returns
void
Inherited from
Sandbox
One loaded game module.
Properties
dead
ts
readonly dead: boolean;True once the guest has trapped or failed. A dead sandbox returns a safe empty frame forever; rebuild it.
error
ts
readonly error: Error | null;Why the sandbox died, when it did.
mode
ts
readonly mode: "wasm" | "direct";How this sandbox runs its guest.
Methods
init()
ts
init(config): void;Call once, before the first tick.
Parameters
| Parameter | Type |
|---|---|
config | HostGameConfig |
Returns
void
restore()
ts
restore(state): void;Restore a state produced by snapshot from the same build.
Parameters
| Parameter | Type |
|---|---|
state | Uint8Array |
Returns
void
shutdown()
ts
shutdown(): void;Release guest-side resources. No further calls follow.
Returns
void
snapshot()
ts
snapshot(): Uint8Array;Serialise the whole guest state.
Returns
Uint8Array
tick()
ts
tick(input): FrameOutput;One fixed simulation step.
Parameters
| Parameter | Type |
|---|---|
input | HostFrameInput |
Returns
WasmSandboxOptions
Load a jco transpiled component.
Properties
getCoreModule
ts
getCoreModule: (path) => Promise<Module>;Compile one of the nine core wasm files by its relative path.
Parameters
| Parameter | Type |
|---|---|
path | string |
Returns
Promise<Module>
guestModuleUrl?
ts
optional guestModuleUrl?: string | URL;URL of the transpiled game.js. Ignored when instantiate is given. Dynamically imported, so bundlers see a runtime specifier.
host
ts
host: HostApi;Host services the guest imports.
instantiate?
ts
optional instantiate?: Instantiate;The transpiled module's instantiate, when it is already imported.
mode
ts
mode: "wasm";wasi?
ts
optional wasi?: MinimalWasiOptions;WASI stub overrides.
Type Aliases
EngineHostOptions
ts
type EngineHostOptions = HostQueriesOptions;Options accepted by createEngineHost: seed, log sink and query capacity.
Instantiate
ts
type Instantiate = (getCoreModule, imports, instantiateCore) => Promise<Record<string, unknown>>;The instantiate a jco transpile --instantiation async module exports.
It resolves to the component's exports by name; the host reads only the versioned gameable:engine/game@0.2.0 one (see gameNamespace).
Parameters
| Parameter | Type |
|---|---|
getCoreModule | (path) => Promise<WebAssembly.Module> |
imports | Record<string, unknown> |
instantiateCore | typeof WebAssembly.instantiate |
Returns
Promise<Record<string, unknown>>
SandboxOptions
ts
type SandboxOptions =
| DirectSandboxOptions
| WasmSandboxOptions;Either kind of sandbox.
StderrSink
ts
type StderrSink = (bytes) => void;Where stub stderr goes. Replaced by minimalWasi({ stderr }).
Parameters
| Parameter | Type |
|---|---|
bytes | Uint8Array |
Returns
void
Variables
PACKAGE
ts
const PACKAGE: "@gameable/wasm-host";Package identity marker.
Example
ts
import { PACKAGE } from 'gameable/host';
console.log(PACKAGE); // 'gameable/host'Functions
applyCommand()
ts
function applyCommand(adapter, command): void;Dispatch one command to the adapter.
The switch is exhaustive over Command['tag']; adding a case to the WIT variant without adding one here is a compile error, which is exactly what should happen.
Parameters
| Parameter | Type | Description |
|---|---|---|
adapter | EngineAdapter | The engine. |
command | Command | The command. |
Returns
void
Nothing.
Example
ts
import { applyCommand } from 'gameable/host';
for (const command of out.commands) applyCommand(adapter, command);applyOutput()
ts
function applyOutput(adapter, out): void;Apply a whole frame-output.
Parameters
| Parameter | Type | Description |
|---|---|---|
adapter | EngineAdapter | The engine. |
out | FrameOutput | The guest's output for this frame. |
Returns
void
Nothing.
Example
ts
import { applyOutput } from 'gameable/host';
applyOutput(adapter, sandbox.tick(input));copyInputState()
ts
function copyInputState(state, snapshot): void;Copy the input module's state into the encoder's shape.
The two differ in exactly two places: the key bitsets are named keysDown / keysPressed / keysReleased rather than down / pressed / released, and mods is a bitfield rather than a record.
Parameters
| Parameter | Type | Description |
|---|---|---|
state | InputState | The input module's published state. |
snapshot | InputSnapshot | The snapshot to rewrite. |
Returns
void
Nothing.
createDirectSandbox()
ts
function createDirectSandbox(options): Sandbox;Build a direct-mode sandbox, synchronously.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | DirectSandboxOptions | The game definition and host services. |
Returns
A sandbox running the SDK runtime in this realm.
Example
ts
import { createDirectSandbox } from 'gameable/host';
const sandbox = createDirectSandbox({ mode: 'direct', game, host });createDomHud()
ts
function createDomHud(options?): HudRenderer;Create the default DOM HUD.
The renderer is deliberately dumb: it knows four keys and draws them the same way for every game. A game that wants its own look passes its own renderer to createEngineAdapter({ hud }), or turns this one off with { hud: false } and reads adapter.hudModel itself.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | DomHudOptions | Container, document and root class name. |
Returns
A renderer, already attached to its container.
Example
ts
import { createDomHud } from 'gameable/host';
const hud = createDomHud();
hud.set(JSON.stringify({ text: { ammo: 12 }, crosshair: true }));createEngineAdapter()
ts
function createEngineAdapter(engine, options?): EngineAdapterHandle;Build the adapter that applies frame-output to a booted engine.
Parameters
| Parameter | Type | Description |
|---|---|---|
engine | Engine | The engine from createEngine. |
options | EngineAdapterOptions | Modules, HUD and capacity. |
Returns
An adapter, plus the per-frame hooks createHostLoop drives.
Example
ts
import { createEngine } from 'gameable/core';
import { createEngineAdapter } from 'gameable/host';
const modules = [physics(), input(), audio(), splat()];
const engine = await createEngine({ canvas, manifest, modules });
const adapter = createEngineAdapter(engine, { modules });createEngineHost()
ts
function createEngineHost(
engine,
adapter,
options?
): HostApi;Build the HostApi a browser sandbox imports.
These are the only synchronous calls the guest may make during tick: three physics queries and two init-time manifest lookups. Everything else the guest wants is a command, applied after it returns. The queries themselves are HostQueries, shared with the server's createServerHost; this wrapper only says where the page's physics, bodies and assets come from.
Physics is looked up lazily, on the first query that finds it registered, so the host can be built before the engine boots.
Parameters
| Parameter | Type | Description |
|---|---|---|
engine | Engine | The booted engine. |
adapter | EngineAdapterHandle | The adapter, for the body-to-entity mapping queries report. |
options | HostQueriesOptions | Seed, log sink and query capacity. |
Returns
A HostApi to hand to createSandbox.
Example
ts
import { createEngineAdapter, createEngineHost, createSandbox } from 'gameable/host';
const adapter = createEngineAdapter(engine, { modules });
const host = createEngineHost(engine, adapter, { seed: 1 });
const sandbox = await createSandbox({ mode: 'direct', game, host });createGameSlot()
ts
function createGameSlot(order?): GameSlot;Reserve the game module's place in the module order.
createEngine wants its module list up front, and the game module wants the booted engine — the adapter needs engine.graph, the host bindings need engine.assets. Rather than make every application shell invent a way round that, the slot registers a module that does nothing until GameSlot.attach hands it the real one.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
order | number | -50 | Module order. Defaults to -50: after input, before physics, matching createHostLoop. The slot's order is the one that counts — the engine sorts the placeholder, not the loop attached to it. |
Returns
The slot.
Example
ts
import { createGameSlot, createHostLoop } from 'gameable/host';
const slot = createGameSlot();
const engine = await createEngine({ canvas, manifest, modules: [...modules, slot.module] });
await slot.attach(createHostLoop(engine, sandbox, adapter), engine.ctx);createHostLoop()
ts
function createHostLoop(
engine,
sandbox,
adapter,
options?
): EngineModule;The game module: one fixed step is one guest tick.
Order -50: after input, before physics. The guest therefore ticks on the freshest input there is, and the move-character, apply-impulse and set-body-velocity commands it emits are simulated by the physics step in the same fixed step rather than the next one. That is one whole step of input latency gone — the difference between a jump landing on the frame the key went down and a frame later.
The bodies the guest reads are still post-step rows, one step old: exactly the state it reacted to when it emitted those commands. They arrive on the physics:stepped event, which this module subscribes to in init — the same handler writes each row onto the entity it drives through EngineAdapterHandle.applyBodyRows, so a physics-driven object gets to the screen without its transform ever crossing the wasm boundary.
Its update hands the interpolation factor to the adapter, which is what makes a 60 Hz simulation look smooth on a 144 Hz display.
The first failure latches: a dead sandbox is not retried, because a trapped component instance stays poisoned. The overlay says so.
Parameters
| Parameter | Type | Description |
|---|---|---|
engine | Engine | The booted engine. |
sandbox | Sandbox | The guest, from createSandbox. |
adapter | EngineAdapterHandle | The adapter from createEngineAdapter. |
options | HostLoopOptions | Seed, capacity and the death handler. |
Returns
A module to register with createEngine.
Example
ts
import { createHostLoop } from 'gameable/host';
const game = createHostLoop(engine, sandbox, adapter, { seed: 1n });
engine.modules.register(game); // or pass it in createEngine({ modules })createInputEncoder()
ts
function createInputEncoder(maxBodies?): InputEncoder;Create a reusable frame-input builder.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
maxBodies | number | 4096 | Initial hint for the memoised view table — not a ceiling. A frame with more rows than this still reaches the guest whole; the hint only decides how many subarray views are preallocated, and the table grows with the game. |
Returns
An encoder that reuses one frame-input record.
Example
ts
import { createInputEncoder } from 'gameable/host';
const encoder = createInputEncoder(2048);
const input = encoder.encode({ frame, dt, elapsed, inputState, bodies, bodyCount });createInputSnapshot()
ts
function createInputSnapshot(): InputSnapshot;A zeroed snapshot, the one a host loop rewrites every fixed step.
Returns
A fresh snapshot.
createSandbox()
ts
function createSandbox(options): Promise<Sandbox>;Build a sandbox in either mode.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | SandboxOptions | Direct or wasm configuration. |
Returns
Promise<Sandbox>
The sandbox, once the component (if any) is instantiated.
Example
ts
import { createSandbox } from 'gameable/host';
const sandbox = await createSandbox({
mode: 'wasm',
guestModuleUrl: new URL('./guest/game.js', import.meta.url),
getCoreModule: (p) => fetch(new URL(p, base)).then((r) => WebAssembly.compileStreaming(r)),
host,
});hostBindings()
ts
function hostBindings(host): HostBindings;Adapt a HostApi to the import object instantiate expects.
Parameters
| Parameter | Type | Description |
|---|---|---|
host | HostApi | The host services. |
Returns
The gameable:engine/* import object, with unversioned keys.
Example
ts
import { hostBindings, minimalWasi } from 'gameable/host';
const root = await instantiate(getCoreModule, {
...minimalWasi(),
...hostBindings(host),
});minimalWasi()
ts
function minimalWasi(options?): Record<string, unknown>;Build the wasi:* half of the import object.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | MinimalWasiOptions | Stderr sink and clock overrides. |
Returns
Record<string, unknown>
An object keyed by unversioned WASI interface name.
Example
ts
import { minimalWasi } from 'gameable/host';
const imports = { ...minimalWasi(), ...hostBindings(host) };NullEngineAdapter()
ts
function NullEngineAdapter(options?): NullAdapter;An adapter that records every call and does nothing else.
The node-side stand-in for the real engine: boundary tests assert on calls, and deepCopy is deliberately absent, because the whole point is that the guest reuses its command objects.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | { appliesLocal?: boolean; } | What the adapter says about itself. |
options.appliesLocal? | boolean | False to stand in for a replica, which skips localCommands. Defaults to true. |
Returns
A recording adapter.
Example
ts
import { NullEngineAdapter } from 'gameable/host';
const adapter = NullEngineAdapter();
applyOutput(adapter, out);
console.log(adapter.by('spawn').length);quantizeInput()
ts
function quantizeInput(input): HostFrameInput;Round every f32 field of a frame-input in place.
bodies is already a Float32Array, so it needs nothing. frame is a u64 and focused a bool; only the timing, mouse, gamepad, event and contact floats can differ.
Parameters
| Parameter | Type | Description |
|---|---|---|
input | HostFrameInput | The frame input to normalise. Mutated in place where it can be, which is every field the host encoder owns. |
Returns
The same object.
Example
ts
import { quantizeInput } from 'gameable/host';
sandbox.tick(quantizeInput(encoder.encode(args)));quantizeSeed()
ts
function quantizeSeed(seed): bigint;Round a game-config's floats. There are none today, but the seed must be a bigint and the counts integers; this is the hook if the record grows.
Parameters
| Parameter | Type | Description |
|---|---|---|
seed | number | bigint | The seed as the host holds it. |
Returns
bigint
The same value, as a bigint.
Example
ts
import { quantizeSeed } from 'gameable/host';
const seed = quantizeSeed(0x5eed1234n);