Skip to content

gameable ​

Classes ​

BodyIndex ​

Maps host body ids back onto entities and ingests frame-input.bodies.

The incoming list is a Float32Array in both modes — jco lifts WIT list<f32> into one, and direct mode hands the guest the host's own buffer (see packages/sdk/src/wit/generated/interfaces/gameable-engine-game.d.ts). It is read purely by index and never copied.

Constructors ​

Constructor ​
ts
new BodyIndex(maxBodies): BodyIndex;
Parameters ​
ParameterTypeDescription
maxBodiesnumberBody-id ceiling.
Returns ​

BodyIndex

Properties ​

bodyToEntity ​
ts
readonly bodyToEntity: Uint32Array;

Body id to entity id. Index 0 is unused: body 0 means "no body".

lastRowCount ​
ts
lastRowCount: number = 0;

Number of rows seen in the most recent ingest.

Methods ​

bind() ​
ts
bind(body, entity): void;

Associate a body with the entity it drives.

Parameters ​
ParameterTypeDescription
bodynumberBody id.
entitynumberEntity id.
Returns ​

void

Nothing.

bodyOf() ​
ts
bodyOf(entity): number;

The body id driving an entity, or 0.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
Returns ​

number

The body id, or 0 when the entity has none.

clear() ​
ts
clear(): void;

Forget every body.

Returns ​

void

Nothing.

ingest() ​
ts
ingest(bodies): void;

Copy post-step body transforms into Transform and Velocity.

This does not mark the entity moved, and that is the point. The host owns a body-driven entity's transform: the physics module hands the same rows straight to the adapter after it steps, so the object in the scene is already where the body is. Marking here would send all twelve floats back across the boundary in frame-output.transforms for the host to write a second time — the same numbers, one step later.

What the guest gets is still the truth for gameplay: read Transform.x[e] to aim at something, Velocity to decide whether it is running. A system that overwrites those lanes is authoring a move rather than observing one, and has to say so with markMoved — see markMoved.

Parameters ​
ParameterTypeDescription
bodiesArrayLike<number>The packed rows, stride 15.
Returns ​

void

Nothing.

unbind() ​
ts
unbind(body): void;

Forget a body.

Parameters ​
ParameterTypeDescription
bodynumberBody id.
Returns ​

void

Nothing.


CommandBuffer ​

Builds and owns one frame's commands list.

Constructors ​

Constructor ​
ts
new CommandBuffer(): CommandBuffer;
Returns ​

CommandBuffer

Properties ​

list ​
ts
readonly list: Command[] = [];

The list handed to the host. Reused every frame; never retain it.

Methods ​

addBody() ​
ts
addBody(
   body, 
   entity, 
   kind, 
   shape, 
   hx, 
   hy, 
   hz, 
   px, 
   py, 
   pz, 
   mass, 
   layer, 
   mask, 
   flags
): AddBodyCmd;

Create a rigid body or character controller.

Parameters ​
ParameterTypeDescription
bodynumberGuest-minted body id.
entitynumberEntity the body drives.
kindBodyKindBody class.
shapeShapeKindCollision shape family.
hxnumberHalf-extent / radius lane 0.
hynumberHalf-extent / half-height lane 1.
hznumberHalf-extent lane 2.
pxnumberPosition x.
pynumberPosition y.
pznumberPosition z.
massnumberKilograms; ignored for fixed and kinematic bodies.
layerCollisionLayersWhat this body is.
maskCollisionLayersWhat this body collides with.
flagsBodyFlagsPer-body switches.
Returns ​

AddBodyCmd

The payload, so the caller can tune friction and damping. Round anything written onto it with Math.fround.

applyImpulse() ​
ts
applyImpulse(
   body, 
   x, 
   y, 
   z, 
   atX?, 
   atY?, 
   atZ?
): void;

Apply a one-shot impulse.

Parameters ​
ParameterTypeDescription
bodynumberBody id.
xnumberImpulse x.
ynumberImpulse y.
znumberImpulse z.
atX?numberWorld-space application point x. Omit for the centre of mass.
atY?numberApplication point y.
atZ?numberApplication point z.
Returns ​

void

Nothing.

cancelCharacterAction() ​
ts
cancelCharacterAction(entity): void;

Take an action's request back.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
Returns ​

void

Nothing.

conversation() ​
ts
conversation(
   entity, 
   action, 
   character?, 
   text?
): void;

Control an optional host conversation module using pooled commands.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedInterviewed entity.
action| "end" | "start" | "ask" | "interrupt" | "microphone-on" | "microphone-off"undefinedLifecycle or text command.
characterstring''Configured character id, never a URL.
textstring''Typed/transcribed question; empty for lifecycle commands.
Returns ​

void

cutscene() ​
ts
cutscene(
   action, 
   asset, 
   fadeInMs?, 
   fadeOutMs?, 
   skippable?, 
   pause?
): void;

A cutscene: preload a clip, play it over the stage, or skip the one playing.

Parameters ​
ParameterTypeDefault valueDescription
action"play" | "preload" | "skip"undefined'preload', 'play' or 'skip'.
assetnumberundefinedThe video asset handle; 0 for skip.
fadeInMsnumber400Fade in, milliseconds.
fadeOutMsnumber400Fade out, milliseconds.
skippablebooleantrueA tap or a key ends it early.
pausebooleantrueThe stage pauses under it and the game's sound is ducked.
Returns ​

void

despawn() ​
ts
despawn(entity): void;

Destroy an entity in the host scene.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
Returns ​

void

Nothing.

doCharacterAction() ​
ts
doCharacterAction(
   entity, 
   action, 
   object, 
   plain
): void;

Ask a character to do an action of its motion set.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
actionstringThe action's name.
objectReadonly<ActionObject> | nullThe thing it is done at, or null for none.
plainbooleanThe plain way, for a comparison.
Returns ​

void

Nothing.

faceCharacter() ​
ts
faceCharacter(
   entity, 
   facing, 
   quick?
): void;

Turn a character on the spot to face a way.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity id.
facingnumberundefinedRadians about +Y (0 faces +Z).
quickbooleanfalseThe quickest turn the set has, instead of an unhurried one.
Returns ​

void

Nothing.

hitCharacter() ​
ts
hitCharacter(
   entity, 
   at, 
   direction, 
   strength
): void;

A blow on a character's physics body.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
atVec3Where the blow lands, world space.
directionVec3 | nullWhich way it travels, world space; null for the character's front.
strengthnumber | "small" | "big" | "shot" | "big-shot"'small', 'big', 'shot', 'big-shot', or a push's newton-seconds.
Returns ​

void

Nothing.

loadAsset() ​
ts
loadAsset(asset, priority): void;

Ask the host to start loading an asset.

Parameters ​
ParameterTypeDescription
assetnumberAsset handle.
prioritynumberHigher runs first.
Returns ​

void

Nothing.

lookAt() ​
ts
lookAt(
   entity, 
   target, 
   weight
): void;

Aim a character's head and eyes.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
targetVec3 | nullWorld-space point, or null to release the look-at.
weightnumberBlend weight in 0..1.
Returns ​

void

Nothing.

moveCharacter() ​
ts
moveCharacter(
   body, 
   vx, 
   vy, 
   vz, 
   jump, 
   crouch, 
   maxSlopeDeg
): void;

Drive a character body for one step.

Parameters ​
ParameterTypeDescription
bodynumberBody id of a character body.
vxnumberDesired velocity x.
vynumberDesired velocity y.
vznumberDesired velocity z.
jumpbooleanRequest a jump this step.
crouchbooleanRequest a crouch this step.
maxSlopeDegnumberMaximum walkable slope in degrees.
Returns ​

void

Nothing.

playSound() ​
ts
playSound(
   sound, 
   asset, 
   entity, 
   volume, 
   pitch, 
   looping, 
   bus
): void;

Start a sound.

Parameters ​
ParameterTypeDescription
soundnumberGuest-minted sound handle.
assetnumberAudio asset handle.
entitynumber | undefinedEntity to follow, or undefined for a non-positional sound.
volumenumberLinear gain in 0..1.
pitchnumberPlayback-rate multiplier.
loopingbooleanLoop the sound.
busAudioBusMixer bus.
Returns ​

void

Nothing.

recoverCharacter() ​
ts
recoverCharacter(entity): void;

Back into the animation: a character that is down blends back over about a second.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
Returns ​

void

Nothing.

removeBody() ​
ts
removeBody(body): void;

Destroy a body.

Parameters ​
ParameterTypeDescription
bodynumberBody id.
Returns ​

void

Nothing.

reset() ​
ts
reset(): void;

Rewind for a new frame. Keeps every pooled object alive.

Returns ​

void

Nothing.

say() ​
ts
say(
   entity, 
   text, 
   audio?, 
   visemes?
): void;

Speak a line.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
textstringSubtitle text.
audio?numberVoice line asset handle.
visemes?stringViseme track as JSON.
Returns ​

void

Nothing.

setAnim() ​
ts
setAnim(
   entity, 
   clip, 
   looping, 
   speed, 
   fadeMs, 
   weight
): void;

Play or cross-fade a clip.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
clipstringClip name inside the entity's asset.
loopingbooleanLoop the clip.
speednumberPlayback rate multiplier.
fadeMsnumberCross-fade duration in milliseconds.
weightnumberTarget layer weight in 0..1.
Returns ​

void

Nothing.

setAsset() ​
ts
setAsset(entity, asset): void;

Attach or detach a renderable.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
assetnumber | undefinedAsset handle, or undefined to detach.
Returns ​

void

Nothing.

setBodyEnabled() ​
ts
setBodyEnabled(body, enabled): void;

Enable or disable a body in the broad phase.

Parameters ​
ParameterTypeDescription
bodynumberBody id.
enabledbooleanWhether the body participates.
Returns ​

void

Nothing.

setBodyTransform() ​
ts
setBodyTransform(
   body, 
   px, 
   py, 
   pz, 
   qx, 
   qy, 
   qz, 
   qw, 
   teleport
): void;

Move a body directly.

Parameters ​
ParameterTypeDescription
bodynumberBody id.
pxnumberPosition x.
pynumberPosition y.
pznumberPosition z.
qxnumberRotation x.
qynumberRotation y.
qznumberRotation z.
qwnumberRotation w.
teleportbooleanClear velocities and skip interpolation.
Returns ​

void

Nothing.

setBodyVelocity() ​
ts
setBodyVelocity(
   body, 
   x, 
   y, 
   z, 
   ax?, 
   ay?, 
   az?
): void;

Overwrite a body's velocity.

Parameters ​
ParameterTypeDescription
bodynumberBody id.
xnumberLinear x.
ynumberLinear y.
znumberLinear z.
ax?numberAngular x, radians per second. Omit to leave spin alone.
ay?numberAngular y.
az?numberAngular z.
Returns ​

void

Nothing.

setCharacterMotion() ​
ts
setCharacterMotion(
   entity, 
   on, 
   set, 
   carry, 
   responsiveness, 
   naturalness, 
   stop?
): void;

How the movement system moves a character.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
onbooleanWhether the movement system moves it at all.
setstring | undefined'own', 'shared' or a name the page gave its bridge; undefined keeps the set it has.
carrybooleanWhether the take carries the walker.
responsivenessnumber0..1; negative keeps what it has.
naturalnessnumber0..1; negative keeps what it has.
stop?StopStyleWhich kind of stop it makes when it runs and is asked to stand: 'gradual' (it slows and stands upright) or 'hard' (it brakes); undefined keeps what it has.
Returns ​

void

Nothing.

setCharacterState() ​
ts
setCharacterState(
   entity, 
   state, 
   vx, 
   vy, 
   vz, 
   grounded
): void;

Drive a character's locomotion state machine.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
statestringState name, for example `'idle'
vxnumberVelocity x.
vynumberVelocity y.
vznumberVelocity z.
groundedbooleanWhether the character is on the ground.
Returns ​

void

Nothing.

setClipWeights() ​
ts
setClipWeights(
   entity, 
   clips, 
   weights, 
   timeScale
): void;

Set explicit per-clip weights.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
clipsreadonly string[]Clip names.
weightsreadonly number[] | Float32Array<ArrayBufferLike>Positional weights; must match clips in length. Copied into pooled storage, so the caller may reuse its own array freely.
timeScalenumberPlayback rate for the whole layer.
Returns ​

void

Nothing.

setExpression() ​
ts
setExpression(
   entity, 
   space, 
   weights
): void;

Set facial expression coefficients.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
spaceExpressionSpaceCoordinate space the weights are in.
weightsreadonly number[] | Float32Array<ArrayBufferLike>Coefficients; length must match the space. Copied into pooled storage, so the caller may reuse its own array freely.
Returns ​

void

Nothing.

setListener() ​
ts
setListener(
   px, 
   py, 
   pz, 
   qx, 
   qy, 
   qz, 
   qw
): void;

Place the audio listener.

Parameters ​
ParameterTypeDescription
pxnumberPosition x.
pynumberPosition y.
pznumberPosition z.
qxnumberRotation x.
qynumberRotation y.
qznumberRotation z.
qwnumberRotation w.
Returns ​

void

Nothing.

setMaterialParam() ​
ts
setMaterialParam(
   entity, 
   name, 
   value
): void;

Set one material uniform.

The value is copied into a pooled holder, rounded to f32: the host never sees the guest's own object, and a colour built inline costs nothing after the first frame. Only a slot that changes variant allocates.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
namestringUniform name.
valueMaterialValueThe value variant.
Returns ​

void

Nothing.

setParent() ​
ts
setParent(
   entity, 
   parent, 
   keepWorldTransform
): void;

Reparent an entity.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
parentnumber | undefinedNew parent, or undefined for the scene root.
keepWorldTransformbooleanPreserve the world transform across the move.
Returns ​

void

Nothing.

setPointerLock() ​
ts
setPointerLock(locked): void;

Request or release pointer lock.

Parameters ​
ParameterTypeDescription
lockedbooleanWhether the canvas should hold pointer lock.
Returns ​

void

Nothing.

setTimeScale() ​
ts
setTimeScale(scale): void;

Scale simulated time.

Parameters ​
ParameterTypeDescription
scalenumberMultiplier; 1 is real time.
Returns ​

void

Nothing.

spawn() ​
ts
spawn(
   entity, 
   asset, 
   px, 
   py, 
   pz, 
   qx, 
   qy, 
   qz, 
   qw, 
   sx, 
   sy, 
   sz, 
   name?
): void;

Create an entity in the host scene.

Parameters ​
ParameterTypeDescription
entitynumberGuest-minted entity id.
assetnumber | undefinedRenderable asset handle, or undefined for a bare node.
pxnumberPosition x.
pynumberPosition y.
pznumberPosition z.
qxnumberRotation x.
qynumberRotation y.
qznumberRotation z.
qwnumberRotation w.
sxnumberScale x.
synumberScale y.
sznumberScale z.
name?stringDebug label.
Returns ​

void

Nothing.

spawnCharacter() ​
ts
spawnCharacter(
   entity, 
   bundle, 
   px, 
   py, 
   pz, 
   qx, 
   qy, 
   qz, 
   qw
): void;

Instantiate a splat character bundle.

Parameters ​
ParameterTypeDescription
entitynumberGuest-minted entity id.
bundlenumberCharacter bundle asset handle.
pxnumberPosition x.
pynumberPosition y.
pznumberPosition z.
qxnumberRotation x.
qynumberRotation y.
qznumberRotation z.
qwnumberRotation w.
Returns ​

void

Nothing.

stopCharacterWalk() ​
ts
stopCharacterWalk(entity): void;

Give up a walk to a spot.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
Returns ​

void

Nothing.

stopSound() ​
ts
stopSound(sound, fadeMs): void;

Stop a playing sound.

Parameters ​
ParameterTypeDescription
soundnumberSound handle.
fadeMsnumberFade-out in milliseconds.
Returns ​

void

Nothing.

take() ​
ts
protected take<T>(tag, make): T;

Take the next pooled slot for a tag, appending it to the frame list.

Type Parameters ​
Type Parameter
T
Parameters ​
ParameterTypeDescription
tag| "spawn" | "send" | "set-player-camera" | "set-player-hud" | "save-player-data" | "save-game-data" | "set-player-entity" | "exchange" | "conversation" | "despawn" | "set-asset" | "set-parent" | "set-anim" | "set-material-param" | "add-body" | "remove-body" | "set-body-transform" | "set-body-velocity" | "apply-impulse" | "set-body-enabled" | "move-character" | "spawn-character" | "set-character-state" | "set-clip-weights" | "set-expression" | "look-at" | "say" | "hit-character" | "recover-character" | "set-character-motion" | "walk-character-to" | "face-character" | "stop-character-walk" | "do-character-action" | "cancel-character-action" | "play-sound" | "stop-sound" | "set-listener" | "load-asset" | "set-pointer-lock" | "set-time-scale" | "cutscene" | "thing"The command tag.
make() => TModule-const factory for a fully shaped payload, called only when the pool has to grow.
Returns ​

T

The payload to mutate. Every field must be written: the slot still holds whatever the last command with this tag left behind.

thing() ​
ts
thing(
   action, 
   thing, 
   x?, 
   y?, 
   z?
): void;

Ask something of a loose thing in a made world: push it, move it, put it back where the package had it, set one of its joints, drive it, or sit a character on it.

Parameters ​
ParameterTypeDefault valueDescription
action| "push" | "joint" | "move" | "reset" | "drive" | "reset-all" | "ride" | "break"undefined'push', 'move', 'reset', 'reset-all', 'joint', 'drive', 'ride' or 'break' (x, y, z: metres a second added to each piece).
thingnumberundefinedThe thing's place in the world's list.
xnumber0push: impulse x, newton-seconds. move: where, x. joint: which joint. drive: steering to the right. ride: the character's entity, 0 for getting off.
ynumber0The same, y. joint: its value. drive: the brakes.
znumber0The same, z. drive: the throttle.
Returns ​

void

walkCharacterTo() ​
ts
walkCharacterTo(
   entity, 
   target, 
   facing, 
   pace, 
   quick?, 
   stop?, 
   start?
): void;

Walk a character to a spot.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity id.
targetVec3undefinedThe spot, world space.
facingnumber | undefinedundefinedThe facing to arrive with, radians about +Y; undefined: as it arrives.
pacenumberundefinedMetres a second; 0 is the set's own walk.
quickbooleanfalseThe shortest stops and turns the set has, instead of unhurried ones.
stop?StopStyleundefinedWhich kind of stop this one walk ends with: 'gradual' (it slows and stands upright) or 'hard' (it brakes); undefined: the character's own.
start?"moving"undefinedHow it is begun: 'moving', the game says the body is under way already; undefined: as the character's takes have the body.
Returns ​

void

Nothing.


MessageDef ​

One game message: what defineMessage returns. Pass it to ctx.net.messages and ctx.net.send.

Example ​

ts
const Ready = defineMessage('ready', (p): p is true => p === true);
console.log(Ready.name, Ready.maxBytes); // 'ready' 2048

Type Parameters ​

Type Parameter
T

Constructors ​

Constructor ​
ts
new MessageDef<T>(
   name, 
   check, 
   maxBytes
): MessageDef<T>;
Parameters ​
ParameterTypeDescription
namestringThe message name on the wire.
checkMessageCheck<T>The payload's type guard.
maxBytesnumberThe payload cap in UTF-8 bytes of JSON.
Returns ​

MessageDef<T>

Properties ​

check ​
ts
readonly check: MessageCheck<T>;

The payload's type guard.

maxBytes ​
ts
readonly maxBytes: number;

The payload cap in UTF-8 bytes of JSON.

name ​
ts
readonly name: string;

The message name on the wire.


TransformPacker ​

Packs entity transforms into frame-output.transforms.

One row is written per entity whose dirty flags are non-zero, in ascending entity order — deterministic, and cheaper than a bitecs query for the densely packed id space the SDK mints.

Constructors ​

Constructor ​
ts
new TransformPacker(maxEntities): TransformPacker;
Parameters ​
ParameterTypeDescription
maxEntitiesnumberEntity ceiling; the buffer holds this many rows.
Returns ​

TransformPacker

Properties ​

dirty ​
ts
readonly dirty: Uint8Array;

Per-entity transform-flags accumulated since the last pack.

highWater ​
ts
highWater: number = 0;

Highest entity id pack scans to.

It rises when a higher id is marked and falls back to the last dirty id every pack, so a level that spawned 4,000 entities and despawned all but ten does not keep scanning 4,000 slots a frame.

Methods ​

clear() ​
ts
clear(): void;

Forget every pending flag, for example after restore.

Returns ​

void

Nothing.

mark() ​
ts
mark(entity, flags): void;

Accumulate dirty flags for one entity.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
flagsnumberAny combination of TRANSFORM_FLAGS.
Returns ​

void

Nothing.

pack() ​
ts
pack(): Float32Array;

Write every dirty entity into the packed buffer and clear the flags.

Returns ​

Float32Array

A memoised subarray of the internal buffer. The same row count always returns the same object, which is what makes a steady-state tick allocation-free; never retain it across frames.

Interfaces ​

ActionObject ​

The thing an action is done at, as the game has it.

Properties ​

depth ​
ts
depth: number;
height ​
ts
height: number;

Its top over that floor, and its size across and along the way, metres.

id ​
ts
id: number;

The game's own number for it, said back in events.

position ​
ts
position: Vec3;

Its middle, on the floor it stands on, world space.

width ​
ts
width: number;
yaw ​
ts
yaw: number;

The way across it, radians about +Y (0 is +Z).


AddBodyCmd ​

Create a rigid body or character controller.

Properties ​

angularDamping ​
ts
angularDamping: number;
body ​
ts
body: number;
entity ​
ts
entity: number;
flags ​
ts
flags: BodyFlags;
friction ​
ts
friction: number;
kind ​
ts
kind: BodyKind;
layer ​
ts
layer: CollisionLayers;
linearDamping ​
ts
linearDamping: number;
mask ​
ts
mask: CollisionLayers;
mass ​
ts
mass: number;
position ​
ts
position: Vec3;
restitution ​
ts
restitution: number;
rotation ​
ts
rotation: Quat;
shape ​
ts
shape: Shape;

AnimEventData ​

An animation clip passed a named marker: 'ended' when a once-only clip finished, 'loop' when a looping clip came round (both from the host's mixer), or a marker embedded in the clip.

Properties ​

clip ​
ts
clip: string;
entity ​
ts
entity: number;
name ​
ts
name: string;
time ​
ts
time: number;

Clip-local time of the marker, seconds.


ApplyImpulseCmd ​

Apply a one-shot impulse.

Properties ​

atPoint? ​
ts
optional atPoint?: Vec3;
body ​
ts
body: number;
impulse ​
ts
impulse: Vec3;

AssetDesc ​

Manifest metadata for one asset handle.

Properties ​

hasCollider ​
ts
hasCollider: boolean;
id ​
ts
id: number;
kind ​
ts
kind: AssetKind;
name ​
ts
name: string;
ready ​
ts
ready: boolean;
rig? ​
ts
optional rig?: string;
tags ​
ts
tags: readonly string[];

AssetLoadedEvent ​

An asset finished loading.

Properties ​

asset ​
ts
asset: number;
name ​
ts
name: string;

Axis2 ​

A two-axis reading. Each facade returns its own object, the same one every call.

Properties ​

x ​
ts
x: number;
y ​
ts
y: number;

BodyFlags ​

Per-body behaviour switches. Omitted keys lower as false.

Properties ​

ccd? ​
ts
optional ccd?: boolean;
debugDraw? ​
ts
optional debugDraw?: boolean;
lockRotation? ​
ts
optional lockRotation?: boolean;
noSleep? ​
ts
optional noSleep?: boolean;
reportContacts? ​
ts
optional reportContacts?: boolean;
sensor? ​
ts
optional sensor?: boolean;

BodySpec ​

The physics body a prefab carries.

Properties ​

dims? ​
ts
optional dims?: readonly number[];

Shape dimensions. box: half extents. sphere: [radius]. capsule / cylinder: [radius, halfHeight]. plane: the normal.

flags? ​
ts
optional flags?: BodyFlags;

Per-body switches.

friction? ​
ts
optional friction?: number;

Coulomb friction. Default 0.5.

kind ​
ts
kind: BodyKind;

Body class. 'character' makes a CharacterVirtual controller.

layer? ​
ts
optional layer?: CollisionLayers;

What this body is. Default { defaultLayer: true }.

mask? ​
ts
optional mask?: CollisionLayers;

What this body collides with. Default every layer.

mass? ​
ts
optional mass?: number;

Kilograms; ignored for fixed and kinematic bodies. Default 1.

restitution? ​
ts
optional restitution?: number;

Bounciness in 0..1. Default 0.

shape ​
ts
shape: ShapeKind;

Collision shape family.


CameraState ​

The camera the host should render from this frame.

Properties ​

armLength ​
ts
armLength: number;
far ​
ts
far: number;
follow? ​
ts
optional follow?: number;
fovYDeg ​
ts
fovYDeg: number;
mode ​
ts
mode: CameraMode;
near ​
ts
near: number;
offset ​
ts
offset: Vec3;
position ​
ts
position: Vec3;
projection ​
ts
projection: ProjectionKind;
rotation ​
ts
rotation: Quat;
target? ​
ts
optional target?: Vec3;

CharacterReadyEvent ​

A character bundle finished loading and reported its expression space.

Properties ​

bundle ​
ts
bundle: number;
entity ​
ts
entity: number;
expressionDim ​
ts
expressionDim: number;
space ​
ts
space: ExpressionSpace;

CharactersOptions ​

Options for the characters feature.

Properties ​

motion? ​
ts
optional motion?: 
  | false
  | {
  actions?: boolean;
  carry?: boolean;
  feet?: "performed" | "own";
  footPlant?: boolean;
  legs?: "performed" | "bent";
  naturalness?: number;
  responsiveness?: number;
  set?: string;
  stand?: "middle" | "sole" | "bearing";
  standing?: "set" | "own";
  turn?: "easy" | "quick";
};

The movement system (exported characters moved by whole takes of a performer, their feet held where they land): on by default. false turns it off for the game: every character walks by the clips' blend, as before. An object keeps it on and sets how it moves every character: whether the take carries the walker (carry, default true), and the two dials, each 0 to 1, default 0.6 (responsiveness: how hard a character follows what is asked; naturalness: how far it may leave its place to move as the take does), what it stands on at rest (standing: 'own', the character's own captured stance, the default; 'set', the takes' own standing) and whether the feet are held (footPlant).

Union Members ​

false


Type Literal ​
ts
{
  actions?: boolean;
  carry?: boolean;
  feet?: "performed" | "own";
  footPlant?: boolean;
  legs?: "performed" | "bent";
  naturalness?: number;
  responsiveness?: number;
  set?: string;
  stand?: "middle" | "sole" | "bearing";
  standing?: "set" | "own";
  turn?: "easy" | "quick";
}
actions? ​
ts
optional actions?: boolean;

Actions of the character's set (a hurdle, a jump: character.do). Off by default: the default is standing, walking, running, starts, stops, turns and the foot hold.

carry? ​
ts
optional carry?: boolean;
feet? ​
ts
optional feet?: "performed" | "own";

How a move's ankle and toe turns are laid on a character's feet: 'performed' (the default: the performer's joint turns as they stand) or 'own' (laid on the character's own stand's sole, so a character made on a raised heel or in a shoe rolls over its own sole as the performer does over his). Left out, nothing changes.

footPlant? ​
ts
optional footPlant?: boolean;
legs? ​
ts
optional legs?: "performed" | "bent";

How straight a leg the foot hold moves may be: 'bent' (the default: never over 0.995 of its length, which dips the hips about 4 mm once a walking step) or 'performed' (as straight as the move has the leg, and no straighter). Left out, nothing changes.

naturalness? ​
ts
optional naturalness?: number;
responsiveness? ​
ts
optional responsiveness?: number;
set? ​
ts
optional set?: string;

The set every character starts on: 'shared' (the engine's shared set alone: a character's own takes are not laid over it), 'own', or a name the page gave a set. Absent: a character's own takes laid over the shared set, part by part.

stand? ​
ts
optional stand?: "middle" | "sole" | "bearing";

How a walk is stood on the floor: 'middle' (the default: by the middle of the joints of the feet marked down), 'sole' (on the character's own lowest sole point of those feet) or 'bearing' (on her lowest sole point, the toe's end too, of every foot from the frame its sole is down to the frame its toes leave). Only the height the hips are drawn at changes; left out, nothing does.

standing? ​
ts
optional standing?: "set" | "own";
turn? ​
ts
optional turn?: "easy" | "quick";

The pace of a turn on the spot, where the set marks its turns by pace: 'quick' (the default) or 'easy' (unhurried: a character in a room).


CharacterStore ​

Splat character bundle handle.

Properties ​

bundle ​
ts
bundle: Uint32Array;

Character bundle asset handle.

dirty ​
ts
dirty: Uint8Array;

Non-zero when the host has not yet seen the current value.


CollisionLayers ​

Broad-phase layer set. Omitted keys lower as false.

Properties ​

character? ​
ts
optional character?: boolean;
debris? ​
ts
optional debris?: boolean;
defaultLayer? ​
ts
optional defaultLayer?: boolean;
enemy? ​
ts
optional enemy?: boolean;
pickup? ​
ts
optional pickup?: boolean;
player? ​
ts
optional player?: boolean;
projectile? ​
ts
optional projectile?: boolean;
staticGeometry? ​
ts
optional staticGeometry?: boolean;
trigger? ​
ts
optional trigger?: boolean;
user0? ​
ts
optional user0?: boolean;
user1? ​
ts
optional user1?: boolean;
user2? ​
ts
optional user2?: boolean;
user3? ​
ts
optional user3?: boolean;
user4? ​
ts
optional user4?: boolean;
user5? ​
ts
optional user5?: boolean;
water? ​
ts
optional water?: boolean;

Contact ​

One reported contact between two bodies.

Properties ​

a ​
ts
a: number;
b ​
ts
b: number;
entityA ​
ts
entityA: number;
entityB ​
ts
entityB: number;
impulse ​
ts
impulse: number;
normal ​
ts
normal: Vec3;
phase ​
ts
phase: ContactPhase;
point ​
ts
point: Vec3;

ConversationCmd ​

Structural interview controls; service addresses stay in host configuration.

Properties ​

action ​
ts
action: 
  | "end"
  | "start"
  | "ask"
  | "interrupt"
  | "microphone-on"
  | "microphone-off";
character ​
ts
character: string;
entity ​
ts
entity: number;
text ​
ts
text: string;

ConversationEvent ​

Low-frequency conversation UI/input event. No audio or facial frames cross WIT.

Properties ​

entity ​
ts
entity: number;
kind ​
ts
kind: "error" | "status" | "input" | "subtitle" | "story";
text ​
ts
text: string;

Story events carry the versioned full snapshot as JSON.


CutsceneCmd ​

A cutscene: a clip the page draws over the stage at a moment that matters. preload fetches it ahead so play starts at once; skip ends the one playing. The clip is a video asset of the manifest, never a URL.

Properties ​

action ​
ts
action: "play" | "preload" | "skip";
asset ​
ts
asset: number;

The video asset; 0 for skip.

fadeInMs ​
ts
fadeInMs: number;

Milliseconds of fade in over the stage.

fadeOutMs ​
ts
fadeOutMs: number;

Milliseconds of fade out.

pause ​
ts
pause: boolean;

The stage pauses under it and the game's sound is ducked.

skippable ​
ts
skippable: boolean;

A tap or a key ends it early.


CutsceneEvent ​

How a cutscene ended.

Properties ​

asset ​
ts
asset: number;

The video asset that was played.

kind ​
ts
kind: "ended" | "failed" | "skipped";

The clip reached its end, the person skipped it, or it could not play.

seconds ​
ts
seconds: number;

Seconds from the call to the end, fades included.


CutscenePlayOptions ​

Options for cutscene.play.

Properties ​

fadeIn? ​
ts
optional fadeIn?: number;

Fade in over the stage, milliseconds. Default 400.

fadeOut? ​
ts
optional fadeOut?: number;

Fade out, milliseconds. Default 400.

pause? ​
ts
optional pause?: boolean;

Pause the stage under it and duck the game's sound. Default true.

skippable? ​
ts
optional skippable?: boolean;

A tap or a key ends it early. Default true.


DataFacade ​

The ctx.data facade, one per guest. Only the authority writes: on a client every call is a no-op (logged once).

Saving is not free: save serialises the document. Call it when the document changed, not every tick; the room writes at most one per player every 6 s anyway, and always when the player leaves or the room closes.

Example ​

ts
function earn(ctx: GameContext): void {
  for (const [id, p] of ctx.players) {
    const doc = (p.data ?? { coins: 0 }) as { coins: number };
    if (ctx.frame % 600 === 0) ctx.data.save(id, { ...doc, coins: doc.coins + 1 });
  }
  for (const r of ctx.data.results()) if (!r.ok) ctx.net.send('trade-failed', { id: r.id, why: r.reason });
}

Accessors ​

game ​
Get Signature ​
ts
get game(): unknown;
Returns ​

unknown

The game's own saved document, once the room has handed it over; else null.

Methods ​

exchange() ​
ts
exchange(
   a, 
   b, 
   give, 
   take
): number;

Trade between two players, all or nothing: a gives b everything in give and takes from b everything in take (numbers move amounts, lists move items; see applyTransfer). The result arrives as an exchange-result event a tick or more later, in DataFacade.results; on success both players' data already show the trade.

Parameters ​
ParameterTypeDescription
anumberThe first player.
bnumberThe second player.
giveTransferDocWhat a gives b, such as { coins: 5 }.
takeTransferDocWhat a takes from b, such as { owned: ['gem'] }.
Returns ​

number

The exchange's id, or 0 on a client.

results() ​
ts
results(): readonly Pick<ExchangeResultEvent, "id" | "reason" | "ok">[];
Returns ​

readonly Pick<ExchangeResultEvent, "id" | "reason" | "ok">[]

This tick's exchange results, in arrival order; reused, read during the tick.

save() ​
ts
save(player, doc): void;

Keep a player's document. ctx.players.get(player).data is the new document at once; the room writes it to its store (throttled).

Parameters ​
ParameterTypeDescription
playernumberA joined player.
docunknownAny JSON value; at most 64 KB as JSON.
Returns ​

void

saveGame() ​
ts
saveGame(doc): void;

Keep the game's own document (one per game, shared by every room).

Parameters ​
ParameterTypeDescription
docunknownAny JSON value; at most 64 KB as JSON.
Returns ​

void


DoCharacterActionCmd ​

Ask a character to do an action of its motion set (see character.do).

Properties ​

action ​
ts
action: string;

The action's name in the set.

entity ​
ts
entity: number;
object? ​
ts
optional object?: ActionObject;
plain ​
ts
plain: boolean;

The plain way, for a comparison: the take simply started, nothing fitted.


ExchangeCmd ​

Trade between two players' documents; the result is an exchange-result event.

Properties ​

a ​
ts
a: number;
b ​
ts
b: number;
give ​
ts
give: string;

JSON: what a gives b.

id ​
ts
id: number;

Guest-minted; echoed in the result.

take ​
ts
take: string;

JSON: what a takes from b.


ExchangeResultEvent ​

The outcome of an exchange command, matched by its id.

Properties ​

aData ​
ts
aData: string;

Player a's document after the trade, as the store wrote it (JSON); empty unless ok.

bData ​
ts
bData: string;

Player b's document after the trade (JSON); empty unless ok.

id ​
ts
id: number;
ok ​
ts
ok: boolean;
reason ​
ts
reason: string;

Empty when ok.


FaceCharacterCmd ​

Turn a character on the spot to face a way (see character.face).

Properties ​

entity ​
ts
entity: number;
facing ​
ts
facing: number;

Radians about +Y (0 faces +Z).

quick ​
ts
quick: boolean;

The quickest turn the set has, instead of an unhurried one.


FeatureSpec ​

The features a game may declare. A key that is false is the same as absent.

Properties ​

characters? ​
ts
optional characters?: boolean | CharactersOptions;

The splat character bridge (spawn-character and friends).

multiplayer? ​
ts
optional multiplayer?: boolean | MultiplayerOptions;

Rooms, players and replication.


FirstPersonOptions ​

Options for camera.firstPerson.

Properties ​

eyeHeight? ​
ts
optional eyeHeight?: number;

Eye height above the entity origin, metres. Default 1.7.

fovYDeg? ​
ts
optional fovYDeg?: number;

Vertical field of view in degrees. Default 75.


FollowOptions ​

Options for camera.follow.

Properties ​

distance? ​
ts
optional distance?: number;

Boom length behind the target, metres. Default 4.

fovYDeg? ​
ts
optional fovYDeg?: number;

Vertical field of view in degrees. Default 60.

height? ​
ts
optional height?: number;

Rig-local height offset, metres. Default 1.6.

pitch? ​
ts
optional pitch?: number;

Orbit pitch in radians; positive looks up. Defaults to the accumulator.

yaw? ​
ts
optional yaw?: number;

Orbit yaw in radians about +Y; 0 puts the camera behind the target.

Defaults to the built-in look accumulator. Pass it when the game keeps its own orbit — a third-person camera usually wants a tighter pitch range and its own sensitivity than the first-person one the accumulator is tuned for.


FrameInput ​

One fixed simulation step of host state handed to the guest.

Properties ​

bodies ​
ts
bodies: ArrayLike<number>;

Post-step body transforms, stride 15, sorted ascending by body id.

contacts ​
ts
contacts: readonly Contact[];
dt ​
ts
dt: number;
elapsed ​
ts
elapsed: number;
events ​
ts
events: readonly GameEvent[];
frame ​
ts
frame: number | bigint;

Monotonic fixed-step counter. jco lifts u64 as a bigint on the host and a number in the guest, so both are legal here; the runtime Number()s it once, on the way in.

input ​
ts
input: InputState;
players ​
ts
players: readonly PlayerInput[];

Every player's input in a room, ascending by id. Empty for a single-player game. A held seat (its player dropped) is left out until they are back.


FrameOutput ​

Everything the guest hands back for one fixed step.

Properties ​

camera ​
ts
camera: CameraState;
commands ​
ts
commands: readonly Command[];
hud? ​
ts
optional hud?: string;

HUD JSON, present only on the frames it changed.

localCommands ​
ts
localCommands: readonly Command[];

Applied by the authority after commands; never forwarded to a client.

transforms ​
ts
transforms: Float32Array;

Entity transforms, stride 12. Never empty: see the zero-row rule.


GameConfig ​

The init payload.

Properties ​

devMode ​
ts
devMode: boolean;
fixedHz ​
ts
fixedHz: number;
options? ​
ts
optional options?: string;
seed ​
ts
seed: number | bigint;

Deterministic run seed. A bigint on the host, a number in the guest; the runtime Number()s it once, on the way in.

viewportHeight ​
ts
viewportHeight: number;
viewportWidth ​
ts
viewportWidth: number;

GameContext ​

Everything a system can reach.

The same object is handed to every system on every frame — it is mutated in place, never rebuilt, so never retain it or destructure frame outside the call.

Properties ​

audio ​
ts
readonly audio: object;

Sound playback.

listener() ​
ts
listener(position, rotation): void;

Place the audio listener.

Parameters ​
ParameterTypeDescription
positionVec3Listener position.
rotationQuatListener rotation, xyzw.
Returns ​

void

Nothing.

play() ​
ts
play(asset, options?): number;

Start a sound.

Parameters ​
ParameterTypeDescription
assetstring | numberManifest string id or asset handle.
options?PlayOptionsAttachment, gain, pitch, looping and bus.
Returns ​

number

The guest-minted sound handle, or 0 when the asset is unknown.

stop() ​
ts
stop(sound, fadeMs?): void;

Stop a playing sound.

Parameters ​
ParameterTypeDefault valueDescription
soundnumberundefinedA handle from play.
fadeMsnumber0Fade-out in milliseconds; 0 stops immediately.
Returns ​

void

Nothing.

camera ​
ts
readonly camera: object;

The camera record for this frame.

look ​
Get Signature ​
ts
get look(): object;

Accumulated look angles, in radians. Mutate to snap the view.

Returns ​

object

The live look state.

pitch ​
ts
pitch: number;
sensitivity ​
ts
sensitivity: number;
yaw ​
ts
yaw: number;
state ​
Get Signature ​
ts
get state(): CameraState;

The whole camera record, for games that want every knob.

Returns ​

CameraState

The live record. Mutate it; do not replace it.

firstPerson() ​
ts
firstPerson(entity, options?): void;

Mount the camera at an entity's eyes.

Yaw and pitch come from the built-in look accumulator, which integrates input.mouse.dx/dy once per tick.

Parameters ​
ParameterTypeDescription
entitynumberEntity to mount on.
options?FirstPersonOptionsEye height and field of view.
Returns ​

void

Nothing.

follow() ​
ts
follow(entity, options?): void;

Put the camera on a spring arm behind an entity.

The host owns the arm and its collision; the guest only states the intent. position is the orbit pivot and rotation the direction the player is looking, so a host with no rig still ends up somewhere sensible.

Parameters ​
ParameterTypeDescription
entitynumberEntity to follow.
options?FollowOptionsBoom length, height offset, field of view and orbit angles.
Returns ​

void

Nothing.

lookAt() ​
ts
lookAt(point): void;

Aim the camera at a world point, overriding its rotation.

Parameters ​
ParameterTypeDescription
pointVec3 | nullThe point to look at, or null to use the rotation again.
Returns ​

void

Nothing.

set() ​
ts
set(
   position, 
   rotation, 
   fovYDeg?
): void;

Place the camera explicitly, detaching it from any entity.

Parameters ​
ParameterTypeDefault valueDescription
positionVec3undefinedEye position.
rotationQuatundefinedEye rotation, xyzw.
fovYDegnumber60Vertical field of view in degrees. Default 60.
Returns ​

void

Nothing.

character ​
ts
readonly character: object;

Splat characters.

bundleOf() ​
ts
bundleOf(entity): number;

The character bundle handle attached to an entity, or 0.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
Returns ​

number

The bundle asset handle.

cancelAction() ​
ts
cancelAction(entity): void;

Take an action's request back (it cannot be taken back between its gathering and its landing).

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
Returns ​

void

Nothing.

do() ​
ts
do(
   entity, 
   action, 
   object?, 
   plain?
): void;

Ask a character to do an action of its motion set (a hurdle, a jump, a sit), at an object when the action needs one. What follows comes as motion-events in ctx.events: started, contact, release (with the point and its velocity, for a thing let go), landed, done, or failed with its reason.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
actionstringundefinedThe action's name in the set.
object?Readonly<ActionObject>undefinedThe thing it is done at, as the game has it; left out for an action without one.
plain?booleanfalseThe plain way, for a comparison: the take simply started, nothing fitted.
Returns ​

void

Nothing.

Example ​
ts
character.do(hero, 'hurdle', { id: bar, position: barAt, yaw: 0, height: 0.6, width: 1.2, depth: 0.05 });
face() ​
ts
face(
   entity, 
   facing, 
   arrive?
): void;

Turn a character on the spot to face a way, by its set's own turns. The motion-event arrived named 'face' says when it faces there.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
facingnumberundefinedRadians about +Y (0 faces +Z).
arrive"easy" | "quick"'easy''easy' (the default: an unhurried turn) or 'quick' (the quickest the set has).
Returns ​

void

Nothing.

Example ​
ts
character.face(guide, Math.PI / 2);
hit() ​
ts
hit(entity, blow): void;

A blow. Every exported character has a physics body (its parts on the engine's physics); the nearest part to at takes the blow along direction, and the body reacts for real: a small hit flinches and recovers over about a second, a big one falls onto the floor and stays down until character.recover, a shot is sharper, a push shoves. Use this before writing a reaction of your own.

What happened comes back as anim-events on the clip ragdoll: hit, fell (the body came to rest on the floor), recovered.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
blow{ at: Vec3; direction?: Vec3; strength: number | "small" | "big" | "shot" | "big-shot"; }Where it lands (at, world), which way it travels (direction, world; omitted: from the character's front) and how hard (strength: 'small', 'big', 'shot', 'big-shot', or a push's newton-seconds: 40 staggers, 90 and over floors).
blow.atVec3-
blow.direction?Vec3-
blow.strengthnumber | "small" | "big" | "shot" | "big-shot"-
Returns ​

void

Nothing.

Example ​
ts
character.hit(enemy, { at: swordTip, direction: swing, strength: 'small' });
character.hit(enemy, { at: swordTip, direction: swing, strength: 'big' }); // down
lookAt() ​
ts
lookAt(
   entity, 
   target, 
   weight?
): void;

Aim the head and eyes at a world point.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
targetVec3 | nullundefinedThe point, or null to release and return to the idle.
weightnumber1Blend weight in 0..1. Default 1.
Returns ​

void

Nothing.

motion() ​
ts
motion(entity, options?): void;

How the movement system moves a character. A character with a motion set (its package's own, else the engine's shared one) is moved by whole takes of a performer matched to the velocity given to character.setState: its starts, stops and turns are the performer's own, its feet are held where they land. That is the default; this call changes it for one character: off, another set, whether the take carries the walker, the two dials, and which kind of stop it makes from a run. What is left out stays as it is.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
optionsCharacterMotionOptionsWhat to change.
Returns ​

void

Nothing.

Example ​
ts
character.motion(hero, { responsiveness: 0.9 }); // a snappier hero
character.motion(guard, { on: false }); // this one by the clips' blend, as before
character.motion(hero, { stop: 'hard' }); // from a run it brakes, instead of slowing to a stand
recover() ​
ts
recover(entity): void;

Back into the animation: a character that is down (or reacting) blends back over about a second, where it stood. Move the entity to where the body lies first (anim-event fell; the head and root joints read where it lies) to have it get up there.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
Returns ​

void

Nothing.

say() ​
ts
say(
   entity, 
   text, 
   voice?, 
   visemes?
): void;

Speak a line.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
textstringSubtitle text; the host decides whether to show it.
voice?string | numberManifest string id or handle of a voice line.
visemes?stringViseme track as JSON, matching the bundle's space.
Returns ​

void

Nothing.

setClipWeights() ​
ts
setClipWeights(
   entity, 
   clips, 
   weights, 
   timeScale?
): void;

Set explicit per-clip weights on the body layer.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
clipsreadonly string[]undefinedClip names.
weightsreadonly number[] | Float32Array<ArrayBufferLike>undefinedPositional weights; must be the same length as clips.
timeScalenumber1Playback rate for the whole layer. Default 1.
Returns ​

void

Nothing.

setExpression() ​
ts
setExpression(
   entity, 
   space, 
   weights
): void;

Set facial expression coefficients.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
spaceExpressionSpaceCoordinate space: 52 ARKit, 387 GNM, or the 68-float view.
weightsreadonly number[] | Float32Array<ArrayBufferLike>Coefficients; length must match the space.
Returns ​

void

Nothing.

setState() ​
ts
setState(
   entity, 
   state, 
   vx, 
   vy, 
   vz, 
   grounded?
): void;

Drive the locomotion state machine.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
statestringundefinedState name, for example `'idle'
vxnumberundefinedWorld-space velocity x, drives the locomotion blend.
vynumberundefinedWorld-space velocity y.
vznumberundefinedWorld-space velocity z.
groundedbooleantrueWhether the character is on the ground.
Returns ​

void

Nothing.

stopWalk() ​
ts
stopWalk(entity): void;

Give up a walk to a spot: the character stops where it is, as its takes stop.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
Returns ​

void

Nothing.

walkTo() ​
ts
walkTo(
   entity, 
   target, 
   how?
): void;

Send a character to a spot: it turns, walks or runs there and arrives facing the way asked. The motion-event arrived (in ctx.events) says it got there; failed says why not; started and then done, both named stop, say when its stop begins and when it no longer travels; limited says once that the speed it is given (amount) is not the one asked. A velocity given to character.setState while it walks takes over.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
targetVec3The spot, world space, on the floor.
how{ arrive?: "easy" | "quick"; facing?: number; pace?: number; start?: "moving"; stop?: StopStyle; }The facing to arrive with (facing, radians about +Y, 0 faces +Z; left out: as it arrives), the pace (pace, metres a second; left out: the set's own walk; above the speeds its walk covers it runs, when its set has a run and the spot is far enough to run to), how it stops (arrive: 'easy', the default, the takes' unhurried stops; 'quick', the shortest stops and turns the set has) and which kind of stop this one walk ends with (stop: 'gradual', it slows and stands upright; 'hard', it brakes; left out: the character's own, see character.motion). arrive says how soon it must be there, stop says which kind of stop; a 'quick' walk that states no stop stops as a quick walk always did. A kind is read on a run's stops: a walk's stop and a sprint's stop are the same under both on the engine's shared set. And how it is begun (start: 'moving', the game says the body is under way already: it comes out of a get-up, it was carried or thrown; the walk is then planned as of a body under way: no turn on the spot first, no start from standing; left out: as its takes have the body).
how.arrive?"easy" | "quick"-
how.facing?number-
how.pace?number-
how.start?"moving"-
how.stop?StopStyle-
Returns ​

void

Nothing.

Example ​
ts
character.walkTo(guide, { x: 2, y: 0, z: -3 }, { facing: Math.PI });
character.walkTo(rider, bikeSide, { pace: 3.4 }); // a run's pace: it runs there
character.walkTo(rider, bikeSide, { pace: 3.4, stop: 'hard' }); // and brakes at the spot
character.walkTo(rider, bikeSide, { pace: 3.4, start: 'moving' }); // out of a get-up: no turn on the spot first
config ​
ts
readonly config: GameConfig;

The init config.

contacts ​
ts
readonly contacts: readonly Contact[];

Contacts reported since the previous tick.

data ​
ts
readonly data: DataFacade;

Player documents and the game's own document in the room's store, and trades between two players. The authority writes; a client's calls do nothing.

dt ​
ts
readonly dt: number;

Fixed timestep in seconds.

elapsed ​
ts
readonly elapsed: number;

Simulated seconds since init.

events ​
ts
readonly events: readonly GameEvent[];

Host-side occurrences since the previous tick, in order.

frame ​
ts
readonly frame: number;

Monotonic fixed-step counter, starting at 0.

hud ​
ts
readonly hud: object;

The HUD model.

clear() ​
ts
clear(): void;

Drop the HUD: emit an empty model this frame.

Idempotent — calling it every frame emits {} once, exactly like set.

Returns ​

void

Nothing.

invalidate() ​
ts
invalidate(): void;

Forget what the host has seen, so the next set emits even if the model did not change. Use it after the host reloaded its overlay.

On its own it sends nothing: the next set does. To send an empty model now, call clear().

Returns ​

void

Nothing.

set() ​
ts
set(model): boolean;

Set the HUD model for this frame.

Nested plain objects are compared by value four levels down, so a model rebuilt inline every frame is recognised as unchanged. Arrays and class instances are compared by identity: keep those out of the model, or build them once and mutate nothing.

Parameters ​
ParameterTypeDescription
modelRecord<string, unknown>A JSON-serialisable object.
Returns ​

boolean

True when the model changed and JSON will cross this frame.

input ​
ts
readonly input: object;

Keyboard, mouse and gamepad.

touch ​
ts
touch: object;

Fingers on a touch screen, as the host's touch layer packs them: the first finger is the pointer (mouse), a tap is pressed('Tap'), and the thumb sticks, the pinch and the turn are here.

touch.active ​
Get Signature ​
ts
get active(): boolean;

Is a finger on the screen? (The touch pad is connected.)

Returns ​

boolean

True while any finger is down.

touch.pinch ​
Get Signature ​
ts
get pinch(): number;

Two fingers' pinch this step, as a scale factor: over 1 the fingers moved apart (zoom in), under 1 together, exactly 1 with no pinch.

Returns ​

number

The scale factor.

touch.turn ​
Get Signature ​
ts
get turn(): number;

Two fingers' turn this step, in radians, counter-clockwise on the screen positive.

Returns ​

number

The turn.

touch.stick() ​
ts
stick(side): Axis2;

A thumb stick's push.

Parameters ​
ParameterTypeDescription
side"left" | "right"The left stick (movement) or the right one (the camera).
Returns ​

Axis2

A pooled { x, y }, -1..1, y up the screen positive. Never retain it.

focused ​
Get Signature ​
ts
get focused(): boolean;

Does the canvas have focus? Treat input as neutral when it does not.

Returns ​

boolean

True while the canvas is focused.

mods ​
Get Signature ​
ts
get mods(): InputMods;

Keyboard modifier state.

Returns ​

InputMods

The modifiers for this frame.

mouse ​
Get Signature ​
ts
get mouse(): MouseState;

Pointer position, per-frame delta, wheel and button bitsets.

Returns ​

MouseState

The mouse state for this frame. Owned by the SDK; never retain it.

axis2() ​
ts
axis2(
   negX, 
   posX, 
   negY, 
   posY, 
   stick?
): Axis2;

A two-axis reading built from four keys, plus a thumb stick on a touch screen: the left one by default, so axis2('A', 'D', 'S', 'W') moves on a phone with no other binding. Pass 'right' for a camera axis, 'none' for keys only.

Parameters ​
ParameterTypeDefault valueDescription
negXstringundefinedKey that drives x negative, for example 'A'.
posXstringundefinedKey that drives x positive, for example 'D'.
negYstringundefinedKey that drives y negative, for example 'S'.
posYstringundefinedKey that drives y positive, for example 'W'.
stickStickSide'left'Which thumb stick to add, 'left' by default.
Returns ​

Axis2

A pooled { x, y } with components in -1..1. Never retain it.

gamepad() ​
ts
gamepad(index): 
  | {
  axes: ArrayLike<number>;
  buttons: number;
  connected: boolean;
  index: number;
  pressed: number;
  released: number;
}
  | null;

One connected gamepad.

Parameters ​
ParameterTypeDescription
indexnumberNavigator gamepad index.
Returns ​

| { axes: ArrayLike<number>; buttons: number; connected: boolean; index: number; pressed: number; released: number; } | null

The gamepad, or null when nothing is connected at that index. Owned by the SDK; never retain it.

isDown() ​
ts
isDown(key): boolean;

Is the key held this frame?

Parameters ​
ParameterTypeDescription
keystringA DOM code ('KeyW'), a bare letter/digit ('W', '1') or an alias ('Shift', 'Esc').
Returns ​

boolean

True while the key is down.

mouseDown() ​
ts
mouseDown(button): boolean;

Is a mouse button held?

Parameters ​
ParameterTypeDescription
buttonnumberA MOUSE_BUTTONS value, or a raw bit mask.
Returns ​

boolean

True while the button is down.

mousePressed() ​
ts
mousePressed(button): boolean;

Did a mouse button go down this frame?

Parameters ​
ParameterTypeDescription
buttonnumberA MOUSE_BUTTONS value, or a raw bit mask.
Returns ​

boolean

True on the frame the button went down.

mouseReleased() ​
ts
mouseReleased(button): boolean;

Did a mouse button come up this frame?

Parameters ​
ParameterTypeDescription
buttonnumberA MOUSE_BUTTONS value, or a raw bit mask.
Returns ​

boolean

True on the frame the button came up.

pressed() ​
ts
pressed(key): boolean;

Did the key go down this frame?

Parameters ​
ParameterTypeDescription
keystringA key name.
Returns ​

boolean

True on the frame the key went down.

released() ​
ts
released(key): boolean;

Did the key come up this frame?

Parameters ​
ParameterTypeDescription
keystringA key name.
Returns ​

boolean

True on the frame the key came up.

localPlayer ​
ts
readonly localPlayer: PlayerHandle | null;

The player this page belongs to, on a client; null on the authority and in solo.

net ​
ts
readonly net: NetFacade;

Where this guest runs, game messages in and out, and local-only commands.

physics ​
ts
readonly physics: object;

Physics queries and body commands.

ALL_LAYERS ​
ts
ALL_LAYERS: CollisionLayers;

Every collision layer, for queries that should hit anything.

applyImpulse() ​
ts
applyImpulse(
   entity, 
   x, 
   y, 
   z, 
   atX?, 
   atY?, 
   atZ?
): void;

Apply a one-shot impulse.

With no application point the impulse acts at the centre of mass. Give one — all three coordinates — to apply it off-centre and impart spin.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a body.
xnumberImpulse x, newton-seconds.
ynumberImpulse y.
znumberImpulse z.
atX?numberWorld-space application point x, or omit for the centre of mass.
atY?numberApplication point y.
atZ?numberApplication point z.
Returns ​

void

Nothing.

isGrounded() ​
ts
isGrounded(entity): boolean;

Actual walkable ground contact from the last host physics step. No host call. Unknown, steep and unsupported contacts return false, even at a jump apex.

Parameters ​
ParameterTypeDescription
entitynumberCharacter entity.
Returns ​

boolean

Whether the character is supported by walkable ground.

moveCharacter() ​
ts
moveCharacter(
   entity, 
   vx, 
   vy, 
   vz, 
   jump?, 
   crouch?, 
   maxSlopeDeg?
): void;

Drive a character body for this step.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity whose body was created with kind: 'character'.
vxnumberundefinedDesired world-space velocity x, metres per second.
vynumberundefinedDesired world-space velocity y.
vznumberundefinedDesired world-space velocity z.
jumpbooleanfalseRequest a jump this step.
crouchbooleanfalseRequest a crouch this step.
maxSlopeDegnumber45Maximum walkable slope.
Returns ​

void

Nothing.

overlapSphere() ​
ts
overlapSphere(
   center, 
   radius, 
   maxResults?, 
   mask?, 
   ignoreEntity?
): readonly OverlapHit[];

Bodies overlapping a sphere, nearest first.

Parameters ​
ParameterTypeDefault valueDescription
centerVec3undefinedSphere centre.
radiusnumberundefinedSphere radius in metres.
maxResultsnumber16Cap on returned hits.
mask?CollisionLayersundefinedLayers to consider; defaults to every layer.
ignoreEntity?numberundefinedEntity to skip.
Returns ​

readonly OverlapHit[]

The overlapping bodies.

raycast() ​
ts
raycast(
   origin, 
   direction, 
   maxDistance, 
   mask?, 
   ignoreEntity?
): RayHit | null;

Closest hit along a ray.

Parameters ​
ParameterTypeDescription
originVec3World-space ray origin.
directionVec3Ray direction; need not be normalised.
maxDistancenumberMaximum distance in metres.
mask?CollisionLayersLayers to consider; defaults to every layer.
ignoreEntity?numberEntity to skip, usually the caster.
Returns ​

RayHit | null

The hit, or null on a miss. The hit object comes from the host and is freshly allocated: this call is not allocation-free.

raycastBatch() ​
ts
raycastBatch(rays): readonly (RayHit | null | undefined)[];

Many rays in one round trip. Result index i matches rays[i].

Parameters ​
ParameterTypeDescription
raysreadonly object[]The rays. Build them once and mutate them in place.
Returns ​

readonly (RayHit | null | undefined)[]

One result per ray; undefined or null entries are misses.

setEnabled() ​
ts
setEnabled(entity, enabled): void;

Enable or disable a body in the broad phase.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a body.
enabledbooleanWhether the body participates.
Returns ​

void

Nothing.

setVelocity() ​
ts
setVelocity(
   entity, 
   x, 
   y, 
   z, 
   ax?, 
   ay?, 
   az?
): void;

Overwrite a body's velocity.

Angular velocity is left alone unless all three angular components are given.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a body.
xnumberLinear velocity x.
ynumberLinear velocity y.
znumberLinear velocity z.
ax?numberAngular velocity x, radians per second.
ay?numberAngular velocity y.
az?numberAngular velocity z.
Returns ​

void

Nothing.

teleport() ​
ts
teleport(
   entity, 
   x, 
   y, 
   z
): void;

Teleport a body, clearing its velocities.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a body.
xnumberPosition x.
ynumberPosition y.
znumberPosition z.
Returns ​

void

Nothing.

player ​
ts
readonly player: number;

The entity the declarative player block spawned in a single-player game, or 0. In a room each player has their own: playerEntity(id).

players ​
ts
readonly players: Players;

The room's players by id: everyone joined and not yet left, plus anyone whose input is in this step's frame-input.players. Empty for a single-player game. Rebuilt only when that set changes, never per tick. Also says who the host is (host) and lists the players in id order (list), which a system walks without allocating.

rng ​
ts
readonly rng: Rng;

The seeded generator. Never Math.random.

rules ​
ts
readonly rules: Readonly<Record<string, unknown>>;

The rules object from defineGame, verbatim.

world ​
ts
readonly world: object;

The bitecs world, for query, addComponent and friends.

Methods ​

assetId() ​
ts
assetId(name): number;

Resolve a manifest string id to a handle, cached.

Parameters ​
ParameterType
namestring
Returns ​

number

despawn() ​
ts
despawn(entity): void;

Destroy an entity and its body.

Parameters ​
ParameterType
entitynumber
Returns ​

void

playerEntity() ​
ts
playerEntity(id): number;

The entity definition.player spawned for a room player, or 0.

Parameters ​
ParameterType
idnumber
Returns ​

number

spawn() ​
ts
spawn(
   def, 
   position, 
   rotation?
): number;

Instantiate a prefab.

Parameters ​
ParameterType
defPrefabDef
positionVec3
rotation?Quat
Returns ​

number


GameDataEvent ​

The room's saved game-wide document as JSON.

Properties ​

data ​
ts
data: string;

GameError ​

The error payload of init and restore.

Properties ​

code ​
ts
code: ErrorCode;
message ​
ts
message: string;

GamepadState ​

One gamepad in the standard mapping.

Properties ​

axes ​
ts
axes: ArrayLike<number>;
buttons ​
ts
buttons: number;
connected ​
ts
connected: boolean;
index ​
ts
index: number;
pressed ​
ts
pressed: number;
released ​
ts
released: number;

GameSpec ​

Everything a game declares.

Properties ​

assets? ​
ts
optional assets?: readonly string[];

Manifest string ids to resolve during init and cache.

features? ​
ts
optional features?: FeatureSpec;

Optional engine modules this game needs. See featuresOf.

init? ​
ts
optional init?: (ctx) => void;

Extra setup, run after the declarative spawns.

Parameters ​
ParameterType
ctxGameContext
Returns ​

void

player? ​
ts
optional player?: PlayerSpec;

The player and its camera. Spawned once at init in a single-player game; on the authority of a room, once per joined player instead.

restore? ​
ts
optional restore?: (state) => void;

Read back what snapshot returned.

Parameters ​
ParameterType
stateunknown
Returns ​

void

rules? ​
ts
optional rules?: Record<string, unknown>;

Arbitrary tuning values, handed back as ctx.rules.

shutdown? ​
ts
optional shutdown?: (ctx) => void;

Called once before the guest is torn down.

Parameters ​
ParameterType
ctxGameContext
Returns ​

void

snapshot? ​
ts
optional snapshot?: () => unknown;

Extra state to fold into snapshot(). Must be JSON-serialisable.

Returns ​

unknown

spawns? ​
ts
optional spawns?: readonly SpawnSpec[];

Entities to create during init.

systems? ​
ts
optional systems?: readonly (SidedSystem | System)[];

User systems, run in order after the built-ins. A bare function runs on the authority once features.multiplayer is declared, everywhere otherwise; { run, on } says where explicitly.

update? ​
ts
optional update?: (ctx) => void;

Convenience: one more system, run after systems.

Parameters ​
ParameterType
ctxGameContext
Returns ​

void

world? ​
ts
optional world?: WorldSpec;

World settings.


Guest ​

A guest instance: the five WIT exports plus a liveness flag.

Extends ​

Properties ​

dead ​
ts
readonly dead: boolean;

True once the runtime has given up on user code.

state ​
ts
readonly state: RuntimeState;

The runtime, for tests and tooling.

Methods ​

init() ​
ts
init(config): void;
Parameters ​
ParameterType
configGameConfig
Returns ​

void

Inherited from ​

GuestExports.init

restore() ​
ts
restore(state): void;
Parameters ​
ParameterType
stateArrayLike<number>
Returns ​

void

Inherited from ​

GuestExports.restore

shutdown() ​
ts
shutdown(): void;
Returns ​

void

Inherited from ​

GuestExports.shutdown

snapshot() ​
ts
snapshot(): Uint8Array;
Returns ​

Uint8Array

Inherited from ​

GuestExports.snapshot

tick() ​
ts
tick(input): FrameOutput;
Parameters ​
ParameterType
inputFrameInput
Returns ​

FrameOutput

Inherited from ​

GuestExports.tick


GuestExports ​

The five functions the WIT game interface exports.

Extended by ​

Methods ​

init() ​
ts
init(config): void;
Parameters ​
ParameterType
configGameConfig
Returns ​

void

restore() ​
ts
restore(state): void;
Parameters ​
ParameterType
stateArrayLike<number>
Returns ​

void

shutdown() ​
ts
shutdown(): void;
Returns ​

void

snapshot() ​
ts
snapshot(): Uint8Array;
Returns ​

Uint8Array

tick() ​
ts
tick(input): FrameOutput;
Parameters ​
ParameterType
inputFrameInput
Returns ​

FrameOutput


HealthStore ​

Current and maximum hit points.

Properties ​

current ​
ts
current: Float32Array;
max ​
ts
max: Float32Array;

HitCharacterCmd ​

A blow on a character: the nearest part of its physics body to at takes an impulse along direction, and the body reacts on the physics. The anim-events hit, fell and recovered on the clip ragdoll say what happened.

Properties ​

at ​
ts
at: Vec3;

Where the blow lands, world space.

direction ​
ts
direction: Vec3;

Which way the blow travels, world space; zero means from the character's front.

entity ​
ts
entity: number;
strength ​
ts
strength: HitStrength;

HostApi ​

The host services a guest may call, in guest-side JS shapes.

This is the SDK's own narrow view of the three gameable:engine import interfaces. packages/sdk/src/wit/entry.ts adapts the real WIT imports to it; gameable/test implements it directly for node tests.

Extended by ​

Methods ​

describe() ​
ts
describe(id): AssetDesc | null | undefined;

Metadata for a handle, or nullish when the handle is unknown.

Parameters ​
ParameterType
idnumber
Returns ​

AssetDesc | null | undefined

log() ​
ts
log(level, msg): void;

Route a message to the host logger.

Parameters ​
ParameterType
levelLogLevel
msgstring
Returns ​

void

nowMs() ​
ts
nowMs(): number;

Monotonic milliseconds since engine start. Never feed this to simulation.

Returns ​

number

overlapSphere() ​
ts
overlapSphere(
   center, 
   radius, 
   filter, 
   maxResults
): readonly OverlapHit[];

Bodies overlapping a sphere, nearest first.

Parameters ​
ParameterType
centerVec3
radiusnumber
filterQueryFilter
maxResultsnumber
Returns ​

readonly OverlapHit[]

raycast() ​
ts
raycast(
   origin, 
   direction, 
   maxDistance, 
   filter
): RayHit | null | undefined;

Closest hit along a ray, or nullish on a miss.

Parameters ​
ParameterType
originVec3
directionVec3
maxDistancenumber
filterQueryFilter
Returns ​

RayHit | null | undefined

raycastBatch() ​
ts
raycastBatch(rays): readonly (RayHit | null | undefined)[];

One round trip for many rays; result index i matches rays[i].

Parameters ​
ParameterType
raysreadonly RayQuery[]
Returns ​

readonly (RayHit | null | undefined)[]

resolveId() ​
ts
resolveId(name): number | null | undefined;

Manifest string id to handle, or nullish when the manifest has no entry.

Parameters ​
ParameterType
namestring
Returns ​

number | null | undefined

seed() ​
ts
seed(): number;

The deterministic run seed, as a number (already Number()-coerced).

Returns ​

number


HostFrameInput ​

frame-input in host-side shapes.

jco lifts u64 to bigint on the host and to number in the guest, and the host is free to hand over real typed arrays. Everything else is identical, which is why the guest types accept ArrayLike<number>.

Properties ​

bodies ​
ts
bodies: Float32Array;
contacts ​
ts
contacts: readonly Contact[];
dt ​
ts
dt: number;
elapsed ​
ts
elapsed: number;
events ​
ts
events: readonly GameEvent[];
frame ​
ts
frame: bigint;
input ​
ts
input: InputState;
players ​
ts
players: readonly PlayerInput[];

HostGameConfig ​

game-config in host-side shapes: seed is a bigint.

Properties ​

devMode ​
ts
devMode: boolean;
fixedHz ​
ts
fixedHz: number;
options? ​
ts
optional options?: string;
seed ​
ts
seed: bigint;
viewportHeight ​
ts
viewportHeight: number;
viewportWidth ​
ts
viewportWidth: number;

HudState ​

HUD change detection state.

Properties ​

last ​
ts
last: Record<string, unknown> | null;

Shallow copy of the last model the game set, or null before the first.

pending ​
ts
pending: string | undefined;

JSON to emit this frame, or undefined when the model did not change.


InputMods ​

Keyboard modifier state. Every key is present on input.

Properties ​

alt ​
ts
alt: boolean;
capsLock ​
ts
capsLock: boolean;
ctrl ​
ts
ctrl: boolean;
meta ​
ts
meta: boolean;
numLock ​
ts
numLock: boolean;
shift ​
ts
shift: boolean;

InputState ​

Everything the host knows about input for one fixed step.

Extended by ​

Properties ​

focused ​
ts
focused: boolean;
gamepads ​
ts
gamepads: readonly GamepadState[];
keys ​
ts
keys: KeyState;
mods ​
ts
mods: InputMods;
mouse ​
ts
mouse: MouseState;

KeyState ​

256 key codes packed into 8 u32 words, one list per edge.

Properties ​

down ​
ts
down: ArrayLike<number>;
pressed ​
ts
pressed: ArrayLike<number>;
released ​
ts
released: ArrayLike<number>;

LoadAssetCmd ​

Ask the host to start loading an asset.

Properties ​

asset ​
ts
asset: number;
priority ​
ts
priority: number;

LookAtCmd ​

Aim a character's head and eyes at a world point.

Properties ​

entity ​
ts
entity: number;
target? ​
ts
optional target?: Vec3;
weight ​
ts
weight: number;

LookState ​

First-person / third-person look accumulator owned by the built-in camera.

Properties ​

pitch ​
ts
pitch: number;
sensitivity ​
ts
sensitivity: number;
yaw ​
ts
yaw: number;

MessageOptions ​

Options for defineMessage.

Example ​

ts
const Chat = defineMessage('chat', (p): p is string => typeof p === 'string', { maxBytes: 256 });

Properties ​

maxBytes? ​
ts
optional maxBytes?: number;

The largest payload, in UTF-8 bytes of its JSON; 1 to 2,048. Default 2,048, the wire cap.


MotionEvent ​

What the movement system says of a character.

Properties ​

amount ​
ts
amount: number;

For arrived: how far from the spot asked it stands, metres (for 'face': how far from the facing asked, radians). For limited: the speed it is given, metres a second.

entity ​
ts
entity: number;
facing ​
ts
facing: number;

The way the character faces there, radians about +Y (0 faces +Z): where a walk left it.

kind ​
ts
kind: 
  | "landed"
  | "limited"
  | "done"
  | "arrived"
  | "failed"
  | "release"
  | "started"
  | "contact"
  | "ready";

ready (its motion set has the body), arrived (a walk to a spot got there), an action's moments (started, contact, release, landed, done), or failed.

limb ​
ts
limb: number;

The limb (0 left hand, 1 right hand, 2 left foot, 3 right foot), or -1.

name ​
ts
name: string;

The action's name; the set's name for ready; 'walk' for a walk to a spot, 'face' for a turn on the spot; the gait ('walk', 'run') for limited.

object ​
ts
object: number;

The object's id as the game gave it, or -1.

point ​
ts
point: Vec3;

Where, world space: the contact, the hand at a release, where the walk arrived.

reason ​
ts
reason: string;

Why, for failed; empty otherwise.

velocity ​
ts
velocity: Vec3;

How fast that point moves, world metres a second: a release gives the object this.


MouseState ​

Pointer position, deltas, wheel and button edges for one frame.

Properties ​

buttons ​
ts
buttons: number;
dx ​
ts
dx: number;
dy ​
ts
dy: number;
locked ​
ts
locked: boolean;
pressed ​
ts
pressed: number;
released ​
ts
released: number;
wheel ​
ts
wheel: number;
x ​
ts
x: number;
y ​
ts
y: number;

MoveCharacterCmd ​

Drive a character body for one step.

Properties ​

body ​
ts
body: number;
crouch ​
ts
crouch: boolean;
desiredVelocity ​
ts
desiredVelocity: Vec3;
jump ​
ts
jump: boolean;
maxSlopeDeg ​
ts
maxSlopeDeg: number;

MultiplayerOptions ​

Options for the multiplayer feature.

Properties ​

maxPlayers? ​
ts
optional maxPlayers?: number;

Seats in a room, ids 0..maxPlayers - 1. Default 8. roomSeats reads it, for the guest's player slots and for the room's door alike.

predict? ​
ts
optional predict?: boolean;

Predict each page's own character body: the page steps its own Jolt world (the level's static colliders and the body its client guest adds for its player) so the player moves on key-down, and the authority's rows correct it. Default false. See the multiplayer concept page.

sendHz? ​
ts
optional sendHz?: number;

Transform rows per second sent to each player. Default 20.


MutableGamepad ​

A gamepad snapshot the SDK owns and reuses every frame.

Properties ​

axes ​
ts
axes: Float32Array;

Standard mapping: lx, ly, rx, ry, left trigger, right trigger.

buttons ​
ts
buttons: number;
connected ​
ts
connected: boolean;
index ​
ts
index: number;
pressed ​
ts
pressed: number;
released ​
ts
released: number;

NetFacade ​

The ctx.net facade, one per guest.

Example ​

ts
function votes(ctx: GameContext): void {
  if (!ctx.net.isAuthority) return;
  for (const vote of ctx.net.messages(Vote)) {
    ctx.net.send('voted', { by: vote.player, for: vote.payload.for });
  }
  ctx.net.local(() => ctx.audio.play('tick')); // never sent to a player
}

Properties ​

stats ​
ts
readonly stats: NetStats;

Counters since init.

Accessors ​

isAuthority ​
Get Signature ​
ts
get isAuthority(): boolean;
Returns ​

boolean

True on the authority and in a single-player game.

localPlayer ​
Get Signature ​
ts
get localPlayer(): number;
Returns ​

number

The player this page belongs to on a client; 0 elsewhere.

role ​
Get Signature ​
ts
get role(): NetRole;
Returns ​

NetRole

Where this guest runs.

Methods ​

beginTick() ​
ts
beginTick(): void;

Start a tick: this tick's messages are read afresh. Runtime only.

Returns ​

void

local() ​
ts
local(fn): void;

Run fn with every command it queues routed to frame-output.local-commands: applied where this guest runs, never sent to a player. Nested calls stay local; a throw still restores the network buffer. Allocates nothing.

Parameters ​
ParameterTypeDescription
fn() => voidThe code whose commands stay local.
Returns ​

void

messages() ​
ts
messages<T>(message): readonly NetMessage<T>[];

This tick's validated messages for one definition, in arrival order.

A payload over the definition's maxBytes, not JSON, or failing its check is dropped and counted in stats.dropped, never thrown at a system; the rest count in stats.received. The list and its entries are pooled and refilled each tick: read them inside the tick, never retain them. Reading the same name twice in a tick counts nothing twice.

A bare name (deprecated) reads the same list without a check, unless the name's definition has been read before in this run; it caps at 2,048 bytes.

Type Parameters ​
Type Parameter
T
Parameters ​
ParameterTypeDescription
messagestring | MessageDef<T>The definition, or a bare message name.
Returns ​

readonly NetMessage<T>[]

The messages, { player, payload }.

reset() ​
ts
reset(): void;

Forget the counters and every cached message list. init only.

Returns ​

void

send() ​
Call Signature ​
ts
send<T>(
   message, 
   payload, 
   options?
): void;

Send a game message: from the authority to one player or all of them, from a client up to the authority (to is ignored there).

Pass a defineMessage definition to check the payload with its guard and cap it at its maxBytes before it leaves; a bare name (deprecated) checks only the 2,048-byte wire cap.

The payload is serialised with JSON.stringify, so a tick that sends allocates that one string; a tick that sends nothing allocates nothing. undefined sends null.

Type Parameters ​
Type Parameter
T
Parameters ​
ParameterTypeDescription
messageMessageDef<T>The definition, or a bare message name.
payloadTAnything JSON-serialisable; at most maxBytes (2,048) as UTF-8 JSON.
options?SendOptionsto one player, and reliable (default true). A payload that does not serialise (a function or a symbol), fails the definition's check, or whose JSON is over the cap sends nothing and counts in stats.unsent; it never throws, since a throwing system fails the tick.
Returns ​

void

Call Signature ​
ts
send(
   name, 
   payload, 
   options?
): void;

Send a game message: from the authority to one player or all of them, from a client up to the authority (to is ignored there).

Pass a defineMessage definition to check the payload with its guard and cap it at its maxBytes before it leaves; a bare name (deprecated) checks only the 2,048-byte wire cap.

The payload is serialised with JSON.stringify, so a tick that sends allocates that one string; a tick that sends nothing allocates nothing. undefined sends null.

Parameters ​
ParameterTypeDescription
namestring-
payloadunknownAnything JSON-serialisable; at most maxBytes (2,048) as UTF-8 JSON.
options?SendOptionsto one player, and reliable (default true). A payload that does not serialise (a function or a symbol), fails the definition's check, or whose JSON is over the cap sends nothing and counts in stats.unsent; it never throws, since a throwing system fails the tick.
Returns ​

void

setPhase() ​
ts
setPhase(word): void;

Say what the room is doing, in a word (lobby, playing, voting), for the public room list beside its code and seats. Authority only: on a client, and in a game with no room, it does nothing. The same word again sends nothing and allocates nothing; a new one sends the reserved message aos:phase, which the room server reads and never forwards to a player.

Parameters ​
ParameterTypeDescription
wordstring1 to 32 ASCII letters, digits or dashes. Anything else sends nothing, counts in stats.unsent and is logged once; it never throws.
Returns ​

void

Example ​
ts
function lobby(ctx: GameContext): void {
  ctx.net.setPhase(started ? 'playing' : 'lobby');
}

NetMessage ​

What messages hands back: one player's message, its payload parsed.

Example ​

ts
for (const m of ctx.net.messages(Vote)) tally(m.player, m.payload.for);

Type Parameters ​

Type Parameter
T

Properties ​

payload ​
ts
readonly payload: T;

The JSON payload, parsed.

player ​
ts
readonly player: number;

The sender.


NetMessageEvent ​

A game message a player sent, delivered to the authority on its next tick.

Named NetMessageEvent rather than the WIT's message-event so it never shadows the DOM's MessageEvent in a page that imports both.

Properties ​

name ​
ts
name: string;
payload ​
ts
payload: string;

JSON.

player ​
ts
player: number;

The sender.


NetStats ​

Counters a game or the debug overlay can read.

Example ​

ts
ctx.hud.set({ dropped: ctx.net.stats.dropped, received: ctx.net.stats.received });

Properties ​

dropped ​
ts
dropped: number;

Messages read and dropped: over their maxBytes, not JSON, or failing their defineMessage check. A payload over 2,048 bytes is dropped by the room before it reaches the guest, and is not counted here.

received ​
ts
received: number;

Messages read and handed to a system.

unsent ​
ts
unsent: number;

ctx.net.send calls since init that sent nothing: the payload failed its check, did not serialise, or was over the cap. Never thrown, because a throw fails the tick and enough of them kill the guest for the room.


OverlapHit ​

One body overlapping a query volume.

Properties ​

body ​
ts
body: number;
depth ​
ts
depth: number;
entity ​
ts
entity: number;
point ​
ts
point: Vec3;

PlayerHandle ​

One player: who they are, the entity definition.player spawned for them, and facades that read their input and write their own camera and HUD.

Example ​

ts
for (const [id, p] of ctx.players) {
  if (p.input.pressed('Space')) jump(p.entity);
  p.hud.set({ name: p.name, id });
}

Properties ​

camera ​
ts
readonly camera: object;

This player's camera: every write queues one set-player-camera per tick.

look ​
Get Signature ​
ts
get look(): object;

Accumulated look angles, in radians. Mutate to snap the view.

Returns ​

object

The live look state.

pitch ​
ts
pitch: number;
sensitivity ​
ts
sensitivity: number;
yaw ​
ts
yaw: number;
state ​
Get Signature ​
ts
get state(): CameraState;

The whole camera record, for games that want every knob.

Returns ​

CameraState

The live record. Mutate it; do not replace it.

firstPerson() ​
ts
firstPerson(entity, options?): void;

Mount the camera at an entity's eyes.

Yaw and pitch come from the built-in look accumulator, which integrates input.mouse.dx/dy once per tick.

Parameters ​
ParameterTypeDescription
entitynumberEntity to mount on.
options?FirstPersonOptionsEye height and field of view.
Returns ​

void

Nothing.

follow() ​
ts
follow(entity, options?): void;

Put the camera on a spring arm behind an entity.

The host owns the arm and its collision; the guest only states the intent. position is the orbit pivot and rotation the direction the player is looking, so a host with no rig still ends up somewhere sensible.

Parameters ​
ParameterTypeDescription
entitynumberEntity to follow.
options?FollowOptionsBoom length, height offset, field of view and orbit angles.
Returns ​

void

Nothing.

lookAt() ​
ts
lookAt(point): void;

Aim the camera at a world point, overriding its rotation.

Parameters ​
ParameterTypeDescription
pointVec3 | nullThe point to look at, or null to use the rotation again.
Returns ​

void

Nothing.

set() ​
ts
set(
   position, 
   rotation, 
   fovYDeg?
): void;

Place the camera explicitly, detaching it from any entity.

Parameters ​
ParameterTypeDefault valueDescription
positionVec3undefinedEye position.
rotationQuatundefinedEye rotation, xyzw.
fovYDegnumber60Vertical field of view in degrees. Default 60.
Returns ​

void

Nothing.

hud ​
ts
readonly hud: object;

This player's HUD: a changed model queues a set-player-hud.

clear() ​
ts
clear(): void;

Drop the HUD: emit an empty model this frame.

Idempotent — calling it every frame emits {} once, exactly like set.

Returns ​

void

Nothing.

invalidate() ​
ts
invalidate(): void;

Forget what the host has seen, so the next set emits even if the model did not change. Use it after the host reloaded its overlay.

On its own it sends nothing: the next set does. To send an empty model now, call clear().

Returns ​

void

Nothing.

set() ​
ts
set(model): boolean;

Set the HUD model for this frame.

Nested plain objects are compared by value four levels down, so a model rebuilt inline every frame is recognised as unchanged. Arrays and class instances are compared by identity: keep those out of the model, or build them once and mutate nothing.

Parameters ​
ParameterTypeDescription
modelRecord<string, unknown>A JSON-serialisable object.
Returns ​

boolean

True when the model changed and JSON will cross this frame.

id ​
ts
readonly id: number;

The player id this slot belongs to.

input ​
ts
readonly input: object;

This player's keys, mouse and gamepads, read like input.

touch ​
ts
touch: object;

Fingers on a touch screen, as the host's touch layer packs them: the first finger is the pointer (mouse), a tap is pressed('Tap'), and the thumb sticks, the pinch and the turn are here.

touch.active ​
Get Signature ​
ts
get active(): boolean;

Is a finger on the screen? (The touch pad is connected.)

Returns ​

boolean

True while any finger is down.

touch.pinch ​
Get Signature ​
ts
get pinch(): number;

Two fingers' pinch this step, as a scale factor: over 1 the fingers moved apart (zoom in), under 1 together, exactly 1 with no pinch.

Returns ​

number

The scale factor.

touch.turn ​
Get Signature ​
ts
get turn(): number;

Two fingers' turn this step, in radians, counter-clockwise on the screen positive.

Returns ​

number

The turn.

touch.stick() ​
ts
stick(side): Axis2;

A thumb stick's push.

Parameters ​
ParameterTypeDescription
side"left" | "right"The left stick (movement) or the right one (the camera).
Returns ​

Axis2

A pooled { x, y }, -1..1, y up the screen positive. Never retain it.

focused ​
Get Signature ​
ts
get focused(): boolean;

Does the canvas have focus? Treat input as neutral when it does not.

Returns ​

boolean

True while the canvas is focused.

mods ​
Get Signature ​
ts
get mods(): InputMods;

Keyboard modifier state.

Returns ​

InputMods

The modifiers for this frame.

mouse ​
Get Signature ​
ts
get mouse(): MouseState;

Pointer position, per-frame delta, wheel and button bitsets.

Returns ​

MouseState

The mouse state for this frame. Owned by the SDK; never retain it.

axis2() ​
ts
axis2(
   negX, 
   posX, 
   negY, 
   posY, 
   stick?
): Axis2;

A two-axis reading built from four keys, plus a thumb stick on a touch screen: the left one by default, so axis2('A', 'D', 'S', 'W') moves on a phone with no other binding. Pass 'right' for a camera axis, 'none' for keys only.

Parameters ​
ParameterTypeDefault valueDescription
negXstringundefinedKey that drives x negative, for example 'A'.
posXstringundefinedKey that drives x positive, for example 'D'.
negYstringundefinedKey that drives y negative, for example 'S'.
posYstringundefinedKey that drives y positive, for example 'W'.
stickStickSide'left'Which thumb stick to add, 'left' by default.
Returns ​

Axis2

A pooled { x, y } with components in -1..1. Never retain it.

gamepad() ​
ts
gamepad(index): 
  | {
  axes: ArrayLike<number>;
  buttons: number;
  connected: boolean;
  index: number;
  pressed: number;
  released: number;
}
  | null;

One connected gamepad.

Parameters ​
ParameterTypeDescription
indexnumberNavigator gamepad index.
Returns ​

| { axes: ArrayLike<number>; buttons: number; connected: boolean; index: number; pressed: number; released: number; } | null

The gamepad, or null when nothing is connected at that index. Owned by the SDK; never retain it.

isDown() ​
ts
isDown(key): boolean;

Is the key held this frame?

Parameters ​
ParameterTypeDescription
keystringA DOM code ('KeyW'), a bare letter/digit ('W', '1') or an alias ('Shift', 'Esc').
Returns ​

boolean

True while the key is down.

mouseDown() ​
ts
mouseDown(button): boolean;

Is a mouse button held?

Parameters ​
ParameterTypeDescription
buttonnumberA MOUSE_BUTTONS value, or a raw bit mask.
Returns ​

boolean

True while the button is down.

mousePressed() ​
ts
mousePressed(button): boolean;

Did a mouse button go down this frame?

Parameters ​
ParameterTypeDescription
buttonnumberA MOUSE_BUTTONS value, or a raw bit mask.
Returns ​

boolean

True on the frame the button went down.

mouseReleased() ​
ts
mouseReleased(button): boolean;

Did a mouse button come up this frame?

Parameters ​
ParameterTypeDescription
buttonnumberA MOUSE_BUTTONS value, or a raw bit mask.
Returns ​

boolean

True on the frame the button came up.

pressed() ​
ts
pressed(key): boolean;

Did the key go down this frame?

Parameters ​
ParameterTypeDescription
keystringA key name.
Returns ​

boolean

True on the frame the key went down.

released() ​
ts
released(key): boolean;

Did the key come up this frame?

Parameters ​
ParameterTypeDescription
keystringA key name.
Returns ​

boolean

True on the frame the key came up.

lanes ​
ts
readonly lanes: InputLanes;

The decoded input this handle's input reads. Internal.

present ​
ts
present: boolean = false;

In this step's frame-input.players. Internal.

seq ​
ts
seq: number = 0;

The input sequence number this step consumed.

Accessors ​

connected ​
Get Signature ​
ts
get connected(): boolean;
Returns ​

boolean

True between this player's player-joined and player-left.

data ​
Get Signature ​
ts
get data(): unknown;
Returns ​

unknown

The player's document: the one the room loaded at join, then whatever ctx.data.save or a finished exchange made it; null for none.

entity ​
Get Signature ​
ts
get entity(): number;
Returns ​

number

The entity this player controls: the one definition.player spawned at join, or the last one possessed; 0 for none (also after that entity is despawned).

isHost ​
Get Signature ​
ts
get isHost(): boolean;
Returns ​

boolean

True for the host (ctx.players.host): the first joiner, until they leave; then the lowest seat still joined.

joinedAt ​
Get Signature ​
ts
get joinedAt(): number | null;
Returns ​

number | null

The server's clock when the room loaded this player's document, in ms since the epoch, or null when the room has no store. The guest has no clock of its own (now-ms counts from engine start), so this is the one wall time it gets: add ctx.elapsed since the join to it.

name ​
Get Signature ​
ts
get name(): string;
Returns ​

string

The display name the room gave at join, or ''.

savedAt ​
Get Signature ​
ts
get savedAt(): number | null;
Returns ​

number | null

When the store last wrote the document handed over at join, in ms since the epoch by the server's clock, or null when there was none. Offline time is joinedAt - savedAt.

Methods ​

forgetEntity() ​
ts
forgetEntity(entity): void;

The possessed entity was despawned: the player controls none. The host clears its own mapping on the despawn, so nothing is sent.

Parameters ​
ParameterTypeDescription
entitynumberA despawned entity.
Returns ​

void

integrateLook() ​
ts
integrateLook(): void;

Integrate this step's mouse movement into the look angles, as the built-in accumulator does for the local player. Allocates nothing.

Returns ​

void

join() ​
ts
join(name, data): void;

The player took this seat. Parses the saved document: a join-tick allocation.

Parameters ​
ParameterTypeDescription
namestringThe display name.
datastring | null | undefinedThe room's { doc, savedAt, now } as JSON, when it has a store (a bare document is taken as the doc).
Returns ​

void

leave() ​
ts
leave(): void;

The player left; the caller has already despawned PlayerHandle.entity.

Returns ​

void

possess() ​
ts
possess(entity): void;

Make this player control another entity: a respawn, a vehicle, a class swap. On the authority it queues a set-player-entity, so the room follows the player there (relevancy) and their client learns which entity is theirs. Despawning the entity later leaves the player with none until the next possess.

Parameters ​
ParameterTypeDescription
entitynumberThe entity, or 0 to control none.
Returns ​

void

Example ​
ts
const body = ctx.spawn(Avatar, spawnPoint);
ctx.players.get(id)?.possess(body);
restoreSeat() ​
ts
restoreSeat(
   connected, 
   name, 
   entity, 
   data
): void;

Overwrite who holds this seat from a snapshot. The caller rebuilds the map.

Parameters ​
ParameterTypeDescription
connectedbooleanJoined and not left.
namestringThe display name.
entitynumberThe player's entity in the restored world, or 0.
dataunknownThe saved document, already parsed.
Returns ​

void

setEntity() ​
ts
setEntity(entity): void;

The authority spawned this player's entity at join: possess it (which tells the host). Nothing is sent for 0 (a game with no player prefab).

Parameters ​
ParameterTypeDescription
entitynumberThe entity spawned for this player, or 0.
Returns ​

void


PlayerInput ​

One player's input for a step, as frame-input.players carries it.

Properties ​

input ​
ts
input: InputState;

That player's keys, mouse and gamepads.

player ​
ts
player: number;

The player id. 0 is the single-player player, which travels as frame-input.input.

seq ​
ts
seq: number;

The client's input sequence number this step consumed; 0 when unknown.


PlayerJoinedEvent ​

A player entered the room.

Properties ​

data? ​
ts
optional data?: string;

The player's saved document as JSON, when the room has a store. Absent otherwise (null in a wasm guest, as every incoming option is).

name ​
ts
name: string;
player ​
ts
player: number;

PlayerLeftEvent ​

A player left the room.

Properties ​

player ​
ts
player: number;
reason ​
ts
reason: string;

Why: "left", "timeout", "kicked", ...


Players ​

The room's players: a read-only Map from id to PlayerHandle, plus who the host is and a list to walk without allocating.

A for...of over the map (or keys(), values(), entries()) makes an iterator, and an entry pair per player, every call: fine in a join handler, not in a system that runs every tick. Walk list with an index there.

Example ​

ts
const players = ctx.players;
for (let i = 0; i < players.list.length; i += 1) {
  const p = players.list[i];
  if (p.isHost && p.input.pressed('Enter')) startRound();
}
const host = players.host === undefined ? undefined : players.get(players.host);

Extends ​

Properties ​

host ​
ts
readonly host: number | undefined;

The host's seat id, or undefined while nobody is joined. The first joiner is the host and stays host until they leave (player-left); only then does it pass to the lowest seat still joined. A newcomer who takes a lower, freed seat does not become host. Snapshots keep it.

A host who drops counts as gone for this alone: while the room holds their seat (they are still joined, but out of the frame's players list), the role passes to the lowest seat in that list, and it stays there when they come back. If nobody else is in the list, the held host keeps it.

list ​
ts
readonly list: readonly PlayerHandle[];

The same players as the map, in id order. The same array for the whole run, updated in place on a join or a leave; never per tick. Read it, do not keep a copy of its contents across ticks.


PlayerSpec ​

The declarative player block.

Properties ​

camera? ​
ts
optional camera?: "firstPerson" | "thirdPerson";

Which built-in camera rig to drive.

character? ​
ts
optional character?: (seat) => string;

Character asset id for a seat, overriding the prefab's character.

Parameters ​
ParameterType
seatnumber
Returns ​

string

distance? ​
ts
optional distance?: number;

Third-person boom length, metres. Default 4.

eyeHeight? ​
ts
optional eyeHeight?: number;

First-person eye height, metres. Default 1.7.

height? ​
ts
optional height?: number;

Third-person height offset, metres. Default 1.6.

prefab? ​
ts
optional prefab?: PrefabDef;

Prefab to spawn for the player.

sensitivity? ​
ts
optional sensitivity?: number;

Radians of look per pixel of mouse movement. Default 0.0025.

spawn? ​
ts
optional spawn?: PlayerSpawn;

Where each seat spawns; see PlayerSpawn. Default [0, 0, 0].


PlayOptions ​

Options for audio.play.

Properties ​

bus? ​
ts
optional bus?: AudioBus;

Mixer bus. Default 'sfx'.

entity? ​
ts
optional entity?: number;

Attach to an entity for positional audio that follows it.

looping? ​
ts
optional looping?: boolean;

Loop until stopped. Default false.

pitch? ​
ts
optional pitch?: number;

Playback-rate multiplier. Default 1.

volume? ​
ts
optional volume?: number;

Linear gain in 0..1. Default 1.


PlaySoundCmd ​

Start a sound.

Properties ​

asset ​
ts
asset: number;
bus ​
ts
bus: AudioBus;
entity? ​
ts
optional entity?: number;
looping ​
ts
looping: boolean;
pitch ​
ts
pitch: number;
position? ​
ts
optional position?: Vec3;
sound ​
ts
sound: number;
volume ​
ts
volume: number;

PrefabDef ​

A prefab, ready to spawn.

Extends ​

Properties ​

asset? ​
ts
optional asset?: string | number;

Renderable asset: a manifest string id, or a handle.

Inherited from ​

PrefabSpec.asset

body? ​
ts
optional body?: BodySpec;

Physics body, if any.

Inherited from ​

PrefabSpec.body

character? ​
ts
optional character?: string | number;

Splat character bundle: a manifest string id, or a handle.

Inherited from ​

PrefabSpec.character

components? ​
ts
optional components?: readonly object[];

Extra bitecs components and tags to add on spawn.

Inherited from ​

PrefabSpec.components

health? ​
ts
optional health?: number;

Starting hit points; adds the Health component when present.

Inherited from ​

PrefabSpec.health

name? ​
ts
optional name?: string;

Debug label shown in the engine overlay.

Inherited from ​

PrefabSpec.name

prefabId ​
ts
readonly prefabId: number;

Stable index, assigned in declaration order.

scale? ​
ts
optional scale?: readonly number[];

Uniform or per-axis scale. Default [1, 1, 1].

Inherited from ​

PrefabSpec.scale


PrefabSpec ​

Everything a prefab can declare.

Extended by ​

Properties ​

asset? ​
ts
optional asset?: string | number;

Renderable asset: a manifest string id, or a handle.

body? ​
ts
optional body?: BodySpec;

Physics body, if any.

character? ​
ts
optional character?: string | number;

Splat character bundle: a manifest string id, or a handle.

components? ​
ts
optional components?: readonly object[];

Extra bitecs components and tags to add on spawn.

health? ​
ts
optional health?: number;

Starting hit points; adds the Health component when present.

name? ​
ts
optional name?: string;

Debug label shown in the engine overlay.

scale? ​
ts
optional scale?: readonly number[];

Uniform or per-axis scale. Default [1, 1, 1].


Quat ​

A unit quaternion in xyzw order (three.js / Jolt order).

Properties ​

w ​
ts
w: number;
x ​
ts
x: number;
y ​
ts
y: number;
z ​
ts
z: number;

QueryFilter ​

Which bodies a physics query considers.

Properties ​

excludeBody? ​
ts
optional excludeBody?: number;
excludeEntity? ​
ts
optional excludeEntity?: number;
layers ​
ts
layers: CollisionLayers;
solidOnly ​
ts
solidOnly: boolean;

RayHit ​

Closest hit along a ray.

Properties ​

body ​
ts
body: number;
distance ​
ts
distance: number;
entity ​
ts
entity: number;
normal ​
ts
normal: Vec3;
point ​
ts
point: Vec3;

RayQuery ​

One ray in a raycastBatch call.

Properties ​

direction ​
ts
direction: Vec3;
filter ​
ts
filter: QueryFilter;
maxDistance ​
ts
maxDistance: number;
origin ​
ts
origin: Vec3;

RenderableStore ​

Renderable asset handle plus host-side flags.

Properties ​

asset ​
ts
asset: Uint32Array;

Manifest asset handle; 0 means "no renderable".

dirty ​
ts
dirty: Uint8Array;

Non-zero when the host has not yet seen the current value.

flags ​
ts
flags: Uint32Array;

Reserved host flags bitset.


Rgba ​

Linear RGBA, components in 0..1.

Properties ​

a ​
ts
a: number;
b ​
ts
b: number;
g ​
ts
g: number;
r ​
ts
r: number;

RigidBodyStore ​

Rigid body handle and classification.

Properties ​

dirty ​
ts
dirty: Uint8Array;

Non-zero when the host has not yet seen the current value.

groundState ​
ts
groundState: Uint8Array;

Post-step contact: 0 unknown, 1 ground, 2 steep, 3 unsupported, 4 air.

handle ​
ts
handle: Uint32Array;

Guest-minted body id; 0 means "no body".

kind ​
ts
kind: Uint8Array;

BODY_KIND index.

shape ​
ts
shape: Uint8Array;

SHAPE_KIND index.


Rng ​

A seeded, serialisable random source.

Methods ​

float() ​
ts
float(): number;

Next float in [0, 1).

Returns ​

number

int() ​
ts
int(n): number;

Next integer in [0, n). Returns 0 when n <= 0.

Parameters ​
ParameterType
nnumber
Returns ​

number

load() ​
ts
load(state): void;

Overwrite the state.

Parameters ​
ParameterType
stateRngState
Returns ​

void

pick() ​
ts
pick<T>(items): T | undefined;

A uniformly chosen element, or undefined when the array is empty.

Type Parameters ​
Type Parameter
T
Parameters ​
ParameterType
itemsArrayLike<T>
Returns ​

T | undefined

range() ​
ts
range(min, max): number;

Next float in [min, max).

Parameters ​
ParameterType
minnumber
maxnumber
Returns ​

number

save() ​
ts
save(out?): RngState;

Copy the state out, into out when given.

Parameters ​
ParameterType
out?RngState
Returns ​

RngState

seed() ​
ts
seed(value): void;

Re-seed from a 32-bit integer.

Parameters ​
ParameterType
valuenumber
Returns ​

void

uint32() ​
ts
uint32(): number;

Next u32.

Returns ​

number


RngState ​

Four-word xoshiro128** state, as it appears in a snapshot.

Properties ​

s0 ​
ts
s0: number;
s1 ​
ts
s1: number;
s2 ​
ts
s2: number;
s3 ​
ts
s3: number;

RuntimeState ​

Everything one guest instance owns.

Properties ​

assetDescs ​
ts
assetDescs: Map<number, AssetDesc | null>;

Asset handle to its description, cached because the manifest is immutable for the life of a run. Per runtime, never module scope: a parity run has a direct guest and a wasm guest, with different hosts, in one realm.

assetIds ​
ts
assetIds: Map<string, number>;

Manifest string id to asset handle, resolved once and cached.

bodyIndex ​
ts
bodyIndex: BodyIndex;
camera ​
ts
camera: CameraState;
carryCommands ​
ts
carryCommands: boolean;

True when the command buffer holds commands built outside tick — the spawns init queued. The next tick keeps them instead of resetting.

commands ​
ts
commands: NetCommandBuffer;

Where the facades queue commands: the network buffer behind frame-output.commands, or localCommands inside ctx.net.local.

config ​
ts
config: GameConfig;
contacts ​
ts
contacts: readonly Contact[];
dead ​
ts
dead: boolean;

Set after repeated user-code failures; the host must rebuild the sandbox.

dt ​
ts
dt: number;
elapsed ​
ts
elapsed: number;
events ​
ts
events: readonly GameEvent[];
failures ​
ts
failures: number;

Consecutive failed ticks.

focused ​
ts
focused: boolean;
frame ​
ts
frame: number;
gamepadCount ​
ts
gamepadCount: number;
gamepads ​
ts
gamepads: MutableGamepad[];
host ​
ts
host: HostApi;
hud ​
ts
hud: HudState;
initialised ​
ts
initialised: boolean;

True once init has completed. Asset resolution warns after this.

inputLanes ​
ts
inputLanes: InputLanes;

The lanes the singleton input reads: this runtime's own (above) in a single-player game and on the authority, the local player's slot on a client.

keysDown ​
ts
keysDown: Uint32Array;
keysPressed ​
ts
keysPressed: Uint32Array;
keysReleased ​
ts
keysReleased: Uint32Array;
localCommands ​
ts
localCommands: NetCommandBuffer;

frame-output.local-commands: applied by the authority, never forwarded.

look ​
ts
look: LookState;
madeWorld ​
ts
madeWorld: WorldList | null;

The made world the host loaded (its list of things), or null: filled from the world-events before the systems run. The things facade reads it.

mods ​
ts
mods: InputMods;
mouse ​
ts
mouse: MouseState;
net ​
ts
net: NetConfig;

The net block of game-config.options, read in init.

nextBody ​
ts
nextBody: number;

Next guest-minted body id. Counters start at 1; 0 means "none".

nextSound ​
ts
nextSound: number;

Next guest-minted sound handle.

packer ​
ts
packer: TransformPacker;
player ​
ts
player: number;

The player entity, when the declarative player block created one.

players ​
ts
players: PlayerTable;

frame-input.players, decoded into slots made in init.

rng ​
ts
rng: Rng;
world ​
ts
world: object;

The bitecs world. Typed loosely so the SDK does not leak bitecs generics.


SaveGameDataCmd ​

Persist the room's game-wide document (JSON). Authority only.

Properties ​

data ​
ts
data: string;

SavePlayerDataCmd ​

Persist one player's document (JSON). Authority only.

Properties ​

data ​
ts
data: string;
player ​
ts
player: number;

SayCmd ​

Speak a line, optionally with audio and a viseme track.

Properties ​

audio? ​
ts
optional audio?: number;
entity ​
ts
entity: number;
text ​
ts
text: string;
visemes? ​
ts
optional visemes?: string;

SendCmd ​

Send a game message to one player, every player, or up to the authority.

Properties ​

name ​
ts
name: string;
payload ​
ts
payload: string;

JSON, at most 2,048 bytes.

reliable ​
ts
reliable: boolean;
to? ​
ts
optional to?: number;

One player; absent sends to every player (authority) or to the authority (client).


SendOptions ​

Options for NetFacade.send.

Example ​

ts
ctx.net.send('role', { role: 'murderer' }, { to: 3 });
ctx.net.send('aim', { x: 1 }, { reliable: false }); // every player, may drop

Properties ​

reliable? ​
ts
optional reliable?: boolean;

Ordered and guaranteed. Default true.

to? ​
ts
optional to?: number;

One player; absent sends to every player. Ignored on a client.


SetAnimCmd ​

Play or cross-fade an animation clip on one layer.

Properties ​

clip ​
ts
clip: string;
entity ​
ts
entity: number;
fadeMs ​
ts
fadeMs: number;
looping ​
ts
looping: boolean;
speed ​
ts
speed: number;
weight ​
ts
weight: number;

SetAssetCmd ​

Attach or detach an entity's renderable.

Properties ​

asset? ​
ts
optional asset?: number;
entity ​
ts
entity: number;

SetBodyEnabledCmd ​

Enable or disable a body in the broad phase.

Properties ​

body ​
ts
body: number;
enabled ​
ts
enabled: boolean;

SetBodyTransformCmd ​

Move a body directly.

Properties ​

body ​
ts
body: number;
position ​
ts
position: Vec3;
rotation ​
ts
rotation: Quat;
teleport ​
ts
teleport: boolean;

SetBodyVelocityCmd ​

Overwrite a body's velocities. undefined leaves one untouched.

Properties ​

angular? ​
ts
optional angular?: Vec3;
body ​
ts
body: number;
linear? ​
ts
optional linear?: Vec3;

SetCharacterMotionCmd ​

How the movement system moves a character (see character.motion).

Properties ​

carry ​
ts
carry: boolean;

Whether the take carries the walker.

entity ​
ts
entity: number;
naturalness ​
ts
naturalness: number;
on ​
ts
on: boolean;

Whether the movement system moves this character at all.

responsiveness ​
ts
responsiveness: number;

0..1; negative keeps what it has.

set? ​
ts
optional set?: string;

'own', 'shared' or a name the page gave its bridge; absent keeps the set it has.

stop? ​
ts
optional stop?: StopStyle;

Which kind of stop it makes when it runs and is asked to stand: 'gradual' (it slows and stands upright) or 'hard' (it brakes). Absent keeps what it has.


SetCharacterStateCmd ​

Drive a character's locomotion state machine.

Properties ​

entity ​
ts
entity: number;
grounded ​
ts
grounded: boolean;
state ​
ts
state: string;
velocity ​
ts
velocity: Vec3;

SetClipWeightsCmd ​

Set explicit per-clip weights on a character's body layer.

Properties ​

clips ​
ts
clips: readonly string[];
entity ​
ts
entity: number;
timeScale ​
ts
timeScale: number;
weights ​
ts
weights: readonly number[] | Float32Array<ArrayBufferLike>;

SetExpressionCmd ​

Set a character's facial expression coefficients.

Properties ​

entity ​
ts
entity: number;
space ​
ts
space: ExpressionSpace;
weights ​
ts
weights: readonly number[] | Float32Array<ArrayBufferLike>;

SetListenerCmd ​

Place the audio listener.

Properties ​

position ​
ts
position: Vec3;
rotation ​
ts
rotation: Quat;
velocity ​
ts
velocity: Vec3;

SetMaterialParamCmd ​

Set one material uniform.

Properties ​

entity ​
ts
entity: number;
name ​
ts
name: string;
value ​
ts
value: MaterialValue;

SetParentCmd ​

Reparent an entity in the scene graph.

Properties ​

entity ​
ts
entity: number;
keepWorldTransform ​
ts
keepWorldTransform: boolean;
parent? ​
ts
optional parent?: number;

SetPlayerCameraCmd ​

The camera one player renders from.

Properties ​

camera ​
ts
camera: CameraState;
player ​
ts
player: number;

SetPlayerEntityCmd ​

Which entity a player controls. The authority sends it when it spawns definition.player for a join and on every PlayerHandle.possess; the host keeps the mapping (relevancy, "which entity is mine" on the client).

Properties ​

entity ​
ts
entity: number;
player ​
ts
player: number;

SetPlayerHudCmd ​

One player's HUD model as JSON.

Properties ​

hud ​
ts
hud: string;
player ​
ts
player: number;

Shape ​

Collision shape description carried by add-body.

Properties ​

asset? ​
ts
optional asset?: number;
halfExtents ​
ts
halfExtents: Vec3;
kind ​
ts
kind: ShapeKind;

SidedSystem ​

A system that says where it runs.

'authority' runs on the room's authority and in a single-player (solo) game; 'client' runs on a player's page and in solo; 'both' runs everywhere. solo is its own authority and its own client, so it runs all three. A bare function is 'authority' once the game declares features.multiplayer, and 'both' otherwise, so a single-player game reads the same as it always did.

Example ​

ts
import { defineGame } from 'gameable';

export default defineGame({
  features: { multiplayer: true },
  systems: [
    (ctx) => { ctx.net.send('tick', ctx.frame); }, // bare: the authority's
    { on: 'client', run: (ctx) => { ctx.hud.set({ ping: ctx.frame }); } },
  ],
});

Properties ​

on ​
ts
on: "authority" | "client" | "both";

Where it runs.

run ​
ts
run: Run;

The system.


SoundEndedEvent ​

A playing sound stopped.

Properties ​

completed ​
ts
completed: boolean;
sound ​
ts
sound: number;

SpawnCharacterCmd ​

Instantiate a splat character bundle.

Properties ​

bundle ​
ts
bundle: number;
entity ​
ts
entity: number;
position ​
ts
position: Vec3;
rotation ​
ts
rotation: Quat;

SpawnCmd ​

Create an entity, optionally with a renderable asset.

Properties ​

asset? ​
ts
optional asset?: number;
entity ​
ts
entity: number;
name? ​
ts
optional name?: string;
parent? ​
ts
optional parent?: number;
position ​
ts
position: Vec3;
rotation ​
ts
rotation: Quat;
scale ​
ts
scale: Vec3;
visible ​
ts
visible: boolean;

SpawnSpec ​

One entry of the declarative spawns list.

Properties ​

position ​
ts
position: readonly number[];

Where, [x, y, z].

prefab ​
ts
prefab: PrefabDef;

What to spawn.

rotation? ​
ts
optional rotation?: readonly number[];

Rotation, [x, y, z, w]. Defaults to identity.


StopSoundCmd ​

Stop a playing sound.

Properties ​

fadeMs ​
ts
fadeMs: number;
sound ​
ts
sound: number;

ThingCmd ​

Something a game asks of a loose thing in a made world (gameable/world): push an impulse at its middle (newton-seconds), move the middle of its base to a point (at rest), reset it to where the package had it, or reset-all for every loose thing. Of a thing with moving parts: joint and drive. Of a thing with rider spots: ride sits a character on it, or takes whoever sits on it off. Of a thing in pieces: break lets its pieces go (named for one piece, that piece alone). The thing is named by its place in the world's list.

Properties ​

action ​
ts
action: 
  | "push"
  | "joint"
  | "move"
  | "reset"
  | "drive"
  | "reset-all"
  | "ride"
  | "break";
thing ​
ts
thing: number;

The thing's place in the world's list; ignored by reset-all.

vector ​
ts
vector: Vec3;

push: the impulse. move: the point. joint: x the joint's place in the thing's list of joints, y its value. drive: x steering to the right (-1 to 1), y the brakes (0 to 1), z the throttle (-1 to 1). ride: x the character's entity, 0 for getting off. Zero otherwise.


ThirdPersonClips ​

Optional authored clips; omit to use the animator's standard locomotion blend.

Properties ​

fall ​
ts
fall: string;
idle ​
ts
idle: string;
land ​
ts
land: string;
rise ​
ts
rise: string;
run ​
ts
run: string;
walk ​
ts
walk: string;

TransformStore ​

Position, rotation (xyzw) and scale, one lane per component.

Properties ​

qw ​
ts
qw: Float32Array;
qx ​
ts
qx: Float32Array;
qy ​
ts
qy: Float32Array;
qz ​
ts
qz: Float32Array;
sx ​
ts
sx: Float32Array;
sy ​
ts
sy: Float32Array;
sz ​
ts
sz: Float32Array;
x ​
ts
x: Float32Array;
y ​
ts
y: Float32Array;
z ​
ts
z: Float32Array;

Vec3 ​

A 3-component vector.

Extended by ​

Properties ​

x ​
ts
x: number;
y ​
ts
y: number;
z ​
ts
z: number;

VelocityStore ​

Linear and angular velocity in metres and radians per second.

Properties ​

ax ​
ts
ax: Float32Array;
ay ​
ts
ay: Float32Array;
az ​
ts
az: Float32Array;
x ​
ts
x: Float32Array;
y ​
ts
y: Float32Array;
z ​
ts
z: Float32Array;

WalkCharacterToCmd ​

Walk a character to a spot (see character.walkTo).

Properties ​

entity ​
ts
entity: number;
facing? ​
ts
optional facing?: number;

The facing to arrive with, radians about +Y (0 faces +Z); absent: as it arrives.

pace ​
ts
pace: number;

Metres a second; 0 is the set's own walk.

quick ​
ts
quick: boolean;

The shortest stops and turns the set has, instead of unhurried ones.

start? ​
ts
optional start?: "moving";

How it is begun: 'moving', the game says the body is under way already. Absent: as the character's takes have the body, as ever.

stop? ​
ts
optional stop?: StopStyle;

Which kind of stop this one walk ends with: 'gradual' (it slows and stands upright) or 'hard' (it brakes). Absent: the character's own; a quick walk that states none stops as a quick walk always did.

target ​
ts
target: Vec3;

The spot, world space, on the floor.


WorldEvent ​

What a made world tells the game: loaded (the list of things, as JSON in text), hit (a loose thing took a real knock: where, and how hard from 0 to 1), moved (a loose thing is somewhere new: the middle of its base and its turn), unloaded, and joint (a joint of a thing with moving parts stands somewhere new: position.x its place in the thing's list of joints, strength its value).

Properties ​

kind ​
ts
kind: "joint" | "hit" | "broken" | "loaded" | "moved" | "unloaded" | "mended";

As above, and for a thing in pieces: broken (text the places in the list of the pieces that came off, with commas; strength 1 when nothing of it holds together) and mended.

position ​
ts
position: Vec3;

hit: where the thing was when knocked. moved: the middle of its base now. joint: x is which joint.

rotation ​
ts
rotation: Quat;

moved: how the thing is turned now.

strength ​
ts
strength: number;

hit: how hard, 0 to 1. joint: the joint's value.

text ​
ts
text: string;

loaded: the world's list as JSON (readWorldList). Empty otherwise.

thing ​
ts
thing: number;

The thing's place in the world's list; 0 for loaded and unloaded.


WorldJoint ​

One joint of a thing with moving parts, as a game sees it.

Properties ​

at ​
ts
at: Vec3;

A point on its axis, in the thing's own frame at rest.

axis ​
ts
axis: Vec3;

Its axis, of length 1: a positive value turns right-handed about it, or slides along it.

free ​
ts
free: boolean;

True for a joint with no limits (a wheel on its axle).

id ​
ts
id: string;

The joint's name in the package, for example steering.

kind ​
ts
kind: "break" | "hinge" | "slide";

A hinge turns (degrees); a slide moves (metres); a break holds two pieces until the thing breaks.

max ​
ts
max: number;

The most its value may be; 0 for a joint that turns freely.

min ​
ts
min: number;

The least its value may be; 0 for a joint that turns freely.

rest ​
ts
rest: number;

The value the thing is drawn at when nothing is asked.

value ​
ts
value: number;

Where it stands now (kept up to date by the joint event for a joint with limits).


WorldList ​

A world as a game sees it: the list handed over by the loaded event.

Properties ​

about ​
ts
about: string;

One or two plain sentences about it.

bounds ​
ts
bounds: 
  | {
  max: Vec3;
  min: Vec3;
}
  | null;

The place's box, when the package gives one.

eyeHeight ​
ts
eyeHeight: number;

The height of a standing person's eyes above the ground, metres.

id ​
ts
id: string;

The package's id.

kind ​
ts
kind: "object" | "open" | "room";

room: walls all round. open: a field, a street. object: no place, a thing by itself on a level floor.

name ​
ts
name: string;

The world's name, for a page.

spawn ​
ts
spawn: WorldStand;

Where the player starts, on the ground.

things ​
ts
things: WorldThing[];

Every thing, loose or fixed, in the package's order.

version ​
ts
version: 1;

The list's own format; 1 today.

walk ​
ts
walk: WorldWalk;

How far the player may walk.


WorldSpec ​

World-level settings.

Properties ​

gravity? ​
ts
optional gravity?: number | readonly number[];

Gravity in metres per second squared, applied by the built-in velocity system to entities that have Velocity but no RigidBody. Bodies get their gravity from the host physics world instead.

maxEntities? ​
ts
optional maxEntities?: number;

Entity ceiling. Sizes every built-in component array. Default 4096.


WorldSpot ​

A named place where a rider meets a thing (seat, gripLeft, gripRight, footLeft, footRight), in the thing's own frame at rest (metres, the origin at the middle of its base, its front along +z, its left +x). It moves with the part it is on: spotOf says where it is now.

Properties ​

forward ​
ts
forward: Vec3;

The way a character there faces (a grip: the way the knuckles point).

joints ​
ts
joints: number[];

The joints that move it, by their place in the thing's list of joints, the nearest to the spot first.

name ​
ts
name: string;

The spot's name in the package.

position ​
ts
position: Vec3;

Where, at rest.

up ​
ts
up: Vec3;

Up at the spot.


WorldSpotNow ​

Where a rider's spot is now, in the world: what spotOf fills.

Properties ​

forward ​
ts
forward: Vec3;

The way a character there faces.

position ​
ts
position: Vec3;

Where.

up ​
ts
up: Vec3;

Up at the spot.


WorldStand ​

A place to stand: a point on the ground and which way to face.

Extends ​

Properties ​

facing ​
ts
facing: number;

Degrees about y, as a turn of a figure whose front is +z: 0 looks along +z, 90 along +x.

x ​
ts
x: number;
Inherited from ​

Vec3.x

y ​
ts
y: number;
Inherited from ​

Vec3.y

z ​
ts
z: number;
Inherited from ​

Vec3.z


WorldThing ​

One thing in a world: its own object (loose) or part of the place (fixed).

Properties ​

about ​
ts
about: string;

One sentence about it.

away? ​
ts
optional away?: boolean;

True while it is not in the world: a piece that has not come off its thing, and a thing all of whose pieces have. find and near pass over it.

body ​
ts
body: number;

The host's physics body for it, or 0 when it has none.

drives ​
ts
drives: boolean;

True for a thing that can be driven (things.drive).

id ​
ts
id: string;

The package's id for it, for example steamer-trunk.

index ​
ts
index: number;

Its place in the list; what world-event and the world command name it by.

joints ​
ts
joints: WorldJoint[];

Its joints, when it has moving parts; a joint's place here is what the joint command names.

kind ​
ts
kind: string;

One plain noun, for example chest.

label ​
ts
label: string;

What a person calls it, for example steamer trunk.

max ​
ts
max: Vec3;

The high corner of its box, now.

min ​
ts
min: Vec3;

The low corner of its box, now, along the world's axes.

moved ​
ts
moved: boolean;

True once it has moved from where the package put it.

pieceOf? ​
ts
optional pieceOf?: number;

For one piece of a thing in pieces: that thing's place in the list. Left out otherwise.

pieces? ​
ts
optional pieces?: number[];

For a thing in pieces: its pieces' places in the list (things.breakApart). Left out otherwise.

position ​
ts
position: Vec3;

The middle of its base, now, in metres.

rests ​
ts
rests: string;

What it rests on: floor, on:<thing id>, hanging or wall.

rider ​
ts
rider: WorldSpot[];

Where a rider meets it (things.getOn), when the package names such spots; else empty.

rotation ​
ts
rotation: Quat;

How it is turned, now.

size ​
ts
size: Vec3;

Width (x), height (y) and depth (z), in metres.

stand ​
ts
stand: WorldStand | null;

Where the package says to stand to use it, or null when it says nothing.

state ​
ts
state: "fixed" | "loose";

loose: its own object, which may move. fixed: part of the place.


WorldWalk ​

How far the player may walk.

Properties ​

centre ​
ts
centre: Vec3;

The circle's middle (radius only).

fadeFrom ​
ts
fadeFrom: number;

From here outward the player slows (radius only).

radius ​
ts
radius: number;

Past this the player goes no further (radius only).

shape ​
ts
shape: "radius" | "inside-collision";

inside-collision: the walls stop the player. radius: a circle with a soft edge.

Type Aliases ​

AssetId ​

ts
type AssetId = number;

Manifest asset handle, resolved from a string id.


AssetKind ​

ts
type AssetKind = "splat" | "gltf" | "character" | "audio" | "collider" | "data" | "video";

Manifest asset family.


AudioBus ​

ts
type AudioBus = "master" | "music" | "sfx" | "voice" | "ui";

Audio mixer bus.


BodyId ​

ts
type BodyId = number;

Rigid body / character controller handle.


BodyKind ​

ts
type BodyKind = "fixed" | "kinematic" | "dynamic" | "character";

Physics body class. fixed is what other engines call static.


CameraMode ​

ts
type CameraMode = "first-person" | "third-person" | "free" | "fixed";

Camera rig family.


Command ​

ts
type Command = 
  | {
  tag: "conversation";
  val: ConversationCmd;
}
  | {
  tag: "spawn";
  val: SpawnCmd;
}
  | {
  tag: "despawn";
  val: Entity;
}
  | {
  tag: "set-asset";
  val: SetAssetCmd;
}
  | {
  tag: "set-parent";
  val: SetParentCmd;
}
  | {
  tag: "set-anim";
  val: SetAnimCmd;
}
  | {
  tag: "set-material-param";
  val: SetMaterialParamCmd;
}
  | {
  tag: "add-body";
  val: AddBodyCmd;
}
  | {
  tag: "remove-body";
  val: BodyId;
}
  | {
  tag: "set-body-transform";
  val: SetBodyTransformCmd;
}
  | {
  tag: "set-body-velocity";
  val: SetBodyVelocityCmd;
}
  | {
  tag: "apply-impulse";
  val: ApplyImpulseCmd;
}
  | {
  tag: "set-body-enabled";
  val: SetBodyEnabledCmd;
}
  | {
  tag: "move-character";
  val: MoveCharacterCmd;
}
  | {
  tag: "spawn-character";
  val: SpawnCharacterCmd;
}
  | {
  tag: "set-character-state";
  val: SetCharacterStateCmd;
}
  | {
  tag: "set-clip-weights";
  val: SetClipWeightsCmd;
}
  | {
  tag: "set-expression";
  val: SetExpressionCmd;
}
  | {
  tag: "look-at";
  val: LookAtCmd;
}
  | {
  tag: "say";
  val: SayCmd;
}
  | {
  tag: "hit-character";
  val: HitCharacterCmd;
}
  | {
  tag: "recover-character";
  val: Entity;
}
  | {
  tag: "set-character-motion";
  val: SetCharacterMotionCmd;
}
  | {
  tag: "walk-character-to";
  val: WalkCharacterToCmd;
}
  | {
  tag: "face-character";
  val: FaceCharacterCmd;
}
  | {
  tag: "stop-character-walk";
  val: Entity;
}
  | {
  tag: "do-character-action";
  val: DoCharacterActionCmd;
}
  | {
  tag: "cancel-character-action";
  val: Entity;
}
  | {
  tag: "play-sound";
  val: PlaySoundCmd;
}
  | {
  tag: "stop-sound";
  val: StopSoundCmd;
}
  | {
  tag: "set-listener";
  val: SetListenerCmd;
}
  | {
  tag: "load-asset";
  val: LoadAssetCmd;
}
  | {
  tag: "set-pointer-lock";
  val: boolean;
}
  | {
  tag: "set-time-scale";
  val: number;
}
  | {
  tag: "cutscene";
  val: CutsceneCmd;
}
  | {
  tag: "thing";
  val: ThingCmd;
}
  | NetCommand;

Everything the guest can ask the host to do, applied front to back.


CommandTag ​

ts
type CommandTag = Command["tag"];

Every Command['tag'], useful for exhaustive host-side switches.


ContactPhase ​

ts
type ContactPhase = "begin" | "stay" | "end";

Lifecycle phase of a contact.


Entity ​

ts
type Entity = number;

ECS entity handle. 0 is reserved and means "none".


ErrorCode ​

ts
type ErrorCode = 
  | "init-failed"
  | "tick-failed"
  | "invalid-state"
  | "unsupported"
  | "asset-missing"
  | "snapshot-version-mismatch"
  | "internal";

Machine-readable half of a GameError.


ExpressionSpace ​

ts
type ExpressionSpace = "arkit52" | "gnm" | "gnm68";

Coordinate space for setExpression weights.


FeatureOptions ​

ts
type FeatureOptions = Readonly<Record<string, Readonly<Record<string, unknown>>>>;

Declared features, normalised: every present feature has an options object.


GameDefinition ​

ts
type GameDefinition = Readonly<GameSpec>;

A validated game declaration.


GameEvent ​

ts
type GameEvent = 
  | {
  tag: "conversation-event";
  val: ConversationEvent;
}
  | {
  tag: "asset-loaded";
  val: AssetLoadedEvent;
}
  | {
  tag: "character-ready";
  val: CharacterReadyEvent;
}
  | {
  tag: "sound-ended";
  val: SoundEndedEvent;
}
  | {
  tag: "anim-event";
  val: AnimEventData;
}
  | {
  tag: "resized";
  val: ResizedEvent;
}
  | {
  tag: "cutscene-event";
  val: CutsceneEvent;
}
  | {
  tag: "world-event";
  val: WorldEvent;
}
  | {
  tag: "motion-event";
  val: MotionEvent;
}
  | NetEvent;

A host-side occurrence since the previous tick.


HitStrength ​

ts
type HitStrength = 
  | {
  tag: "small";
}
  | {
  tag: "big";
}
  | {
  tag: "shot";
}
  | {
  tag: "big-shot";
}
  | {
  tag: "push";
  val: number;
};

How hard a blow lands on a character's physics body: small (a flinch and a recovery over about a second), big (a fall that stays down until recover-character), shot (a sharp blow with a flinch), big-shot (a sharp blow that floors), or a push of so many newton-seconds (40 staggers, 90 and over floors).


KeyName ​

ts
type KeyName = string;

Any string this table accepts: a DOM code, a bare letter or digit, or one of the friendly aliases.


LogLevel ​

ts
type LogLevel = "trace" | "debug" | "info" | "warn" | "error";

Log severity accepted by env.log.


LogSink ​

ts
type LogSink = (level, msg) => void;

Where prelude console output goes.

Parameters ​

ParameterType
levelLogLevel
msgstring

Returns ​

void


MaterialValue ​

ts
type MaterialValue = 
  | {
  tag: "scalar";
  val: number;
}
  | {
  tag: "boolean";
  val: boolean;
}
  | {
  tag: "color";
  val: Rgba;
}
  | {
  tag: "vector";
  val: Vec3;
}
  | {
  tag: "texture";
  val: AssetId;
};

A material parameter value.


MessageCheck ​

ts
type MessageCheck<T> = (payload) => payload is T;

The game's own type guard for a payload, already parsed from JSON. It must be pure: no wall time, no Math.random, no state, so the authority and every replay agree on what it drops.

Type Parameters ​

Type Parameter
T

Parameters ​

ParameterType
payloadunknown

Returns ​

payload is T


NetCommand ​

ts
type NetCommand = 
  | {
  tag: "send";
  val: SendCmd;
}
  | {
  tag: "set-player-camera";
  val: SetPlayerCameraCmd;
}
  | {
  tag: "set-player-hud";
  val: SetPlayerHudCmd;
}
  | {
  tag: "save-player-data";
  val: SavePlayerDataCmd;
}
  | {
  tag: "save-game-data";
  val: SaveGameDataCmd;
}
  | {
  tag: "set-player-entity";
  val: SetPlayerEntityCmd;
}
  | {
  tag: "exchange";
  val: ExchangeCmd;
};

The net and data members of the command variant.


NetEvent ​

ts
type NetEvent = 
  | {
  tag: "player-joined";
  val: PlayerJoinedEvent;
}
  | {
  tag: "player-left";
  val: PlayerLeftEvent;
}
  | {
  tag: "message";
  val: NetMessageEvent;
}
  | {
  tag: "exchange-result";
  val: ExchangeResultEvent;
}
  | {
  tag: "game-data";
  val: GameDataEvent;
};

The net and data members of the event variant.


NetRole ​

ts
type NetRole = "solo" | "authority" | "client";

Where a guest runs: alone (solo), as the room's authority, or as one player's client.

Example ​

ts
const role: NetRole = ctx.net.role;
if (role === 'client') showLatency();

PlayerSpawn ​

ts
type PlayerSpawn = 
  | readonly number[]
  | readonly readonly number[][]
  | ((seat, ctx) => Vec3);

Where definition.player spawns each seat: one point [x, y, z] for everyone, a list of points (seat i takes list[i % list.length]), or a function of the seat. A single-player game spawns seat 0.

The function runs on the authority at the seat's join, inside the step, so it must be deterministic: read only the seat, ctx.rules, ctx.rng and the world, never the clock or Math.random. It runs before ctx.players is updated for the step, so read the seat, not ctx.players: the map still holds the previous step's players there.

Example ​

ts
import { defineGame, type PlayerSpawn } from 'gameable';

const corners: PlayerSpawn = [[-8, 0, -8], [8, 0, -8], [8, 0, 8], [-8, 0, 8]];
const ring: PlayerSpawn = (seat) => ({ x: Math.cos(seat) * 6, y: 0, z: Math.sin(seat) * 6 });
export default defineGame({ player: { prefab: Hero, spawn: corners } });

ProjectionKind ​

ts
type ProjectionKind = "perspective" | "orthographic";

Camera projection family.


ShapeKind ​

ts
type ShapeKind = 
  | "box"
  | "sphere"
  | "capsule"
  | "cylinder"
  | "plane"
  | "convex-hull"
  | "mesh"
  | "height-field";

Collision shape family.


SoundId ​

ts
type SoundId = number;

Playing-sound handle.


StopStyle ​

ts
type StopStyle = "gradual" | "hard";

Which kind of stop a running character asked to stand makes: 'gradual', it slows and stands upright; 'hard', it brakes. It says WHICH KIND of stop; arrive (see character.walkTo) says how soon it must be there. Read where the character's motion set has stops that state a kind (a run's, on the engine's shared set); a walk's stop and a sprint's stop are the same under both there.


System ​

ts
type System = (ctx) => void;

A system: one plain function, run once per fixed step. In systems it may also be a SidedSystem, { run, on }, that says where it runs.

Parameters ​

ParameterType
ctxGameContext

Returns ​

void


TransferDoc ​

ts
type TransferDoc = Record<string, unknown>;

A player document as a transfer reads it: a plain object.


WalkStart ​

ts
type WalkStart = "moving";

How a walk to a spot is begun when the game knows more than the character's takes show: 'moving', the body is under way already (it comes out of a get-up, it was carried or thrown), so the walk is planned as of a body under way: no turn on the spot first, no one take from stand to stand, and a pace above the walk's needs room for its stop only, not for a start from standing. See character.walkTo.

Variables ​

audio ​

ts
const audio: object;

The audio facade.

Type Declaration ​

listener() ​
ts
listener(position, rotation): void;

Place the audio listener.

Parameters ​
ParameterTypeDescription
positionVec3Listener position.
rotationQuatListener rotation, xyzw.
Returns ​

void

Nothing.

play() ​
ts
play(asset, options?): number;

Start a sound.

Parameters ​
ParameterTypeDescription
assetstring | numberManifest string id or asset handle.
options?PlayOptionsAttachment, gain, pitch, looping and bus.
Returns ​

number

The guest-minted sound handle, or 0 when the asset is unknown.

stop() ​
ts
stop(sound, fadeMs?): void;

Stop a playing sound.

Parameters ​
ParameterTypeDefault valueDescription
soundnumberundefinedA handle from play.
fadeMsnumber0Fade-out in milliseconds; 0 stops immediately.
Returns ​

void

Nothing.

Example ​

ts
import { audio } from 'gameable';

const id = audio.play('shot', { entity: player, volume: 0.8 });
audio.stop(id, 50);

AUTHORITY_SENDER ​

ts
const AUTHORITY_SENDER: 4294967295 = 0xffffffff;

The sender id of a message from the authority itself. Room seats start at 0, so the authority is not 0: this is past every player id and still a u32 (the WIT's message-event.player). Keep ids unsigned: in an Int32Array this reads back as -1.

Example ​

ts
import { AUTHORITY_SENDER } from 'gameable';

const fromServer = (from: number): boolean => from === AUTHORITY_SENDER;

BODY_KINDS ​

ts
const BODY_KINDS: readonly ["fixed", "kinematic", "dynamic", "character"];

Physics body classes, in the index order RigidBody.kind stores.


BODY_STRIDE ​

ts
const BODY_STRIDE: 15 = 15;

Floats per row of frame-input.bodies.


BUILTIN_COMPONENT_NAMES ​

ts
const BUILTIN_COMPONENT_NAMES: readonly ["Transform", "Renderable", "RigidBody", "Character", "Velocity", "Health", "Player", "Enemy", "Pickup"];

Names matching BUILTIN_COMPONENTS, used in snapshot headers.


BUILTIN_COMPONENTS ​

ts
const BUILTIN_COMPONENTS: readonly [TransformStore, RenderableStore, RigidBodyStore, CharacterStore, VelocityStore, HealthStore, Record<string, never>, Record<string, never>, Record<string, never>];

Every built-in component, in the fixed order snapshot serialises them.


camera ​

ts
const camera: object;

The camera facade: writes the frame's camera.

Type Declaration ​

look ​
Get Signature ​
ts
get look(): object;

Accumulated look angles, in radians. Mutate to snap the view.

Returns ​

object

The live look state.

pitch ​
ts
pitch: number;
sensitivity ​
ts
sensitivity: number;
yaw ​
ts
yaw: number;
state ​
Get Signature ​
ts
get state(): CameraState;

The whole camera record, for games that want every knob.

Returns ​

CameraState

The live record. Mutate it; do not replace it.

firstPerson() ​
ts
firstPerson(entity, options?): void;

Mount the camera at an entity's eyes.

Yaw and pitch come from the built-in look accumulator, which integrates input.mouse.dx/dy once per tick.

Parameters ​
ParameterTypeDescription
entitynumberEntity to mount on.
options?FirstPersonOptionsEye height and field of view.
Returns ​

void

Nothing.

follow() ​
ts
follow(entity, options?): void;

Put the camera on a spring arm behind an entity.

The host owns the arm and its collision; the guest only states the intent. position is the orbit pivot and rotation the direction the player is looking, so a host with no rig still ends up somewhere sensible.

Parameters ​
ParameterTypeDescription
entitynumberEntity to follow.
options?FollowOptionsBoom length, height offset, field of view and orbit angles.
Returns ​

void

Nothing.

lookAt() ​
ts
lookAt(point): void;

Aim the camera at a world point, overriding its rotation.

Parameters ​
ParameterTypeDescription
pointVec3 | nullThe point to look at, or null to use the rotation again.
Returns ​

void

Nothing.

set() ​
ts
set(
   position, 
   rotation, 
   fovYDeg?
): void;

Place the camera explicitly, detaching it from any entity.

Parameters ​
ParameterTypeDefault valueDescription
positionVec3undefinedEye position.
rotationQuatundefinedEye rotation, xyzw.
fovYDegnumber60Vertical field of view in degrees. Default 60.
Returns ​

void

Nothing.

Example ​

ts
import { camera } from 'gameable';

camera.firstPerson(player, { eyeHeight: 1.7 });

character ​

ts
const character: object;

The character facade.

Type Declaration ​

bundleOf() ​
ts
bundleOf(entity): number;

The character bundle handle attached to an entity, or 0.

Parameters ​
ParameterTypeDescription
entitynumberEntity id.
Returns ​

number

The bundle asset handle.

cancelAction() ​
ts
cancelAction(entity): void;

Take an action's request back (it cannot be taken back between its gathering and its landing).

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
Returns ​

void

Nothing.

do() ​
ts
do(
   entity, 
   action, 
   object?, 
   plain?
): void;

Ask a character to do an action of its motion set (a hurdle, a jump, a sit), at an object when the action needs one. What follows comes as motion-events in ctx.events: started, contact, release (with the point and its velocity, for a thing let go), landed, done, or failed with its reason.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
actionstringundefinedThe action's name in the set.
object?Readonly<ActionObject>undefinedThe thing it is done at, as the game has it; left out for an action without one.
plain?booleanfalseThe plain way, for a comparison: the take simply started, nothing fitted.
Returns ​

void

Nothing.

Example ​
ts
character.do(hero, 'hurdle', { id: bar, position: barAt, yaw: 0, height: 0.6, width: 1.2, depth: 0.05 });
face() ​
ts
face(
   entity, 
   facing, 
   arrive?
): void;

Turn a character on the spot to face a way, by its set's own turns. The motion-event arrived named 'face' says when it faces there.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
facingnumberundefinedRadians about +Y (0 faces +Z).
arrive"easy" | "quick"'easy''easy' (the default: an unhurried turn) or 'quick' (the quickest the set has).
Returns ​

void

Nothing.

Example ​
ts
character.face(guide, Math.PI / 2);
hit() ​
ts
hit(entity, blow): void;

A blow. Every exported character has a physics body (its parts on the engine's physics); the nearest part to at takes the blow along direction, and the body reacts for real: a small hit flinches and recovers over about a second, a big one falls onto the floor and stays down until character.recover, a shot is sharper, a push shoves. Use this before writing a reaction of your own.

What happened comes back as anim-events on the clip ragdoll: hit, fell (the body came to rest on the floor), recovered.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
blow{ at: Vec3; direction?: Vec3; strength: number | "small" | "big" | "shot" | "big-shot"; }Where it lands (at, world), which way it travels (direction, world; omitted: from the character's front) and how hard (strength: 'small', 'big', 'shot', 'big-shot', or a push's newton-seconds: 40 staggers, 90 and over floors).
blow.atVec3-
blow.direction?Vec3-
blow.strengthnumber | "small" | "big" | "shot" | "big-shot"-
Returns ​

void

Nothing.

Example ​
ts
character.hit(enemy, { at: swordTip, direction: swing, strength: 'small' });
character.hit(enemy, { at: swordTip, direction: swing, strength: 'big' }); // down
lookAt() ​
ts
lookAt(
   entity, 
   target, 
   weight?
): void;

Aim the head and eyes at a world point.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
targetVec3 | nullundefinedThe point, or null to release and return to the idle.
weightnumber1Blend weight in 0..1. Default 1.
Returns ​

void

Nothing.

motion() ​
ts
motion(entity, options?): void;

How the movement system moves a character. A character with a motion set (its package's own, else the engine's shared one) is moved by whole takes of a performer matched to the velocity given to character.setState: its starts, stops and turns are the performer's own, its feet are held where they land. That is the default; this call changes it for one character: off, another set, whether the take carries the walker, the two dials, and which kind of stop it makes from a run. What is left out stays as it is.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
optionsCharacterMotionOptionsWhat to change.
Returns ​

void

Nothing.

Example ​
ts
character.motion(hero, { responsiveness: 0.9 }); // a snappier hero
character.motion(guard, { on: false }); // this one by the clips' blend, as before
character.motion(hero, { stop: 'hard' }); // from a run it brakes, instead of slowing to a stand
recover() ​
ts
recover(entity): void;

Back into the animation: a character that is down (or reacting) blends back over about a second, where it stood. Move the entity to where the body lies first (anim-event fell; the head and root joints read where it lies) to have it get up there.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
Returns ​

void

Nothing.

say() ​
ts
say(
   entity, 
   text, 
   voice?, 
   visemes?
): void;

Speak a line.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
textstringSubtitle text; the host decides whether to show it.
voice?string | numberManifest string id or handle of a voice line.
visemes?stringViseme track as JSON, matching the bundle's space.
Returns ​

void

Nothing.

setClipWeights() ​
ts
setClipWeights(
   entity, 
   clips, 
   weights, 
   timeScale?
): void;

Set explicit per-clip weights on the body layer.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
clipsreadonly string[]undefinedClip names.
weightsreadonly number[] | Float32Array<ArrayBufferLike>undefinedPositional weights; must be the same length as clips.
timeScalenumber1Playback rate for the whole layer. Default 1.
Returns ​

void

Nothing.

setExpression() ​
ts
setExpression(
   entity, 
   space, 
   weights
): void;

Set facial expression coefficients.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
spaceExpressionSpaceCoordinate space: 52 ARKit, 387 GNM, or the 68-float view.
weightsreadonly number[] | Float32Array<ArrayBufferLike>Coefficients; length must match the space.
Returns ​

void

Nothing.

setState() ​
ts
setState(
   entity, 
   state, 
   vx, 
   vy, 
   vz, 
   grounded?
): void;

Drive the locomotion state machine.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity with a Character component.
statestringundefinedState name, for example `'idle'
vxnumberundefinedWorld-space velocity x, drives the locomotion blend.
vynumberundefinedWorld-space velocity y.
vznumberundefinedWorld-space velocity z.
groundedbooleantrueWhether the character is on the ground.
Returns ​

void

Nothing.

stopWalk() ​
ts
stopWalk(entity): void;

Give up a walk to a spot: the character stops where it is, as its takes stop.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
Returns ​

void

Nothing.

walkTo() ​
ts
walkTo(
   entity, 
   target, 
   how?
): void;

Send a character to a spot: it turns, walks or runs there and arrives facing the way asked. The motion-event arrived (in ctx.events) says it got there; failed says why not; started and then done, both named stop, say when its stop begins and when it no longer travels; limited says once that the speed it is given (amount) is not the one asked. A velocity given to character.setState while it walks takes over.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a Character component.
targetVec3The spot, world space, on the floor.
how{ arrive?: "easy" | "quick"; facing?: number; pace?: number; start?: "moving"; stop?: StopStyle; }The facing to arrive with (facing, radians about +Y, 0 faces +Z; left out: as it arrives), the pace (pace, metres a second; left out: the set's own walk; above the speeds its walk covers it runs, when its set has a run and the spot is far enough to run to), how it stops (arrive: 'easy', the default, the takes' unhurried stops; 'quick', the shortest stops and turns the set has) and which kind of stop this one walk ends with (stop: 'gradual', it slows and stands upright; 'hard', it brakes; left out: the character's own, see character.motion). arrive says how soon it must be there, stop says which kind of stop; a 'quick' walk that states no stop stops as a quick walk always did. A kind is read on a run's stops: a walk's stop and a sprint's stop are the same under both on the engine's shared set. And how it is begun (start: 'moving', the game says the body is under way already: it comes out of a get-up, it was carried or thrown; the walk is then planned as of a body under way: no turn on the spot first, no start from standing; left out: as its takes have the body).
how.arrive?"easy" | "quick"-
how.facing?number-
how.pace?number-
how.start?"moving"-
how.stop?StopStyle-
Returns ​

void

Nothing.

Example ​
ts
character.walkTo(guide, { x: 2, y: 0, z: -3 }, { facing: Math.PI });
character.walkTo(rider, bikeSide, { pace: 3.4 }); // a run's pace: it runs there
character.walkTo(rider, bikeSide, { pace: 3.4, stop: 'hard' }); // and brakes at the spot
character.walkTo(rider, bikeSide, { pace: 3.4, start: 'moving' }); // out of a get-up: no turn on the spot first

Example ​

ts
import { character } from 'gameable';

character.setState(npc, 'walk', 0, 0, 1.4, true);
character.lookAt(npc, { x: 0, y: 1.6, z: 0 });

Character ​

ts
const Character: CharacterStore;

Splat character bundle attached to an entity.


conversation ​

ts
const conversation: object;

Structural interview controls; all streams remain in optional host modules.

Type Declaration ​

command() ​
ts
command(
   entity, 
   action, 
   character?, 
   text?
): void;

Queue one control using the reusable command pool.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedInterview entity.
action| "end" | "start" | "ask" | "interrupt" | "microphone-on" | "microphone-off"undefinedLifecycle or question action.
characterstring''Host-configured id.
textstring''Question, if any.
Returns ​

void

Example ​

ts
import { conversation } from 'gameable';
conversation.command(npc, 'start', 'steward');
conversation.command(npc, 'ask', 'steward', 'Who had the study key?');

cutscene ​

ts
const cutscene: object;

The cutscene facade.

Type Declaration ​

play() ​
ts
play(asset, options?): number;

Play a clip over the stage.

Parameters ​
ParameterTypeDescription
assetstring | numberManifest id of a video entry, or its handle.
options?CutscenePlayOptionsFades, skip, pause.
Returns ​

number

The asset handle (the one a cutscene-event will name), or 0 when the id is unknown.

preload() ​
ts
preload(asset): number;

Fetch a clip ahead of time so play starts the moment it is called.

Parameters ​
ParameterTypeDescription
assetstring | numberManifest id of a video entry, or its handle.
Returns ​

number

The asset handle, or 0 when the id is unknown.

skip() ​
ts
skip(): void;

End the clip playing now (it comes back as skipped).

Returns ​

void

Nothing.

Example ​

ts
import { cutscene } from 'gameable';

cutscene.preload('kael-falls'); // when the fight starts
cutscene.play('kael-falls', { fadeIn: 300, skippable: true }); // when the boss falls
// later, in the events: { tag: 'cutscene-event', val: { asset, kind: 'ended' | 'skipped' | 'failed', seconds } }

DEFAULT_MAX_ENTITIES ​

ts
const DEFAULT_MAX_ENTITIES: 4096 = 4096;

Default entity ceiling. Every built-in component array is this long.


DEFAULT_MAX_PLAYERS ​

ts
const DEFAULT_MAX_PLAYERS: 16 = 16;

The highest player id a guest makes a slot for when net.maxPlayers is not in game-config.options.

Example ​

ts
import { DEFAULT_MAX_PLAYERS } from 'gameable';

const options = JSON.stringify({ net: { maxPlayers: DEFAULT_MAX_PLAYERS * 2 } });

DEFAULT_ROOM_SEATS ​

ts
const DEFAULT_ROOM_SEATS: 8 = 8;

Seats in a room when the game declares features.multiplayer without a maxPlayers.

Example ​

ts
import { DEFAULT_ROOM_SEATS, defineGame, roomSeats } from 'gameable';

const game = defineGame({ features: { multiplayer: true } });
roomSeats(game) === DEFAULT_ROOM_SEATS; // true

Enemy ​

ts
const Enemy: Record<string, never> = {};

Tag: a hostile entity.


EXPRESSION_DIMS ​

ts
const EXPRESSION_DIMS: Readonly<Record<ExpressionSpace, number>>;

Coefficient counts each expression space expects.


Health ​

ts
const Health: HealthStore;

Hit points.


hud ​

ts
const hud: object;

The HUD facade: writes the frame's HUD.

Type Declaration ​

clear() ​
ts
clear(): void;

Drop the HUD: emit an empty model this frame.

Idempotent — calling it every frame emits {} once, exactly like set.

Returns ​

void

Nothing.

invalidate() ​
ts
invalidate(): void;

Forget what the host has seen, so the next set emits even if the model did not change. Use it after the host reloaded its overlay.

On its own it sends nothing: the next set does. To send an empty model now, call clear().

Returns ​

void

Nothing.

set() ​
ts
set(model): boolean;

Set the HUD model for this frame.

Nested plain objects are compared by value four levels down, so a model rebuilt inline every frame is recognised as unchanged. Arrays and class instances are compared by identity: keep those out of the model, or build them once and mutate nothing.

Parameters ​
ParameterTypeDescription
modelRecord<string, unknown>A JSON-serialisable object.
Returns ​

boolean

True when the model changed and JSON will cross this frame.

Example ​

ts
import { hud } from 'gameable';

hud.set({ health: 100, ammo: 30 }); // emitted once
hud.set({ health: 100, ammo: 30 }); // unchanged, nothing crosses

input ​

ts
const input: object;

The keyboard, mouse and gamepad facade: the local player's input. That is frame-input.input in a single-player game and on the authority, and the local player's slot of frame-input.players on a client.

Type Declaration ​

touch ​
ts
touch: object;

Fingers on a touch screen, as the host's touch layer packs them: the first finger is the pointer (mouse), a tap is pressed('Tap'), and the thumb sticks, the pinch and the turn are here.

touch.active ​
Get Signature ​
ts
get active(): boolean;

Is a finger on the screen? (The touch pad is connected.)

Returns ​

boolean

True while any finger is down.

touch.pinch ​
Get Signature ​
ts
get pinch(): number;

Two fingers' pinch this step, as a scale factor: over 1 the fingers moved apart (zoom in), under 1 together, exactly 1 with no pinch.

Returns ​

number

The scale factor.

touch.turn ​
Get Signature ​
ts
get turn(): number;

Two fingers' turn this step, in radians, counter-clockwise on the screen positive.

Returns ​

number

The turn.

touch.stick() ​
ts
stick(side): Axis2;

A thumb stick's push.

Parameters ​
ParameterTypeDescription
side"left" | "right"The left stick (movement) or the right one (the camera).
Returns ​

Axis2

A pooled { x, y }, -1..1, y up the screen positive. Never retain it.

focused ​
Get Signature ​
ts
get focused(): boolean;

Does the canvas have focus? Treat input as neutral when it does not.

Returns ​

boolean

True while the canvas is focused.

mods ​
Get Signature ​
ts
get mods(): InputMods;

Keyboard modifier state.

Returns ​

InputMods

The modifiers for this frame.

mouse ​
Get Signature ​
ts
get mouse(): MouseState;

Pointer position, per-frame delta, wheel and button bitsets.

Returns ​

MouseState

The mouse state for this frame. Owned by the SDK; never retain it.

axis2() ​
ts
axis2(
   negX, 
   posX, 
   negY, 
   posY, 
   stick?
): Axis2;

A two-axis reading built from four keys, plus a thumb stick on a touch screen: the left one by default, so axis2('A', 'D', 'S', 'W') moves on a phone with no other binding. Pass 'right' for a camera axis, 'none' for keys only.

Parameters ​
ParameterTypeDefault valueDescription
negXstringundefinedKey that drives x negative, for example 'A'.
posXstringundefinedKey that drives x positive, for example 'D'.
negYstringundefinedKey that drives y negative, for example 'S'.
posYstringundefinedKey that drives y positive, for example 'W'.
stickStickSide'left'Which thumb stick to add, 'left' by default.
Returns ​

Axis2

A pooled { x, y } with components in -1..1. Never retain it.

gamepad() ​
ts
gamepad(index): 
  | {
  axes: ArrayLike<number>;
  buttons: number;
  connected: boolean;
  index: number;
  pressed: number;
  released: number;
}
  | null;

One connected gamepad.

Parameters ​
ParameterTypeDescription
indexnumberNavigator gamepad index.
Returns ​

| { axes: ArrayLike<number>; buttons: number; connected: boolean; index: number; pressed: number; released: number; } | null

The gamepad, or null when nothing is connected at that index. Owned by the SDK; never retain it.

isDown() ​
ts
isDown(key): boolean;

Is the key held this frame?

Parameters ​
ParameterTypeDescription
keystringA DOM code ('KeyW'), a bare letter/digit ('W', '1') or an alias ('Shift', 'Esc').
Returns ​

boolean

True while the key is down.

mouseDown() ​
ts
mouseDown(button): boolean;

Is a mouse button held?

Parameters ​
ParameterTypeDescription
buttonnumberA MOUSE_BUTTONS value, or a raw bit mask.
Returns ​

boolean

True while the button is down.

mousePressed() ​
ts
mousePressed(button): boolean;

Did a mouse button go down this frame?

Parameters ​
ParameterTypeDescription
buttonnumberA MOUSE_BUTTONS value, or a raw bit mask.
Returns ​

boolean

True on the frame the button went down.

mouseReleased() ​
ts
mouseReleased(button): boolean;

Did a mouse button come up this frame?

Parameters ​
ParameterTypeDescription
buttonnumberA MOUSE_BUTTONS value, or a raw bit mask.
Returns ​

boolean

True on the frame the button came up.

pressed() ​
ts
pressed(key): boolean;

Did the key go down this frame?

Parameters ​
ParameterTypeDescription
keystringA key name.
Returns ​

boolean

True on the frame the key went down.

released() ​
ts
released(key): boolean;

Did the key come up this frame?

Parameters ​
ParameterTypeDescription
keystringA key name.
Returns ​

boolean

True on the frame the key came up.

Example ​

ts
import { input } from 'gameable';

const move = input.axis2('A', 'D', 'S', 'W'); // x = strafe, y = forward
if (input.pressed('Space')) jump();
if (input.mouseDown(1)) fire();

IS_COMPONENT_GUEST ​

ts
const IS_COMPONENT_GUEST: boolean;

True when this realm looks like the QuickJS component guest rather than V8.

Decided once, before anything is polyfilled: a realm with neither console nor TextEncoder is componentize-qjs. It is the only realm whose Math.random the prelude is allowed to replace — patching the global in V8 would reach vitest, Vite and the host application too.


KEY_BITS ​

ts
const KEY_BITS: 256 = 256;

Number of key bits the WIT key-state bitsets can carry.


KEY_COUNT ​

ts
const KEY_COUNT: number = KEY_NAMES.length;

Number of key names currently assigned.


KEY_NAMES ​

ts
const KEY_NAMES: readonly string[];

Every key name in index order. The array index is the bit index.

Do not reorder; append only.


KEY_WORDS ​

ts
const KEY_WORDS: number;

Number of u32 words in one key-state bitset.


LAYER_KEYS ​

ts
const LAYER_KEYS: readonly ["defaultLayer", "staticGeometry", "player", "enemy", "projectile", "pickup", "trigger", "character", "debris", "water", "user0", "user1", "user2", "user3", "user4", "user5"];

Every WIT collision-layers member, in declaration order.

Bit i of the physics module's numeric layer/mask is member i of this list. It is a contract between the guest, which writes the flags record, and the host, which folds it into a bitmask — so both sides import this one list rather than keeping a copy each.

Example ​

ts
import { LAYER_KEYS } from 'gameable';

const bit = LAYER_KEYS.indexOf('enemy'); // 3

MOUSE_BUTTONS ​

ts
const MOUSE_BUTTONS: Readonly<{
  BACK: 8;
  FORWARD: 16;
  LEFT: 1;
  MIDDLE: 4;
  RIGHT: 2;
}>;

Mouse button bit positions, matching mouse-state.buttons.


PACKAGE ​

ts
const PACKAGE: "@gameable/sdk";

Package identity marker.

Example ​

ts
import { PACKAGE } from 'gameable';

console.log(PACKAGE); // 'gameable'

physics ​

ts
const physics: object;

Physics queries and body commands.

Type Declaration ​

ALL_LAYERS ​
ts
ALL_LAYERS: CollisionLayers;

Every collision layer, for queries that should hit anything.

applyImpulse() ​
ts
applyImpulse(
   entity, 
   x, 
   y, 
   z, 
   atX?, 
   atY?, 
   atZ?
): void;

Apply a one-shot impulse.

With no application point the impulse acts at the centre of mass. Give one — all three coordinates — to apply it off-centre and impart spin.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a body.
xnumberImpulse x, newton-seconds.
ynumberImpulse y.
znumberImpulse z.
atX?numberWorld-space application point x, or omit for the centre of mass.
atY?numberApplication point y.
atZ?numberApplication point z.
Returns ​

void

Nothing.

isGrounded() ​
ts
isGrounded(entity): boolean;

Actual walkable ground contact from the last host physics step. No host call. Unknown, steep and unsupported contacts return false, even at a jump apex.

Parameters ​
ParameterTypeDescription
entitynumberCharacter entity.
Returns ​

boolean

Whether the character is supported by walkable ground.

moveCharacter() ​
ts
moveCharacter(
   entity, 
   vx, 
   vy, 
   vz, 
   jump?, 
   crouch?, 
   maxSlopeDeg?
): void;

Drive a character body for this step.

Parameters ​
ParameterTypeDefault valueDescription
entitynumberundefinedEntity whose body was created with kind: 'character'.
vxnumberundefinedDesired world-space velocity x, metres per second.
vynumberundefinedDesired world-space velocity y.
vznumberundefinedDesired world-space velocity z.
jumpbooleanfalseRequest a jump this step.
crouchbooleanfalseRequest a crouch this step.
maxSlopeDegnumber45Maximum walkable slope.
Returns ​

void

Nothing.

overlapSphere() ​
ts
overlapSphere(
   center, 
   radius, 
   maxResults?, 
   mask?, 
   ignoreEntity?
): readonly OverlapHit[];

Bodies overlapping a sphere, nearest first.

Parameters ​
ParameterTypeDefault valueDescription
centerVec3undefinedSphere centre.
radiusnumberundefinedSphere radius in metres.
maxResultsnumber16Cap on returned hits.
mask?CollisionLayersundefinedLayers to consider; defaults to every layer.
ignoreEntity?numberundefinedEntity to skip.
Returns ​

readonly OverlapHit[]

The overlapping bodies.

raycast() ​
ts
raycast(
   origin, 
   direction, 
   maxDistance, 
   mask?, 
   ignoreEntity?
): RayHit | null;

Closest hit along a ray.

Parameters ​
ParameterTypeDescription
originVec3World-space ray origin.
directionVec3Ray direction; need not be normalised.
maxDistancenumberMaximum distance in metres.
mask?CollisionLayersLayers to consider; defaults to every layer.
ignoreEntity?numberEntity to skip, usually the caster.
Returns ​

RayHit | null

The hit, or null on a miss. The hit object comes from the host and is freshly allocated: this call is not allocation-free.

raycastBatch() ​
ts
raycastBatch(rays): readonly (RayHit | null | undefined)[];

Many rays in one round trip. Result index i matches rays[i].

Parameters ​
ParameterTypeDescription
raysreadonly object[]The rays. Build them once and mutate them in place.
Returns ​

readonly (RayHit | null | undefined)[]

One result per ray; undefined or null entries are misses.

setEnabled() ​
ts
setEnabled(entity, enabled): void;

Enable or disable a body in the broad phase.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a body.
enabledbooleanWhether the body participates.
Returns ​

void

Nothing.

setVelocity() ​
ts
setVelocity(
   entity, 
   x, 
   y, 
   z, 
   ax?, 
   ay?, 
   az?
): void;

Overwrite a body's velocity.

Angular velocity is left alone unless all three angular components are given.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a body.
xnumberLinear velocity x.
ynumberLinear velocity y.
znumberLinear velocity z.
ax?numberAngular velocity x, radians per second.
ay?numberAngular velocity y.
az?numberAngular velocity z.
Returns ​

void

Nothing.

teleport() ​
ts
teleport(
   entity, 
   x, 
   y, 
   z
): void;

Teleport a body, clearing its velocities.

Parameters ​
ParameterTypeDescription
entitynumberEntity with a body.
xnumberPosition x.
ynumberPosition y.
znumberPosition z.
Returns ​

void

Nothing.

Example ​

ts
import { physics, Transform } from 'gameable';

const hit = physics.raycast(eye, forward, 100);
if (hit) console.log('hit entity', hit.entity, 'at', hit.distance);

Pickup ​

ts
const Pickup: Record<string, never> = {};

Tag: something the player can pick up.


Player ​

ts
const Player: Record<string, never> = {};

Tag: the entity the player controls.


Renderable ​

ts
const Renderable: RenderableStore;

Renderable asset attached to an entity.


RigidBody ​

ts
const RigidBody: RigidBodyStore;

Physics body attached to an entity.


SHAPE_KINDS ​

ts
const SHAPE_KINDS: readonly ["box", "sphere", "capsule", "cylinder", "plane", "convex-hull", "mesh", "height-field"];

Collision shapes, in the index order RigidBody.shape stores.


SNAPSHOT_VERSION ​

ts
const SNAPSHOT_VERSION: 3 = 3;

Bumped whenever the byte layout changes. Mismatches refuse to restore.


TAG_ORDINAL ​

ts
const TAG_ORDINAL: Record<CommandTag, number>;

Every command tag mapped to its pool index.

Written out rather than derived so the compiler checks it: Record over the CommandTag union rejects both a missing tag and one that is not in the WIT variant. packages/wasm-host/src/apply.test.ts pins the same list from the host side.

Example ​

ts
import { TAG_ORDINAL } from 'gameable';

console.log(TAG_ORDINAL['set-time-scale']); // 24

things ​

ts
const things: object;

The things facade: the made world the host loaded, as game code sees it.

The list arrives once (world-event, kind loaded) and is kept up to date as loose things move (moved); the questions answer from it with no call to the host. push, move and reset are commands the host applies to a loose thing's body. A knock arrives in ctx.events as a world-event of kind hit, with the thing's index, where, and how hard (0 to 1).

Type Declaration ​

all ​
Get Signature ​
ts
get all(): readonly WorldThing[];

Every thing, loose or fixed; empty before a world has loaded.

Returns ​

readonly WorldThing[]

world ​
Get Signature ​
ts
get world(): WorldList | null;

The world the things are in (its name, the start, the walk limit), or null before one has loaded.

Returns ​

WorldList | null

breakApart() ​
ts
breakApart(
   thing, 
   x?, 
   y?, 
   z?
): void;

Break a thing in pieces (thing.pieces): each piece becomes a body of its own where it stood, moving as the thing moved, and a piece the package marks fixed stays put. Given one piece (thing.pieceOf), that piece alone comes off. The broken event follows, and reset makes the thing whole again.

Parameters ​
ParameterTypeDefault valueDescription
thingnumber | WorldThingundefinedThe thing, a piece of one, or the index of either.
xnumber0Metres a second added to each piece that comes off, x.
ynumber0The same, y.
znumber0The same, z.
Returns ​

void

Nothing; a thing that is not in pieces is left as it is.

drive() ​
ts
drive(
   thing, 
   throttle, 
   right, 
   brake?
): void;

Drive a thing that can be driven (thing.drives): the rider's wish, held until the next call. Send zeros to let go.

Parameters ​
ParameterTypeDefault valueDescription
thingnumber | WorldThingundefinedThe thing, or its index.
throttlenumberundefinedFrom -1 (back) to 1 (forward).
rightnumberundefinedSteering, from -1 (left) to 1 (right).
brakenumber0The brakes, from 0 to 1.
Returns ​

void

Nothing.

find() ​
ts
find(words): WorldThing | null;

The thing some words name ("the trunk"), or null.

Parameters ​
ParameterTypeDescription
wordsstringWhat was said.
Returns ​

WorldThing | null

The best match, or null.

findAll() ​
ts
findAll(words, out?): WorldThing[];

Every thing that answers some words, the best first.

Parameters ​
ParameterTypeDefault valueDescription
wordsstringundefinedWhat was said.
outWorldThing[][]The array to fill.
Returns ​

WorldThing[]

out.

getOff() ​
ts
getOff(thing): void;

Whoever sits on a thing gets off: the character is back on its entity. Move the entity to where it should stand first (physics.teleport), beside the thing.

Parameters ​
ParameterTypeDescription
thingnumber | WorldThingThe thing, or its index.
Returns ​

void

Nothing.

getOn() ​
ts
getOn(thing, entity): void;

Sit a character on a thing that has rider spots (thing.rider): its hips go on the seat, its hands are held to the grips as they turn, its feet to the rests, and it leans and moves with the thing. The host does it every frame from the character's own skeleton; the entity itself stays where it was (take its body out of the simulation with physics.setEnabled(entity, false) so the thing does not run into it).

Parameters ​
ParameterTypeDescription
thingnumber | WorldThingThe thing, or its index.
entitynumberThe character's entity.
Returns ​

void

Nothing; a thing with no rider spots is ignored.

joint() ​
ts
joint(
   thing, 
   joint, 
   value
): void;

Set one joint of a thing with moving parts: a lid opened, handlebars turned. The value is held to the joint's limits by the host.

Parameters ​
ParameterTypeDescription
thingWorldThingThe thing.
jointstring | numberThe joint's name ('steering') or its place in thing.joints.
valuenumberDegrees for a hinge, metres for a slide.
Returns ​

void

Nothing; a name the thing does not have is ignored.

limit() ​
ts
limit(
   x, 
   z, 
   velocity
): void;

Keep a walker inside the world's walk limit: changes velocity in place.

Parameters ​
ParameterTypeDescription
xnumberWhere the walker is, x.
znumberWhere the walker is, z.
velocityVec3The velocity asked for.
Returns ​

void

Nothing.

move() ​
ts
move(
   thing, 
   x, 
   y, 
   z
): void;

Put a loose thing somewhere: the middle of its base at this point, at rest.

Parameters ​
ParameterTypeDescription
thingnumber | WorldThingThe thing, or its index.
xnumberWhere, x.
ynumberWhere, y.
znumberWhere, z.
Returns ​

void

Nothing.

near() ​
ts
near(at, radius): readonly WorldThing[];

What is near a point, the nearest first. The array is reused by the next call.

Parameters ​
ParameterTypeDescription
atVec3The point.
radiusnumberMetres.
Returns ​

readonly WorldThing[]

The things within radius.

push() ​
ts
push(
   thing, 
   x, 
   y, 
   z
): void;

Shove a loose thing: an impulse at its middle, in newton-seconds.

Parameters ​
ParameterTypeDescription
thingnumber | WorldThingThe thing, or its index.
xnumberImpulse x.
ynumberImpulse y.
znumberImpulse z.
Returns ​

void

Nothing.

reset() ​
ts
reset(thing?): void;

Put a loose thing back where the package had it; with no thing, all of them.

Parameters ​
ParameterTypeDescription
thing?number | WorldThingThe thing, its index, or nothing for every loose thing.
Returns ​

void

Nothing.

spot() ​
ts
spot(thing, name): WorldSpotNow | null;

Where one of a thing's rider spots is now, in the world (seat, gripLeft, gripRight, footLeft, footRight): a grip turns with the handlebars. The record is reused by the next call.

Parameters ​
ParameterTypeDescription
thingWorldThingThe thing.
namestringThe spot's name.
Returns ​

WorldSpotNow | null

The spot's place, the way it faces and its up; null when the thing has no such spot.

standFor() ​
ts
standFor(thing, from?): WorldStand;

Where to stand to use a thing. The record is reused by the next call.

Parameters ​
ParameterTypeDefault valueDescription
thingWorldThingundefinedThe thing.
fromVec3 | nullnullWhere the asker is, to stand on the nearest side; omit for the package's own spot.
Returns ​

WorldStand

The spot and the facing.

Example ​

ts
import { defineGame, things } from 'gameable';

export default defineGame({
  update(ctx) {
    for (const event of ctx.events) {
      if (event.tag !== 'world-event') continue;
      if (event.val.kind === 'loaded') {
        const trunk = things.find('the trunk');
        if (trunk) console.log('stand at', things.standFor(trunk));
      } else if (event.val.kind === 'hit') {
        console.log(things.all[event.val.thing]?.label, 'was knocked', event.val.strength);
      }
    }
  },
});

Transform ​

ts
const Transform: TransformStore;

World transform of an entity. Position, rotation (xyzw), scale.


TRANSFORM_ALL ​

ts
const TRANSFORM_ALL: number;

POSITION | ROTATION | SCALE, what a freshly spawned entity needs.


TRANSFORM_FLAGS ​

ts
const TRANSFORM_FLAGS: Readonly<{
  DESTROYED: 32;
  POSITION: 1;
  ROTATION: 2;
  SCALE: 4;
  TELEPORT: 16;
  VISIBLE: 8;
}>;

Meaning of lane 1 of a transform row, matching WIT transform-flags.


TRANSFORM_STRIDE ​

ts
const TRANSFORM_STRIDE: 12 = 12;

Floats per row of frame-output.transforms.


Velocity ​

ts
const Velocity: VelocityStore;

Guest-integrated velocity, for entities the host physics does not own.

Functions ​

activeRuntime() ​

ts
function activeRuntime(): RuntimeState;

The runtime the SDK facades are currently bound to.

Returns ​

RuntimeState

The active runtime.

Throws ​

When called outside init, a system, update or shutdown.


applyTransfer() ​

ts
function applyTransfer(
   docA, 
   docB, 
   give, 
   take
): 
  | {
  a: TransferDoc;
  b: TransferDoc;
}
  | null;

Trade between two player documents: a gives b everything in give, and takes from b everything in take. A number field moves that amount (the giver must have at least that much); a list field moves those items (the giver must hold each one; an object item matches by value, whatever its key order). A missing document counts as {}.

Parameters ​

ParameterTypeDescription
docAunknownPlayer a's document, or null.
docBunknownPlayer b's document, or null.
giveunknownWhat a gives b, such as { coins: 5 }.
takeunknownWhat a takes from b, such as { owned: ['gem'] }.

Returns ​

| { a: TransferDoc; b: TransferDoc; } | null

Both new documents (the inputs are untouched), or null when the trade is impossible.

Example ​

ts
import { applyTransfer } from 'gameable';

applyTransfer({ coins: 10 }, { owned: ['gem'] }, { coins: 4 }, { owned: ['gem'] });
// { a: { coins: 6, owned: ['gem'] }, b: { owned: [], coins: 4 } }

assetId() ​

ts
function assetId(name): number;

Resolve a manifest string id to an asset handle, caching the result.

Parameters ​

ParameterTypeDescription
namestringThe manifest string id, for example 'arena'.

Returns ​

number

The handle, or 0 when the manifest has no such entry.

Example ​

ts
import { assetId } from 'gameable';

const arena = assetId('arena');

commandPoolSize() ​

ts
function commandPoolSize(): number;

Total pooled command slots created since the module loaded.

Tests assert this stops growing once a game reaches its steady state.

Returns ​

number

The number of slots ever allocated.

Example ​

ts
const before = commandPoolSize();
for (let i = 0; i < 100; i += 1) guest.tick(input);
console.log(commandPoolSize() === before); // true, in a steady state

configureEcs() ​

ts
function configureEcs(n): void;

Resize every built-in component array.

Call this before defineGame runs any system — the runtime calls it from init out of world.maxEntities. The component objects keep their identity, so bitecs registrations survive; only the arrays inside are replaced, so never cache Transform.x across a call.

Parameters ​

ParameterTypeDescription
nnumberThe new entity ceiling. Values below 2 are clamped to 2.

Returns ​

void

Nothing.


createGuest() ​

ts
function createGuest(host, definition): Guest;

Create a guest from a host and a game definition.

Parameters ​

ParameterTypeDescription
hostHostApiThe host services, in guest-side JS shapes.
definitionGameDefinitionThe result of defineGame.

Returns ​

Guest

The five WIT exports, plus dead and state.

Example ​

ts
import { createGuest } from 'gameable';
import { createMockHost, createFrameInput } from 'gameable/test';

const guest = createGuest(createMockHost(), game);
guest.init({ seed: 1, fixedHz: 60, viewportWidth: 1, viewportHeight: 1, devMode: true });
const out = guest.tick(createFrameInput({ frame: 0 }));

createRng() ​

ts
function createRng(initialSeed?): Rng;

Create a seeded xoshiro128** generator.

Parameters ​

ParameterTypeDefault valueDescription
initialSeednumber1A 32-bit seed. 0 is remapped so the state is never all zero.

Returns ​

Rng

A generator whose whole state is four integers.


createThirdPersonController() ​

ts
function createThirdPersonController(clips?): object;

Create one allocation-free camera-relative controller. Call reset in game init; update from a guest system. Tuning comes from ctx.rules: walkSpeed, runSpeed, acceleration, deceleration, jumpSpeed, landingSeconds, moveTurnRate, idleTurnRate, idleTurnThreshold and camera pitch/distance/height.

update drives the single player: ctx.player from ctx.input, with ctx.camera. updatePlayers drives a room on its authority: each player's own entity (PlayerHandle.entity, so a possess moves the controller too) from that player's own input, with that player's own camera. Each seat has its own state, made the first time the seat is seen and reset whenever the seat's entity changes (a join, a respawn, a possess).

Parameters ​

ParameterTypeDescription
clips?ThirdPersonClipsOptional complete base-layer clip mapping, configured once.

Returns ​

Persistent state, reset and update functions.

reset ​
ts
reset: (ctx) => void;

Reset the single player's state and look; forget every seat.

Parameters ​
ParameterTypeDescription
ctxGameContextThe init context.
Returns ​

void

state ​
ts
state: object = locomotionState;
state.airborne ​
ts
airborne: number = 0;
state.descending ​
ts
descending: boolean = false;
state.facing ​
ts
facing: number = Math.PI;
state.grounded ​
ts
grounded: boolean = false;
state.landing ​
ts
landing: number = 0;
state.pitch ​
ts
pitch: number = 0;
state.speed ​
ts
speed: number = 0;
state.state ​
ts
state: string = IDLE;
state.turning ​
ts
turning: boolean = false;
state.vx ​
ts
vx: number = 0;
state.vz ​
ts
vz: number = 0;
state.yaw ​
ts
yaw: number = 0;
stateOf ​
ts
stateOf: (player) => 
  | {
  airborne: number;
  descending: boolean;
  facing: number;
  grounded: boolean;
  landing: number;
  pitch: number;
  speed: number;
  state: string;
  turning: boolean;
  vx: number;
  vz: number;
  yaw: number;
}
  | undefined;
Parameters ​
ParameterTypeDescription
playernumberA player id.
Returns ​

| { airborne: number; descending: boolean; facing: number; grounded: boolean; landing: number; pitch: number; speed: number; state: string; turning: boolean; vx: number; vz: number; yaw: number; } | undefined

That seat's state, or undefined before it was first driven.

update ​
ts
update: (ctx, freeze) => void;

Drive the single player one step.

Parameters ​
ParameterTypeDefault valueDescription
ctxGameContextundefinedThe frame context.
freezebooleanfalseTrue to hold the player still.
Returns ​

void

updatePlayers ​
ts
updatePlayers: (ctx, freeze) => void;

Drive every room player's own entity one step, from their own input.

Parameters ​
ParameterTypeDefault valueDescription
ctxGameContextundefinedThe frame context, on the authority.
freezeboolean | ((player) => boolean)falseTrue to hold everyone still, or a test per player (hoist it: a function made per frame allocates), such as "this player is talking".
Returns ​

void

Example ​

ts
const controller = createThirdPersonController();
// In init: controller.reset(ctx); in a system:
if (ctx.net.role === 'solo') controller.update(ctx);
else controller.updatePlayers(ctx);

defineGame() ​

ts
function defineGame(spec): GameDefinition;

Declare a game.

Parameters ​

ParameterTypeDescription
specGameSpecThe declaration.

Returns ​

GameDefinition

The frozen definition, ready for createGuest or a build.

Example ​

ts
import { defineGame, prefab } from 'gameable';

const Player = prefab({
  body: { shape: 'capsule', dims: [0.3, 0.9], kind: 'character' },
});

export default defineGame({
  assets: ['arena'],
  world: { gravity: -9.81 },
  player: { prefab: Player, spawn: [0, 1, 0], camera: 'firstPerson' },
  systems: [(ctx) => { ctx.hud.set({ frame: ctx.frame }); }],
});

defineMessage() ​

ts
function defineMessage<T>(
   name, 
   check, 
   options?
): MessageDef<T>;

Declare a game message. Call it at module scope, once per name: a second definition with the same name before the next init throws.

A received payload that is over maxBytes, does not parse, fails check or makes check throw is dropped and counted in ctx.net.stats.dropped; a system never sees it.

Type Parameters ​

Type Parameter
T

Parameters ​

ParameterTypeDescription
namestringThe message name; unique within the game.
checkMessageCheck<T>The game's own type guard. Pure: no clock, no randomness.
options?MessageOptionsmaxBytes, default 2,048 (the wire cap).

Returns ​

MessageDef<T>

The definition.

Throws ​

On a duplicate name, an empty name, a name starting with aos: (reserved for the engine, as ctx.net.setPhase's aos:phase), or a maxBytes that is not a whole number from 1 to 2,048.

Example ​

ts
import { defineMessage, hasKeys } from 'gameable';

const hasFor = hasKeys('for');
export const Vote = defineMessage(
  'vote',
  (p): p is { for: number } => hasFor(p) && typeof p.for === 'number',
  { maxBytes: 64 },
);

describeAsset() ​

ts
function describeAsset(idOrName): AssetDesc | null;

Metadata for an asset handle or manifest name.

Parameters ​

ParameterTypeDescription
idOrNamestring | numberA handle from assetId, or a manifest string id.

Returns ​

AssetDesc | null

The description, or null when the asset is unknown.

Example ​

ts
import { describeAsset } from 'gameable';

const desc = describeAsset('myra');
if (desc?.kind === 'character') console.log('rig backend', desc.rig);

despawn() ​

ts
function despawn(entity): void;

Destroy an entity, its body and its host-side representation.

Parameters ​

ParameterTypeDescription
entitynumberThe entity id.

Returns ​

void

Nothing.

Example ​

ts
import { despawn } from 'gameable';

despawn(enemy);

featuresOf() ​

ts
function featuresOf(definition): FeatureOptions;

Normalise a game's features block.

Parameters ​

ParameterTypeDescription
definitionGameDefinitionThe defineGame result.

Returns ​

FeatureOptions

A frozen table: feature name to its options; true becomes {}, false is dropped.

Example ​

ts
import { defineGame, featuresOf } from 'gameable';

const game = defineGame({ features: { characters: true, multiplayer: { maxPlayers: 6 } } });
console.log(featuresOf(game)); // { characters: {}, multiplayer: { maxPlayers: 6 } }

findThing() ​

ts
function findThing(things, words): WorldThing | null;

The thing some words name, or null.

Parameters ​

ParameterTypeDescription
thingsreadonly WorldThing[]The world's things.
wordsstringWhat was said, for example "the trunk".

Returns ​

WorldThing | null

The best match, or null when nothing answers.

Example ​

ts
import { findThing } from 'gameable';

const trunk = findThing(things, 'the trunk');
console.log(trunk?.label); // 'steamer trunk'

findThings() ​

ts
function findThings(
   things, 
   words, 
   out?
): WorldThing[];

Every thing that answers some words, the best first.

An occasional question, not a per-step one: it splits the words asked.

Parameters ​

ParameterTypeDefault valueDescription
thingsreadonly WorldThing[]undefinedThe world's things.
wordsstringundefinedWhat was said, for example "the trunk" or "walk to the round window".
outWorldThing[][]The array to fill; emptied first.

Returns ​

WorldThing[]

out.

Example ​

ts
import { findThings, type WorldThing } from 'gameable';

const found: WorldThing[] = [];
findThings(things, 'a box', found);
console.log(found.map((thing) => thing.label)); // ['hat box', 'steamer trunk']

getActiveRuntime() ​

ts
function getActiveRuntime(): RuntimeState | null;

The runtime currently executing, or null outside a guest call.

Returns ​

RuntimeState | null

The active runtime.


getMaxEntities() ​

ts
function getMaxEntities(): number;

How many entities the built-in component arrays currently hold.

Returns ​

number

The configured entity ceiling.


hasKeys() ​

ts
function hasKeys<K>(...keys): (x) => x is Record<K, unknown>;

A guard for a record with every one of keys as an own property (any value, even undefined); extra keys are allowed. Make it once, at module scope: the guard it returns allocates nothing per call.

Type Parameters ​

Type Parameter
K extends string

Parameters ​

ParameterTypeDescription
...keysK[]The keys a payload must have.

Returns ​

The guard.

(x) => x is Record<K, unknown>

Example ​

ts
const hasItemSlot = hasKeys('item', 'slot');
const Pick = defineMessage(
  'pick',
  (p): p is { item: string; slot: number } =>
    hasItemSlot(p) && typeof p.item === 'string' && typeof p.slot === 'number',
);

isRecord() ​

ts
function isRecord(x): x is Record<string, unknown>;

A plain JSON object: not null, not an array.

Parameters ​

ParameterTypeDescription
xunknownA parsed payload.

Returns ​

x is Record<string, unknown>

True for an object record.

Example ​

ts
const Move = defineMessage('move', (p): p is { x: number } => isRecord(p) && typeof p.x === 'number');

keyIndex() ​

ts
function keyIndex(name): number;

Bit index for a key name, or -1 when the name is unknown. Names are case-sensitive, except that a bare letter or F-key also answers in lower case ('w', 'f1'). Allocates nothing.

Parameters ​

ParameterTypeDescription
namestringA DOM KeyboardEvent.code, a bare letter/digit, or an alias.

Returns ​

number

The bit index in 0..255, or -1.


keyIndex2() ​

ts
function keyIndex2(name): number;

Second bit index for names that cover a left/right pair ('Shift'), or -1. Case-sensitive, like the aliases it covers. Allocates nothing.

Parameters ​

ParameterTypeDescription
namestringA key name or alias.

Returns ​

number

The second bit index, or -1 when the name maps to one key.


limitWalk() ​

ts
function limitWalk(
   walk, 
   x, 
   z, 
   velocity
): void;

Keep a walker inside the world's walk limit: change the velocity it asked for.

A room's walls do the stopping (inside-collision: nothing changes here). An open place has a circle with a soft edge: from fadeFrom outward the speed away from the middle falls off, at radius it is none, and past it the walker is eased back in. Walking along the edge or back in is never slowed.

Parameters ​

ParameterTypeDescription
walkWorldWalkThe world's walk limit.
xnumberWhere the walker is, x.
znumberWhere the walker is, z.
velocityVec3The velocity asked for; x and z are changed in place.

Returns ​

void

Nothing.

Example ​

ts
import { limitWalk } from 'gameable';

const velocity = { x: 2, y: 0, z: 0 };
limitWalk(list.walk, 12.5, 0, velocity);
console.log(velocity.x); // 1: half way through the soft edge of an 11 to 14 metre limit

loadAsset() ​

ts
function loadAsset(idOrName, priority?): void;

Ask the host to start loading an asset.

Parameters ​

ParameterTypeDefault valueDescription
idOrNamestring | numberundefinedA handle or manifest string id.
prioritynumber0Higher runs first. Default 0.

Returns ​

void

Nothing.

Example ​

ts
import { loadAsset } from 'gameable';

loadAsset('boss-arena', 10);

markMoved() ​

ts
function markMoved(entity, flags?): void;

Tell the packer an entity's Transform changed.

spawn and the built-in velocity integration mark for you. Two cases they do not cover: a system that writes Transform.x[e] (or any other lane) by hand, and a body-driven entity, whose transform the host now owns outright — BodyIndex.ingest copies the physics rows in for the guest to read and deliberately does not mark them. Either way, nothing notices the write, the row is never packed and the host never moves the object. Call this after such a write. To move a physics body, send a command (setBodyTransform) rather than writing the lane.

Parameters ​

ParameterTypeDefault valueDescription
entitynumberundefinedEntity id. Out-of-range ids are ignored.
flagsnumberTRANSFORM_ALLWhich lanes changed; defaults to position, rotation and scale.

Returns ​

void

Nothing.

Example ​

ts
import { Transform, TRANSFORM_FLAGS, markMoved } from 'gameable';

Transform.y[e] = Transform.y[e] + 0.1;
markMoved(e, TRANSFORM_FLAGS.POSITION);

maxEntities() ​

ts
function maxEntities(): number;

The entity ceiling the built-in components are currently sized for.

Returns ​

number

The configured maximum.

Example ​

ts
import { maxEntities } from 'gameable';

console.log(maxEntities()); // 4096

moveThing() ​

ts
function moveThing(
   thing, 
   position, 
   rotation, 
   moved?
): void;

Put a thing somewhere new: its position, its turn, and its box round both.

The host's loader and the guest's list both call this, so the box a game reads is the same on either side.

Parameters ​

ParameterTypeDefault valueDescription
thingWorldThingundefinedThe thing; changed in place.
positionVec3undefinedThe middle of its base.
rotationQuatundefinedHow it is turned.
movedbooleantrueWhether this counts as having moved from where it was made.

Returns ​

void

Nothing.

Example ​

ts
import { moveThing } from 'gameable';

moveThing(thing, { x: 1, y: 0, z: -2 }, { x: 0, y: 0, z: 0, w: 1 });
console.log(thing.min, thing.max); // the box where it is now

prefab() ​

ts
function prefab(spec): PrefabDef;

Declare a prefab.

Safe at module scope: nothing is resolved until the first spawn.

Parameters ​

ParameterTypeDescription
specPrefabSpecWhat the entity is made of.

Returns ​

PrefabDef

The prefab, ready to spawn.

Example ​

ts
import { prefab } from 'gameable';

export const Crate = prefab({
  asset: 'crate',
  body: { shape: 'box', dims: [0.5, 0.5, 0.5], kind: 'dynamic', mass: 20 },
});

prefabRegistry() ​

ts
function prefabRegistry(): readonly PrefabDef[];

Every prefab declared so far, in declaration order.

Returns ​

readonly PrefabDef[]

The registry, for tooling and tests.


quatFromYawPitch() ​

ts
function quatFromYawPitch(
   out, 
   yaw, 
   pitch
): void;

Write a yaw/pitch pair into a quaternion, in the engine's Y-up convention.

Parameters ​

ParameterTypeDescription
outQuatQuaternion to overwrite.
yawnumberYaw in radians, around +Y.
pitchnumberPitch in radians, around the camera's local +X.

Returns ​

void

Nothing; out is mutated.


readKeyBit() ​

ts
function readKeyBit(words, index): boolean;

Read one bit out of an 8-word key bitset.

Parameters ​

ParameterTypeDescription
wordsArrayLike<number>The bitset, exactly KEY_WORDS long.
indexnumberA bit index from keyIndex.

Returns ​

boolean

True when the bit is set.


readSnapshot() ​

ts
function readSnapshot(rt, state): unknown;

Restore a state previously produced by writeSnapshot from the same build.

Parameters ​

ParameterTypeDescription
rtRuntimeStateThe runtime to overwrite.
stateArrayLike<number>The bytes.

Returns ​

unknown

The user state from defineGame({ snapshot }), if any.

Throws ​

A GameError-shaped object when the magic or version does not match.


readWorldList() ​

ts
function readWorldList(text): WorldList;

Read the list a world-event of kind loaded carries.

The world facade does this for a game; the function is here for a host, a test, or a tool that holds the same text.

Parameters ​

ParameterTypeDescription
textstringThe event's text: the list as JSON.

Returns ​

WorldList

The list.

Throws ​

When the text is not a world list, or is of a newer format.

Example ​

ts
import { readWorldList } from 'gameable';

const list = readWorldList(event.val.text);
console.log(list.name, list.things.length);

requireRuntime() ​

ts
function requireRuntime(): RuntimeState;

The runtime currently executing.

Returns ​

RuntimeState

The active runtime.

Throws ​

When called outside init, tick or shutdown.


resetBuiltinStores() ​

ts
function resetBuiltinStores(): void;

Zero every built-in component array without changing its length.

Returns ​

void

Nothing.


resetPrefabRegistry() ​

ts
function resetPrefabRegistry(): void;

Reset prefab numbering. Tests only — a game never calls this.

Returns ​

void

Nothing.


roomSeats() ​

ts
function roomSeats(definition): number | undefined;

The seats a game declares: features.multiplayer.maxPlayers. Seats are ids 0..seats - 1. The guest makes exactly that many player slots and ignores (with one warning) a join or input past them; a room built by createEngineRoomGame refuses the next joiner with full. Both read this function, so the two cannot disagree.

Parameters ​

ParameterTypeDescription
definitionGameDefinitionThe defineGame result.

Returns ​

number | undefined

The seat count, DEFAULT_ROOM_SEATS for multiplayer: true, or undefined when the game does not declare features.multiplayer.

Throws ​

When maxPlayers is not a whole number from 1 to 4097.

Example ​

ts
import { defineGame, roomSeats } from 'gameable';

const game = defineGame({ features: { multiplayer: { maxPlayers: 6 } } });
roomSeats(game); // 6: seats 0 to 5

roomSendHz() ​

ts
function roomSendHz(definition): number;

The rows rate a game declares, checked: features.multiplayer.sendHz, from 1 to 60 per second (60 is the simulation rate, so more would repeat rows).

Parameters ​

ParameterTypeDescription
definitionGameDefinitionThe defineGame result.

Returns ​

number

The declared rate, or 20 when none is declared.

Throws ​

When sendHz is declared but is not a number from 1 to 60.

Example ​

ts
import { defineGame, roomSendHz } from 'gameable';

roomSendHz(defineGame({ features: { multiplayer: { sendHz: 10 } } })); // 10
roomSendHz(defineGame({ features: { multiplayer: true } })); // 20

setActiveRuntime() ​

ts
function setActiveRuntime(next): RuntimeState | null;

Install the runtime the facades resolve against.

Parameters ​

ParameterTypeDescription
nextRuntimeState | nullThe runtime, or null when leaving a guest call.

Returns ​

RuntimeState | null

The previously active runtime, so calls can nest.


setLogSink() ​

ts
function setLogSink(next): void;

Point prelude console at the host logger.

The runtime calls this at the top of init. Any lines buffered before then are flushed in order, so module-scope logging is not silently lost.

Parameters ​

ParameterTypeDescription
nextLogSink | nullThe sink, or null to go back to buffering.

Returns ​

void

Nothing.


setRandomSource() ​

ts
function setRandomSource(next): void;

Route Math.random at the seeded SDK generator.

The runtime calls this from init. Until then Math.random() throws with RANDOM_MESSAGE, which is far kinder than a game that silently replays the same "random" sequence on every instantiation.

Only effective in the component guest; see IS_COMPONENT_GUEST.

Parameters ​

ParameterTypeDescription
next(() => number) | nullThe seeded generator, or null to re-arm the guard.

Returns ​

void

Nothing.


spawn() ​

ts
function spawn(
   def, 
   position, 
   rotation?
): number;

Instantiate a prefab.

Mints the entity id, writes the built-in components and queues the spawn / add-body / spawn-character commands the host needs.

Parameters ​

ParameterTypeDefault valueDescription
defPrefabDefundefinedA prefab from prefab().
positionVec3undefinedWorld position.
rotationQuatIDENTITYWorld rotation, xyzw. Defaults to identity.

Returns ​

number

The new entity id.

Example ​

ts
import { spawn } from 'gameable';

const crate = spawn(Crate, { x: 0, y: 2, z: -5 });

spotOf() ​

ts
function spotOf(
   thing, 
   name, 
   out
): WorldSpotNow | null;

Where one of a thing's rider spots is now, in the world: the seat, a grip, a foot rest.

A spot is on a part and moves with it, so a grip turns with the handlebars: the spot goes through each joint between its part and the thing's root at the value the joint stands at (thing.joints[i].value), then to where the thing is and how it is turned. Allocates nothing when out is reused.

Parameters ​

ParameterTypeDescription
thingWorldThingThe thing.
namestringThe spot's name: seat, gripLeft, gripRight, footLeft, footRight.
outWorldSpotNowThe record to fill.

Returns ​

WorldSpotNow | null

out, or null when the thing has no such spot.

Example ​

ts
import { spotOf, type WorldSpotNow } from 'gameable';

const seat: WorldSpotNow = {
  position: { x: 0, y: 0, z: 0 },
  forward: { x: 0, y: 0, z: 1 },
  up: { x: 0, y: 1, z: 0 },
};
if (spotOf(bike, 'seat', seat)) console.log(seat.position); // where the seat is now

standFor() ​

ts
function standFor(
   thing, 
   from?, 
   out?
): WorldStand;

Where to stand to use a thing, and which way to face.

The package's own spot while the thing is where it was made. For a thing that has moved, or one the package gave no spot, a spot beside it, facing it: on the side of from when given (the nearest side to whoever asks), else on the side the package's spot was, else on its +z side.

Parameters ​

ParameterTypeDefault valueDescription
thingWorldThingundefinedThe thing.
fromVec3 | nullnullWhere the asker is, or null.
outWorldStand...The record to fill.

Returns ​

WorldStand

out.

Example ​

ts
import { findThing, standFor } from 'gameable';

const trunk = findThing(things, 'the trunk');
if (trunk) {
  const spot = standFor(trunk, null);
  console.log(spot.x, spot.z, spot.facing); // walk here, turn to this
}

thingsNear() ​

ts
function thingsNear(
   things, 
   point, 
   radius, 
   out?
): WorldThing[];

What is near a point: every thing whose box is within radius, the nearest first.

Allocates nothing when out is reused, so a system may ask every step.

Parameters ​

ParameterTypeDefault valueDescription
thingsreadonly WorldThing[]undefinedThe world's things.
pointVec3undefinedThe point, for example the player's feet.
radiusnumberundefinedMetres.
outWorldThing[][]The array to fill; emptied first.

Returns ​

WorldThing[]

out.

Example ​

ts
import { thingsNear, type WorldThing } from 'gameable';

const near: WorldThing[] = [];
thingsNear(things, { x: 0, y: 0, z: -2 }, 1.5, near);
console.log(near[0]?.label); // the nearest thing within a metre and a half

utf8Decode() ​

ts
function utf8Decode(
   b, 
   start?, 
   end?
): string;

Decode UTF-8 bytes without TextDecoder.

Parameters ​

ParameterTypeDefault valueDescription
bArrayLike<number>undefinedThe bytes. Any ArrayLike<number> works, including the plain Array jco hands the guest.
startnumber0First byte to read.
end?numberundefinedOne past the last byte to read; defaults to b.length.

Returns ​

string

The decoded string.


utf8Encode() ​

ts
function utf8Encode(s): Uint8Array;

Encode a JavaScript string as UTF-8 without TextEncoder.

Parameters ​

ParameterTypeDescription
sstringThe string to encode.

Returns ​

Uint8Array

A freshly allocated UTF-8 byte array.


writeKeyBit() ​

ts
function writeKeyBit(
   words, 
   index, 
   value
): void;

Set or clear one bit in an 8-word key bitset, in place.

Parameters ​

ParameterTypeDescription
wordsUint32ArrayThe bitset, exactly KEY_WORDS long.
indexnumberA bit index from keyIndex.
valuebooleanTrue to set the bit, false to clear it.

Returns ​

void

Nothing; words is mutated.


writeSnapshot() ​

ts
function writeSnapshot(rt, userState?): Uint8Array;

Serialise the whole guest state.

Parameters ​

ParameterTypeDescription
rtRuntimeStateThe runtime to serialise.
userState?unknownExtra state from defineGame({ snapshot }).

Returns ​

Uint8Array

A freshly allocated byte string. Opaque to the host.