ErrorCode
error.constants.ts:13Stable string codes attached to every EngineError thrown by the engine. Codes are part of the public contract — user code is expected to branch on them when handling engine failures — so renumbering or removing a code is a breaking change.
Each value is prefixed with a short domain tag (COMP, PREFAB, DEP,
GAME, WORLD, ASSET, RAND, GFX, AUDIO, PHYS, GRID) followed by
a zero-padded
sequence number, so codes sort by domain and the wire format is stable
across catalog growth.
Enumeration Members
ANIMATED_SPRITE_EMPTY_FRAMES An AnimatedSprite was constructed with an empty frames array —
an animation with no frames has nothing to draw.
ANIMATED_SPRITE_INVALID_FPS An AnimatedSprite was given a non-positive, non-finite, or NaN
fps. Frame duration is 1000 / fps, so a zero/negative/NaN rate
yields an animation that never advances or spins without bound. Context:
{ fps }.
ASSET_KEY_CONFLICT An asset was stored under a (namespace, key) already holding a
different asset.
ASSET_LOAD_FAILED An asset failed to load — the underlying loader (PIXI, fetch/decode)
rejected. The original failure is attached as cause. Context:
{ path, key, namespace, cause }.
ASSET_TYPE_MISMATCH An asset was retrieved via getAs with a type that doesn't match the
stored asset, or a load couldn't resolve the asset's type.
AUDIO_LOAD_FAILED An audio file failed to load — the fetch resolved with a non-OK HTTP
status. Context: { path, status, statusText }.
COMPONENT_ALREADY_EXISTS A component was added under a key already in use, without replacement
being permitted. Context: { key }.
COMPONENT_AMBIGUOUS_TYPE A lookup by type matched more than one registered component, so the
engine can't pick one unambiguously. Look it up by key instead, use
getComponentsByType to retrieve them all, or register only one
component of the type. Context: { type }.
COMPONENT_NOT_FOUND A component lookup by key found nothing. Thrown by the strict
getComponent accessors on a component host when the key is absent;
the nullable accessors return null instead. Context: { key }.
GAME_WORLD_ALREADY_EXISTS Game.createWorld was called while the game already has an active
world. Destroy the existing world first if you mean to replace it.
Context: { game }.
GAME_WORLD_NOT_FOUND A world operation (e.g. Game.destroyWorld) was attempted while
the Game has no active world. Context: { game }.
GRID_CELL_IMMUTABLE A write was attempted to a Cell's x or y coordinate — directly
(cell.x = …) or via an inherited Point mutator (add, scale,
forward, …). A cell's coordinate is its identity within the
Grid index and is immutable; mutating it would desynchronise
lookups. Call Point.clone to obtain a detached, mutable point for
vector math. Context: { cell, axis }.
GRID_INVALID_SIZE A Grid was constructed with a width or height that isn't a
positive integer. A grid's dimensions are its fixed cell counts, so a
fractional, zero, or negative size has no meaning. Context:
{ width, height }.
LAYER_DUPLICATE_NAME defineLayers was given the same layer name twice. Layer names are
the lookup key, so they must be unique within a set. Context: { name }.
LAYER_NOT_IN_SET A layer was looked up that the set doesn't contain: LayerSet.get
with an unknown name, or Scene.containerForLayer / the
AbstractGraphics.layer setter with a Layer token minted by
a different LayerSet. Context: { name }.
LAYER_SET_ABSENT A graphics component named a GraphicsOptions.layer, but its world's
Scene has no LayerSet — most often a forgotten layers: on
the Game.createWorld call. Context identifies the host.
LAYER_SET_EMPTY defineLayers (or the LayerSet constructor) was called with no layer names — a layer set must declare at least one layer.
LAYER_UNSPECIFIED A graphics component was added to a world whose Scene has a LayerSet, but the component named no GraphicsOptions.layer. In a layered world every graphic must choose a layer — there is no implicit default. Context identifies the host.
PHYSICS_BODY_NOT_ATTACHED A RigidBody operation needed the body to be attached to a PhysicsWorld, but it wasn't (yet, or any longer).
PHYSICS_INVALID_SHAPE A collider was described with a shape the physics layer can't translate into a Rapier collider (e.g. a degenerate or unsupported shape).
PHYSICS_NO_COLLIDER A RigidBody was constructed with no colliders — a body needs at least one collider to participate in the simulation.
PHYSICS_NOT_INITIALISED A physics operation was attempted before initPhysics completed — Rapier's WebAssembly module hasn't been initialised yet.
PREFAB_ALREADY_REGISTERED A prefab was registered under a name already taken in the registry.
Context: { name }.
PREFAB_BUILD_UNAUTHORIZED Prefab.buildObject was called without the internal build token —
i.e. not via World.createFromPrefab/createFromPrefabName. The token
gates the build path so objects are always registered with the world.
PREFAB_INVALID_NAME A prefab name failed validation (empty, or otherwise malformed) at
registration time. Context: { name }.
PREFAB_REGISTRY_NOT_ATTACHED A prefab operation needed a PrefabRegistry but none was attached to the world.
RANDOM_EMPTY_ITEMS A weighted/uniform random pick was asked to choose from an empty collection. Context: identifies the calling method.
WORLD_COMPONENT_DEPENDENCY_AMBIGUOUS A dependency lookup by type matched more than one candidate, so the resolver can't bind it unambiguously.
WORLD_COMPONENT_DEPENDENCY_MISSING A component's resolveDependencies required a sibling or world-tier
component that isn't registered. Context: identifies the requesting
component and the missing dependency.
WORLD_COMPONENT_DEPENDENCY_REENTRANT A component's resolveDependencies re-entered dependency resolution
(e.g. by adding components mid-resolve), which would corrupt the
resolving state.
WORLD_OBJECT_HIERARCHY_CYCLE WorldObject.setParent would have created a cycle — the
prospective parent is the object itself or one of its descendants.
Parenting must form a tree, so a node can never be nested beneath its
own subtree. Context: { child, parent }.
WORLD_OBJECT_ID_CONFLICT An object was added to a World under an id already held by
another object. Object ids must be unique within a world so
World.findById resolves unambiguously. Context: { id }.
WORLD_OBJECT_PARENT_FOREIGN WorldObject.setParent was given a prospective parent that belongs
to a different World. The transform hierarchy is scoped to a
single world — a parent and child must share one. Context:
{ child, parent }.