Skip to content

@aosengine/core ​

Classes ​

ModuleError ​

A module that could not be registered, initialised or found.

Extends ​

  • Error

Constructors ​

Constructor ​
ts
new ModuleError(
   moduleId, 
   message, 
   options?
): ModuleError;

Build a module error.

Parameters ​
ParameterTypeDescription
moduleIdstringModule or service id involved.
messagestringWhat went wrong.
options?ErrorOptionsStandard Error options, used to keep the cause.
Returns ​

ModuleError

Overrides ​
ts
Error.constructor

Properties ​

moduleId ​
ts
readonly moduleId: string;

The module or service id involved.


SceneGraph ​

Maps entity ids to scene objects.

Constructors ​

Constructor ​
ts
new SceneGraph(scene, name?): SceneGraph;

Build a scene graph and attach its root to the scene.

Parameters ​
ParameterTypeDefault valueDescription
sceneSceneundefinedScene to attach to.
namestring'aosengine:root'Name given to the root group, for debugging.
Returns ​

SceneGraph

Properties ​

root ​
ts
readonly root: Group;

Group every spawned object is parented under.

scene ​
ts
readonly scene: Scene;

The scene the root was added to.

Accessors ​

size ​
Get Signature ​
ts
get size(): number;

How many entities are in the graph.

Returns ​

number

The entity count.

Methods ​

despawn() ​
ts
despawn(id): boolean;

Remove an entity.

Children are re-parented to the root rather than removed with it, so a despawn cannot silently take a subtree the caller still tracks. Despawn them explicitly if that is what you want.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
Returns ​

boolean

True when the entity existed.

dispose() ​
ts
dispose(): void;

Remove every entity and detach the root from the scene.

Returns ​

void

get() ​
ts
get(id): Object3D<Object3DEventMap> | undefined;

Look up an entity's object.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
Returns ​

Object3D<Object3DEventMap> | undefined

The object, or undefined when the id is not spawned.

idOf() ​
ts
idOf(object): number;

The entity id an object was spawned under.

Parameters ​
ParameterTypeDescription
objectObject3DAny object in the graph.
Returns ​

number

The id, or 0 when the object was not spawned here.

ids() ​
ts
ids(): IterableIterator<number>;

Every spawned entity id, in insertion order.

Returns ​

IterableIterator<number>

An iterator over ids.

setParent() ​
ts
setParent(id, parentId?): void;

Re-parent an entity.

Parameters ​
ParameterTypeDefault valueDescription
idnumberundefinedEntity id to move.
parentIdnumberNO_ENTITYNew parent's entity id, or 0 for the root.
Returns ​

void

spawn() ​
ts
spawn(
   id, 
   object, 
   parentId?
): Object3D;

Add an object under an entity id.

Parameters ​
ParameterTypeDefault valueDescription
idnumberundefinedEntity id. Must be a positive integer; 0 is the root.
objectObject3DundefinedThe object to add.
parentIdnumberNO_ENTITYParent entity id, or 0 for the root.
Returns ​

Object3D

The object, so calls can be chained.

Example ​
ts
import { SceneGraph } from '@aosengine/core';
import { Group, Scene } from 'three/webgpu';

const graph = new SceneGraph(new Scene());
graph.spawn(1, new Group());
graph.spawn(2, new Group(), 1); // child of entity 1

TransformStore ​

Previous and current position, rotation and scale for a set of entity ids.

Constructors ​

Constructor ​
ts
new TransformStore(capacity?): TransformStore;

Build a transform store.

Parameters ​
ParameterTypeDefault valueDescription
capacitynumberDEFAULT_TRANSFORM_CAPACITYSlots to reserve up front.
Returns ​

TransformStore

Accessors ​

capacity ​
Get Signature ​
ts
get capacity(): number;

Slots currently allocated.

Returns ​

number

The number of addressable entity slots.

highWater ​
Get Signature ​
ts
get highWater(): number;

One past the highest slot ever written.

Returns ​

number

The bound commit scans to.

Methods ​

clear() ​
ts
clear(id): void;

Forget an entity. Its slot is reset to the identity transform.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
Returns ​

void

commit() ​
ts
commit(): void;

Make the current transform the previous one, for every slot that changed.

Call once per fixed step, before that step writes new values. Costs a byte per slot to scan plus ten floats per slot that actually moved.

Returns ​

void

ensure() ​
ts
ensure(id): void;

Grow so that id is addressable.

Capacity doubles until it fits, so a run of spawn calls is amortised O(1).

Parameters ​
ParameterTypeDescription
idnumberEntity id that must fit.
Returns ​

void

getPosition() ​
ts
getPosition(id, out): number[] | Float32Array<ArrayBufferLike>;

Read the current position into out.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
outnumber[] | Float32Array<ArrayBufferLike>A length-3 array to fill.
Returns ​

number[] | Float32Array<ArrayBufferLike>

out.

getQuaternion() ​
ts
getQuaternion(id, out): number[] | Float32Array<ArrayBufferLike>;

Read the current rotation into out.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
outnumber[] | Float32Array<ArrayBufferLike>A length-4 array to fill.
Returns ​

number[] | Float32Array<ArrayBufferLike>

out.

has() ​
ts
has(id): boolean;

Whether an entity has ever been written.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
Returns ​

boolean

True when the slot holds a transform.

isDirty() ​
ts
isDirty(id): boolean;

Whether an entity is mid-motion or still owes its object a write.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
Returns ​

boolean

True when the next writeInterpolated will touch the object.

set() ​
ts
set(
   id, 
   px, 
   py, 
   pz, 
   qx, 
   qy, 
   qz, 
   qw, 
   sx, 
   sy, 
   sz
): void;

Write a whole transform at once. This is the packed-buffer entry point.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
pxnumberPosition x.
pynumberPosition y.
pznumberPosition z.
qxnumberQuaternion x.
qynumberQuaternion y.
qznumberQuaternion z.
qwnumberQuaternion w.
sxnumberScale x.
synumberScale y.
sznumberScale z.
Returns ​

void

setPosition() ​
ts
setPosition(
   id, 
   x, 
   y, 
   z
): void;

Write the current position of an entity.

The first write to a slot also seeds the previous transform, so a freshly spawned entity does not interpolate in from the origin.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
xnumberPosition x.
ynumberPosition y.
znumberPosition z.
Returns ​

void

setQuaternion() ​
ts
setQuaternion(
   id, 
   x, 
   y, 
   z, 
   w
): void;

Write the current rotation of an entity.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
xnumberQuaternion x.
ynumberQuaternion y.
znumberQuaternion z.
wnumberQuaternion w.
Returns ​

void

setScale() ​
ts
setScale(
   id, 
   x, 
   y, 
   z
): void;

Write the current scale of an entity.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
xnumberScale x.
ynumberScale y.
znumberScale z.
Returns ​

void

snap() ​
ts
snap(id): void;

Collapse one entity's history, so the next frame does not interpolate.

Use after a teleport.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
Returns ​

void

writeInterpolated() ​
ts
writeInterpolated(
   id, 
   object, 
   alpha
): boolean;

Write the blend of previous and current onto an Object3D.

Once previous and current agree and the object has received that value, this returns without touching the object — and so without dirtying its world matrix — until the entity moves again.

Parameters ​
ParameterTypeDescription
idnumberEntity id.
objectObject3DTarget object; its position, quaternion and scale are written.
alphanumberInterpolation factor, normally the loop's alpha in [0, 1).
Returns ​

boolean

True when the entity existed, whether or not the object needed writing.

Interfaces ​

CreateEngineOptions ​

Options accepted by createEngine.

Properties ​

canvas ​
ts
readonly canvas: HTMLCanvasElement;

The canvas to render into. The engine observes it for size changes.

debug? ​
ts
readonly optional debug?: boolean;

Create the F3 debug overlay. Defaults to false.

dracoDecoderPath? ​
ts
readonly optional dracoDecoderPath?: string;

Draco decoder directory handed to the default gltf loader.

fixedHz? ​
ts
readonly optional fixedHz?: number;

Simulation rate. Defaults to 60.

ktx2TranscoderPath? ​
ts
readonly optional ktx2TranscoderPath?: string;

Basis transcoder directory handed to the default gltf loader.

loaders? ​
ts
readonly optional loaders?: Readonly<Record<string, AssetLoader>>;

Asset loaders, replacing the built-in gltf and audio pair.

Adding a type is engine.ctx.assets.registerLoader(...), not this.

manifest? ​
ts
readonly optional manifest?: string | object | AssetManifest;

The asset manifest: a URL to fetch, or an already-parsed document.

Omit for an engine with an empty registry, which is what the unit tests and the splat viewer use.

maxSubsteps? ​
ts
readonly optional maxSubsteps?: number;

Most fixed steps one frame may run. Defaults to 5.

modules? ​
ts
readonly optional modules?: readonly EngineModule[];

Modules to register, in any order; order decides the run order.

renderer? ​
ts
readonly optional renderer?: EngineRendererOptions;

Renderer options.


DebugOverlay ​

The debug overlay.

Properties ​

element ​
ts
readonly element: HTMLElement | null;

The panel element, or null when there is no DOM to mount into.

stats ​
ts
readonly stats: FrameStats;

The frame-time window behind the numbers.

visible ​
ts
readonly visible: boolean;

Whether the panel is currently shown.

Methods ​

dispose() ​
ts
dispose(): void;

Remove the panel and the key listener.

Returns ​

void

sample() ​
ts
sample(frameMs, nowMs): void;

Record a frame and, at most every intervalMs, redraw.

Parameters ​
ParameterTypeDescription
frameMsnumberHow long the frame took, in milliseconds.
nowMsnumberCurrent timestamp, in milliseconds.
Returns ​

void

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

Show or hide the panel.

Parameters ​
ParameterTypeDescription
valuebooleanTrue to show.
Returns ​

void

toggle() ​
ts
toggle(): void;

Flip visibility. This is what the hotkey does.

Returns ​

void


DebugOverlayOptions ​

Options accepted by createDebugOverlay.

Properties ​

backendName ​
ts
readonly backendName: string;

Backend label, for example webgpu or webgl.

container? ​
ts
readonly optional container?: HTMLElement;

Where to mount the panel. Defaults to document.body.

hotkey? ​
ts
readonly optional hotkey?: string;

KeyboardEvent.code that toggles visibility. Defaults to F3.

intervalMs? ​
ts
readonly optional intervalMs?: number;

How often the text is rewritten, in milliseconds. Defaults to 250.

renderer ​
ts
readonly renderer: WebGPURenderer;

Renderer whose info.render counters are shown.

samples? ​
ts
readonly optional samples?: number;

Frames in the percentile window. Defaults to 120.

visible? ​
ts
readonly optional visible?: boolean;

Whether the panel starts visible. Defaults to true.


Engine ​

A booted engine.

Properties ​

assets ​
ts
readonly assets: AssetRegistry;

The asset registry.

camera ​
ts
readonly camera: PerspectiveCamera;

The camera being rendered from.

ctx ​
ts
readonly ctx: EngineContext;

The module context, for code that is not a module.

events ​
ts
readonly events: Events<EngineEventMap>;

The engine event bus.

graph ​
ts
readonly graph: SceneGraph;

Entity-id to Object3D mapping, rooted in the scene.

loop ​
ts
readonly loop: FixedLoop;

The fixed-step loop.

modules ​
ts
readonly modules: ModuleRegistry;

The module registry.

overlay ​
ts
readonly overlay: DebugOverlay | null;

The debug overlay, when debug was set.

renderer ​
ts
readonly renderer: WebGPURenderer;

The initialised renderer.

running ​
ts
readonly running: boolean;

Whether the loop is running.

scene ​
ts
readonly scene: Scene;

The scene being rendered.

Methods ​

dispose() ​
ts
dispose(): Promise<void>;

Stop, dispose every module in reverse order, then the renderer.

Returns ​

Promise<void>

Resolves once the renderer has released its device.

get() ​
ts
get<K>(id): EngineServices[K];

Look up a module's service.

Type Parameters ​
Type Parameter
K extends "physics"
Parameters ​
ParameterTypeDescription
idKService id, typed through EngineServices.
Returns ​

EngineServices[K]

The service.

resize() ​
ts
resize(width, height): void;

Resize the drawing buffer and the camera.

Called automatically by the canvas ResizeObserver; call it yourself only when you manage the canvas size some other way.

Parameters ​
ParameterTypeDescription
widthnumberCSS width in pixels.
heightnumberCSS height in pixels.
Returns ​

void

start() ​
ts
start(): void;

Start the loop.

Returns ​

void

stop() ​
ts
stop(): void;

Stop the loop. Modules keep their resources; start resumes.

Returns ​

void


EngineCaps ​

What the host turned out to be able to do, decided once after renderer.init().

Properties ​

characters ​
ts
readonly characters: boolean;

True when splat characters can run.

Characters need compute shaders and a shared GPUDevice, so this tracks webgpu exactly. Check it before calling createCharacter.

webgpu ​
ts
readonly webgpu: boolean;

True when the renderer got a real WebGPU backend rather than the WebGL fallback.


EngineConfig ​

The engine options after defaults were applied.

Properties ​

antialias ​
ts
readonly antialias: boolean;

Whether MSAA was requested.

backend ​
ts
readonly backend: RendererBackend;

Backend that was requested (not necessarily the one that was obtained).

debug ​
ts
readonly debug: boolean;

Whether the debug overlay was created.

fixedDt ​
ts
readonly fixedDt: number;

Length of one fixed step, in seconds: 1 / fixedHz.

fixedHz ​
ts
readonly fixedHz: number;

Simulation rate in hertz.

maxSubsteps ​
ts
readonly maxSubsteps: number;

Most fixed steps one frame may run.

pixelRatioCap ​
ts
readonly pixelRatioCap: number;

Upper bound applied to devicePixelRatio.


EngineContext ​

Everything a module is given at init.

Properties ​

assets ​
ts
readonly assets: AssetRegistry;

The asset registry built from the manifest.

camera ​
ts
readonly camera: PerspectiveCamera;

The camera the engine renders with. Camera rigs drive this.

caps ​
ts
readonly caps: EngineCaps;

What this host can actually do.

config ​
ts
readonly config: EngineConfig;

The resolved engine options.

events ​
ts
readonly events: Events<EngineEventMap>;

The engine event bus.

renderer ​
ts
readonly renderer: WebGPURenderer;

The initialised renderer. Its backend.device is the one shared GPU device.

scene ​
ts
readonly scene: Scene;

The scene the engine renders.

time ​
ts
readonly time: Time;

The engine clock.

Methods ​

get() ​
ts
get<K>(id): EngineServices[K];

Look up another module's service.

Only valid after that module's init has run, which order controls.

Type Parameters ​
Type Parameter
K extends "physics"
Parameters ​
ParameterTypeDescription
idKService id.
Returns ​

EngineServices[K]

The service.

registerService() ​
ts
registerService(id, service): void;

Publish a service under an id, so other modules can get it.

Equivalent to returning the service from init; use this when a module exposes something before it has finished initialising, or exposes nothing but wants to register under a different id.

Parameters ​
ParameterTypeDescription
idstringService id, matching a key of EngineServices.
serviceobjectThe service object.
Returns ​

void


EngineEventMap ​

Events the engine itself publishes.

Other packages add their own by declaration merging, exactly as they do for EngineServices:

ts
declare module '@aosengine/core' {
  interface EngineEventMap {
    'physics:contact': { a: number; b: number };
  }
}

Properties ​

engine:frame ​
ts
engine:frame: object;

A frame finished, after rendering.

The payload object is reused every frame; read it in the handler and never retain it.

alpha ​
ts
alpha: number;
dtReal ​
ts
dtReal: number;
frame ​
ts
frame: number;
substeps ​
ts
substeps: number;
engine:resize ​
ts
engine:resize: object;

The drawing buffer changed size.

height ​
ts
height: number;
width ​
ts
width: number;
engine:start ​
ts
engine:start: undefined;

The loop has started.

engine:stop ​
ts
engine:stop: undefined;

The loop has stopped.


EngineModule ​

One host subsystem.

init runs once, in order. dispose runs in reverse order and must release everything the module took. The per-frame hooks are optional and are called only on the modules that implement them, so an empty hook costs nothing.

Nothing in beginFrame, fixedUpdate, update or endFrame may allocate: they run at least 60 times a second.

Extended by ​

Properties ​

id ​
ts
readonly id: string;

Unique id. Also the service id when init returns a service.

order? ​
ts
readonly optional order?: number;

Sort key. Lower runs first; equal keys keep registration order.

Rough convention: input -100, gameplay -50, physics 0, rendering helpers 200. Gameplay runs before physics so that the commands a guest tick emits are simulated by the step that follows rather than the next one.

Methods ​

beginFrame()? ​
ts
optional beginFrame(): void;

Run before the frame's fixed steps. Input capture lives here.

Returns ​

void

dispose() ​
ts
dispose(): void;

Release everything this module took.

Returns ​

void

endFrame()? ​
ts
optional endFrame(): void;

Run after rendering. Input's end-of-frame bookkeeping lives here.

Returns ​

void

fixedUpdate()? ​
ts
optional fixedUpdate(dt): void;

Run once per fixed step.

Parameters ​
ParameterTypeDescription
dtnumberAlways ctx.config.fixedDt, whatever time.timeScale is; time scale changes how many steps a frame runs, not their length.
Returns ​

void

init() ​
ts
init(ctx): void | object | Promise<void | object>;

Acquire resources.

Parameters ​
ParameterTypeDescription
ctxEngineContextThe host surface.
Returns ​

void | object | Promise<void | object>

Nothing, or the service to publish under id.

update()? ​
ts
optional update(dt, alpha): void;

Run once per frame, after the fixed steps and before rendering.

Parameters ​
ParameterTypeDescription
dtnumberClamped wall-clock seconds since the previous frame, scaled by time.timeScale.
alphanumberInterpolation factor in [0, 1) for smoothing transforms.
Returns ​

void


EngineRendererOptions ​

Renderer options accepted by createEngine.

Properties ​

antialias? ​
ts
readonly optional antialias?: boolean;

Request MSAA. Defaults to true.

backend? ​
ts
readonly optional backend?: RendererBackend;

Which backend to target.

auto takes WebGPU when the browser has it and falls back to WebGL otherwise. webgpu refuses to boot without it. webgl forces the fallback, which is useful for reproducing what a WebGL player sees — characters are unavailable there.

pixelRatioCap? ​
ts
readonly optional pixelRatioCap?: number;

Upper bound on devicePixelRatio. Defaults to 2.


Events ​

Typed pub/sub over the event map M.

Type Parameters ​

Type Parameter
M extends EventMap

Methods ​

clear() ​
ts
clear(): void;

Drop every handler.

Returns ​

void

emit() ​
ts
emit<K>(type, payload): void;

Publish an event.

Type Parameters ​
Type Parameter
K extends string | number | symbol
Parameters ​
ParameterTypeDescription
typeKEvent name.
payloadM[K]Payload, matching the map.
Returns ​

void

listenerCount() ​
ts
listenerCount(type): number;

How many handlers are subscribed to an event.

Parameters ​
ParameterTypeDescription
typekeyof MEvent name.
Returns ​

number

The live listener count.

off() ​
ts
off<K>(type, listener): void;

Unsubscribe a handler.

Type Parameters ​
Type Parameter
K extends string | number | symbol
Parameters ​
ParameterTypeDescription
typeKEvent name.
listenerListener<M[K]>The exact function passed to on.
Returns ​

void

on() ​
ts
on<K>(type, listener): () => void;

Subscribe to an event.

Type Parameters ​
Type Parameter
K extends string | number | symbol
Parameters ​
ParameterTypeDescription
typeKEvent name.
listenerListener<M[K]>Handler.
Returns ​

An unsubscribe function, so callers need not keep the reference.

() => void

once() ​
ts
once<K>(type, listener): () => void;

Subscribe to the next occurrence only.

Type Parameters ​
Type Parameter
K extends string | number | symbol
Parameters ​
ParameterTypeDescription
typeKEvent name.
listenerListener<M[K]>Handler.
Returns ​

An unsubscribe function.

() => void


FirstPersonRig ​

A first-person camera rig.

Properties ​

camera ​
ts
readonly camera: PerspectiveCamera;

The camera being driven.

eyeHeight ​
ts
eyeHeight: number;

Metres from the pose position up to the eyes. Writable: crouching changes it.

pitch ​
ts
readonly pitch: number;

Last applied pitch, in radians, after clamping.

yaw ​
ts
readonly yaw: number;

Last applied yaw, in radians.

Methods ​

setPose() ​
ts
setPose(
   position, 
   yaw, 
   pitch
): void;

Place the camera.

position is the body's position — feet, or capsule base — not the eyes; eyeHeight is added to y.

Parameters ​
ParameterTypeDescription
positionVector3LikeBody position in world space.
yawnumberRotation about world +Y, in radians. 0 looks down −Z.
pitchnumberRotation about the camera's local +X, in radians. Positive looks up.
Returns ​

void


FirstPersonRigOptions ​

Options accepted by createFirstPersonRig.

Properties ​

camera ​
ts
readonly camera: PerspectiveCamera;

The camera to drive.

eyeHeight? ​
ts
readonly optional eyeHeight?: number;

Metres from the given position up to the eyes. Defaults to 1.7.

maxPitch? ​
ts
readonly optional maxPitch?: number;

Pitch is clamped to plus or minus this, in radians.


FixedLoop ​

A driven fixed-step accumulator.

Properties ​

accumulator ​
ts
readonly accumulator: number;

Unconsumed simulation time, always in [0, fixedDt) after a step.

alpha ​
ts
readonly alpha: number;

Interpolation factor for the last frame, in [0, 1).

fixedDt ​
ts
readonly fixedDt: number;

Length of one fixed step, in seconds.

frame ​
ts
readonly frame: number;

Frames stepped so far.

maxSubsteps ​
ts
readonly maxSubsteps: number;

Most fixed steps one frame may run.

timeScale ​
ts
timeScale: number;

Simulation speed multiplier. 1 is real time, 0.5 is half speed, 0 pauses the simulation while frames keep rendering.

Scales how much simulation time a frame buys, not the step length: a fixed step is always fixedDt long, so physics and the game see the same dt at every speed and a recording replays at any speed. Negative values are treated as 0.

Methods ​

reset() ​
ts
reset(): void;

Forget the accumulator and the baseline timestamp.

Call after a long pause (tab hidden, breakpoint, level load) so the next step starts clean instead of clamping.

Returns ​

void

step() ​
ts
step(nowMs): FrameTiming;

Advance the loop to nowMs.

The very first call only establishes the baseline: dtReal is 0 and no fixed step runs, so a slow boot cannot manufacture a burst of simulation.

Parameters ​
ParameterTypeDescription
nowMsnumberA monotonic timestamp in milliseconds, usually from rAF.
Returns ​

FrameTiming

What this frame did. The same record every call; do not retain it.


FixedLoopOptions ​

Options accepted by createFixedLoop.

Properties ​

fixedDt? ​
ts
readonly optional fixedDt?: number;

Length of one fixed step, in seconds. Defaults to 1/60.

fixedUpdate? ​
ts
readonly optional fixedUpdate?: (dt) => void;

Run once per fixed step, always with exactly fixedDt.

Parameters ​
ParameterTypeDescription
dtnumberAlways fixedDt, whatever timeScale is.
Returns ​

void

maxSubsteps? ​
ts
readonly optional maxSubsteps?: number;

Most fixed steps one frame may run. Defaults to 5.

render? ​
ts
readonly optional render?: (alpha) => void;

Run once per frame, last.

Parameters ​
ParameterTypeDescription
alphanumberInterpolation factor in [0, 1).
Returns ​

void

update? ​
ts
readonly optional update?: (dtReal, alpha) => void;

Run once per frame, after the fixed steps.

Parameters ​
ParameterTypeDescription
dtRealnumberClamped wall-clock seconds since the previous frame. Not scaled by timeScale; presentation code decides for itself.
alphanumberInterpolation factor in [0, 1).
Returns ​

void


FrameStats ​

A rolling window of frame durations.

Properties ​

capacity ​
ts
readonly capacity: number;

Frames the window holds.

count ​
ts
readonly count: number;

Samples recorded so far, capped at capacity.

fps ​
ts
readonly fps: number;

Smoothed frames per second.

last ​
ts
readonly last: number;

Duration of the most recent frame, in milliseconds.

Methods ​

percentile() ​
ts
percentile(p): number;

A percentile of the window.

Parameters ​
ParameterTypeDescription
pnumberPercentile in [0, 1]; 0.5 is the median.
Returns ​

number

The frame time in milliseconds, or 0 before any sample.

push() ​
ts
push(frameMs): void;

Record one frame.

Parameters ​
ParameterTypeDescription
frameMsnumberHow long the frame took, in milliseconds.
Returns ​

void

reset() ​
ts
reset(): void;

Forget every sample.

Returns ​

void


FrameTiming ​

What a call to FixedLoop.step did.

The loop hands back the same record every frame. Read it before the next step; never retain it.

Properties ​

alpha ​
ts
readonly alpha: number;

Interpolation factor for rendering, always in [0, 1).

clamped ​
ts
readonly clamped: boolean;

True when time had to be thrown away to avoid a death spiral.

dtReal ​
ts
readonly dtReal: number;

Wall-clock seconds since the previous frame, after clamping.

rawDt ​
ts
readonly rawDt: number;

Wall-clock seconds since the previous frame, before clamping.

substeps ​
ts
readonly substeps: number;

Fixed steps run this frame, 0 to maxSubsteps.


ModuleRegistry ​

Holds modules, orders them, initialises them and takes them down again.

Properties ​

beginFrameHooks ​
ts
readonly beginFrameHooks: readonly EngineModule[];

Modules implementing beginFrame, in run order.

endFrameHooks ​
ts
readonly endFrameHooks: readonly EngineModule[];

Modules implementing endFrame, in run order.

fixedUpdateHooks ​
ts
readonly fixedUpdateHooks: readonly EngineModule[];

Modules implementing fixedUpdate, in run order.

modules ​
ts
readonly modules: readonly EngineModule[];

Registered modules in run order.

updateHooks ​
ts
readonly updateHooks: readonly EngineModule[];

Modules implementing update, in run order.

Methods ​

disposeAll() ​
ts
disposeAll(): void;

Dispose every initialised module in reverse order.

A throwing dispose is collected and rethrown at the end, so one bad module cannot strand the others.

Returns ​

void

get() ​
ts
get<K>(id): EngineServices[K];

Look up a service, typed through EngineServices.

Type Parameters ​
Type Parameter
K extends "physics"
Parameters ​
ParameterTypeDescription
idKService id.
Returns ​

EngineServices[K]

The service.

has() ​
ts
has(id): boolean;

Whether a service is registered under an id.

Parameters ​
ParameterTypeDescription
idstringService id.
Returns ​

boolean

True when get would succeed.

initAll() ​
ts
initAll(ctx): Promise<void>;

Initialise every module in order, awaiting each one.

Modules are initialised sequentially, not in parallel, because order is a dependency order: a module may ctx.get anything registered before it.

Parameters ​
ParameterTypeDescription
ctxEngineContextThe host surface.
Returns ​

Promise<void>

Resolves once every module has initialised.

register() ​
ts
register(module): void;

Add a module. Must happen before ModuleRegistry.initAll.

Parameters ​
ParameterTypeDescription
moduleEngineModuleThe module.
Returns ​

void

registerService() ​
ts
registerService(id, service): void;

Publish a service under an id.

Parameters ​
ParameterTypeDescription
idstringService id.
serviceobjectThe service object.
Returns ​

void

tryGet() ​
ts
tryGet(id): unknown;

Look up a service without the typed table.

The escape hatch for code that does not know the id at compile time, and for core itself, which must not know what modules exist.

Parameters ​
ParameterTypeDescription
idstringService id.
Returns ​

unknown

The service, or undefined when nothing is registered.


MutableTime ​

The engine's own handle on the clock: the same object, writable.

Extends ​

Properties ​

elapsed ​
ts
elapsed: number;

Scaled seconds simulated since start().

Overrides ​

Time.elapsed

fixedDt ​
ts
fixedDt: number;

Length of one fixed step, in seconds.

Overrides ​

Time.fixedDt

now ​
ts
now: number;

performance.now() of the current frame, in milliseconds.

Overrides ​

Time.now

renderFrame ​
ts
renderFrame: number;

Frames rendered since start(), starting at 0.

Rendered frames, not fixed steps: on a 144 Hz display this runs ahead of the simulation's own step counter, which the guest sees as its frame.

Overrides ​

Time.renderFrame

timeScale ​
ts
timeScale: number;

Simulation speed multiplier. 0 pauses, 0.5 is half speed.

Changes how many fixed steps a frame buys, never how long a step is: a fixed step is always fixedDt.

Inherited from ​

Time.timeScale


PatchableAdapterPrototype ​

The parts of GPUAdapter the patch touches.

Methods ​

requestDevice() ​
ts
requestDevice(descriptor?): Promise<GPUDevice>;

The method being wrapped.

Parameters ​
ParameterTypeDescription
descriptor?GPUDeviceDescriptorDevice descriptor, as the caller wrote it.
Returns ​

Promise<GPUDevice>

The requested device.


ThirdPersonRig ​

A third-person orbit camera with a collision-aware spring arm.

Properties ​

actualDistance ​
ts
readonly actualDistance: number;

Arm length actually used last frame, after collision.

camera ​
ts
readonly camera: PerspectiveCamera;

The camera being driven.

collisionProbe ​
ts
collisionProbe: CollisionProbe | null;

Obstacle probe. Assign to swap it at runtime, or null to disable collision.

distance ​
ts
readonly distance: number;

Requested arm length, before collision.

pitch ​
ts
readonly pitch: number;

Last applied pitch, in radians, after clamping.

pivotHeight ​
ts
pivotHeight: number;

Height of the orbit pivot above the target.

yaw ​
ts
readonly yaw: number;

Last applied yaw, in radians.

Methods ​

apply() ​
ts
apply(): void;

Re-run the probe and reposition the camera with the current target and orbit.

Both setters call this; you only need it when the world changed but the inputs did not.

Returns ​

void

setOrbit() ​
ts
setOrbit(
   yaw, 
   pitch, 
   distance
): void;

Set the orbit and apply the result.

Parameters ​
ParameterTypeDescription
yawnumberRotation about world +Y, in radians. 0 puts the camera on +Z.
pitchnumberRotation above the horizon, in radians. Positive looks down at the target.
distancenumberRequested arm length, in metres.
Returns ​

void

setTarget() ​
ts
setTarget(position): void;

Point the rig at a target and apply the result.

Parameters ​
ParameterTypeDescription
positionVector3LikeThe target's world position, at its feet.
Returns ​

void

setTargetAndOrbit() ​
ts
setTargetAndOrbit(
   position, 
   yaw, 
   pitch, 
   distance
): void;

Set the target and the orbit together and apply once.

The per-frame entry point: one probe, one camera write, instead of the two that calling setTarget then setOrbit would cost.

Parameters ​
ParameterTypeDescription
positionVector3LikeThe target's world position, at its feet.
yawnumberRotation about world +Y, in radians.
pitchnumberRotation above the horizon, in radians.
distancenumberRequested arm length, in metres.
Returns ​

void


ThirdPersonRigOptions ​

Options accepted by createThirdPersonRig.

Properties ​

camera ​
ts
readonly camera: PerspectiveCamera;

The camera to drive.

collisionPadding? ​
ts
readonly optional collisionPadding?: number;

Gap left between camera and obstacle. Defaults to 0.15.

collisionProbe? ​
ts
readonly optional collisionProbe?: CollisionProbe;

Obstacle probe. Omit for a rig that never collides.

maxPitch? ​
ts
readonly optional maxPitch?: number;

Pitch is clamped to plus or minus this, in radians.

minDistance? ​
ts
readonly optional minDistance?: number;

Closest the arm may pull in. Defaults to 0.4.

pivotHeight? ​
ts
readonly optional pivotHeight?: number;

Height of the orbit pivot above the target position. Defaults to 1.5.


Time ​

Read-only view of the engine clock, as modules and game code see it.

Extended by ​

Properties ​

elapsed ​
ts
readonly elapsed: number;

Scaled seconds simulated since start().

fixedDt ​
ts
readonly fixedDt: number;

Length of one fixed step, in seconds.

now ​
ts
readonly now: number;

performance.now() of the current frame, in milliseconds.

renderFrame ​
ts
readonly renderFrame: number;

Frames rendered since start(), starting at 0.

Rendered frames, not fixed steps: on a 144 Hz display this runs ahead of the simulation's own step counter, which the guest sees as its frame.

timeScale ​
ts
timeScale: number;

Simulation speed multiplier. 0 pauses, 0.5 is half speed.

Changes how many fixed steps a frame buys, never how long a step is: a fixed step is always fixedDt.


Vector3Like ​

Anything with x, y and z. Avoids allocating a Vector3 per call.

Properties ​

x ​
ts
readonly x: number;

X component.

y ​
ts
readonly y: number;

Y component.

z ​
ts
readonly z: number;

Z component.


WebGPUPatchOptions ​

Options accepted by initWebGPUPatches.

Properties ​

maxStorageBuffersPerShaderStage? ​
ts
readonly optional maxStorageBuffersPerShaderStage?: number;

Storage buffers per shader stage to ask for.

The patch requests min(this, adapter.limits.maxStorageBuffersPerShaderStage), so asking for more than the adapter has is harmless. Defaults to DEFAULT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE.

target? ​
ts
readonly optional target?: PatchableAdapterPrototype;

Prototype to patch. Defaults to the global GPUAdapter.prototype.

Tests pass a fake here; production never sets it.

timestampQuery? ​
ts
readonly optional timestampQuery?: boolean;

Also request the timestamp-query feature when the adapter has it.

Needed to time GPU passes in the debug overlay and the benchmarks. Off by default, because the feature has a cost.

Type Aliases ​

CollisionProbe ​

ts
type CollisionProbe = (from, to) => number | null;

Asks how far a ray gets before it hits something.

Parameters ​

ParameterTypeDescription
fromVector3LikeStart of the ray, the orbit pivot.
toVector3LikeWhere the camera would like to be.

Returns ​

number | null

Distance from from to the hit, in metres, or null for a clear line.


EventMap ​

ts
type EventMap = object;

Shape of an event map: an interface mapping event name to payload type.

Deliberately object rather than Record<string, unknown>: interfaces have no implicit index signature, and the whole point of EngineEventMap is that packages declaration-merge into it.


Listener ​

ts
type Listener<T> = (payload) => void;

A handler for one event.

Type Parameters ​

Type Parameter
T

Parameters ​

ParameterType
payloadT

Returns ​

void


RendererBackend ​

ts
type RendererBackend = "auto" | "webgpu" | "webgl";

Which three.js backend the renderer should target.

Variables ​

DEFAULT_COLLISION_PADDING ​

ts
const DEFAULT_COLLISION_PADDING: 0.15 = 0.15;

Default gap left between the camera and whatever the probe hit, in metres.


DEFAULT_EYE_HEIGHT ​

ts
const DEFAULT_EYE_HEIGHT: 1.7 = 1.7;

Default eye height above the feet, in metres.


DEFAULT_FIXED_DT ​

ts
const DEFAULT_FIXED_DT: number;

Default simulation rate: 60 Hz.


DEFAULT_MAX_PITCH ​

ts
const DEFAULT_MAX_PITCH: number;

Default pitch limit: just short of straight up or down, in radians.


DEFAULT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE ​

ts
const DEFAULT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE: 10 = 10;

Storage buffers per shader stage the engine asks for. The WebGPU default is 8.


DEFAULT_MAX_SUBSTEPS ​

ts
const DEFAULT_MAX_SUBSTEPS: 5 = 5;

Default cap on fixed steps per frame.


DEFAULT_MIN_DISTANCE ​

ts
const DEFAULT_MIN_DISTANCE: 0.4 = 0.4;

Default closest the arm may pull in, in metres.


DEFAULT_OVERLAY_HOTKEY ​

ts
const DEFAULT_OVERLAY_HOTKEY: "F3" = 'F3';

KeyboardEvent.code that toggles the panel.


DEFAULT_OVERLAY_INTERVAL_MS ​

ts
const DEFAULT_OVERLAY_INTERVAL_MS: 250 = 250;

How often the panel's text is rewritten, in milliseconds.


DEFAULT_PIVOT_HEIGHT ​

ts
const DEFAULT_PIVOT_HEIGHT: 1.5 = 1.5;

Default height of the orbit pivot above the target, in metres.


DEFAULT_PIXEL_RATIO_CAP ​

ts
const DEFAULT_PIXEL_RATIO_CAP: 2 = 2;

Default upper bound on devicePixelRatio.


DEFAULT_SAMPLE_COUNT ​

ts
const DEFAULT_SAMPLE_COUNT: 120 = 120;

Frames kept in the window by default: two seconds at 60 Hz.


DEFAULT_TRANSFORM_CAPACITY ​

ts
const DEFAULT_TRANSFORM_CAPACITY: 256 = 256;

Default number of entity slots a new store reserves.


NO_ENTITY ​

ts
const NO_ENTITY: 0 = 0;

The entity id that means "no entity"; also the id of the root group.


PACKAGE ​

ts
const PACKAGE: "@aosengine/core";

Package identity marker.

Example ​

ts
import { PACKAGE } from '@aosengine/core';

console.log(PACKAGE); // '@aosengine/core'

Functions ​

candleFlicker() ​

ts
function candleFlicker(seconds, index): number;

Deterministic, continuous candle gain in [0.58, 1.2], with a steady core and shallow draught dips.

Parameters ​

ParameterTypeDescription
secondsnumberElapsed scene time in seconds.
indexnumberStable fixture seed; different fixtures flicker independently.

Returns ​

number

Intensity multiplier; no random state or frame allocation.

Example ​

ts
light.intensity = 2.6 * candleFlicker(elapsed, 3);

createDebugOverlay() ​

ts
function createDebugOverlay(options): DebugOverlay;

Build the debug overlay.

On a host with no document — Node, a worker, a test — this returns a working overlay whose element is null: the statistics still accumulate and can be read, nothing is mounted, and nothing throws.

Parameters ​

ParameterTypeDescription
optionsDebugOverlayOptionsRenderer, backend label and panel settings.

Returns ​

DebugOverlay

The overlay.

Example ​

ts
import { createDebugOverlay } from '@aosengine/core';
import { WebGPURenderer } from 'three/webgpu';

const renderer = new WebGPURenderer({ canvas: document.createElement('canvas') });
const overlay = createDebugOverlay({ renderer, backendName: 'webgpu' });
overlay.sample(16.6, performance.now()); // call once per frame

createEngine() ​

ts
function createEngine(options): Promise<Engine>;

Boot an engine around a canvas.

Parameters ​

ParameterTypeDescription
optionsCreateEngineOptionsCanvas, manifest, modules, loop rate and renderer settings.

Returns ​

Promise<Engine>

The booted engine. The loop is not running; call start().

Example ​

ts
import { createEngine } from '@aosengine/core';

const canvas = document.querySelector('canvas')!;
const engine = await createEngine({
  canvas,
  manifest: '/assets/assets.json',
  modules: [],
  fixedHz: 60,
  renderer: { backend: 'auto' },
  debug: import.meta.env?.DEV === true,
});
engine.start();

createEvents() ​

ts
function createEvents<M>(): Events<M>;

Build a typed event bus.

The type parameter is the event map. Packages extend the engine's map by declaration-merging into EngineEventMap; standalone buses pass their own.

Type Parameters ​

Type Parameter
M extends object

Returns ​

Events<M>

An empty bus.

Example ​

ts
import { createEvents } from '@aosengine/core';

const events = createEvents<{ hit: { damage: number } }>();
const off = events.on('hit', (e) => console.log(e.damage));
events.emit('hit', { damage: 7 }); // logs 7
off();

createFirstPersonRig() ​

ts
function createFirstPersonRig(options): FirstPersonRig;

Build a first-person rig.

The camera's Euler order is set to YXZ once, which is what makes yaw and pitch independent: yaw always turns about world up, pitch always about the camera's own right, and there is no roll.

Parameters ​

ParameterTypeDescription
optionsFirstPersonRigOptionsCamera, eye height and pitch limit.

Returns ​

FirstPersonRig

The rig.

Example ​

ts
import { createFirstPersonRig } from '@aosengine/core';
import { PerspectiveCamera } from 'three/webgpu';

const rig = createFirstPersonRig({ camera: new PerspectiveCamera(), eyeHeight: 1.7 });
rig.setPose({ x: 0, y: 0, z: 0 }, Math.PI, 0);
console.log(rig.camera.position.y); // 1.7

createFixedLoop() ​

ts
function createFixedLoop(options?): FixedLoop;

Build a fixed-step loop.

The accumulator drains at most maxSubsteps times per frame. Anything left over is thrown away rather than carried, because carrying it is what turns a slow frame into a spiral of death: each frame owes more simulation than the last and the game never catches up. clamped in the returned FrameTiming says when that happened.

Parameters ​

ParameterTypeDescription
optionsFixedLoopOptionsStep length, substep cap and the three callbacks.

Returns ​

FixedLoop

The loop. Nothing runs until you call step.

Example ​

ts
import { createFixedLoop } from '@aosengine/core';

let ticks = 0;
const loop = createFixedLoop({ fixedUpdate: () => { ticks += 1; } });
loop.step(0);      // baseline: no fixed steps
loop.step(1000/30); // 33.3 ms buys two 60 Hz steps
console.log(ticks); // 2

createFpsCounter() ​

ts
function createFpsCounter(engine, value): () => void;

Count rendered frames in a supplied HUD element; update twice a second. Resets on tab visibility changes and returns an idempotent cleanup callback. The caller owns markup and styling; no overlay is created unless requested.

Parameters ​

ParameterTypeDescription
enginePick<EngineContext, "events">Host event source.
valueHTMLElementElement displaying only the numeric FPS value.

Returns ​

Cleanup callback; call when disposing the owning module.

() => void

Example ​

ts
const dispose = createFpsCounter(engine, document.querySelector('#fps-value')!);

createFrameStats() ​

ts
function createFrameStats(capacity?): FrameStats;

Build a frame-time window.

Parameters ​

ParameterTypeDefault valueDescription
capacitynumberDEFAULT_SAMPLE_COUNTFrames to keep. Defaults to 120.

Returns ​

FrameStats

An empty window.

Example ​

ts
import { createFrameStats } from '@aosengine/core';

const stats = createFrameStats(4);
for (const ms of [10, 20, 30, 40]) stats.push(ms);
console.log(stats.percentile(0.5)); // 20

createModuleRegistry() ​

ts
function createModuleRegistry(): ModuleRegistry;

Build a module registry.

Returns ​

ModuleRegistry

An empty registry.

Example ​

ts
import { createModuleRegistry } from '@aosengine/core';

const registry = createModuleRegistry();
registry.register({ id: 'clock', order: -10, init: () => ({ t: 0 }), dispose: () => {} });
console.log(registry.modules[0]?.id); // 'clock'

createThirdPersonRig() ​

ts
function createThirdPersonRig(options): ThirdPersonRig;

Build a third-person rig.

Parameters ​

ParameterTypeDescription
optionsThirdPersonRigOptionsCamera, pivot height, arm limits and the collision probe.

Returns ​

ThirdPersonRig

The rig.

Example ​

ts
import { createThirdPersonRig } from '@aosengine/core';
import { PerspectiveCamera } from 'three/webgpu';

const rig = createThirdPersonRig({ camera: new PerspectiveCamera(), pivotHeight: 1.5 });
rig.setTarget({ x: 0, y: 0, z: 0 });
rig.setOrbit(0, 0, 4);
console.log(rig.camera.position.z); // 4

createTime() ​

ts
function createTime(fixedDt): MutableTime;

Build an engine clock.

Parameters ​

ParameterTypeDescription
fixedDtnumberLength of one fixed step, in seconds.

Returns ​

MutableTime

A clock at render frame 0, elapsed 0, timeScale 1.

Example ​

ts
import { createTime } from '@aosengine/core';

const time = createTime(1 / 60);
time.timeScale = 0.5; // slow motion
console.log(time.fixedDt); // 0.016666…

initWebGPUPatches() ​

ts
function initWebGPUPatches(options?): boolean;

Patch GPUAdapter.prototype.requestDevice so every device the page creates clears the engine's limits.

Idempotent. Calling it again does not wrap the method twice; it raises the requested limits if the new call asks for more. Safe to call on a host with no WebGPU at all, where it does nothing and returns false.

Must run before renderer.init(), and before anything else creates a device.

Parameters ​

ParameterTypeDescription
optionsWebGPUPatchOptionsLimits to request, and the prototype to patch.

Returns ​

boolean

True when the patch is installed, false when the host has no WebGPU.

Example ​

ts
import { initWebGPUPatches } from '@aosengine/core';
import { WebGPURenderer } from 'three/webgpu';

initWebGPUPatches({ maxStorageBuffersPerShaderStage: 10 });
const renderer = new WebGPURenderer({ canvas: document.createElement('canvas') });
await renderer.init();

isWebGPUBackend() ​

ts
function isWebGPUBackend(renderer): boolean;

Whether a renderer ended up on a real WebGPU backend.

three sets isWebGPUBackend on WebGPUBackend and isWebGLBackend on the fallback, but neither class is exported from three/webgpu, so this is a duck-type check rather than an instanceof.

Parameters ​

ParameterTypeDescription
rendererWebGPURendererAn initialised renderer.

Returns ​

boolean

True on WebGPU, false on the WebGL fallback.

Example ​

ts
import { isWebGPUBackend } from '@aosengine/core';
import { WebGPURenderer } from 'three/webgpu';

const renderer = new WebGPURenderer({ canvas: document.createElement('canvas') });
await renderer.init();
console.log(isWebGPUBackend(renderer));

isWebGPUPatched() ​

ts
function isWebGPUPatched(target?): boolean;

Whether a prototype already carries the patch.

Parameters ​

ParameterTypeDescription
target?PatchableAdapterPrototypePrototype to check. Defaults to the global GPUAdapter.prototype.

Returns ​

boolean

True when initWebGPUPatches has run against it.

Example ​

ts
import { initWebGPUPatches, isWebGPUPatched } from '@aosengine/core';

initWebGPUPatches();
console.log(isWebGPUPatched()); // true in a browser with WebGPU

resolveEngineConfig() ​

ts
function resolveEngineConfig(options?): EngineConfig;

Apply the documented defaults to the engine options.

Exported for the unit tests; createEngine is the real entry point.

Parameters ​

ParameterTypeDescription
optionsOmit<CreateEngineOptions, "canvas">Options as the caller wrote them.

Returns ​

EngineConfig

The resolved configuration.

Example ​

ts
import { resolveEngineConfig } from '@aosengine/core';

const config = resolveEngineConfig({ fixedHz: 120 });
console.log(config.fixedDt); // 0.008333…