NET FORGE DOCS

@netforge/engine-sim API reference

Last updated Checked against @netforge/engine 0.2.0View as Markdown

Net Forge, the open-source multiplayer browser game engine built for AI coding agents, is published on npm under @netforge with source at github.com/netnetdev/net-forge.

The shared simulation: ECS, deterministic Rapier physics, the fixed tick and bit-exact snapshots. It runs the same in the browser and on the server and has no rendering dependency.

import { initSim, createPhysics } from "@netforge/engine-sim";

Generated from packages/engine-sim/src/index.ts by apps/forge-docs/scripts/api.mjs. Signatures are what the TypeScript compiler reports for the current source; long types are cut and say so.

KindCount
Functions117
Classes2
Constants47
Types93

Functions

addKart

function addKart(w: KartWorld, id: number, opts?: { bot?: boolean; frozen?: boolean; slot?: number; }): Kart;

Source: packages/engine-sim/src/kart.ts

addPlatformPlayer

function addPlatformPlayer(w: PlatformWorld, id: number, opts?: { bot?: boolean; frozen?: boolean; }): PlatformPlayer;

Source: packages/engine-sim/src/platform.ts

addPlayer

Spawn a player's character. Throws if the id is already present.

function addPlayer(world: SimWorld, playerId: PlayerId, spawn?: Vec3): NetId;

Source: packages/engine-sim/src/world.ts

applyBeamHit

Apply a lag-compensated beam hit (the rewind found target, a NetId). Its events come out of the next step.

function applyBeamHit(world: SimWorld, shot: BeamShot, target: NetId): void;

Source: packages/engine-sim/src/control.ts

applyKart

function applyKart(w: KartWorld, s: KartWire): Kart;

Source: packages/engine-sim/src/kart.ts

applyPlatformPlayer

Overwrite (or create) a player from wire state, and take the world tick from it.

function applyPlatformPlayer(w: PlatformWorld, s: PlatformPlayerWire): PlatformPlayer;

Source: packages/engine-sim/src/platform.ts

applyState

Make the world match state: update entities present in both, spawn missing ones with their netIds, remove the rest. Lossless for captured states. Interpolation history is reset (prev = current).

function applyState(world: SimWorld, state: SimState): void;

Source: packages/engine-sim/src/snapshot.ts

arenaHitboxes

Living players' and enemies' hitboxes this tick (the room's rewind buffer records them).

function arenaHitboxes(world: SimWorld): ArenaHitbox[];

Source: packages/engine-sim/src/control.ts

arenaSpawn

Where a player joining or respawning now would stand: the spawn point farthest from opponents.

function arenaSpawn(world: SimWorld, playerId: PlayerId): [number, number];

Source: packages/engine-sim/src/control.ts

beamRange

How far a beam from (x, z) along the unit (dx, dz) reaches before a pillar or the arena wall stops it, capped at range. Clients draw beams with it; the server clamps hitscans with it.

function beamRange(config: ResolvedSimConfig, x: number, z: number, dx: number, dz: number, range: number): number;

Source: packages/engine-sim/src/arena.ts

beamShot

A human player's beam this tick, for a room's lag compensation. Call before step with the command it will consume.

function beamShot(world: SimWorld, playerId: PlayerId, cmd: InputCommand): BeamShot | null;

Source: packages/engine-sim/src/control.ts

buildKartTrack

Sample a closed Catmull-Rom centreline every ~2 m. Pure arithmetic, identical on every side.

function buildKartTrack(def: KartTrackDef): KartTrack;

Source: packages/engine-sim/src/kart.ts

captureKart

function captureKart(w: KartWorld, k: Kart): KartWire;

Source: packages/engine-sim/src/kart.ts

capturePlatformPlayer

function capturePlatformPlayer(w: PlatformWorld, p: PlatformPlayer): PlatformPlayerWire;

Source: packages/engine-sim/src/platform.ts

captureState

Read the world's networked state. include filters entities (interest management).

function captureState(world: SimWorld, include?: (e: EntityState) => boolean): SimState;

Source: packages/engine-sim/src/snapshot.ts

collisionGroups

Rapier interaction groups: membership in the high 16 bits, filter in the low 16.

function collisionGroups(layer: number, mask: number): number;

Source: packages/engine-sim/src/physics/layers.ts

createKartWorld

function createKartWorld(cfg: KartConfig): KartWorld;

Source: packages/engine-sim/src/kart.ts

createPhysics

Build a physics world. Requires await initSim() first (it loads the Rapier WebAssembly).

function createPhysics(opts?: PhysicsOptions): PhysicsWorld;

Source: packages/engine-sim/src/physics/world.ts

createPlatformWorld

function createPlatformWorld(cfg: PlatformConfig): PlatformWorld;

Source: packages/engine-sim/src/platform.ts

createWorld

Create a world: static arena colliders, empty of entities, tick 0. Requires initSim().

function createWorld(config?: SimConfig): SimWorld;

Source: packages/engine-sim/src/world.ts

critRoll

The crit roll for hits on enemy netId at tick, in [0, 1): a fixed hash, so clients can mark crit numbers.

function critRoll(tick: number, netId: number): number;

Source: packages/engine-sim/src/content.ts

decodeChoices

The three offered upgrade indices (-1 for none) and the pending level-ups.

function decodeChoices(choices: number): { offers: [number, number, number]; pending: number; };

Source: packages/engine-sim/src/content.ts

decodeInput

function decodeInput(bytes: Uint8Array, offset?: number): InputCommand;

Source: packages/engine-sim/src/input.ts

decodeInputs

function decodeInputs(bytes: Uint8Array): InputCommand[];

Source: packages/engine-sim/src/input.ts

decodeSnapshot

function decodeSnapshot(bytes: Uint8Array, baseline?: SimState): SimState;

Source: packages/engine-sim/src/snapshot.ts

decodeTelegraph

Decode a telegraph word (clients and bots).

function decodeTelegraph(word: number): { kind: number; progress: number; angle: number; radius: number; };

Source: packages/engine-sim/src/roles.ts

destroyWorld

Free the world's physics memory. The world is unusable afterwards.

function destroyWorld(world: SimWorld): void;

Source: packages/engine-sim/src/world.ts

edgeSpawnPoint

A point just off the screen of playerId (or of a random living player), inside the arena, clear of pillars and off every other player's screen. Null when there is none: skip the spawn, never clamp it on screen.

function edgeSpawnPoint(world: SimWorld, playerId: PlayerId | undefined, opts?: EdgeSpawnOptions): [number, number] | null;

Source: packages/engine-sim/src/control.ts

encodeInput

15 bytes, little endian: seq u32, tick u32, moveX i8, moveZ i8, yaw u16, buttons u16, reserved u8 (0).

function encodeInput(cmd: InputCommand, out?: Uint8Array, offset?: number): Uint8Array;

Source: packages/engine-sim/src/input.ts

encodeInputs

Count byte (u8, max 255) followed by that many 15-byte commands.

function encodeInputs(cmds: readonly InputCommand[]): Uint8Array;

Source: packages/engine-sim/src/input.ts

encodeSnapshot

Binary snapshot. With baseline, a delta against it (the receiver must hold the same baseline).

function encodeSnapshot(state: SimState, baseline?: SimState): Uint8Array;

Source: packages/engine-sim/src/snapshot.ts

enemyCount

Living (non-corpse) enemies, of one type or all.

function enemyCount(world: SimWorld, type?: number): number;

Source: packages/engine-sim/src/control.ts

enemyMaxHealth

An enemy's max health as spawned (scaled), by NetId; undefined when gone or not an enemy.

function enemyMaxHealth(world: SimWorld, netId: NetId): number | undefined;

Source: packages/engine-sim/src/control.ts

enemyTypeOf

An enemy's type index by NetId, or -1 when it is gone or not an enemy.

function enemyTypeOf(world: SimWorld, netId: NetId): number;

Source: packages/engine-sim/src/control.ts

entityHeadroom

Room left under maxEntities (spawners should stop before 0).

function entityHeadroom(world: SimWorld): number;

Source: packages/engine-sim/src/control.ts

entityHealth

An entity's health by NetId, or undefined when it is gone.

function entityHealth(world: SimWorld, netId: NetId): number | undefined;

Source: packages/engine-sim/src/control.ts

entityPosition

An entity's ground position by NetId, or undefined when it is gone.

function entityPosition(world: SimWorld, netId: NetId): [number, number] | undefined;

Source: packages/engine-sim/src/control.ts

grantKartStat

function grantKartStat(w: KartWorld, id: number, stat: KartStat): boolean;

Source: packages/engine-sim/src/kart.ts

grantLevels

Raise a player by levels levels now (a late joiner catching up): each level arrives as if from gems, with its card pending. Returns the levels granted.

function grantLevels(world: SimWorld, playerId: PlayerId, levels: number): number;

Source: packages/engine-sim/src/control.ts

grantPlatformStat

Add one level of a stat (store upgrades and gear). Returns false at the 4-bit cap.

function grantPlatformStat(w: PlatformWorld, id: number, stat: PlatStat): boolean;

Source: packages/engine-sim/src/platform.ts

grantUpgrade

Give a player one level of passive index (content.stats) for the rest of the run: a store upgrade.

function grantUpgrade(world: SimWorld, playerId: PlayerId, index: number): boolean;

Source: packages/engine-sim/src/control.ts

grantXp

Give a player XP now (levels and cards follow as from gems). Returns false when the player is absent.

function grantXp(world: SimWorld, playerId: PlayerId, amount: number): boolean;

Source: packages/engine-sim/src/control.ts

initSim

Load the Rapier WebAssembly. Call once per process before createWorld. Idempotent.

function initSim(): Promise<void>;

Source: packages/engine-sim/src/world.ts

inWall

True when a circle at (x, z) of radius r overlaps any wall.

function inWall(walls: readonly WallBox[], x: number, z: number, r: number): boolean;

Source: packages/engine-sim/src/walls.ts

isOnScreen

True when (x, z) is on the screen of any player who is up.

function isOnScreen(world: SimWorld, x: number, z: number): boolean;

Source: packages/engine-sim/src/control.ts

kartCoinCount

function kartCoinCount(k: { coinsLo: number; coinsHi: number; }): number;

Source: packages/engine-sim/src/kart.ts

kartCoinTaken

function kartCoinTaken(k: { coinsLo: number; coinsHi: number; }, i: number): boolean;

Source: packages/engine-sim/src/kart.ts

kartProgress

Race progress in laps (lap + this lap's fraction), for standings.

function kartProgress(w: KartWorld, k: Kart): number;

Source: packages/engine-sim/src/kart.ts

kartStatLevel

function kartStatLevel(k: { stats: number; }, stat: KartStat): number;

Source: packages/engine-sim/src/kart.ts

kartStep

One fixed tick.

function kartStep(w: KartWorld, inputs: ReadonlyMap<number, InputCommand>): KartEvent[];

Source: packages/engine-sim/src/kart.ts

keeperButtons

Input bits that choose keeper index (0..14).

function keeperButtons(index: number): number;

Source: packages/engine-sim/src/api.ts

lastProcessedSeq

The last input seq the sim consumed for this player (the reconciliation ack). 0 if none or absent.

function lastProcessedSeq(world: SimWorld, playerId: PlayerId): number;

Source: packages/engine-sim/src/world.ts

lateralOffset

Signed sideways offset from the centreline at sample seg (positive to the right of travel).

function lateralOffset(t: KartTrack, seg: number, x: number, z: number): number;

Source: packages/engine-sim/src/kart.ts

layerMask

A mask from layer names or bits: layerMask("Level", "Enemy").

function layerMask(...layers: readonly (LayerName | number)[]): number;

Source: packages/engine-sim/src/physics/layers.ts

layersCollide

True when two bodies with these layers and masks collide (Rapier's pairwise rule).

function layersCollide(layerA: number, maskA: number, layerB: number, maskB: number): boolean;

Source: packages/engine-sim/src/physics/layers.ts

listPickups

Pickups on the floor: position (m) and value (XP, or heal in the arena).

function listPickups(world: SimWorld): { x: number; z: number; value: number; }[];

Source: packages/engine-sim/src/control.ts

listPlayers

Every player, in playerId order.

function listPlayers(world: SimWorld): PlayerSummary[];

Source: packages/engine-sim/src/control.ts

maxHealthFor

Max health for a packed stats field (clients draw health bars with it).

function maxHealthFor(config: ResolvedSimConfig, stats: number): number;

Source: packages/engine-sim/src/control.ts

metaBonusOf

A player's meta bonus as the sim applies it (zeros when none).

function metaBonusOf(world: SimWorld, playerId: PlayerId): MetaBonus;

Source: packages/engine-sim/src/control.ts

moverBox

A moving platform's box at a tick: a smooth there-and-back swing.

function moverBox(m: PlatformMover, tick: number): PlatBox;

Source: packages/engine-sim/src/platform.ts

nearestSample

Nearest centreline sample to (x, z), searching around from (or everywhere).

function nearestSample(t: KartTrack, x: number, z: number, from?: number, reach?: number): number;

Source: packages/engine-sim/src/kart.ts

onFloor

True when the circle at (x, z) of radius r lies on some floor rectangle (its centre inside it, with r of margin where it can).

function onFloor(floors: readonly WallBox[], x: number, z: number, r: number): boolean;

Source: packages/engine-sim/src/walls.ts

orbitAngle

Orbit blade angle for blade i of n at a tick (radians). Exported so renderers draw blades where the sim hits.

function orbitAngle(tick: number, tickRate: number, speed: number, i: number, n: number): number;

Source: packages/engine-sim/src/content.ts

pendingCards

Cards a player has waiting (level-ups not yet picked).

function pendingCards(world: SimWorld, playerId: PlayerId): number;

Source: packages/engine-sim/src/control.ts

platBox

Normalize a box so x0 < x1 and y0 < y1.

function platBox(x0: number, y0: number, x1: number, y1: number): PlatBox;

Source: packages/engine-sim/src/platform.ts

platformCoinCount

function platformCoinCount(p: { coinsLo: number; coinsHi: number; }): number;

Source: packages/engine-sim/src/platform.ts

platformCoinTaken

function platformCoinTaken(p: { coinsLo: number; coinsHi: number; }, i: number): boolean;

Source: packages/engine-sim/src/platform.ts

platformProgress

How far along the course a player is, 0..1 (by x from start to flag).

function platformProgress(w: PlatformWorld, p: { x: number; flags: number; }): number;

Source: packages/engine-sim/src/platform.ts

platformRespawnPoint

Where a fall puts you back: the furthest checkpoint touched, or the start.

function platformRespawnPoint(w: PlatformWorld, cp: number): readonly [number, number];

Source: packages/engine-sim/src/platform.ts

platformStep

One fixed tick. Inputs by player id; a player with none gets a neutral input.

function platformStep(w: PlatformWorld, inputs: ReadonlyMap<number, InputCommand>): PlatformEvent[];

Source: packages/engine-sim/src/platform.ts

platStatLevel

A stat's level (0..15) from the packed word.

function platStatLevel(p: { stats: number; }, stat: PlatStat): number;

Source: packages/engine-sim/src/platform.ts

playerBuild

function playerBuild(world: SimWorld, playerId: PlayerId): PlayerBuild | null;

Source: packages/engine-sim/src/control.ts

playerNetId

The NetId of a player's character, if present.

function playerNetId(world: SimWorld, playerId: PlayerId): NetId | undefined;

Source: packages/engine-sim/src/world.ts

pushOutOfWalls

Push a circle out of every wall it overlaps. Returns the new centre and the push normal of the last wall met (0, 0 when nothing was in the way).

function pushOutOfWalls(walls: readonly WallBox[], x: number, z: number, r: number): [x: number, z: number, nx: number, nz: number];

Source: packages/engine-sim/src/walls.ts

quantizeInput

Snap a command onto the wire grid. The sim applies this to every input it consumes.

function quantizeInput(cmd: InputCommand): InputCommand;

Source: packages/engine-sim/src/input.ts

recycleEnemies

Move far-off-screen non-boss enemies back to the spawn edge (see content.ts). Call every periodTicks.

function recycleEnemies(world: SimWorld, periodTicks: number, afterTicks: number, margin: number): { moved: number; removed: number; };

Source: packages/engine-sim/src/control.ts

removeEnemies

Remove every living enemy of a type at once, with no kills or drops. Returns how many.

function removeEnemies(world: SimWorld, type: number): number;

Source: packages/engine-sim/src/control.ts

removeKart

function removeKart(w: KartWorld, id: number): boolean;

Source: packages/engine-sim/src/kart.ts

removePlatformPlayer

function removePlatformPlayer(w: PlatformWorld, id: number): boolean;

Source: packages/engine-sim/src/platform.ts

removePlayer

Remove a player's character. No-op if absent.

function removePlayer(world: SimWorld, playerId: PlayerId): void;

Source: packages/engine-sim/src/world.ts

renderView

Dense arrays for rendering this tick, in netId order, with last tick's transforms for interpolation. The buffers are reused: copy anything you need to keep past the next step or applyState.

function renderView(world: SimWorld): RenderView;

Source: packages/engine-sim/src/render.ts

resetKart

Back to the grid for a fresh race (stats kept; the runner clears them).

function resetKart(w: KartWorld, k: Kart, frozen: boolean): void;

Source: packages/engine-sim/src/kart.ts

resetPlatformPlayer

Put a player back at the start of a fresh round (stats are kept; the runner clears them per run).

function resetPlatformPlayer(w: PlatformWorld, p: PlatformPlayer, frozen: boolean): void;

Source: packages/engine-sim/src/platform.ts

resetRun

A fresh run in place: enemies, gems and projectiles cleared; players reset at the spawn. NetIds of players are kept.

function resetRun(world: SimWorld): void;

Source: packages/engine-sim/src/control.ts

resolveCharacter

Fill a character description with defaults and validate it.

function resolveCharacter(d: CharacterDesc): ResolvedCharacterDesc;

Source: packages/engine-sim/src/physics/character.ts

resolveConfig

function resolveConfig(config?: SimConfig): ResolvedSimConfig;

Source: packages/engine-sim/src/config.ts

respawnDead

Bring dead (out) players back beside a living teammate. Returns who came back.

function respawnDead(world: SimWorld): PlayerId[];

Source: packages/engine-sim/src/control.ts

restorePhysics

Rebuild a world from snapshot() bytes. Stepping it gives exactly what the original would have.

function restorePhysics(bytes: Uint8Array): PhysicsWorld;

Source: packages/engine-sim/src/physics/world.ts

revivePlayer

Revive one downed or dead player now (a paid revive). Returns false if they were up or absent.

function revivePlayer(world: SimWorld, playerId: PlayerId): boolean;

Source: packages/engine-sim/src/control.ts

ringSpawnPoint

A ring point around (cx, cz) inside the arena and clear of pillars (headings retried, never clamped). Null if none.

function ringSpawnPoint(world: SimWorld, cx: number, cz: number, radius: number, enemyRadius?: number): [number, number] | null;

Source: packages/engine-sim/src/control.ts

scaledWeapon

A weapon at a level with a player's passives applied.

function scaledWeapon(def: WeaponDef, level: number, mods: WeaponMods): Scaled;

Source: packages/engine-sim/src/weapons.ts

scatterEnemies

Scatter count enemies of a type (props) over the field, off every screen. Returns how many.

function scatterEnemies(world: SimWorld, type: number, count: number): number;

Source: packages/engine-sim/src/control.ts

segmentWalls

The first hit of a moving circle of radius r on a wall: the segment from (x0, z0) along (dx, dz), as a fraction 0..1, or -1 when it meets none. A box grown by r, slab method.

function segmentWalls(walls: readonly WallBox[], x0: number, z0: number, dx: number, dz: number, r: number): number;

Source: packages/engine-sim/src/walls.ts

selectedSlot

The selected weapon slot (0..3) in a player's packed choices field (arena mode).

function selectedSlot(choices: number): number;

Source: packages/engine-sim/src/arena.ts

setCosmetic

Set a player's cosmetic id (drawn by clients; no gameplay effect).

function setCosmetic(world: SimWorld, playerId: PlayerId, cosmetic: number): void;

Source: packages/engine-sim/src/control.ts

setEnemySpeed

Authority: multiply every non-boss enemy's steering speed by k (0.25..3) from now on.

function setEnemySpeed(world: SimWorld, k: number): void;

Source: packages/engine-sim/src/control.ts

setKartsFrozen

function setKartsFrozen(w: KartWorld, frozen: boolean): void;

Source: packages/engine-sim/src/kart.ts

setKartTrack

function setKartTrack(w: KartWorld, index: number): void;

Source: packages/engine-sim/src/kart.ts

setMetaBonus

Set a player's permanent (meta) stat bonus for this world: fractions, 0.05 = +5%. Each stat is clamped to META_MAX_PER_STAT and the sum to META_MAX_TOTAL (scaled down evenly past it). A player at full health stays at full health. Pass an empty object to clear it.

function setMetaBonus(world: SimWorld, playerId: PlayerId, bonus: Partial<MetaBonus>): void;

Source: packages/engine-sim/src/control.ts

setPlatformFrozen

The countdown: hold (or release) every player.

function setPlatformFrozen(w: PlatformWorld, frozen: boolean): void;

Source: packages/engine-sim/src/platform.ts

setPlatformLevel

Switch the course (a new round). Players keep their state; reset them after.

function setPlatformLevel(w: PlatformWorld, index: number): void;

Source: packages/engine-sim/src/platform.ts

setXpBoost

Multiply the XP of gems dropped from now on (1 turns it off). Server-side, for timed events.

function setXpBoost(world: SimWorld, multiplier: number): void;

Source: packages/engine-sim/src/control.ts

simPaused

True while the sim is paused for a solo player's upgrade cards.

function simPaused(world: SimWorld): boolean;

Source: packages/engine-sim/src/control.ts

simRandom

The world's seeded PRNG, 0..1 (server-side game logic).

function simRandom(world: SimWorld): number;

Source: packages/engine-sim/src/control.ts

slotLevel

function slotLevel(weapons: number, slot: number): number;

Source: packages/engine-sim/src/content.ts

slotWeapon

Weapon index in a slot, or -1 when empty.

function slotWeapon(weapons: number, slot: number): number;

Source: packages/engine-sim/src/content.ts

snapshotBaseTick

The baseline tick a delta snapshot needs, or null for a full snapshot.

function snapshotBaseTick(bytes: Uint8Array): number | null;

Source: packages/engine-sim/src/snapshot.ts

spawnEnemy

Spawn an enemy of type (index into content.enemyTypes) at (x, z). Returns its NetId.

function spawnEnemy(world: SimWorld, type: number, x: number, z: number): NetId;

Source: packages/engine-sim/src/control.ts

spawnEnemyScaled

function spawnEnemyScaled(world: SimWorld, type: number, x: number, z: number, scale: SpawnScale): NetId;

Source: packages/engine-sim/src/control.ts

spawnPickupAt

Spawn special pickup index (content.pickups) at (x, z). Returns its NetId, or 0 when the world is full.

function spawnPickupAt(world: SimWorld, index: number, x: number, z: number): NetId;

Source: packages/engine-sim/src/control.ts

spawnRingPoint

A point on a ring of radius m around a random living player (the arena spawn if none). Consumes the world PRNG.

function spawnRingPoint(world: SimWorld, radius: number): [number, number];

Source: packages/engine-sim/src/control.ts

statLevel

function statLevel(stats: number, i: number): number;

Source: packages/engine-sim/src/content.ts

step

THE API: advance the world exactly one fixed tick.

Systems run in a fixed order: input, AI, physics, combat, pickups, spawners, game rules, lifetime. Every loop that touches floats walks entities in netId order, so a world restored from a snapshot steps exactly like the one it was captured from.

function step(world: SimWorld, inputs: TickInputs): StepResult;

Source: packages/engine-sim/src/step.ts

teleWord

Telegraph word: kind, progress 0..1, and an angle (lanes) or a radius in metres (circles).

function teleWord(kind: number, progress: number, angleOrRadius: number, isRadius?: boolean): number;

Source: packages/engine-sim/src/roles.ts

viewEdge

Distance from a player to the edge of the screen at a heading (radians from +x toward +z), m.

function viewEdge(world: SimWorld, heading: number): number;

Source: packages/engine-sim/src/control.ts

weaponModsFor

A player's weapon multipliers from a packed stats field (clients draw weapons the size the sim uses).

function weaponModsFor(config: ResolvedSimConfig, stats: number): { might: number; haste: number; area: number; amount: number; };

Source: packages/engine-sim/src/control.ts

xpForLevel

XP needed to go from level to level + 1.

function xpForLevel(config: ResolvedSimConfig, level: number): number;

Source: packages/engine-sim/src/control.ts

Classes

FixedStepper

Fixed-timestep accumulator (Glenn Fiedler, "Fix Your Timestep!"). Pure: no timers, no clock. The client feeds it frame deltas from requestAnimationFrame, the room server feeds it from its own loop, and both run step exactly ticks times per advance.

class FixedStepper {
  constructor(tickRate: number, maxTicksPerAdvance?: number);
  readonly tickRate: number;
  readonly tickMs: number;
  readonly maxTicksPerAdvance: number;
  advance(elapsedMs: number): StepperAdvance;
  reset(): void;
}

Source: packages/engine-sim/src/stepper.ts

PhysicsWorld

class PhysicsWorld {
  constructor(raw: RapierWorld, tickRate: number, gravity: Vec3);
  readonly dt: number;
  get tick(): number;
  get bodyCount(): number;
  addBody(desc: BodyDesc): BodyId;
  addStaticBox(halfExtents: Vec3, position: Vec3, opts?: Omit<BodyDesc, "type" | "shape" | "position">): BodyId;
  addTrigger(shape: ShapeDesc, position: Vec3, opts?: Omit<BodyDesc, "type" | "shape" | "position" | "sensor">): BodyId;
  removeBody(id: BodyId): void;
  has(id: BodyId): boolean;
  userData(id: BodyId): number;
  bodyType(id: BodyId): BodyType;
  bodyIds(): BodyId[];
  position(id: BodyId): Vec3;
  rotation(id: BodyId): Quat;
  velocity(id: BodyId): Vec3;
  angularVelocity(id: BodyId): Vec3;
  mass(id: BodyId): number;
  setPosition(id: BodyId, p: Vec3): void;
  setRotation(id: BodyId, q: Quat): void;
  setLinearVelocity(id: BodyId, v: Vec3): void;
  setAngularVelocity(id: BodyId, v: Vec3): void;
  applyImpulse(id: BodyId, impulse: Vec3): void;
  applyForce(id: BodyId, force: Vec3): void;
  applyKnockback(id: BodyId, from: Vec3, strength: number, opts?: KnockbackOptions): void;
  setKinematicTarget(id: BodyId, p: Vec3, q?: Quat): void;
  wake(id: BodyId): void;
  sleep(id: BodyId): void;
  isSleeping(id: BodyId): boolean;
  addJoint(desc: JointDesc): JointId;
  removeJoint(id: JointId): void;
  addCharacter(desc: CharacterDesc): BodyId;
  characterState(id: BodyId): CharacterState;
  setCharacterState(id: BodyId, s: CharacterState): void;
  isCharacter(id: BodyId): boolean;
  step(inputs?: ReadonlyMap<BodyId, CharacterInput>): PhysicsStepResult;
  raycast(origin: Vec3, dir: Vec3, maxDist: number, opts?: QueryOptions): RayHit | null;
  raycastAll(origin: Vec3, dir: Vec3, maxDist: number, opts?: QueryOptions): RayHit[];
  shapeCast(shape: ShapeDesc, from: Vec3, dir: Vec3, maxDist: number, opts?: QueryOptions & { rotation?: Quat; }): ShapeHit | null;
  overlap(shape: ShapeDesc, position: Vec3, opts?: QueryOptions & { rotation?: Quat; }): BodyId[];
  // ... 5 more lines in the source

Source: packages/engine-sim/src/physics/world.ts

Constants

ALL_LAYERS

Every layer (the default mask).

const ALL_LAYERS: 65535;

Source: packages/engine-sim/src/physics/layers.ts

ARENA_BOLT_RADIUS

Projectile hit radius, m, and the height projectiles fly at.

const ARENA_BOLT_RADIUS: 0.2;

Source: packages/engine-sim/src/arena.ts

ARENA_HITBOX_PAD

Extra reach of a player's hitbox over their capsule radius, m (beams and the rewind buffer).

const ARENA_HITBOX_PAD: 0.2;

Source: packages/engine-sim/src/arena.ts

ARENA_SPAWN_CLEAR

A spawn never lands within this many metres of a living opponent when anywhere else is free, m.

const ARENA_SPAWN_CLEAR: 12;

Source: packages/engine-sim/src/arena.ts

BOT_PLAYER_BASE

Player ids from here up are server-side bots (seat fillers). They play through the same sim; their arena beams resolve in the sim, never through the room's lag compensation (a bot sees the present).

const BOT_PLAYER_BASE: 65280;

Source: packages/engine-sim/src/api.ts

Button

Input button bits. Games may use bits 8..15 for their own actions.

const Button: { readonly Jump: number; readonly Fire: number; readonly Alt: number; readonly Use: number; readonly Sprint: number; readonly Choice1: number; readonly Choice2: number; readonly Choice3: number; readonly Reroll: number; readonly Skip: number; readonly Ready: number; };

Source: packages/engine-sim/src/api.ts

DEFAULT_ARENA

const DEFAULT_ARENA: ArenaConfig;

Source: packages/engine-sim/src/config.ts

DEFAULT_ARENA_RULES

const DEFAULT_ARENA_RULES: ArenaRules;

Source: packages/engine-sim/src/config.ts

DEFAULT_COOP

const DEFAULT_COOP: CoopRules;

Source: packages/engine-sim/src/config.ts

DEFAULT_ENEMIES

const DEFAULT_ENEMIES: EnemyRules;

Source: packages/engine-sim/src/config.ts

DEFAULT_KART_TUNING

const DEFAULT_KART_TUNING: KartTuning;

Source: packages/engine-sim/src/kart.ts

DEFAULT_PLATFORM_TUNING

const DEFAULT_PLATFORM_TUNING: PlatformTuning;

Source: packages/engine-sim/src/platform.ts

DEFAULT_PLAYER

const DEFAULT_PLAYER: PlayerRules;

Source: packages/engine-sim/src/config.ts

DEFAULT_PROGRESSION

const DEFAULT_PROGRESSION: ProgressionRules;

Source: packages/engine-sim/src/config.ts

DEFAULT_TICK_RATE

Default fixed tick rate in Hz (spec: 30 Hz default, 60 for shooters).

const DEFAULT_TICK_RATE: 30;

Source: packages/engine-sim/src/api.ts

DEFAULT_VIEW

Default view: a 22 m circle (games compile their camera's real footprint into this).

const DEFAULT_VIEW: ViewRules;

Source: packages/engine-sim/src/config.ts

EntityFlag

Per-entity state flag bits (EntityState.flags).

const EntityFlag: { readonly Grounded: number; readonly Dead: number; readonly Downed: number; readonly Dashing: number; readonly Solo: number; readonly Shielded: number; readonly Elite: number; readonly Hostile: number; };

Source: packages/engine-sim/src/api.ts

EntityKind

Entity kinds carried in snapshots.

const EntityKind: { readonly Player: 1; readonly Enemy: 2; readonly Projectile: 3; readonly Pickup: 4; };

Source: packages/engine-sim/src/api.ts

INPUT_BYTES

Bytes per encoded InputCommand.

const INPUT_BYTES: 15;

Source: packages/engine-sim/src/api.ts

KART_COIN_CAP

Coins held that raise top speed, and how much each adds.

const KART_COIN_CAP: 10;

Source: packages/engine-sim/src/kart.ts

KART_COIN_SPEED

const KART_COIN_SPEED: 0.01;

Source: packages/engine-sim/src/kart.ts

KART_MAX_COINS

const KART_MAX_COINS: 62;

Source: packages/engine-sim/src/kart.ts

KART_RADIUS

Kart body radius for bumps, m.

const KART_RADIUS: 0.9;

Source: packages/engine-sim/src/kart.ts

KART_STAT_DOC

const KART_STAT_DOC: Readonly<Record<"magnet" | "speed" | "armor" | "might" | "haste", string>>;

Source: packages/engine-sim/src/kart.ts

KART_STATS

Upgrade stats a kart can carry (4 bits each in stats).

const KART_STATS: readonly ["speed", "haste", "might", "armor", "magnet"];

Source: packages/engine-sim/src/kart.ts

KartFlag

const KartFlag: { readonly Drifting: number; readonly DriftRight: number; readonly OnGrass: number; readonly Finished: number; readonly Frozen: number; readonly Bot: number; readonly Bumped: number; readonly Boosting: number; };

Source: packages/engine-sim/src/kart.ts

KEEPER_MASK

const KEEPER_MASK: number;

Source: packages/engine-sim/src/api.ts

KEEPER_SHIFT

Keeper (character) choice rides input bits 11..14 as index + 1 (0: no choice). It is held, not pressed: the sim takes it while the keeper is still level 1 with nothing pending (the start of a run), so a client keeps sending its pick and it lands on the first tick of every run.

const KEEPER_SHIFT: 11;

Source: packages/engine-sim/src/api.ts

Layer

Collision layers. Every body is on exactly one layer and carries a mask of the layers it collides with. Rapier's rule is pairwise: two bodies touch only when EACH one's mask contains the other's layer, so both sides of a pair must agree (a projectile that wants to hit enemies needs Enemy in its mask, and enemies need Projectile in theirs). Queries (raycasts, shape casts, overlaps) only look at the layers in the query's mask.

const Layer: { readonly Level: number; readonly Player: number; readonly Enemy: number; readonly Projectile: number; readonly Pickup: number; readonly Prop: number; readonly Trigger: number; readonly Debris: number; readonly User1: number; readonly User2: number; readonly User3: number; readonly User4: number; readonly User5: number; readonly User6: number; readonly User7: number; readonly User8: number; };

Source: packages/engine-sim/src/physics/layers.ts

META_MAX_PER_STAT

Hard ceilings on a meta bonus, whatever a caller passes: +15% per stat, +30% across stats.

const META_MAX_PER_STAT: 0.15;

Source: packages/engine-sim/src/control.ts

META_MAX_TOTAL

const META_MAX_TOTAL: 0.3;

Source: packages/engine-sim/src/control.ts

METEOR_FALL_SECONDS

Seconds a meteor's circle shows before it lands.

const METEOR_FALL_SECONDS: 0.6;

Source: packages/engine-sim/src/weapons.ts

ORBIT_BLADE_RADIUS

Orbit blade hit radius, m.

const ORBIT_BLADE_RADIUS: 0.45;

Source: packages/engine-sim/src/content.ts

ORBIT_HIT_EVERY

Ticks between hits from one orbit blade on one enemy.

const ORBIT_HIT_EVERY: 8;

Source: packages/engine-sim/src/content.ts

PICKUP_SPECIAL

Pickup entity types from here up are special pickups (index = type - PICKUP_SPECIAL).

const PICKUP_SPECIAL: 16;

Source: packages/engine-sim/src/api.ts

PLAT_HALF_W

Half width and height of the body box (feet at y).

const PLAT_HALF_W: 0.34;

Source: packages/engine-sim/src/platform.ts

PLAT_HEIGHT

const PLAT_HEIGHT: 1.4;

Source: packages/engine-sim/src/platform.ts

PLAT_MAX_COINS

Most coins a level holds (two u31 masks).

const PLAT_MAX_COINS: 62;

Source: packages/engine-sim/src/platform.ts

PLAT_STAT_DOC

What one level of each stat does (the declared upgrade's step scales it).

const PLAT_STAT_DOC: Readonly<Record<"magnet" | "speed" | "amount" | "maxHealth" | "haste", string>>;

Source: packages/engine-sim/src/platform.ts

PLAT_STATS

Upgrade stats a platformer player can carry (4 bits each in stats).

const PLAT_STATS: readonly ["speed", "amount", "magnet", "maxHealth", "haste"];

Source: packages/engine-sim/src/platform.ts

PlatFlag

Player flags (u16 on the wire).

const PlatFlag: { readonly Grounded: number; readonly FacingLeft: number; readonly Rising: number; readonly Dead: number; readonly Finished: number; readonly Frozen: number; readonly DashReady: number; readonly Bot: number; readonly OnMover: number; };

Source: packages/engine-sim/src/platform.ts

POSITION_SCALE

Fixed-point units per metre for positions in state and snapshots.

const POSITION_SCALE: 1024;

Source: packages/engine-sim/src/api.ts

ROLE_DEFAULTS

Defaults per role (seconds and metres are converted at use).

const ROLE_DEFAULTS: { readonly runner: { readonly lead: 0.5; }; readonly charger: { readonly range: 6; readonly windup: 0.55; readonly act: 0.6; readonly recover: 1; readonly cooldown: 2.5; readonly speed: 3.4; }; readonly ranged: { readonly range: 10; readonly windup: 0.3; readonly cooldown: 2.6; readonly speed: 7; }; readonly bomber: { readonly range: 1.8; readonly windup: 1; readonly radius: 2.5; readonly damage: 1.4; }; readonly shielder: { readonly cooldown: 6; readonly windup: 0.8; readonly radius: 8; readonly count: 6; readonly share: 0.35; readonly seconds: 8; }; readonly healer: { readonly cooldown: 3.5; /* ... */;

Source: packages/engine-sim/src/roles.ts

SNAPSHOT_VERSION

Snapshot wire format version (first byte after the magic).

const SNAPSHOT_VERSION: 2;

Source: packages/engine-sim/src/api.ts

Telegraph

Enemy telegraph word (EntityState.level on enemies and hostile projectiles; it rides snapshots): kind in bits 0-2, fill progress 0..31 in bits 3-7, and an angle (lanes, 256 steps of a turn) or a radius (circles, in 0.1 m) in bits 8-15.

const Telegraph: { readonly None: 0; readonly Circle: 1; readonly Lane: 2; readonly Aura: 3; };

Source: packages/engine-sim/src/api.ts

VELOCITY_SCALE

Fixed-point units per metre/second for velocities.

const VELOCITY_SCALE: 1024;

Source: packages/engine-sim/src/api.ts

YAW_UNITS

Yaw is a u16 turn: 65536 units per full revolution.

const YAW_UNITS: 65536;

Source: packages/engine-sim/src/api.ts

Types

ArenaConfig

The static level. Part of the world's config, never of a snapshot.

interface ArenaConfig {
  readonly halfExtent: number;
  readonly wallHeight: number;
  readonly pillars: readonly Pillar[];
  readonly walls?: readonly WallBox[];
  readonly floors?: readonly WallBox[];
  readonly spawn: Vec3;
}

Source: packages/engine-sim/src/api.ts

ArenaHitbox

What the rewind buffer records each tick: living players and enemies.

interface ArenaHitbox {
  readonly netId: NetId;
  readonly owner: PlayerId;
  readonly x: number;
  readonly z: number;
  readonly r: number;
}

Source: packages/engine-sim/src/arena.ts

ArenaRules

Arena (shooter) mode: players aim with yaw and move in the world frame, fire their selected loadout weapon on Button.Fire, hurt each other, die and respawn at the spawn point farthest from their opponents.

interface ArenaRules {
  readonly enabled: boolean;
  readonly authority: boolean;
  readonly externalHitscan: boolean;
  readonly respawnTicks: number;
  readonly spawnIframeTicks: number;
  readonly spawns: readonly (readonly [number, number])[];
  readonly dropHeal: number;
  readonly pickupTicks: number;
}

Source: packages/engine-sim/src/api.ts

BeamShot

A human's beam this tick, for the room's rewind.

interface BeamShot {
  readonly shooter: PlayerId;
  readonly x: number;
  readonly z: number;
  readonly dx: number;
  readonly dz: number;
  readonly range: number;
  readonly damage: number;
  readonly knockback: number;
}

Source: packages/engine-sim/src/arena.ts

BodyDesc

interface BodyDesc {
  readonly type: BodyType;
  readonly shape: ShapeDesc;
  readonly position?: Vec3;
  readonly rotation?: Quat;
  readonly mass?: number;
  readonly density?: number;
  readonly friction?: number;
  readonly restitution?: number;
  readonly linearDamping?: number;
  readonly angularDamping?: number;
  readonly gravityScale?: number;
  readonly layer?: number;
  readonly mask?: number;
  readonly sensor?: boolean;
  readonly ccd?: boolean;
  readonly lockRotations?: boolean;
  readonly linearVelocity?: Vec3;
  readonly angularVelocity?: Vec3;
  readonly userData?: number;
}

Source: packages/engine-sim/src/physics/types.ts

BodyId

A stable id for one body in a PhysicsWorld (u32, assigned in creation order, never reused).

type BodyId = number;

Source: packages/engine-sim/src/physics/types.ts

BodyType

type BodyType = "dynamic" | "kinematic" | "static";

Source: packages/engine-sim/src/physics/types.ts

BossAttack

What a boss can do. Each is telegraphed before it lands.

type BossAttack = "slam" | "dash" | "leap" | "rain" | "ring" | "fan" | "summon";

Source: packages/engine-sim/src/api.ts

BossPattern

interface BossPattern {
  readonly attacks: readonly BossAttack[];
  readonly enrageAt: number;
  readonly summon?: number;
  readonly mini?: boolean;
}

Source: packages/engine-sim/src/api.ts

ButtonBit

type ButtonBit = (typeof Button)[keyof typeof Button];

Source: packages/engine-sim/src/api.ts

CharacterDef

A playable character: its start weapon and a signature passive at level 1. Clients draw it from its index (Player value bits 12..15).

interface CharacterDef {
  readonly weapon: number;
  readonly stat: number;
}

Source: packages/engine-sim/src/api.ts

CharacterDesc

A kinematic character (capsule on Rapier's character controller). All fields optional except where noted.

interface CharacterDesc {
  readonly position: Vec3;
  readonly radius?: number;
  readonly halfHeight?: number;
  readonly layer?: number;
  readonly mask?: number;
  readonly offset?: number;
  readonly maxSlopeClimb?: number;
  readonly minSlopeSlide?: number;
  readonly stepHeight?: number;
  readonly stepWidth?: number;
  readonly stepOverDynamic?: boolean;
  readonly snapToGround?: number;
  readonly maxSpeed?: number;
  readonly groundAccel?: number;
  readonly groundDecel?: number;
  readonly airAccel?: number;
  readonly airDecel?: number;
  readonly jumpVelocity?: number;
  readonly jumpCut?: number;
  readonly gravityScale?: number;
  readonly terminalVelocity?: number;
  readonly coyoteTicks?: number;
  readonly jumpBufferTicks?: number;
  readonly dashTicks?: number;
  readonly dashSpeed?: number;
  readonly dashCooldownTicks?: number;
  readonly dashBufferTicks?: number;
  readonly dashInvulnerable?: boolean;
  readonly pushBodies?: boolean;
  readonly mass?: number;
  readonly userData?: number;
}

Source: packages/engine-sim/src/physics/types.ts

CharacterInput

One tick of character input. Move is in world space (x right, z toward the camera), -1..1.

interface CharacterInput {
  readonly moveX: number;
  readonly moveZ: number;
  readonly jump?: boolean;
  readonly dash?: boolean;
}

Source: packages/engine-sim/src/physics/types.ts

CharacterReport

interface CharacterReport {
  readonly id: BodyId;
  readonly grounded: boolean;
  readonly landed: boolean;
  readonly jumped: boolean;
  readonly dashed: boolean;
  readonly hitCeiling: boolean;
  readonly groundNormal: Vec3;
}

Source: packages/engine-sim/src/physics/types.ts

CharacterState

A character's whole motor state: plain numbers, serialized in snapshots.

interface CharacterState {
  x: number;
  y: number;
  z: number;
  vx: number;
  vy: number;
  vz: number;
  grounded: boolean;
  coyote: number;
  jumpBuffer: number;
  jumping: boolean;
  dashTicks: number;
  dashCooldown: number;
  dashBuffer: number;
  dashX: number;
  dashZ: number;
  facingX: number;
  facingZ: number;
  invulnerable: boolean;
  buttons: number;
  groundNormalX: number;
  groundNormalY: number;
  groundNormalZ: number;
}

Source: packages/engine-sim/src/physics/types.ts

ContentConfig

Game content: when weapons is non-empty the world runs in content mode (auto-firing weapons, XP gems, level-ups, co-op downed and revive, dash) instead of the week-2 arena rules (Fire = pulse, respawn on death).

interface ContentConfig {
  readonly enemyTypes?: readonly EnemyTypeDef[];
  readonly weapons?: readonly WeaponDef[];
  readonly stats?: readonly StatDef[];
  readonly progression?: Partial<ProgressionRules>;
  readonly coop?: Partial<CoopRules>;
  readonly arena?: Partial<ArenaRules>;
  readonly view?: ViewRules;
  readonly pickups?: readonly PickupTypeDef[];
  readonly loot?: { readonly chest: number; readonly heal: number; readonly vacuum: number; readonly bossChest?: number };
  readonly mergeGemsAbove?: number;
  readonly characters?: readonly CharacterDef[];
}

Source: packages/engine-sim/src/api.ts

CoopRules

interface CoopRules {
  readonly downedTicks: number;
  readonly reviveTicks: number;
  readonly reviveRadius: number;
  readonly reviveHealth: number;
  readonly iframeTicks: number;
  readonly corpseTicks: number;
  readonly dashTicks: number;
  readonly dashSpeed: number;
  readonly dashCooldownTicks: number;
  readonly dashBufferTicks: number;
  readonly hitIframeTicks: number;
  readonly pauseSolo: boolean;
  readonly soloFromFlag: boolean;
  readonly choicePulseRadius: number;
  readonly choicePulseIframeTicks: number;
  readonly reviveBuffTicks: number;
  readonly reviveBuffMight: number;
  readonly reviveBuffSpeed: number;
  readonly crawlSpeed: number;
  readonly selfRevives: number;
  readonly selfReviveDelayTicks: number;
  readonly respawnTicks: number;
  readonly risePulseRadius: number;
}

Source: packages/engine-sim/src/api.ts

EdgeSpawnOptions

interface EdgeSpawnOptions {
  readonly heading?: number;
  readonly spread?: number;
  readonly margin?: number;
  readonly radius?: number;
  readonly relative?: "ahead" | "behind";
}

Source: packages/engine-sim/src/control.ts

EnemyAi

Enemy behaviours the sim runs (content mode).

type EnemyAi =
  | "chase"
  | "idle"
  | "runner"
  | "charger"
  | "ranged"
  | "bomber"
  | "shielder"
  | "healer"
  | "summoner"
  | "flee"
  | "wander";

Source: packages/engine-sim/src/api.ts

EnemyAttack

Attack numbers for an enemy role. Every field is optional; the role's defaults (roles.ts ROLE_DEFAULTS) fill the rest. Seconds and metres.

interface EnemyAttack {
  readonly damage?: number;
  readonly range?: number;
  readonly windupTicks?: number;
  readonly cooldownTicks?: number;
  readonly speed?: number;
  readonly radius?: number;
  readonly summon?: number;
  readonly count?: number;
}

Source: packages/engine-sim/src/api.ts

EnemyRules

interface EnemyRules {
  readonly target: number;
  readonly spawnPerTick: number;
  readonly spawnRadius: number;
  readonly speed: number;
  readonly radius: number;
  readonly maxHealth: number;
  readonly contactDamage: number;
  readonly contactCooldownTicks: number;
}

Source: packages/engine-sim/src/api.ts

EnemyTypeDef

One enemy prefab, compiled from the game API (prefab(...)). Enemy type 0 is always the arena's EnemyRules (the built-in target spawner uses it).

interface EnemyTypeDef {
  readonly health: number;
  readonly speed: number;
  readonly radius: number;
  readonly damage: number;
  readonly xp: number;
  readonly boss?: boolean;
  readonly mass?: number;
  readonly ai?: EnemyAi;
  readonly attack?: EnemyAttack;
  readonly split?: { readonly type: number; readonly count: number };
  readonly pattern?: BossPattern;
  readonly drops?: readonly { readonly pickup: number; readonly chance: number }[];
  readonly prop?: boolean;
}

Source: packages/engine-sim/src/api.ts

EntityKindId

type EntityKindId = (typeof EntityKind)[keyof typeof EntityKind];

Source: packages/engine-sim/src/api.ts

EntityState

One entity's networked state. Every field is an integer: positions and velocities in fixed point (POSITION_SCALE, VELOCITY_SCALE), yaw as a u16 turn. The sim keeps its own state on this grid at every tick boundary, so capture → apply is lossless.

interface EntityState {
  netId: NetId;
  kind: EntityKindId;
  owner: PlayerId;
  px: number;
  py: number;
  pz: number;
  vx: number;
  vy: number;
  vz: number;
  yaw: number;
  health: number;
  flags: number;
  ack: number;
  cooldown: number;
  buttons: number;
  timers: number;
  type: number;
  value: number;
  level: number;
  xp: number;
  weapons: number;
  wcd: number;
  stats: number;
  choices: number;
  bleed: number;
  revive: number;
  iframes: number;
  dash: number;
}

Source: packages/engine-sim/src/api.ts

HitSource

What dealt a hit to a player. Everything but "contact" was telegraphed first.

type HitSource = "contact" | "charge" | "blast" | "projectile" | "slam" | "hazard";

Source: packages/engine-sim/src/api.ts

InputCommand

One player's input for one tick. Serializable and sequence-numbered.

The sim quantizes every command on entry (quantizeInput), so a client's prediction and the server's authority consume bit-identical inputs. Wire size: 15 bytes (INPUT_BYTES).

interface InputCommand {
  seq: number;
  tick: number;
  moveX: number;
  moveZ: number;
  yaw: number;
  buttons: number;
}

Source: packages/engine-sim/src/api.ts

JointDesc

interface JointDesc {
  readonly kind: JointKind;
  readonly a: BodyId;
  readonly b: BodyId;
  readonly anchorA?: Vec3;
  readonly anchorB?: Vec3;
  readonly axis?: Vec3;
}

Source: packages/engine-sim/src/physics/types.ts

JointId

A stable id for one joint.

type JointId = number;

Source: packages/engine-sim/src/physics/types.ts

JointKind

type JointKind = "fixed" | "ball" | "hinge" | "slider";

Source: packages/engine-sim/src/physics/types.ts

Kart

interface Kart {
  readonly id: number;
  x: number;
  z: number;
  yaw: number;
  vx: number;
  vz: number;
  flags: number;
  charge: number;
  boost: number;
  seg: number;
  lap: number;
  cps: number;
  coinsLo: number;
  coinsHi: number;
  finishTick: number;
  stats: number;
  cosmetic: number;
  slot: number;
  ack: number;
  held: number;
}

Source: packages/engine-sim/src/kart.ts

KartConfig

interface KartConfig {
  readonly tickRate: number;
  readonly tracks: readonly KartTrackDef[];
  readonly tuning?: Partial<KartTuning>;
  readonly statSteps?: readonly number[];
  readonly authority?: boolean;
}

Source: packages/engine-sim/src/kart.ts

KartEvent

type KartEvent =
  | { readonly type: "coin"; readonly kart: number; readonly index: number }
  | { readonly type: "lap"; readonly kart: number; readonly lap: number }
  | { readonly type: "finish"; readonly kart: number; readonly tick: number }
  | { readonly type: "turbo"; readonly kart: number; readonly tier: number }
  | { readonly type: "pad"; readonly kart: number }
  | { readonly type: "wall"; readonly kart: number; readonly speed: number }
  | { readonly type: "bump"; readonly kart: number; readonly other: number };

Source: packages/engine-sim/src/kart.ts

KartStat

type KartStat = (typeof KART_STATS)[number];

Source: packages/engine-sim/src/kart.ts

KartTrack

A track, sampled.

interface KartTrack {
  readonly def: KartTrackDef;
  readonly x: Float64Array;
  readonly z: Float64Array;
  readonly tx: Float64Array;
  readonly tz: Float64Array;
  readonly dist: Float64Array;
  readonly length: number;
  readonly count: number;
  readonly half: number;
  readonly wall: number;
  readonly pads: readonly { readonly x: number; readonly z: number; readonly tx: number; readonly tz: number }[];
  readonly coinAt: readonly (readonly [number, number])[];
  readonly grid: readonly (readonly [number, number, number])[];
}

Source: packages/engine-sim/src/kart.ts

KartTrackDef

interface KartTrackDef {
  readonly points: readonly (readonly [number, number])[];
  readonly width: number;
  readonly laps: number;
  readonly boosts: readonly (readonly [number, number])[];
  readonly coins: readonly (readonly [number, number])[];
  readonly verge?: number;
}

Source: packages/engine-sim/src/kart.ts

KartTuning

interface KartTuning {
  readonly topSpeed: number;
  readonly accel: number;
  readonly brake: number;
  readonly drag: number;
  readonly turn: number;
  readonly grip: number;
  readonly driftGrip: number;
  readonly grass: number;
  readonly boostSpeed: number;
  readonly turbo: readonly [number, number, number];
  readonly turboAt: readonly [number, number, number];
  readonly padSeconds: number;
  readonly coinRadius: number;
}

Source: packages/engine-sim/src/kart.ts

KartWire

Integer wire state of one kart.

interface KartWire {
  readonly id: number;
  readonly x: number;
  readonly z: number;
  readonly yaw: number;
  readonly vx: number;
  readonly vz: number;
  readonly flags: number;
  readonly timers: number;
  readonly track: number;
  readonly coinsLo: number;
  readonly coinsHi: number;
  readonly finishTick: number;
  readonly stats: number;
  readonly cosmetic: number;
  readonly clock: number;
}

Source: packages/engine-sim/src/kart.ts

KartWorld

interface KartWorld {
  readonly tickRate: number;
  readonly dt: number;
  readonly tracks: readonly KartTrack[];
  track: KartTrack;
  trackIndex: number;
  readonly tuning: KartTuning;
  readonly statSteps: readonly number[];
  readonly authority: boolean;
  tick: number;
  readonly karts: Map<number, Kart>;
}

Source: packages/engine-sim/src/kart.ts

KnockbackOptions

interface KnockbackOptions {
  readonly lift?: number;
  readonly byMass?: boolean;
}

Source: packages/engine-sim/src/physics/types.ts

LayerBit

One bit of Layer.

type LayerBit = (typeof Layer)[LayerName];

Source: packages/engine-sim/src/physics/layers.ts

LayerName

type LayerName = keyof typeof Layer;

Source: packages/engine-sim/src/physics/layers.ts

MetaBonus

A player's permanent stat bonus from meta upgrades bought with coins (opt-in per game). Fractions: 0.05 is +5%. speed, might and area multiply; haste cuts cooldowns; maxHealth and magnet add that fraction of the base value.

interface MetaBonus {
  speed: number;
  maxHealth: number;
  magnet: number;
  might: number;
  haste: number;
  area: number;
}

Source: packages/engine-sim/src/world.ts

NetId

A stable network id for one entity (u32, never reused within a world). 0 means "none". Snapshots are keyed by NetId, never by ECS entity id.

type NetId = number;

Source: packages/engine-sim/src/api.ts

PhysicsEvent

A contact or trigger change during one step. a < b; for triggers one of them is the sensor.

interface PhysicsEvent {
  readonly type: PhysicsEventType;
  readonly a: BodyId;
  readonly b: BodyId;
}

Source: packages/engine-sim/src/physics/types.ts

PhysicsEventType

type PhysicsEventType = "contact.start" | "contact.end" | "trigger.enter" | "trigger.exit";

Source: packages/engine-sim/src/physics/types.ts

PhysicsOptions

interface PhysicsOptions {
  readonly gravity?: Vec3;
  readonly tickRate?: number;
}

Source: packages/engine-sim/src/physics/world.ts

PhysicsStepResult

interface PhysicsStepResult {
  readonly tick: number;
  readonly events: readonly PhysicsEvent[];
  readonly characters: readonly CharacterReport[];
}

Source: packages/engine-sim/src/physics/types.ts

PickupEffect

What a special pickup does when a player collects it.

type PickupEffect = "heal" | "vacuum" | "bomb" | "chest";

Source: packages/engine-sim/src/api.ts

PickupTypeDef

A special pickup (content.pickups). Entities carry PICKUP_SPECIAL + index as their type; gem tiers stay 0..2.

  • heal: amount of max health (0..1) or hit points (above 1);
  • vacuum: every gem on the floor flies to the collector;
  • bomb: kills every non-boss enemy on the collector's screen;
  • chest: amount card picks (1-3; a ready evolution shows first).
interface PickupTypeDef {
  readonly effect: PickupEffect;
  readonly amount: number;
  readonly evolve?: boolean;
}

Source: packages/engine-sim/src/api.ts

Pillar

A cylindrical pillar in the arena (static collider).

interface Pillar {
  readonly x: number;
  readonly z: number;
  readonly radius: number;
  readonly height: number;
}

Source: packages/engine-sim/src/api.ts

PlatBox

An axis-aligned box: [x0, y0, x1, y1] in metres, x0 < x1, y0 < y1.

type PlatBox = readonly [number, number, number, number];

Source: packages/engine-sim/src/platform.ts

PlatformConfig

interface PlatformConfig {
  readonly tickRate: number;
  readonly levels: readonly PlatformLevel[];
  readonly tuning?: Partial<PlatformTuning>;
  readonly statSteps?: readonly number[];
}

Source: packages/engine-sim/src/platform.ts

PlatformEvent

type PlatformEvent =
  | { readonly type: "coin"; readonly player: number; readonly index: number }
  | { readonly type: "checkpoint"; readonly player: number; readonly index: number }
  | { readonly type: "finish"; readonly player: number; readonly tick: number }
  | { readonly type: "fell"; readonly player: number; readonly hazard: boolean }
  | { readonly type: "shield"; readonly player: number }
  | { readonly type: "jump"; readonly player: number; readonly air: boolean }
  | { readonly type: "land"; readonly player: number; readonly speed: number }
  | { readonly type: "spring"; readonly player: number }
  | { readonly type: "dash"; readonly player: number }
  | { readonly type: "respawn"; readonly player: number };

Source: packages/engine-sim/src/platform.ts

PlatformLevel

interface PlatformLevel {
  readonly start: readonly [number, number];
  readonly flag: readonly [number, number];
  readonly killY: number;
  readonly solids: readonly PlatBox[];
  readonly ledges: readonly PlatBox[];
  readonly hazards: readonly PlatBox[];
  readonly springs: readonly PlatformSpring[];
  readonly movers: readonly PlatformMover[];
  readonly coins: readonly (readonly [number, number])[];
  readonly checkpoints: readonly (readonly [number, number])[];
}

Source: packages/engine-sim/src/platform.ts

PlatformMover

interface PlatformMover {
  readonly box: PlatBox;
  readonly dx: number;
  readonly dy: number;
  readonly periodTicks: number;
  readonly phaseTicks: number;
}

Source: packages/engine-sim/src/platform.ts

PlatformPlayer

interface PlatformPlayer {
  readonly id: number;
  x: number;
  y: number;
  vx: number;
  vy: number;
  flags: number;
  coyote: number;
  buffer: number;
  airLeft: number;
  dashT: number;
  dashCd: number;
  drop: number;
  cp: number;
  coinsLo: number;
  coinsHi: number;
  finishTick: number;
  respawn: number;
  iframes: number;
  shield: number;
  stats: number;
  cosmetic: number;
  ack: number;
  held: number;
}

Source: packages/engine-sim/src/platform.ts

PlatformPlayerWire

Integer wire state of one player (positions and speeds in 1/1024).

interface PlatformPlayerWire {
  readonly id: number;
  readonly x: number;
  readonly y: number;
  readonly vx: number;
  readonly vy: number;
  readonly flags: number;
  readonly timers: number;
  readonly timers2: number;
  readonly cp: number;
  readonly coinsLo: number;
  readonly coinsHi: number;
  readonly finishTick: number;
  readonly stats: number;
  readonly cosmetic: number;
  readonly clock: number;
}

Source: packages/engine-sim/src/platform.ts

PlatformSpring

interface PlatformSpring {
  readonly x: number;
  readonly y: number;
  readonly power: number;
}

Source: packages/engine-sim/src/platform.ts

PlatformTuning

Motor numbers. Seconds become ticks at world creation.

interface PlatformTuning {
  readonly runSpeed: number;
  readonly groundAccel: number;
  readonly airAccel: number;
  readonly friction: number;
  readonly jumpHeight: number;
  readonly timeToApex: number;
  readonly fallGravity: number;
  readonly jumpCut: number;
  readonly apexHang: number;
  readonly apexWindow: number;
  readonly coyoteSeconds: number;
  readonly bufferSeconds: number;
  readonly terminal: number;
  readonly airJumps: number;
  readonly airJumpScale: number;
  readonly dashSpeed: number;
  readonly dashSeconds: number;
  readonly dashCooldown: number;
  readonly coinRadius: number;
  readonly respawnSeconds: number;
  readonly iframeSeconds: number;
}

Source: packages/engine-sim/src/platform.ts

PlatformWorld

interface PlatformWorld {
  readonly tickRate: number;
  readonly levels: readonly PlatformLevel[];
  level: PlatformLevel;
  levelIndex: number;
  readonly tuning: PlatformTuning;
  readonly motor: Motor;
  readonly statSteps: readonly number[];
  tick: number;
  readonly players: Map<number, PlatformPlayer>;
}

Source: packages/engine-sim/src/platform.ts

PlatStat

type PlatStat = (typeof PLAT_STATS)[number];

Source: packages/engine-sim/src/platform.ts

PlayerBuild

One player's build this run: weapons (with levels), passives, keeper, and damage per weapon index.

interface PlayerBuild {
  readonly keeper: number;
  readonly weapons: readonly { readonly index: number; readonly level: number }[];
  readonly stats: readonly { readonly index: number; readonly level: number }[];
  readonly damage: readonly number[];
}

Source: packages/engine-sim/src/control.ts

PlayerId

A player slot in a room, 1..65535. 0 means "no player".

type PlayerId = number;

Source: packages/engine-sim/src/api.ts

PlayerRules

interface PlayerRules {
  readonly speed: number;
  readonly sprintMultiplier: number;
  readonly jumpVelocity: number;
  readonly gravity: number;
  readonly radius: number;
  readonly halfHeight: number;
  readonly maxHealth: number;
  readonly pulseRadius: number;
  readonly pulseCooldownTicks: number;
  readonly jumpBufferTicks: number;
  readonly coyoteTicks: number;
}

Source: packages/engine-sim/src/api.ts

PlayerSummary

One player as game logic sees it (listPlayers).

interface PlayerSummary {
  readonly playerId: PlayerId;
  readonly netId: NetId;
  readonly x: number;
  readonly y: number;
  readonly z: number;
  readonly health: number;
  readonly maxHealth: number;
  readonly level: number;
  readonly up: boolean;
  readonly downed: boolean;
  readonly dead: boolean;
  readonly slot: number;
  readonly keeper: number;
  readonly buffed: boolean;
  readonly selfRevives: number;
}

Source: packages/engine-sim/src/api.ts

ProgressionRules

interface ProgressionRules {
  readonly xpBase: number;
  readonly xpGrowth: number;
  readonly magnet: number;
  readonly maxWeapons: number;
  readonly startWeapon: number;
  readonly maxPickups: number;
  readonly rerolls: number;
  readonly xpExponent: number;
  readonly loadout: readonly number[];
  readonly xpShare: XpShare;
  readonly critChance: number;
  readonly critMultiplier: number;
}

Source: packages/engine-sim/src/api.ts

Quat

Quaternion [x, y, z, w].

type Quat = readonly [x: number, y: number, z: number, w: number];

Source: packages/engine-sim/src/physics/types.ts

QueryOptions

interface QueryOptions {
  readonly mask?: number;
  readonly exclude?: readonly BodyId[];
  readonly includeSensors?: boolean;
}

Source: packages/engine-sim/src/physics/types.ts

RayHit

interface RayHit {
  readonly body: BodyId;
  readonly point: Vec3;
  readonly normal: Vec3;
  readonly distance: number;
}

Source: packages/engine-sim/src/physics/types.ts

RenderView

Dense, renderer-friendly arrays for the current tick, plus the previous tick's transform for interpolation (alpha from FixedStepper). Valid until the next step or applyState on the same world.

interface RenderView {
  readonly tick: number;
  readonly count: number;
  readonly netId: Uint32Array;
  readonly kind: Uint8Array;
  readonly owner: Uint16Array;
  readonly health: Uint16Array;
  readonly flags: Uint8Array;
  readonly x: Float32Array;
  readonly y: Float32Array;
  readonly z: Float32Array;
  readonly yaw: Float32Array;
  readonly prevX: Float32Array;
  readonly prevY: Float32Array;
  readonly prevZ: Float32Array;
  readonly prevYaw: Float32Array;
}

Source: packages/engine-sim/src/api.ts

ResolvedCharacterDesc

type ResolvedCharacterDesc = Required<Omit<CharacterDesc, "position">> & { readonly position: Vec3 };

Source: packages/engine-sim/src/physics/types.ts

ResolvedContent

interface ResolvedContent {
  readonly enabled: boolean;
  readonly enemyTypes: readonly EnemyTypeDef[];
  readonly weapons: readonly WeaponDef[];
  readonly stats: readonly StatDef[];
  readonly progression: ProgressionRules;
  readonly coop: CoopRules;
  readonly arena: ArenaRules;
  readonly view: ViewRules;
  readonly pickups: readonly PickupTypeDef[];
  readonly loot: { readonly chest: number; readonly heal: number; readonly vacuum: number; readonly bossChest?: number };
  readonly mergeGemsAbove: number;
  readonly characters: readonly CharacterDef[];
}

Source: packages/engine-sim/src/api.ts

ResolvedSimConfig

interface ResolvedSimConfig {
  readonly tickRate: number;
  readonly seed: number;
  readonly maxEntities: number;
  readonly arena: ArenaConfig;
  readonly player: PlayerRules;
  readonly enemies: EnemyRules;
  readonly content: ResolvedContent;
}

Source: packages/engine-sim/src/api.ts

Scaled

A weapon's numbers at a player's level, after passives.

interface Scaled {
  damage: number;
  cooldown: number;
  count: number;
  range: number;
  speed: number;
  pierce: number;
  knockback: number;
  spread: number;
}

Source: packages/engine-sim/src/weapons.ts

ShapeDesc

Collision shapes. Capsules and cylinders stand along +y.

type ShapeDesc =
  | { readonly box: Vec3 }
  | { readonly sphere: number }
  | { readonly capsule: readonly [halfHeight: number, radius: number] }
  | { readonly cylinder: readonly [halfHeight: number, radius: number] };

Source: packages/engine-sim/src/physics/types.ts

ShapeHit

interface ShapeHit {
  readonly body: BodyId;
  readonly distance: number;
  readonly point: Vec3;
  readonly normal: Vec3;
}

Source: packages/engine-sim/src/physics/types.ts

SimConfig

interface SimConfig {
  readonly tickRate?: number;
  readonly seed?: number;
  readonly maxEntities?: number;
  readonly arena?: Partial<ArenaConfig>;
  readonly player?: Partial<PlayerRules>;
  readonly enemies?: Partial<EnemyRules>;
  readonly content?: ContentConfig;
}

Source: packages/engine-sim/src/api.ts

SimEvent

Things that happened during one step, in the order they happened.

type SimEvent =
  | { readonly type: "player.joined"; readonly playerId: PlayerId; readonly netId: NetId }
  | { readonly type: "player.left"; readonly playerId: PlayerId; readonly netId: NetId }
  | {
      readonly type: "player.hit";
      readonly playerId: PlayerId;
      readonly netId: NetId;
      readonly by: NetId;
      readonly damage: number;
      readonly health: number;
      readonly source?: HitSource;
      readonly enemyType?: number;
    }
  | { readonly type: "player.died"; readonly playerId: PlayerId; readonly netId: NetId }
  | { readonly type: "player.killed"; readonly playerId: PlayerId; readonly netId: NetId; readonly by: PlayerId }
  | { readonly type: "player.shot"; readonly playerId: PlayerId; readonly netId: NetId; readonly slot: number }
  | { readonly type: "player.respawned"; readonly playerId: PlayerId; readonly netId: NetId }
  | { readonly type: "player.pulse"; readonly playerId: PlayerId; readonly netId: NetId }
  | {
      readonly type: "enemy.killed";
      readonly netId: NetId;
      readonly by: PlayerId;
      readonly enemyType: number;
      readonly boss: boolean;
      readonly elite?: boolean;
    }
  | { readonly type: "player.downed"; readonly playerId: PlayerId; readonly netId: NetId }
  | { readonly type: "player.revived"; readonly playerId: PlayerId; readonly netId: NetId; readonly by: PlayerId }
  | { readonly type: "player.levelup"; readonly playerId: PlayerId; readonly netId: NetId; readonly level: number }
  | { readonly type: "player.upgraded"; readonly playerId: PlayerId; readonly netId: NetId; readonly upgrade: number; readonly evolved?: boolean }
  | { readonly type: "player.collected"; readonly playerId: PlayerId; readonly netId: NetId; readonly effect: PickupEffect }
  | {
      readonly type: "entity.spawned";
      readonly netId: NetId;
      readonly kind: EntityKindId;
      readonly from?: NetId;
    }
  | { readonly type: "entity.removed"; readonly netId: NetId; readonly kind: EntityKindId };

Source: packages/engine-sim/src/api.ts

SimState

A whole world's networked state at one tick. Entities sorted by netId.

interface SimState {
  tick: number;
  rng: number;
  nextNetId: number;
  kills: number;
  entities: EntityState[];
}

Source: packages/engine-sim/src/api.ts

SimWorld

A simulation world. Opaque on purpose: callers read it through the functions in this package, never through ECS or Rapier handles.

interface SimWorld {
  readonly tick: number;
  readonly tickRate: number;
  readonly dt: number;
  readonly config: ResolvedSimConfig;
}

Source: packages/engine-sim/src/api.ts

SpawnScale

Per-spawn multipliers (the spawn director's difficulty curve and density compensation). Health and damage are rounded to integers on the entity.

interface SpawnScale {
  readonly health?: number;
  readonly damage?: number;
  readonly xp?: number;
  readonly elite?: boolean;
  readonly from?: number;
}

Source: packages/engine-sim/src/api.ts

StatDef

A passive upgrade. Per level: speed and might multiply by (1 + step x level), haste multiplies cooldowns by (1 - step x level) (floor 0.3), maxHealth and magnet add step x level, regen heals step x level per second, armor removes step x level from each contact hit (floor 1).

interface StatDef {
  readonly stat: StatKind;
  readonly step: number;
  readonly maxLevel: number;
}

Source: packages/engine-sim/src/api.ts

StatKind

type StatKind = "speed" | "maxHealth" | "magnet" | "might" | "haste" | "regen" | "armor" | "area" | "amount";

Source: packages/engine-sim/src/api.ts

StepperAdvance

Result of advancing a FixedStepper by wall-clock time.

interface StepperAdvance {
  readonly ticks: number;
  readonly alpha: number;
  readonly dropped: number;
}

Source: packages/engine-sim/src/api.ts

StepResult

interface StepResult {
  readonly tick: number;
  readonly events: readonly SimEvent[];
}

Source: packages/engine-sim/src/api.ts

TickInputs

The inputs for one tick, by player. A player with no entry this tick gets a neutral input (no move, no buttons, facing kept). A room server that wants "repeat last input on packet loss" passes the repeat explicitly.

type TickInputs = ReadonlyMap<PlayerId, InputCommand>;

Source: packages/engine-sim/src/api.ts

Vec3

A 3-vector in metres, y up.

type Vec3 = readonly [x: number, y: number, z: number];

Source: packages/engine-sim/src/api.ts

ViewRules

The visible ground around a player, as distances from the player to the edge of the screen at evenly spaced headings (index i is the heading 2pii/n, measured from +x toward +z). The spawn director spawns just outside it, and the playtest counts what is inside it as "on screen".

interface ViewRules {
  readonly radii: readonly number[];
}

Source: packages/engine-sim/src/api.ts

WallBox

An axis-aligned box standing on the floor, wallHeight tall: a dungeon's walls. Centre (x, z) and half sizes hx, hz in metres.

interface WallBox {
  readonly x: number;
  readonly z: number;
  readonly hx: number;
  readonly hz: number;
}

Source: packages/engine-sim/src/api.ts

WeaponDef

interface WeaponDef {
  readonly kind: WeaponKind;
  readonly damage: number;
  readonly cooldownTicks: number;
  readonly range: number;
  readonly count: number;
  readonly speed: number;
  readonly pierce: number;
  readonly knockback: number;
  readonly maxLevel: number;
  readonly spread?: number;
  readonly levels?: readonly WeaponLevelStats[];
  readonly blast?: number;
  readonly evolved?: boolean;
  readonly evolve?: { readonly into: number; readonly requires: number };
}

Source: packages/engine-sim/src/api.ts

WeaponKind

Weapon behaviours (content mode). Survivor weapons fire by themselves:

  • nova: a burst that hits every enemy within range, when one is in range.
  • bolt: count projectiles at the nearest enemy within range, moving at speed m/s, passing through pierce enemies.
  • orbit: count blades circling at range m and speed rad/s; each blade hits an enemy at most every 8 ticks. Arena weapons fire on Button.Fire along the player's aim (yaw):
  • blaster: count projectiles fanned over spread radians at speed m/s for range m.
  • beam: an instant hitscan to range m (stopped by pillars and walls); a room server resolves it with lag compensation.
  • nova (arena): a blast hitting every opponent within range m.
type WeaponKind = "nova" | "bolt" | "orbit" | "blaster" | "beam" | "cone" | "chain" | "aura" | "meteor" | "boomerang";

Source: packages/engine-sim/src/api.ts

WeaponLevelStats

A weapon's numbers at one level (absolute, before passives).

interface WeaponLevelStats {
  readonly damage: number;
  readonly cooldownTicks: number;
  readonly range: number;
  readonly count: number;
  readonly speed: number;
  readonly pierce: number;
  readonly knockback: number;
  readonly spread: number;
}

Source: packages/engine-sim/src/api.ts

XpShare

How a gem's XP is shared in co-op.

interface XpShare {
  readonly mode: "collector" | "nearby" | "all";
  readonly fraction: number;
  readonly radius: number;
}

Source: packages/engine-sim/src/api.ts