Rule codes
Every rule the contract and the critics can raise. A message opens with its code.
| Name | Summary |
|---|---|
| air-out-of-range | meta.environment.air with a value outside its range: density outside 0..10 kg/m3, wind.speedMps outside 0..100, wind.gustMps outside 0..50 or wind.gustPeriodS outside 1..120. The air uses the nearest limit. Warning: see SEVERITY. |
| animator-blend-coverage | A blend tree's points do not cover its parameter space: two at one coordinate, or a plane's worth all on one line. |
| animator-blend-degenerate | A blend tree has too few points for its kind: fewer than two on a line, fewer than three on a plane. |
| animator-blend-parameters | A blend tree reads the wrong number of parameters, one the animator does not declare, the same one twice, or gives a point the wrong number of coordinates. |
| animator-damp-invalid | An animator parameter's damp is negative (a smoothing time cannot be); a non-finite one is animator-not-finite. |
| animator-event-data-invalid | An animation event's data has too many keys or is too large. |
| animator-event-invalid | An animation event sits outside its clip (at not in 0..1), or names no clip or no event. |
| animator-event-window-invalid | An animation event's until / untilFrame is not a window: not above its start, past the end of the clip, or in other units than at / frame. |
| animator-feet-invalid | An animator.feet names fewer than two or more than four joints, an empty name, or one name twice. |
| animator-ik-invalid | An IK chain has a duplicate name, a bone listed twice, both kinds of pole, a pole bone from its own chain, a weight outside 0..1, or an empty name. |
| animator-initial-undefined | animator.initial is not one of the animator's state names. |
| animator-invalid | Animator states, transitions, blend trees, events and clips resolve |
| animator-layer-invalid | An animator layer that cannot be built: an empty or repeated name, a weight outside 0..1, a negative or non-finite blendIn or blendOut, a weightParam or initial that names nothing declared, an empty mask or a mask weight outside 0..1, or a reference on a layer that is not additive or a referenceAt without one or outside 0..1. |
| animator-look-at-invalid | A look-at has no bones, a bone listed twice, an empty bone name, a limit outside 0..180 degrees, a weight outside 0..1, or a negative smoothing time. |
| animator-loop-range-invalid | An animator state's or blend point's loopStart/loopEnd is outside 0..1, or loopStart is not below loopEnd, or the range is on a state that does not loop, a one-shot, a clips list, or at state level on a blend state (a tree takes it per point). Non-finite values are animator-not-finite. |
| animator-not-finite | A blend point, a parameter value, an animation event position or a transition blend time is NaN or infinite. |
| animator-once-invalid | A one-shot state (once) loops, hands over to a state that does not exist or to itself, lets an undefined state interrupt it, has a negative blendOut, or raises an empty event name. |
| animator-rest-pose-straight | A rig with foot IK rests with its legs bent enough to plant a foot downhill |
| animator-retarget-duplicate | Two of a retarget map's keys name the same bone of the target rig, so one of the two limbs loses its animation to the other. |
| animator-retarget-unmapped | A retarget map leaves a bone the built-in clips animate unmapped, names a bone the profile does not have, or maps one to an empty name. |
| animator-root-motion-source | A state with rootMotion reads a parameter bound to a measured-velocity source, which is a closed loop. Warning: see SEVERITY. |
| animator-speed-invalid | An animator state's or blend point's speed, or a speedParam.scale, is negative, NaN or infinite, or a speedParam names a parameter the animator does not declare. |
| animator-state-duplicate | Two of an animator's states share a name, so initial and every transition are ambiguous. |
| animator-state-source | An animator state has both a clip and a blend, or neither. |
| animator-transition-undefined | An animator transition targets a state that does not exist. |
| asset-builtin-unknown | An assets[*].path of builtin:<name> names nothing built in: a glb asset whose name is not one of the built-in meshes (cube, sphere, capsule, plane, cylinder, cone), or a builtin: path on a kind that has no built-ins (only glb and audio do). |
| asset-forward-invalid | An assets[*].forward sits on an asset that is not a model, so there is no nose to turn. |
| asset-import-invalid | An assets[*].import declares a scale or an axis pair that cannot be applied. |
| asset-path-not-relative | An assets[*].path is absolute, names a drive, or climbs out with ... |
| attach-owner-missing | An attach.to that names no entity of the scene, or the attached entity itself. Bone attachments, first of 2. |
| attach-owner-no-animator | An attach.to that names an entity with no animator component, so there is no skeleton to follow. Bone attachments, second of 2. |
| audio-bus-unknown | Every bus meta.audio names is a bus meta.audio declares |
| audio-missing-file | Every sound the scene names is an audio asset that exists |
| audio-orphan | Spatial audio sits on something with a position you can see |
| behavior-position-ignores-teleport | A behaviour that writes a position every tick from its own state adopts a teleport |
| behavior-wrap-drops-event | A behaviour that runs another's init or update forwards its onEvent too |
| buoyancy-without-body | A buoyancy component on an entity that has no rigidbody of kind dynamic: forces only move a dynamic body. |
| buoyancy-without-ocean | A buoyancy component in a scene with no meta.environment.ocean and no water component: there is no water to float on. |
| camera-clip | The camera's default position is not inside or behind geometry |
| camera-hides-everything | A camera's layers / hideLayers leaves out every layer the scene's meshes and sprites are on, so it draws nothing. Warning: see SEVERITY. |
| camera-layers-invalid | A camera sets both layers and hideLayers, or one of them is an empty list. |
| camera-point-invalid | GET /camera/project or GET /camera/ray was given a missing or non-finite x, y or z, an unknown entity, or entity together with x/y/z. Answered 400 by the query server; no scene produces it. |
| camera-priority-tie | Two or more screen cameras share the top priority and none of them is primary, so scene order picks the view. Warning: see SEVERITY. |
| camera-projection-invalid | A camera's orthoSize or pixelsPerUnit that is not a finite number above zero: an orthographic view has no size to draw at. 2D camera. |
| camera-rig-invalid | A camera's rig, output or blendIn cannot work: a following rig with no target, viewport without output: "viewport" or the reverse, a rectangle outside the window or with no area, an overlay or viewport camera that is primary, a negative blend time. |
| camera-view-unknown | GET /camera/project or GET /camera/ray named a view the running world does not have: not a number, 0, or beyond the split-screen layout's live views. Answered 400 by the query server; no scene produces it. |
| character-unanimated | A skinned character with a controller has an animator whose states follow movement |
| collider-detail-ignored | A collider.detail sits where nothing reads it: on a box, sphere or capsule, or on a trimesh whose entity is not a dynamic body (static and kinematic trimeshes are always exact). Warning: see SEVERITY. |
| collider-material-invalid | A collider.material has a negative friction, a restitution outside 0..1, or a slope limit outside 0..90 degrees. |
| controller-invalid | A controller.gravity is negative, a controller.maxFallSpeed is 0 or less, or a controller.step is not more than 0 and under 1.8 m (the standing height); any of them NaN or infinite. |
| dangling-asset | An asset reference names a key that is not in scene.assets. |
| dangling-parent | entity.parent names an entity that is not in the scene. |
| dangling-ref | Asset, script, parent and target references resolve |
| dangling-target | camera.target names an entity that is not in the scene. |
| duplicate-entity-id | Two entities share an id. |
| dynamic-needs-collider | A rigidbody of kind dynamic has no non-trigger collider. Warning: see SEVERITY. |
| face-invalid | A face that is wrong whatever the model is: no animator on the same entity; blink (0..60), gaze (0..25), expression or headMotion (0..2) not finite or out of range; a seed that is not a whole number from 0 to 4294967295; eyes that is not exactly two different non-empty names; or an empty head. Bones and shapes the model lacks are found at load: face-degraded, a runtime code (docs/RUNTIME-CODES.md). |
| feel/action-out-of-reach | an action's hit volume (an attached trigger collider) never came within 0.25 m of the nearest thing it could hit while its strike window was open, so the swing cannot land from where the probe pressed it; the message gives the gap to the target and the reach |
| feel/action-window-unreachable | an action's cancel window (cancel, combo, chain) opens after the animator's state has already handed back, so the chain it was built for can never be used |
| feel/anim-backwards | the character walks backwards: its planted foot is carried the body's way at about twice its speed, so the model faces away from where it goes (an error for the player and what moves with it) |
| feel/anim-bind-pose | a skinned character stood in its bind (T-)pose: no clip reached the skeleton while the probe drove it (an error for the player and what moves with it, a warning for any other animator) |
| feel/anim-foot-slide | the planted foot slid over the ground: the locomotion clip's pace does not match the ground speed (a warning past 50% of the body's speed, an error past 75% for the player and what moves with it) |
| feel/anim-frozen | an animator's clip did not advance: the playhead and pose stayed still while the state said it was playing (an error for the player and what moves with it, a warning for any other animator) |
| feel/anim-loop-seam | a looping state plays a clip whose last frame does not meet its first (or one clip of a clips state that does not meet the next), so the pose jumps at every wrap (runtime animator-loop-seam) |
| feel/anim-no-air-state | the character left the ground and the animator kept its grounded state: no jump or fall pose |
| feel/anim-no-handle | a behavior read ctx.animator and got null (the engine's null-handle warning): the entity has no running animator, so every animation call it makes goes nowhere |
| feel/anim-pop | a joint turned far more in one tick than on the ticks either side while the probes drove the character: a pose that jumps (an error for the player and what moves with it, a warning for any other animator) |
| feel/anim-run-in-place | a walk or run clip played while the body stood still (not reported for an animator the stick does not drive whose rig plays one clip) |
| feel/anim-slow-response | the player's animator answered a press (move or jump) more than 6 ticks late: the state or its blend parameter changed after the body did, which reads as input lag |
| feel/anim-stuck | the body moved but the animator stayed in the state and clip it had while standing, so the character glides (an error for the player and what moves with it, a warning for any other animator) |
| feel/anim-unknown-name | ctx.animator.set or play named a state or clip this animator does not have; set changes nothing, so the character never enters it |
| feel/audio-jump-silent | the jump made no sound, though the game plays sounds elsewhere |
| feel/audio-loops-stacked | three or more copies of one loop played at once with none placed in the world: they add up to one louder sound that masks the mix (usually one loop per entity, such as every car's engine) |
| feel/audio-none | the scene has gameplay events (a jump, goals, triggers, emitted events) and no audio anywhere: no audio asset, component, meta.audio sound or behavior that plays one |
| feel/audio-silent | not one voice started: the player jumped or reached goals, or 30 s went by, in silence |
| feel/audio-unplayable | the game called ctx.audio.play for assets with no sound behind them, so nothing played |
| feel/buried | a body a script or kinematic body moves went more than 0.15 m into the ground under it for 3 reads running (an error), or its height jumped up over 0.5 m between two reads with little travel, a sunk body snapped out (a warning) |
| feel/camera-clip | the camera's near plane was inside a collider: the frame showed the inside of a wall |
| feel/camera-close | the camera sat within 0.3 m of solid geometry in more than 15% of samples: most of the frame is a surface up against the lens |
| feel/camera-collapsed | the camera's arm (or its distance to the player) was under 1 m in more than 5% of samples, so the view is the back of the character's head |
| feel/camera-occluded | something solid hid the player from the camera for longer than a second |
| feel/camera-target-hidden | the focus target (the lock target, else the nearest opponent, else the next goal) was behind the player's own body from the camera in a quarter of the reads or more |
| feel/camera-wall-collapse | walked into a wall, the camera's arm pulled in under 1 m though the space behind the character along the arm was open: the view went into the character's head with room to spare |
| feel/controls-dead | no stick direction moved the player (after the probe held input for the wait cap, 12 s of simulated time by default) |
| feel/controls-rotated | a stick direction moved the player the wrong way on screen: over 30° off by half a second, or over 45° off after 3 s held while the camera moved |
| feel/facing-actions-silent | the aimed buttons (fire, use, interact) raised no event once a teleport faced the player at something the game runs, though the same presses at the player's own heading did |
| feel/impact-no-reaction | the victim of an impact did not react within 300 ms: it moved under 5 cm, kept its animation state, did not stop and was not removed |
| feel/impact-silent | an impact (the player's sensor on something, another character's sensor on the player, or a hit, damage, impact or hurt event) gave no feedback within 300 ms: no hit-stop, shake, sound, particles, rumble or HUD change, every channel measurable |
| feel/look-capped | mouse look has a top speed: a fast synthetic mouse sweep turned the view fewer degrees per pixel than a slow one (under 60%), so a flick turns no faster than a stick; the view reads the mouse as a rate (axis × speed × dt, clamped) instead of an angle |
| feel/movement-facing-off | at steady speed the character faced over 60 degrees off the way it travelled: it moves sideways or backwards |
| feel/movement-slippery | the walker took over 1.5 s to stop after the stick was let go: it slides |
| feel/movement-sluggish | the walker took over 1.5 s to reach 90% of its top speed with the stick held: it feels heavy |
| feel/movement-steer-dead | a full steer at 90% of top speed turned the vehicle under 3 deg/s: the steering does nothing |
| feel/movement-turn-slow | the character turned under 60 deg/s to a 90 degree stick flick at speed: it does not follow the stick |
| feel/player-died-in-probe | the player died or respawned during a probe, so later rows are unmeasured |
| feel/player-fell-off | the player walked off the level and fell (nothing under it), so the camera lost it |
| feel/response-dead | pressing a gameplay action changed nothing in half a second: no bus event, animator state, pose, velocity or camera answered it (interact and use are not judged) |
| feel/response-slow | a gameplay action's press was answered (animator state, pose, velocity or camera) later than the budget (100 ms by default; a profile refines it) |
| feel/roll-mismatch | a ball moving along the ground spun against its travel (backwards, about the wrong axis, or under 30% of the rolling rate) in over half the stretches judged |
| feel/skipped | a feel probe could not run on this scene and says why |
| feel/telegraph-unreactable | another character's strike opened less than 250 ms (a person's reaction time) after its wind-up began |
| feel/teleport-facing-ignored | a tool's teleport with a heading faced the player at something, and a few ticks later the view still faced another way: a behaviour writes the old heading back (judged only where the look stick turns the camera) |
| feel/viewmodel-static | the first-person view-model (an image in the lower middle of the screen) stood still while the player walked a metre or more: nothing bobs it; forgiven where its screen says data-bob=\"off\" |
| floor-gap | No holes in the floor under the walkable areas or around a spawn |
| fog-density-and-visibility | meta.environment.fog writes both density and visibilityM, two spellings of the same extinction (density = 3 / visibilityM); write one. |
| fog-value-range | A meta.environment.fog value is outside its range (density 0..1, heightFalloff 0.001..10, start 0 or more, end past start, maxOpacity 0..1, hd.sunAnisotropy 0..0.95, hd.skyDistanceM 1..1000000) or not finite, or a colour is not #RGB/#RRGGBB. |
| gi-intensity-range | An indirectIntensity (meta.environment.gi, a light, or a giVolume) that is not a finite number within 0..16. |
| gi-volume-limit | More than 8 giVolume components of one mode; only the first 8 in scene order count. Warning: see SEVERITY. |
| gi-volume-shape | A giVolume that cannot be built: a size axis of 0 or less or not finite, a blend below 0 or not finite, or in region mode a blend of more than half the smallest extent. |
| goal-order | Goals carrying order do not form the strict sequence 1..n. |
| ground-cover-layer-invalid | A ground cover layer or document with a value out of range: an empty id, a duplicate id, a range with min above max, a colour channel outside 0..1, more than 32 layers, a flower share or palette that does not fit, seed heads on a flowers or mat layer. The message names the layer and the field. |
| ground-cover-no-terrain | A scene with ground cover and no terrain to grow it on. Reserved: nothing emits it until a scene can hold ground cover. |
| ground-cover-source-unknown | A ground cover layer whose source.channel is not a channel of the terrain. Reserved: it needs the terrain's channels beside the document, and nothing holds both yet (a scene has no ground cover component). |
| ground-cover-too-dense | A ground cover layer whose densityPerM2 is above 200. |
| hd-only-ignored | A field or component only the HD renderer draws (a splat component) on a project whose render.profile is not hd: the scene draws without it. Reported only when the validator is told the project's profile. Warning: see SEVERITY. |
| hud-layout-invalid | A meta.hud element declares a size, colour, offset or number format that cannot be drawn. |
| input-conflict | No two actions in one context share a device source |
| input-key-unknown | A meta.input key name the runtime binds nothing to ("Back", "Rigth"): input-keys.ts is the list Key::from_name reads. The message names the nearest key, or the gamepad button a pad word is. Warning: see SEVERITY. |
| input-reader-not-player | A behaviour that reads ctx.input runs on an entity player input is not routed to (the scene's spawn { for: "player" } entity beside another component, else the first controller, else the first vehicle; with meta.players, each seated player's first spawn { for: "player", player: N } entity too, and no check where a behaviour calls ctx.players.bind), so every action reads false. Warning: see SEVERITY. Reported by the critic, which reads the behaviour; the same mistake at run time is the input-read-without-routing script warning (docs/RUNTIME-CODES.md). |
| input-unbound | Every action a script reads is bound by the scene's action map |
| instanced-mesh-candidate | No <…> or more copies of one static mesh written out as separate entities |
| joint-invalid | A joint that cannot be built: connectedTo names no entity, the owner itself, or an entity with no dynamic or kinematic rigidbody; the owner has none either; a revolute or prismatic axis is zero or not finite; limits are not finite or min > max; a motor's maxForce, stiffness or damping is negative or not finite; or an entity carries two joints. |
| layer-unknown | An entity's layer, or a camera's layers, hideLayers or rig.collisionLayers, names a layer the scene's table does not declare (the project's layers, or a standalone scene's meta.layers). The message names the nearest layer. Layers and cameras, 81 (81-87). |
| layers-in-project-scene | A scene inside a project declares meta.layers: the project's layers is the one table. |
| layers-invalid | A standalone scene's meta.layers is not a layer table: more than 32, a repeated or badly formed name, default not first, or ignores naming no layer. |
| light-directional-horizontal | Every directional light in the scene lies within 5 degrees of the horizon (none points further down). A light travels along its local -Z, so an identity rotation is level: floors and ground get only sky light and look flat and washed out. Fix: tilt the light 30-60 degrees down (e.g. "rotation": [-0.4769, 0.2086, 0, 0.8538], about 55 degrees), or set meta.environment.sky.sunFromSky. Silent outside a project, when sunFromSky is true, and for lights of zero intensity. Warning: see SEVERITY. |
| light-shadow-tint-ignored | A shadowTint on a point or spot light: only a directional light's shadows are tinted, so it does nothing. Fix: move it to the directional light, or remove it. Warning: see SEVERITY. |
| light-shadow-tint-range | A light's shadowTint with a strength that is not a finite number within 0..1, or a color that is not a hex colour (#RGB or #RRGGBB). |
| lipsync-invalid | A lipsync component that cannot move a mouth: its entity has no animator (the model whose morph targets it drives) or no audio (the voice it follows), or its gain is not a finite number from 0 to 4. |
| lipsync-track-unknown | lipsync.track names a scene asset whose kind is not visemes. (A track id that is not a scene asset at all is dangling-asset.) |
| material-field-ignored | A *.material.json field that nothing reads: alphaCutoff without alphaMode mask, a normalScale with no normal map, an emissive map on a black emissive. Warning: see SEVERITY. |
| material-height-from-mixed | The layers of one *.material.json that have maskFrom.heightM disagree on maskFrom.heightFrom (one mesh, another root): a drawn instance carries one height reference. docs/MATERIALS.md. |
| material-mask-from-wear-both | A layer of a *.material.json has more than one of maskFrom.edge, cavity, ao, convexity and concavity: a layer reads one wear signal, so use two layers for both. docs/MATERIALS.md. |
| material-shader-missing | A *.material.json shader names no file the project holds, or its reference is empty, absolute, names a drive or climbs out with .. (the same path rule as a texture). A header error in the file it names is reported under that error's own code. |
| material-shader-param-range | A *.material.json params value is outside the [min, max] its shader's header declares. |
| material-shader-param-unknown | A *.material.json params key is not a param or texture the shader declares (an instance value is set per entity by a behaviour, not by the material). The message suggests the closest declared name. |
| material-texture-invalid | A *.material.json texture reference is empty, absolute, names a drive or climbs out with .., or both ormTexture and metallicRoughnessTexture are set. |
| material-value-range | A *.material.json number is outside its range or not finite: a colour or factor outside 0..1, a negative strength, an ior below 1, a uvTransform scale of 0. docs/MATERIALS.md. |
| mesh-collide-conflict | A mesh's colliderMode and its deprecated collide disagree. Warning: see SEVERITY. |
| missing-collider | Dynamic bodies have a collider; triggers have a trigger collider |
| missing-string | Every text key resolves in meta.strings |
| nav-undeclared | A navlink in a scene that declares no navigation (no meta.nav, no navagent): no navmesh is built, so it does nothing. Warning: see SEVERITY. The same code is what ctx.world.path throws in such a scene (docs/RUNTIME-CODES.md). |
| navlink-invalid | A navlink.hold is negative or not finite. |
| navmesh-failed | The navmesh builds and has polygons |
| navmesh-trap | No walkable region the player can get into and not out of |
| ocean-bathymetry-asset-missing | meta.environment.ocean.bathymetry.asset names an asset that is not in assets. Shoreline, 102 (102-105). |
| ocean-bathymetry-not-16bit | The bathymetry asset is not a 16-bit greyscale PNG: not a texture asset, or a path that does not end in .png (and, at load, a PNG whose header says otherwise). The raster is not used. |
| ocean-bathymetry-range-invalid | A bathymetry value that cannot describe a raster: sizeM not above 0 or not finite, stepM not above 0, a non-finite originXz or baseM, or minDepthM outside 0.01..1. |
| ocean-layer-field-mismatch | An ocean wave layer with fields of the other kind: windSpeedMps or fetchKm on a swell, heightM or periodS on a wind layer. |
| ocean-shore-without-bathymetry | meta.environment.ocean.shore without a bathymetry: nothing for the shoreline controls to act on, so they are ignored. Warning: see SEVERITY. |
| ocean-swell-without-period | An ocean swell layer with no periodS: a swell is defined by its period. |
| ocean-wave-mask-asset-missing | meta.environment.ocean.waveMask.asset names an asset that is not in assets. Wave paint (appended after terrain). |
| ocean-wave-mask-not-greyscale | The wave mask asset is not a greyscale PNG: not a texture asset, or a path that does not end in .png (and, at load, a PNG whose header is not greyscale). The mask is not used. |
| ocean-wave-mask-range-invalid | A wave mask value that cannot describe a raster: sizeM not above 0 or not finite, a non-finite originXz, minScale outside 0..1 or maxScale outside 1..4. |
| ocean-weather-not-ascending | A meta.environment.ocean.weather whose timeS values are not strictly ascending (a repeat counts). The blend needs ordered keys. Ocean and buoyancy, 92 (92-98). |
| ocean-wind-out-of-range | An ocean wind or fetch outside its range (wind above 60 m/s or below 0, fetch outside 1..2000 km): the sea uses the nearest limit. Warning: see SEVERITY. |
| out-of-bounds | An entity's world position is outside meta.bounds (critic.check also reads a scale axis under a millimetre or over a kilometre as this code). |
| outliner-folder-stale | Every Outliner folder entry names a root entity |
| outliner-folder-unknown-entity | A meta.outliner.folders entry names no root entity: no entity has that id, or it has a parent (a child, or a part of a prefab instance), which follows its parent rather than a folder. Warning: see SEVERITY. |
| over-budget | Triangles, draw calls, texture MB and dynamic bodies within meta.budgets |
| parent-cycle | Parent chain loops back on itself. |
| particles-source | Exactly one of particles.preset and particles.effect is required, and particles.material is not supported together with an effect yet. |
| physics-quality-invalid | A meta.physics.overrides number is outside its range: solverIterations 1..64 and substeps 1..16 (whole numbers), sleep values 0 or more. |
| plant-material-missing | A foliage recipe whose materials names a project file that does not exist. procedural: names are always present. Emitted by the foliage.* tools, which can see the project. |
| plant-param-invalid | A foliage recipe value the generator cannot take: a parameter that is not a number or a [min, max] pair with min at most max, an unsupported version, an ages entry outside 0..1, or (from the generator) a parameter the species lacks or one outside its allowed range. The message names the parameter. |
| plant-species-unknown | A foliage recipe whose species is not one of the closed species list. Emitted by the recipe validator and by the generator. |
| plant-template-locked | A foliage recipe that sets a parameter its template locks, because changing it breaks the template's look. Emitted by the generator. |
| plant-template-unknown | A foliage recipe whose template names no library or project template. Emitted by the generator and the foliage.* tools (the template library is not part of the contract). |
| plant-too-heavy | A plant whose level-0 mesh has more than 150,000 triangles. Emitted by the generator. |
| plant-variants-invalid | A foliage recipe with variants outside 1..64, or more than 8 ages. |
| play/bad-start | critic.play's from named no goal or entity of the scene, or the player could not be put there |
| play/dead-button | a menu button that, pressed, changed nothing: no screen opened or closed, nothing it shows, no state, save store, sound or game event |
| play/dialog-never-closes | a blocking dialog kept turning pages (each press changed what it shows) and was still up after 24 of them, so the walk could not go on |
| play/drive-hits | a driven player hit obstacles (entities tagged cone, pylon, barrier, …) or drew the game's penalty on the way to a goal; the message lists each hit with where it stood, the speed and frame, the game's penalty events and HUD penalty lines, and a careful retry of that section at 6 m/s |
| play/ended-early | the game put up a screen that owns the input and could not be answered (its own results or game-over screen) before the playtester reached a goal, so the goals after it were not played |
| play/fell-out | the player fell below the scene's bounds on the way to a goal |
| play/interaction-noop | the bot walked to an interactable, pressed interact, and nothing happened: no event, no change in the world, none on screen |
| play/interaction-unreached | the interaction sweep could not walk to an interactable or a trigger to try it |
| play/menu-dead-end | a screen reached from the menus that neither Back nor any of its buttons leaves |
| play/no-goals | the scene has no goal component, so the playtester had nowhere to walk; nothing was driven, no route was tested, and passed only means nothing failed |
| play/no-player | no entity carries a controller or a vehicle component, so the playtester has nothing to drive |
| play/no-response | the playtester pressed every action the game declares, each one many times, and none of them changed the game: no entity, script state, HUD or goal differed from doing nothing |
| play/nothing-to-drive | no entity carries a controller or a vehicle, and the input context in force declares no actions, so the playtester had nothing to press |
| play/over-budget | at the pace the run was making, the goals left would not fit in the simulated time budget, so it stopped between goals instead of running out of time on the way; the goals it played are judged, the rest are skipped |
| play/player-script-error | the player's own behaviour threw or overran its budget during the run; when the engine disabled it and it is what moves the player (input script), the player's behaviour died and the player cannot move, so the playtest stops there |
| play/quit | the game called ctx.session.quit() during the run; a headless engine keeps running |
| play/respawned | the game moved the player somewhere at once on the way to a goal (a respawn at a checkpoint, a send-back to the start): a jump of more than 2 m in a tick the bot did not make; the bot reset its link attempts and tried again |
| play/script-error | a behaviour other than the player's threw or overran its budget during the run, and the engine disabled it (a throw used to show only in the editor's log), so whatever it did stopped happening |
| play/softlock | no progress toward a goal and no change anywhere in the world for a while |
| play/stuck | the bot stopped moving on the way to a goal (blocked by an entity, or no path there), or kept moving for 20 s without its route getting shorter (slid back, fell off the route, missed a jump link) |
| play/timeout | the run spent its simulated time budget before reaching every goal |
| play/trigger-noop | the player walked through a trigger volume and its event never fired |
| play/unknown-goal | critic.play was asked for a goal id the scene does not have |
| play/untested-flows | the scene has no goal component and its project has no self-test scenario (selftest/*.json), so no flow of the game (start, a key pressed, the value or event it should give) was played by anything; passed only means nothing failed |
| player-spawn | No entity carries a spawn component with for: "player". |
| prefab-candidate | No <…> or more identical entities written out one by one |
| prefab-cycle | A prefab that contains itself, through source instances: a.prefab.json holds an instance of b.prefab.json which holds one of a.prefab.json. The message names the whole loop. The instance that closes the loop stays an empty shell; the rest of the scene loads. Nested prefabs, first of 3. |
| prefab-depth | Prefabs nested more than 8 levels deep (the scene instance's own prefab is level 1). The instance that would be the ninth stays an empty shell. Nested prefabs, second of 3. |
| prefab-depth-high | No instance nests prefabs more than <…> levels deep |
| prefab-id-collision | An instance expands to an entity id the scene already has, or its prefab declares an asset key the scene means differently. |
| prefab-invalid | A prefab file that cannot be used: its shape, not exactly one root, an entity outside the root's tree, an id with / or used twice, or a prefab instance inside a version 1 file (a file with a nested instance says version 2), or a version other than 1 and 2. Also an instance with tags or components of its own. |
| prefab-missing | A prefab instance's source does not resolve to a readable .prefab.json in the project. |
| prefab-override-redundant | No prefab override repeats the prefab's own value |
| prefab-override-shadowed | No override stored in a nested prefab is hidden by the instance's own |
| prefab-override-stale | Every prefab override still points at something in its prefab |
| prefab-override-unknown | An override on an instance does not apply to its prefab: no such entity, component or path, or the value does not fit there. Warning: see SEVERITY. |
| prefab-too-large | One instance that expands to more than 10,000 entities, counted as it expands. The instance stays an empty shell. Nested prefabs, third of 3. |
| prefab-unused | Every prefab file is placed in a scene or named by a script |
| primary-camera | The scene does not have exactly one camera with primary: true. |
| project-default-invalid | A scene rule's error on a value the scene takes from its project's defaults (argus.project.json physics, graphics.render, input, audio; D19). The message names the rule, and the manifest pointer to fix. A warning there keeps its own code. |
| render-clouds-without-atmosphere | sky.clouds is set on a sky whose kind is not "atmosphere" (no sky means the default procedural one): clouds are drawn only over the HD renderer's atmosphere sky, so nothing draws them. Fix: set "kind": "atmosphere", or remove clouds. Warning: see SEVERITY. |
| render-field-ignored | A meta.environment.fog field its mode does not read: density or height on linear fog, height or end on exponential, end on height. Warning: see SEVERITY. |
| render-ocean-without-hd | meta.environment.ocean in a project whose render.profile is not hd: the standard renderer draws the sea as a flat lit plane at seaLevel. Buoyancy still works. Warning: see SEVERITY. |
| render-value-range | meta.render.exposure is not more than 0 and at most 64, or meta.render.scale is outside 0.1..1. |
| render-waterways-without-hd | A waterways component in a project whose render.profile is a known profile other than hd: rivers are drawn as flat tinted ribbons, and falls and lakes are not drawn. Warning: see SEVERITY. |
| scale-zero | A scale axis is exactly zero. |
| scene-over-triangle-budget | The scene's meshes add up to more full-detail triangles (each mesh at its asset's triangles) than meta.budgets.triangles. The message names the total and a budget that would hold it. Warning: the scene still loads and plays. |
| scene-unorganized | A big scene is filed into Outliner folders |
| schema-shape | The document does not match the schema: wrong type, missing field, unknown key, bad enum member. |
| shader-compile-error | The shader's WGSL does not compile (a name that does not exist, a type mismatch, a uniformity error). Reported in the agent's own line numbers, with a "did you mean" where one fits. Not emitted by validation: it needs the shader compiler. |
| shader-cost-high | The shader's static cost estimate is over the soft cap for the project's targets but under the hard cap. Warning: see SEVERITY. Not emitted by validation: it needs the shader compiler. |
| shader-cost-over-cap | The shader's static cost estimate (cost units per pixel, or texture fetches) is over the hard cap for the project's targets. Not emitted by validation: it needs the shader compiler. |
| shader-forbidden | The shader uses something the sandbox refuses: a module-scope var, @group/@binding, an entry point, override, an enable directive, textureStore, atomics, barriers, arrayLength, a raw texture or sampler, or discard. Not emitted by validation: it needs the shader compiler. |
| shader-header-invalid | A *.shader.wgsl header or file shape that cannot be read: an unknown //! key, a malformed or repeated line, a header line after the first line of WGSL, no fn surface(, a fn vertex( with no bounds (or bounds with none), a bounds that is not above 0, or a source over 16 KB. The agent's own line:col is in the message; docs/SHADERS.md. |
| shader-loop-unbounded | The shader has a while or loop, a for whose trip count is not a constant of at most 32, more than 256 iterations across nested loops, or an induction variable that is written other than by an increment. Not emitted by validation: it needs the shader compiler. |
| shader-model-mismatch | The functions and the model disagree: model: stylized without both fn light( and fn ambient(, either of them under another model, or tonemap on a model that is not unlit. |
| shader-param-invalid | A param or instance header line that cannot be built: a name that is not camelCase or is declared twice, an unknown type, a default of the wrong type, a [min, max] that is backwards or on a bool, a default outside it, more than 256 B of params, or more than 4 instance floats. Also a material params value of the wrong type for the shader's param. |
| shader-raw-disabled | A *.shader.wgsl says kind: raw or kind: pass (the escape hatch) in a project that has not set render.shaders.raw: true. Reported by the shader compiler, not by validation. |
| shader-texture-invalid | A texture header line that cannot be built: a name that is not camelCase or is declared twice, an unknown kind, a default that is not "white", "black", "flat", "builtin:noise" or a relative path, or more than 6 textures. Also a material params texture that names an unknown builtin: texture. |
| shader-variants-over-cap | The project's shaders compile to more pipeline families than the cap allows. Not emitted by validation: it needs every shader of the project. |
| shot-blend-long | A shot's blendIn.time is longer than the shot, so the blend never finishes, or the first shot has a blendIn with nothing to blend from. Warning: see SEVERITY. |
| shot-keys-unordered | A path shot's key times are not strictly ascending, or a key is past the shot's duration. |
| shot-target-missing | A shot names an entity (follow.entity, a look or orbit center entity) the scene does not have. |
| shots-invalid | A meta.shots timeline that cannot play as written: no shots or an empty path, a duration not above zero, an orbit radius not above zero, a fov outside 0..180 (on a shot or a key), a number that is not finite, a look or orbit center that names both an entity and a point or neither, or a negative blendIn.time. Camera shots, 95 (95-98). |
| sky-asset-wrong-kind | sky.asset, or the deprecated envMap, names an asset whose kind is not envmap. |
| sky-color-ignored | meta.environment.skyColor is set and the sky is not "kind": "color" (no sky means the default procedural one), so nothing reads it and the scene does not show that colour. Fix: add "sky": { "kind": "color", "intensity": 1, "rotation": 0 } to use the colour, or remove skyColor. Warning: see SEVERITY. |
| sky-envmap-conflict | sky.asset and the deprecated envMap name different assets. Warning: see SEVERITY. |
| sky-hdr-needs-asset | sky.kind is "hdr" and no sky.asset names the panorama to use. |
| sky-value-range | A sky number is outside its stated range, or is NaN or infinite, or a sky.background colour is not a hex colour. |
| spring-collider-invalid | A springBones collider with a radius that is not above 0 and at most 10, or an offset or tip entry that is not finite. |
| spring-invalid | A springBones chain that is wrong whatever the rig is: it gives both joints and root/tip, gives neither, gives a tip without a root, or lists no bones; or one of its numbers is outside its range or not finite (stiffness 0..100000, damping 0..1000, radius 0..10, a gravity or tail entry). Bones the rig lacks, a tip that is not below its root, and a bone in two chains are found at load: spring-bone-unknown and spring-chain-bad, runtime codes (docs/RUNTIME-CODES.md). |
| spring-needs-animator | A springBones on an entity with no animator: there is no skeleton to swing, so it does nothing. Warning: see SEVERITY. |
| sprite-frame-missing | A sprite name that resolves to nothing: an animation lists a frame the sprite does not have, or has no frames; animation names an animation it does not have; or two frames or two animations share a name. |
| sprite-invalid | A sprite that cannot draw as written: no frames; pixelsPerMetre, fps or a duration not above zero; opacity or alphaCutoff outside 0..1; a durations list whose length is not the frames'; a rect outside its image's origin or of zero size; a pivot not finite; an image that is not a texture asset; or a second sprite on one entity. |
| sprite-rotation-count-invalid | A sprite frame with a number of views other than 1 (the same from every side) or 2, 4, 8 or 16 (one per direction). |
| static-overlap | Static trimeshes do not intersect |
| steering-gameplay | No behaviour reads ctx.controller.steering, which the engine removed |
| terrain-extent-invalid | A terrain file whose extentM is not above zero on both axes, or is not a whole multiple of its cellSize, or whose cellSize is not above zero. |
| terrain-in-2d-scene | A terrain component in a 2D-kind project: terrain is a 3D feature. Needs the project's kind (SceneContext.projectKind); silent without it. |
| terrain-layer-unknown | A shoreline, material.rules, volume.shape or volume.cliff op of a terrain file names a layer the file's layers does not declare. The message names the nearest layer. |
| terrain-layers-too-many | A terrain file declares more than 8 layers. A terrain material blends at most 8 in one draw, so the terrain used to load and then silently not be drawn. The message names the count and the list. |
| terrain-multiple | A scene with more than one terrain component. Whether two terrains overlap needs their files' extents, which a scene rule cannot read, so a second terrain is refused outright until WorldStream places several. |
| terrain-op-id-duplicate | Two ops of a terrain file's stack share an id. The id seeds the op and names it in agent tools, so it must be unique. |
| terrain-sample-invalid | A terrain file's sampleM, or a detail entry's, that is not 0.25, 0.5, 1, 2 or 4; or a detail region that is not a rectangle whose corners sit on cell boundaries. |
| terrain-transform | An entity with a terrain component whose own transform is rotated or scaled: the entity's translation is the terrain's origin and nothing else. |
| terrain-volume-invalid | A volume.shape or volume.cliff op cannot be built. The message gives the reason: a voxelM not in 0.25, 0.5, 1, 2 or not dividing the terrain's sampleM; a terrain with detail regions (a volume needs one sample spacing); mask or strength on a volume op; a keep part with no add before it; or a number out of its range. |
| terrain-volume-order | A height or material op of a terrain file's stack comes after a volume.shape or volume.cliff op. Volume ops are built on the finished heightfield, so they come last in the stack. |
| terrain/entity-buried | a collider's base is more than 0.25 m under the terrain's ground at its x and z: the entity is sunk into the hill |
| terrain/entity-floating | a static collider's base is more than 0.5 m above the terrain's ground at its x and z (a dynamic body, a controller or a spawn settles by itself and is not checked) |
| terrain/road-buried | a stretch of road (its centre, its edges and the footprint of each wall outside gapsAt, probed every 2 m) is more than 0.1 m under the terrain's ground: a car there drives into the hill and wedges, or over a buried wall; the finding gives sFrom and sTo along the road, the worst line, overWallTop and the terrain cell |
| terrain/spawn-slope | a spawn stands on ground steeper than a character can stand on (the terrain layer's physics slopeLimit there, else the controller's 45 degrees), so it slides off at once |
| terrainmod-no-terrain | A terrainmod whose terrain names no entity with a terrain component, or, with no terrain named, in a scene that has none. |
| tilemap-invalid | A tilemap that cannot draw as written: a tileset image that is not a texture asset; tileSize or grid not whole numbers above zero; margin or spacing not whole numbers from 0; cellSize not above zero; alphaCutoff outside 0..1; a legend key that is not one character, or is "." or " "; no layers, or two with one name; a layer's sortLayer or order out of range; rows of different lengths; a collision layer on an entity with its own collider or rigidbody; or a second tilemap on one entity. |
| tilemap-tile-unknown | A tilemap tile that resolves to nothing: a legend index that is not a whole number below the tileset's columns × rows, or a row character that is neither a legend key nor empty ("." or " "). |
| tilemap-too-large | A tilemap too big to load in one piece: more than 16 layers, a layer of more than 1024 rows or a row of more than 1024 cells, or more than 1,048,576 cells over all layers. Split it over entities. |
| transform-not-finite | A transform component is not finite (NaN or infinity). |
| trigger-needs-trigger-collider | A trigger component sits on an entity with no isTrigger collider. Warning: see SEVERITY. |
| trigger-volume-unheard | A trigger volume that behaviours listen for has a trigger component |
| ui-clipped | an interactive node a clipping ancestor cuts into |
| ui-colour-only | a state that differs from its siblings only in colour |
| ui-contrast | text below the minimum contrast against its resolved background |
| ui-default-font | The game's screens draw in a face of its own, not only the engine's fallback mono font |
| ui-ellipsis | text cut off by an ellipsis, a line limit or a clip, where the rest of the string is not on screen |
| ui-expectation | the live tree is not what the component library meant to build |
| ui-field-no-label | an editable field with nothing saying what it is for |
| ui-font-face-missing | Every @font-face rule names a font file, and a bitmap font an atlas image, that the project has |
| ui-locale-gap | a key the base table has and this locale does not translate |
| ui-matrix-refused | an engine refused a cell of the matrix |
| ui-missing-string | a text key with no string in this locale |
| ui-no-way-back | a screen that takes input, cannot be dismissed, and has no way off it |
| ui-offscreen | an interactive node outside the viewport |
| ui-overlap | two interactive rectangles on top of each other |
| ui-reduced-motion | a transition still running when reduced motion is on |
| ui-relayout | a node relaid out between two frames with nothing touched |
| ui-scroll-hidden | a container that clips content it cannot scroll to |
| ui-start-screen | meta.ui.startScreen is a name no defineScreen could have given a screen. |
| ui-target-size | an interactive target below the minimum size |
| ui-text-overflow | text that does not fit the box it was laid out into |
| ui-undefined-token | a stylesheet reads a token a theme leaves undefined |
| ui-unknown-prop | a node that is not a text carries words, which nothing draws |
| ui-unreachable | a focusable node Tab and directional navigation never reach |
| ui-untranslated | a visible string with no key, in a locale that cannot translate it |
| unlit | Something lights the scene |
| unreachable-goal | Every goal is reachable from the player spawn |
| vehicle-cannot-steer-or-brake | No wheel has steerable above 0, or none has braked above 0. Warning: see SEVERITY. |
| vehicle-capability-absent | The scene carries a vehicle component and this build of the engine has no vehicle capability, so the scene loads and the vehicle is not there.
The first code NO VALIDATOR EMITS — see {@link CODES_NOT_EMITTED_BY_VALIDATION}. | | vehicle-geometry | A wheel sits outside the chassis collider's bounds, a wheel's suspension travel exceeds the ground clearance under the chassis, or the centre of mass is above the collider's top. Warning: see SEVERITY. | | vehicle-invalid | A vehicle that cannot be built: an unknown preset; a part or field missing with no preset to fill it; wheels empty; two wheels sharing an id; no wheel with driven above 0; an empty or unsorted torqueCurve; empty gears; a number non-finite, non-positive where it must be positive, or a fraction outside 0..1; or a wheel visual that names no entity. | | vehicle-needs-dynamic-body | The entity has no dynamic rigidbody, or no non-trigger collider, so there is nothing for the wheels to carry. Warning: see SEVERITY. | | vehicle-value-implausible | A wheel radius outside 0.15..0.6 m or a chassis mass outside 400..8000 kg: most likely a unit mistake. Warning: see SEVERITY. | | vfx-collide-invalid | A *.vfx.json collide module names no surface, a surface that is not ground, water or depth, the same surface twice, or a response that is not kill, bounce or stick. | | vfx-effect-missing | particles.effect names no effect: not a scene asset of kind effect, not a *.vfx.json path, and not one of the builtin:<preset> names. | | vfx-event-invalid | A *.vfx.json emitter's role or events break the event rules: an unknown role or event, a child with spawn or its own events, more than 4 events, a collision event without collide, an emit that names no child, a child targeted twice or by no event, or a child too small for its parent's capacity times count. | | vfx-inherit-invalid | A *.vfx.json emitter's init.inherit (the share of the emitter's own velocity a particle starts with) is not in [0, 1]. | | vfx-max-screen-invalid | A *.vfx.json sprite's render.maxScreen is not a share of the viewport height in (0, 4], or a ribbon sets it (it applies to sprites only). | | vfx-param-invalid | A *.vfx.json binding names a param the effect does not declare, a number field binds a vec3 or colour param (or the reverse), a param name is malformed, or there are more than 16 params. | | vfx-preset-invalid | A *.vfx.json that names an effect preset ("preset": "builtin:fx/<name>") names an unknown preset, a param the preset does not have, or sets anything besides name, preset and params (the param values). | | vfx-shape-invalid | A *.vfx.json sprite names an unknown render.shape (allowed: disc, ring, star, blade, puff, flake), sets a texture or flipbook together with a shape, or sets band or rim without one. | | vfx-texture-invalid | A *.vfx.json sprite texture is empty, absolute, names a drive or climbs out with ... | | vfx-texture-missing | An export packs an effect (*.vfx.json) whose sprite, ribbon or decal texture is a path from the effect file that names no file the project holds; the exporter reports it, so the game never ships the effect without its texture. | | vfx-value-range | A *.vfx.json number is outside its range, a curve or gradient has more than 8 keys or keys that do not increase, a module appears twice, an age curve has no span, or a count (emitters, bursts, capacity, flipbook cells) is out of bounds. | | water-shape-invalid | A water component whose size has an axis that is not a finite number above 0: a lake needs an outline. Lakes, 109 (109-110). | | water-waves-invalid | A water component with a wave value out of range: windMps outside 0..30 or not finite, a non-finite windDirectionRad, a seed that is not a whole number from 0, or a priority that is not a whole number within -100..100. | | watercraft-invalid | A vehicle water number out of its documented range (a negative thrust, a reverse outside 0..1, a rudder.maxAngle of 1.5 rad or more, ...), or a planing fullSpeed not above its minSpeed. | | watercraft-without-buoyancy | A vehicle with a water block on an entity with no buoyancy component: nothing floats it. Watercraft, first of 2. | | waterways-look-invalid | A waterways value out of range: roughness outside 0.02..0.15, flowScale outside 0..4, foam or mist outside 0..2, or a non-finite number, in the component or an override. | | waterways-override-invalid | A waterways override that names none or more than one of river, waterfall and lake, a non-whole or negative id, or more than 64 overrides. | | waterways-without-terrain | A waterways component with no terrain: terrain names no entity with a terrain component, or it is absent and neither this entity nor exactly one other entity is a terrain. Waterways, first of 4. | | wheel-invalid | A wheel that cannot work: no dynamic rigidbody above it; a number non-finite, non-positive where it must be positive, or a fraction outside 0..1; no radius on a wheel no vehicle composes; a second wheel component on one entity; or an entity in its visuals that cannot turn with it (missing, the wheel or above it, below it, with a rigidbody, on another body, or drawn by another wheel). |