Component Reference
Every component type Awaken registers, with its fields, types, and defaults. Components are the data you attach to entities; systems and the renderer read them each frame. For the entity/component model see GameObjects & Components.
How components work
A component is plain data with no methods, described by a reflection spec. defineComponent(name, fields, create) returns a ComponentType whose fields are FieldSpecs - each a { name, type, default }. Because the spec is data:
- Serialization is automatic. The scene serializer walks
fieldsand reads/writes each one, so a new field ships with no serializer changes. See Data Formats. - The Inspector is automatic. Each
FieldSpec.typepicks an editor control -number→ drag field,color→ swatch,enum→ dropdown,assetRef→ asset picker, and so on. AshowIfpredicate can hide a field conditionally (e.g. a collider'sradiuswhen the shape is a mesh).
📸 Screenshot - save as img/api-inspector-reflection.png
The Inspector showing a selected object's components, with each FieldSpec.type rendered as its control (a color swatch, a vec3 triple, an enum dropdown) - the reflection-driven UI these field tables describe.
The enabled flag
Every component silently gains an enabled field (bool, default true), injected by defineComponent as ENABLED_FIELD. It mirrors Unity's Behaviour.enabled:
- It is stored only when explicitly
false- an enabled component writes nothing, keeping scenes lean. - Systems skip a disabled component (a disabled
Lightisn't gathered, a disabledScriptslot tears down, a disabledCollideris excluded from collision tests). - It is hidden from the Inspector body (
showIfreturns false); the Inspector's per-component header checkbox drives it instead.
This lives on ComponentBase, which every component interface extends. It is separate from the entity-level active and Static flags, which live on the World (setActive/setStatic), not on any component.
The registered components
These seventeen types make up the editor's component registry (the add-menu, Inspector, and serializer all read from it). Field types come from FieldType.
Transform · @awaken/core
Local position/rotation/scale. Every visible or spatial object has one; it composes up the hierarchy into a world matrix.
| Field | Type | Default |
|---|---|---|
position | vec3 | {0, 0, 0} |
rotation | quat | {0, 0, 0, 1} |
scale | vec3 | {1, 1, 1} |
MeshRenderer · @awaken/render
Makes an entity visible: which mesh to draw and its base PBR surface. opacity < 1 (or transparent) routes it to the alpha-blended pass.
| Field | Type | Default |
|---|---|---|
mesh | assetRef | "cube" |
color | color | [0.8, 0.8, 0.85] |
metallic | number | 0.0 |
roughness | number | 0.6 |
texture | assetRef | "" (none → white) |
opacity | number | 1.0 |
transparent | bool | false |
castShadow | bool | true |
receiveShadow | bool | true |
doubleSided | bool | false |
alphaCutoff | number | 0.5 |
emissive | color | [0, 0, 0] |
normalTexture | assetRef | "" |
dataVertexColors | bool | false |
normalTexture is a tangent-space normal map. Awaken stores normal maps two-channel (bc5-rg-unorm) and reconstructs Z in the shader; a normal map read as three channels leaves z = -1, which turns the surface black and immune to every lighting setting.
dataVertexColors means "vertex colours are shader data, do not tint albedo with them" - what a generated mesh wants when it packs values per vertex.
See PBR & Lighting. Clear castShadow on a mesh that shouldn't drop a shadow (backdrops, ground fill). (The old per-renderer "static" flag is now the entity-level Static flag.)
The built-in mesh ids are cube, sphere, plane, quad, cylinder, and capsule. quad is a unit quad in the XY plane facing +Z (the plane builtin lies flat on XZ, so it is edge-on to a camera looking down -Z); the Add menu's 2D group ▸ Sprite builds a quad MeshRenderer with transparent: true and castShadow: false, to pair with an orthographic 2D camera.
MeshMaterial · @awaken/render
Attaches an authored Material (custom WGSL hooks) by id, overriding the default PBR shading.
| Field | Type | Default |
|---|---|---|
material | assetRef | "" (none) |
The interface also carries a runtime overrides map (per-object parameter values), set through the Shader Editor rather than serialized as a reflected field.
Light · @awaken/render
A directional, point or spot light. intensity scales the colour; range bounds a point or spot.
| Field | Type | Default | Notes |
|---|---|---|---|
kind | enum | "directional" | directional | point | spot |
color | color | [1, 1, 1] | Multiplied by intensity before it reaches the shader, so the two are interchangeable in the result |
intensity | number | 1 | Direct lighting carries no 1/π, so ~1 is roughly a fully-lit surface. Not clamped |
range | number | 10 | Point and spot falloff radius. Ignored by a directional light |
spotAngle | number | 60 | Spot only: the full cone angle in degrees. The edge is feathered over the outer quarter |
Directional lights are always kept when a scene has more lights than the shader's budget; point lights compete for the rest by brightness and nearness to the camera, unless clustered lighting is on.
See Shadows - the first directional light casts cascaded shadows.
LodGroup · @awaken/render
Swaps this object's mesh for a cheaper one as the camera gets further away. Imported from a source engine's LOD group, which lists one mesh per level and shows one at a time.
| Field | Type | Default | Notes |
|---|---|---|---|
meshes | string | "" | Comma-separated mesh asset ids, one per level, highest detail first. One entry or none means no switching |
distances | string | "" | Comma-separated ascending distances past which each next level takes over, so one fewer entry than meshes |
The object keeps one MeshRenderer throughout - only the mesh id changes - so materials, colliders and everything else stay put. A switch fires only once the camera has moved a further 10% past a boundary, so an object sitting exactly on one does not flicker. See Performance.
Camera · @awaken/render
Defines the game camera's projection. The first active, enabled Camera is the render viewpoint in Game/Play; a second camera is ignored until the first is disabled or deleted.
| Field | Type | Default | Notes |
|---|---|---|---|
projection | enum | "perspective" | perspective | orthographic |
fov | number | 60 (degrees) | vertical FOV; perspective only |
orthoSize | number | 5 | half the view height in world units (Unity's orthographicSize); orthographic only |
near | number | 0.1 | |
far | number | 1000 |
orthographic drops perspective foreshortening, so a sprite keeps the same on-screen size at any depth - the projection a 2D or isometric game uses. The Add menu's 2D group ▸ 2D Camera (Orthographic) spawns one preset to projection: "orthographic", orthoSize: 5. See Camera.
Animator · @awaken/runtime
Per-entity skeletal-animation playback state. References a clip + skeleton asset; the animation system samples the clip at time, builds bone matrices, and CPU-skins the mesh each frame. Only these are authored in the Inspector:
| Field | Type | Default | Notes |
|---|---|---|---|
clip | assetRef | "" | hidden when an AnimStateMachine is present (the graph owns the clip) |
skeleton | assetRef | "" | skeleton asset this entity is skinned to |
speed | number | 1 | playback rate; negative reverses |
loop | bool | true | hidden when an AnimStateMachine is present |
The rest are runtime state - written by the animation system or scripts, hidden from the Inspector, but reflected fields so they persist:
- Playback:
playing(bool) andtime(seconds into the clip). - Crossfade:
fadeClip/fadeTime/fadeDuration/fadeElapsed.playClip(id, { fade, speed, loop })starts a crossfade - whilefadeClipis set the system samples both clips and blends the current pose toward the target overfadeseconds (coreblendPoses), then commits. - Play window:
clipStart/clipEnd(plusfadeStart/fadeEnd), normalized[0,1]fractions of the clip's duration, so a state can play only a slice of a longer clip. - Root motion:
rootDx/rootDz- the clip's character-local horizontal displacement this frame, read by a controller viaapi.rootMotion()to drive ground movement without foot-slide.flatRootY(bool) hands the animation's vertical to physics: while set, the system flattens the baked pelvis rise out of the pose and skips foot IK, so a physics jump doesn't double the clip's rise. A script flips it, e.g.api.setRootMotionVertical(!airborne).
A clip authored for one rig plays on a different character via humanoid cross-rig retargeting (per-slot bone mapping + auto-T-pose + geometric frame-map); auto-avatars are built at import, and a whole animation pack can import to rig-space clips before any character exists, then bind per character.
INFO
Skeletons, baked clips, and skins ride the exported .awaken.json / game.html container, and the animation system + foot IK run in the shipped player - animated characters animate in an export identically to editor Play.
Limitations
CPU skinning only (no GPU skinning path); up to 4 bone influences per vertex; glTF cubicspline tracks are sampled as linear. There are no blend-spaces / speed-matched locomotion yet.
See Animation.
AnimStateMachine · @awaken/runtime
Drives an Animator from an authored animation graph - states plus declarative-condition transitions - instead of hand-playing clips. Gameplay writes parameters (api.setAnimParam, api.setAnimTrigger); each frame the graph takes the first firing transition and crossfades the Animator to the target state's clip. The Animator may live on this entity or a child mesh, so a machine on a parent capsule drives the skinned child.
| Field | Type | Default | Notes |
|---|---|---|---|
graph | assetRef | "" | the authored AnimGraph asset (or a built-in id) |
clips | clipMap | {} | per-character binding: each state's logical clip name → this character's baked clip id |
state | string | "" | runtime-only active state (hidden; seeds to the graph's initial) |
params (a live bag gameplay writes) is a plain object, not a reflected field - any param name works and it re-seeds from the graph's defaults, so it isn't serialized.
The graph is authored in the editor's Anim Graph tab. Transitions can fire from a specific state or from "*" (any state), gate on parameter conditions, and consume one-shot triggers. The clip binding (clips) is what makes one graph reusable across the hero and every NPC - each binds its own baked clips to the graph's logical names. A built-in LOCOMOTION_GRAPH (id builtin:locomotion) and a starter tps-locomotion graph ship ready to use.
See Animation and the ScriptApi Reference.
Ragdoll · @awaken/runtime
Hands a skinned character from animation to physics. When active flips true (via api.ragdoll(vx, vy, vz)), the current posed skeleton is handed to physics - a dynamic capsule per major humanoid bone, linked by spherical joints - and each frame the bodies are read back into the bone matrices so the mesh skins to the physics pose. The character crumples, collides with the world, and flops.
| Field | Type | Default | Notes |
|---|---|---|---|
active | bool | false | set true to turn into a ragdoll; persists (a dead character stays a ragdoll) |
seedVx | number | 0 | world velocity every body inherits at activation (hidden runtime field) |
seedVy | number | 0 | |
seedVz | number | 0 |
Experimental
Joint limits are generous - the ragdoll flops loosely rather than posing realistically.
See Animation.
BoneAnchor · @awaken/runtime
Makes an entity a live mirror of one named skeleton bone: each frame the animation system writes that bone's animated local pose into the entity's Transform, so anything parented under the anchor - a sword under LeftHand, a hat under Head - rides the bone with the animation through the normal parent-transform composition (no special attach logic). The editor's "Expand skeleton" action spawns one anchor per bone, mirroring the bone hierarchy; a bone's owning character is the nearest ancestor carrying an Animator.
| Field | Type | Default | Notes |
|---|---|---|---|
bone | string | "" | skeleton bone name (stable across re-rigs, unlike an index) |
See Animation.
SkinBones · @awaken/runtime
Keeps a skinned model's mesh live: every frame the bone child entities under it (one per skeleton bone, created by the importer) drive the mesh by CPU skinning, so rotating a bone - with the editor gizmo, or from a script via api.setBoneRotation - bends the mesh as it does in the source engine.
| Field | Type | Default | Notes |
|---|---|---|---|
skeleton | assetRef | "" | The skeleton asset the mesh is skinned to. Empty, or naming an unknown skeleton, leaves the mesh at its imported shape |
Bones are matched to descendant entities by name, the same convention BoneAnchor uses; a missing bone entity falls back to that bone's bind local, so deleting part of the chain degrades rather than collapsing the mesh. Nothing recomputes while no bone moves, so an unposed model costs nothing per frame. An Animator with a clip set takes over instead - clip playback owns the skin then.
Volume · @awaken/render
A post-processing volume: an effect stack blended over the scene's base look while the camera is inside it. This is Unity's Volume, authorable as an object.
| Field | Type | Default | Notes |
|---|---|---|---|
mode | enum | "local" | local grades only while the camera is inside (or within blendDistance of) the shape; global grades everywhere and ignores the shape |
shape | enum | "box" | box or sphere, centred on the object and carrying its rotation and scale |
size | vec3 | 5,5,5 | Box half-extents in metres before scale, along the object's own axes |
radius | number | 5 | Sphere radius, multiplied by the largest world-scale axis so a scaled sphere stays a sphere |
priority | number | 0 | Application order, ascending. The highest is applied last and wins |
weight | number | 1 | Multiplier on the computed influence, clamped 0..1 |
blendDistance | number | 0 | The fade ramp outside the bounds. 0 is a hard switch at the boundary |
A volume's name is no guide to what it does: a global volume ignores its shape entirely. Each effect also carries per-field overrides, so a volume can blend only the fields it actually sets; an effect with no override entry blends all of its fields.
RigidBody · @awaken/runtime
Marks an entity as physics-simulated. In Play it becomes a dynamic Rapier body.
| Field | Type | Default |
|---|---|---|
velocity | vec3 | {0, 0, 0} |
useGravity | bool | true |
restitution | number | 0.3 (bounciness) |
See Rigidbody.
Collider · @awaken/runtime
A collision body made of one or more shapes (colliderShapes - a list rendered as Inspector blocks). A new Collider starts with a single box shape.
| Field | Type | Default |
|---|---|---|
shapes | colliderShapes | one default box shape |
Each ColliderShape has:
| Shape field | Type | Default | Notes |
|---|---|---|---|
kind | enum | "box" | box | sphere | capsule | cylinder | mesh |
center | vec3 | {0, 0, 0} | local offset |
size | vec3 | {0.5, 0.5, 0.5} | box half-extents |
radius | number | 0.5 | sphere/capsule/cylinder |
height | number | 2 | capsule/cylinder height |
mesh | string | "" | kind:"mesh" asset id ("" = render mesh) |
convex | bool | false | convex hull vs exact triangles |
trigger | bool | false | sensor: reports overlaps, doesn't block |
enabled | bool | true | |
pinned | bool? | (unset) | keep the shape world-anchored, ignoring the object's own motion |
See Colliders.
AudioSource · @awaken/runtime
Plays an audio clip, optionally on Play start.
| Field | Type | Default |
|---|---|---|
clip | assetRef | "" |
volume | number | 1 |
loop | bool | false |
playOnStart | bool | true |
tempo | number | 1 |
transpose | number | 0 |
instrument | number | -1 |
timbre | enum | "rich" |
The last four are MIDI only and ignored for a recording. See Audio and Changing the performance.
Script · @awaken/runtime
Attaches one or more script behaviours (scriptList - Inspector blocks). Each entry references a script by stable id and carries its per-instance parameter overrides + entity references.
| Field | Type | Default |
|---|---|---|
scripts | scriptList | one empty entry |
Each ScriptEntry has name (script id), params (public-field overrides), refs (entity-reference fields), and enabled. See Script Parameters and the Code Panel.
Tag · @awaken/runtime
A string tag for lookup via api.findByTag, so a script finds an object by tag instead of by name (which changes when you rename it).
| Field | Type | Default |
|---|---|---|
value | string | "" |
UINode · @awaken/runtime
A screen-space UI element (HUD text, a panel, a button, or an image), rendered as a DOM overlay in both the editor Game view and the shipped player. A UI element carries a Transform (so it is a first-class entity in the hierarchy/selection), but the overlay ignores it: position comes from anchor plus the pixel offsets, not the Transform.
| Field | Type | Default | Notes |
|---|---|---|---|
kind | enum | "text" | text | panel | button | image |
anchor | enum | "top-left" | 9-point anchor (corners/edges/center) |
x | number | 20 | pixel offset from the anchor |
y | number | 20 | |
w | number | 0 | 0 = auto (fit content) |
h | number | 0 | 0 = auto |
text | string | "Text" | |
fontSize | number | 24 | |
color | color | [1, 1, 1] | text / foreground |
bg | color | [0, 0, 0] | panel / button background |
opacity | number | 0.5 | background alpha (and the image's alpha) |
visible | bool | true | scripts toggle via api.ui.show/hide |
image | string | "" | kind:"image": imported texture/sprite id to draw (api.ui.setImage swaps it) |
fit | enum | "contain" | kind:"image": contain | cover | stretch - how the sprite fills w×h |
rotation | number | 0 | degrees clockwise about the centre (driven mostly by UI animation) |
scaleX | number | 1 | horizontal scale about the centre |
scaleY | number | 1 | vertical scale about the centre |
font | string | "" | font-family: an imported .ttf/.otf name, or "" for the default system font |
kind:"button" is the only clickable kind; text, panel, and image are click-through. See UI and Scripting UI.
UIAnimator · @awaken/runtime
Plays a UIClip on a UI widget - this entity plus its descendant UINodes, which the clip's tracks address by name. driveUIAnimators advances the playhead each frame and writes the sampled values (x/y/w/h/opacity/rotation/scale/colour) onto the nodes before the overlay syncs. UI clips are imported from Unity .anim files.
| Field | Type | Default | Notes |
|---|---|---|---|
clip | string | "" | UIClip id (from AssetStore.uiClips) |
playing | bool | true | whether the playhead advances; api.ui.play/stop toggle it |
speed | number | 1 | playback rate (0 = frozen) |
time | number | 0 | runtime playhead in seconds (set to 0 to restart) |
See UI and Scripting UI.
ParticleEmitter · @awaken/core
Plays a particle effect at this entity - fire, smoke, dust, a jet of sparks. The effect asset holds every tuning value; the component only says which effect and whether it is running.
| Field | Type | Default | Notes |
|---|---|---|---|
effect | assetRef | "" | ParticleEffect asset id ("" = none). An unknown id is skipped silently - the emitter simply emits nothing. |
playing | bool | true | Clear it to stop emitting; the emitter's particles and GPU buffers are released, and re-enabling starts a fresh pool. |
Each frame the particle engine advances one live-particle pool per emitter and uploads the result to the renderer's billboard pass. An emitter is driven only when its whole subtree is active, the component is enabled, and playing is true.
The emitter's world transform is applied at spawn: it places the emission shape and aims the launch direction (the emitter's local +Y). Particles then live in world space, so a moving emitter trails its particles rather than carrying them.
INFO
Emitters simulate live while you edit, not only in Play - a frozen emitter would show nothing at all, so a placed campfire has to burn in the Viewport to be tunable. Scripted api.burst one-shots are the exception: scripts run in Play.
See Particles and the Particle Editor.
See also
- GameObjects & Components - attaching and editing components.
- The Inspector - the reflection-driven UI over these fields.
- @awaken/core → component -
defineComponent,FieldSpec,FieldType. - Data Formats & Versions - how these fields serialize into a scene.