@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
| Parameter | Type | Description |
|---|---|---|
moduleId | string | Module or service id involved. |
message | string | What went wrong. |
options? | ErrorOptions | Standard Error options, used to keep the cause. |
Returns
Overrides
ts
Error.constructorProperties
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
| Parameter | Type | Default value | Description |
|---|---|---|---|
scene | Scene | undefined | Scene to attach to. |
name | string | 'aosengine:root' | Name given to the root group, for debugging. |
Returns
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
| Parameter | Type | Description |
|---|---|---|
id | number | Entity 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
| Parameter | Type | Description |
|---|---|---|
id | number | Entity 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
| Parameter | Type | Description |
|---|---|---|
object | Object3D | Any 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
| Parameter | Type | Default value | Description |
|---|---|---|---|
id | number | undefined | Entity id to move. |
parentId | number | NO_ENTITY | New 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
| Parameter | Type | Default value | Description |
|---|---|---|---|
id | number | undefined | Entity id. Must be a positive integer; 0 is the root. |
object | Object3D | undefined | The object to add. |
parentId | number | NO_ENTITY | Parent 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 1TransformStore
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
| Parameter | Type | Default value | Description |
|---|---|---|---|
capacity | number | DEFAULT_TRANSFORM_CAPACITY | Slots to reserve up front. |
Returns
Accessors
capacity
Get Signature
ts
get capacity(): number;Slots currently allocated.
Returns
number
The number of addressable entity slots.
Methods
clear()
ts
clear(id): void;Forget an entity. Its slot is reset to the identity transform.
Parameters
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
Returns
void
commit()
ts
commit(): void;Make the current transform the previous one, for every slot.
Call once per fixed step, before that step writes new values.
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
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id that must fit. |
Returns
void
getPosition()
ts
getPosition(id, out): number[] | Float32Array<ArrayBufferLike>;Read the current position into out.
Parameters
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
out | number[] | 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
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
out | number[] | 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
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
Returns
boolean
True when the slot holds a transform.
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
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
px | number | Position x. |
py | number | Position y. |
pz | number | Position z. |
qx | number | Quaternion x. |
qy | number | Quaternion y. |
qz | number | Quaternion z. |
qw | number | Quaternion w. |
sx | number | Scale x. |
sy | number | Scale y. |
sz | number | Scale 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
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
x | number | Position x. |
y | number | Position y. |
z | number | Position z. |
Returns
void
setQuaternion()
ts
setQuaternion(
id,
x,
y,
z,
w
): void;Write the current rotation of an entity.
Parameters
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
x | number | Quaternion x. |
y | number | Quaternion y. |
z | number | Quaternion z. |
w | number | Quaternion w. |
Returns
void
setScale()
ts
setScale(
id,
x,
y,
z
): void;Write the current scale of an entity.
Parameters
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
x | number | Scale x. |
y | number | Scale y. |
z | number | Scale 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
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
Returns
void
writeInterpolated()
ts
writeInterpolated(
id,
object,
alpha
): boolean;Write the blend of previous and current onto an Object3D.
Parameters
| Parameter | Type | Description |
|---|---|---|
id | number | Entity id. |
object | Object3D | Target object; its position, quaternion and scale are written. |
alpha | number | Interpolation factor, normally the loop's alpha in [0, 1). |
Returns
boolean
True when the entity existed and the object was written.
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
| Parameter | Type | Description |
|---|---|---|
frameMs | number | How long the frame took, in milliseconds. |
nowMs | number | Current timestamp, in milliseconds. |
Returns
void
setVisible()
ts
setVisible(value): void;Show or hide the panel.
Parameters
| Parameter | Type | Description |
|---|---|---|
value | boolean | True 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
| Parameter | Type | Description |
|---|---|---|
id | K | Service 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
| Parameter | Type | Description |
|---|---|---|
width | number | CSS width in pixels. |
height | number | CSS 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
| Parameter | Type | Description |
|---|---|---|
id | K | Service 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
| Parameter | Type | Description |
|---|---|---|
id | string | Service id, matching a key of EngineServices. |
service | object | The 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 simulating, just before rendering.
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, physics 0, gameplay 100, rendering helpers 200.
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
| Parameter | Type | Description |
|---|---|---|
dt | number | Always ctx.config.fixedDt. |
Returns
void
init()
ts
init(ctx): void | object | Promise<void | object>;Acquire resources.
Parameters
| Parameter | Type | Description |
|---|---|---|
ctx | EngineContext | The 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
| Parameter | Type | Description |
|---|---|---|
dt | number | Clamped wall-clock seconds since the previous frame. |
alpha | number | Interpolation 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
| Parameter | Type | Description |
|---|---|---|
type | K | Event name. |
payload | M[K] | Payload, matching the map. |
Returns
void
listenerCount()
ts
listenerCount(type): number;How many handlers are subscribed to an event.
Parameters
| Parameter | Type | Description |
|---|---|---|
type | keyof M | Event 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
| Parameter | Type | Description |
|---|---|---|
type | K | Event name. |
listener | Listener<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
| Parameter | Type | Description |
|---|---|---|
type | K | Event name. |
listener | Listener<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
| Parameter | Type | Description |
|---|---|---|
type | K | Event name. |
listener | Listener<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
| Parameter | Type | Description |
|---|---|---|
position | Vector3Like | Body position in world space. |
yaw | number | Rotation about world +Y, in radians. 0 looks down −Z. |
pitch | number | Rotation 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.
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
| Parameter | Type | Description |
|---|---|---|
nowMs | number | A monotonic timestamp in milliseconds, usually from rAF. |
Returns
What this frame did.
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
| Parameter | Type | Description |
|---|---|---|
dt | number | Always fixedDt. |
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
| Parameter | Type | Description |
|---|---|---|
alpha | number | Interpolation factor in [0, 1). |
Returns
void
update?
ts
readonly optional update?: (dtReal, alpha) => void;Run once per frame, after the fixed steps.
Parameters
| Parameter | Type | Description |
|---|---|---|
dtReal | number | Clamped wall-clock seconds since the previous frame. |
alpha | number | Interpolation 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
| Parameter | Type | Description |
|---|---|---|
p | number | Percentile 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
| Parameter | Type | Description |
|---|---|---|
frameMs | number | How 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.
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
| Parameter | Type | Description |
|---|---|---|
id | K | Service id. |
Returns
EngineServices[K]
The service.
has()
ts
has(id): boolean;Whether a service is registered under an id.
Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Service 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
| Parameter | Type | Description |
|---|---|---|
ctx | EngineContext | The 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
| Parameter | Type | Description |
|---|---|---|
module | EngineModule | The module. |
Returns
void
registerService()
ts
registerService(id, service): void;Publish a service under an id.
Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Service id. |
service | object | The 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
| Parameter | Type | Description |
|---|---|---|
id | string | Service 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
fixedDt
ts
fixedDt: number;Length of one fixed step, in seconds.
Overrides
frame
ts
frame: number;Frames rendered since start(), starting at 0.
Overrides
now
ts
now: number;performance.now() of the current frame, in milliseconds.
Overrides
timeScale
ts
timeScale: number;Simulation speed multiplier. 0 pauses, 0.5 is half speed.
Inherited from
PatchableAdapterPrototype
The parts of GPUAdapter the patch touches.
Methods
requestDevice()
ts
requestDevice(descriptor?): Promise<GPUDevice>;The method being wrapped.
Parameters
| Parameter | Type | Description |
|---|---|---|
descriptor? | GPUDeviceDescriptor | Device 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
| Parameter | Type | Description |
|---|---|---|
yaw | number | Rotation about world +Y, in radians. 0 puts the camera on +Z. |
pitch | number | Rotation above the horizon, in radians. Positive looks down at the target. |
distance | number | Requested arm length, in metres. |
Returns
void
setTarget()
ts
setTarget(position): void;Point the rig at a target and apply the result.
Parameters
| Parameter | Type | Description |
|---|---|---|
position | Vector3Like | The target's world position, at its feet. |
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.
frame
ts
readonly frame: number;Frames rendered since start(), starting at 0.
now
ts
readonly now: number;performance.now() of the current frame, in milliseconds.
timeScale
ts
timeScale: number;Simulation speed multiplier. 0 pauses, 0.5 is half speed.
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
| Parameter | Type | Description |
|---|---|---|
from | Vector3Like | Start of the ray, the orbit pivot. |
to | Vector3Like | Where 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
| Parameter | Type |
|---|---|
payload | T |
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
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
| Parameter | Type | Description |
|---|---|---|
options | DebugOverlayOptions | Renderer, backend label and panel settings. |
Returns
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 framecreateEngine()
ts
function createEngine(options): Promise<Engine>;Boot an engine around a canvas.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | CreateEngineOptions | Canvas, 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
| Parameter | Type | Description |
|---|---|---|
options | FirstPersonRigOptions | Camera, eye height and pitch limit. |
Returns
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.7createFixedLoop()
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
| Parameter | Type | Description |
|---|---|---|
options | FixedLoopOptions | Step length, substep cap and the three callbacks. |
Returns
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); // 2createFrameStats()
ts
function createFrameStats(capacity?): FrameStats;Build a frame-time window.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
capacity | number | DEFAULT_SAMPLE_COUNT | Frames to keep. Defaults to 120. |
Returns
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)); // 20createModuleRegistry()
ts
function createModuleRegistry(): ModuleRegistry;Build a module registry.
Returns
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
| Parameter | Type | Description |
|---|---|---|
options | ThirdPersonRigOptions | Camera, pivot height, arm limits and the collision probe. |
Returns
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); // 4createTime()
ts
function createTime(fixedDt): MutableTime;Build an engine clock.
Parameters
| Parameter | Type | Description |
|---|---|---|
fixedDt | number | Length of one fixed step, in seconds. |
Returns
A clock at 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
| Parameter | Type | Description |
|---|---|---|
options | WebGPUPatchOptions | Limits 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
| Parameter | Type | Description |
|---|---|---|
renderer | WebGPURenderer | An 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
| Parameter | Type | Description |
|---|---|---|
target? | PatchableAdapterPrototype | Prototype 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 WebGPUresolveEngineConfig()
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
| Parameter | Type | Description |
|---|---|---|
options | Omit<CreateEngineOptions, "canvas"> | Options as the caller wrote them. |
Returns
The resolved configuration.
Example
ts
import { resolveEngineConfig } from '@aosengine/core';
const config = resolveEngineConfig({ fixedHz: 120 });
console.log(config.fixedDt); // 0.008333…