---
name: incanto-node-reference
description: GENERATED complete reference of every Incanto node type — props, defaults, kinds, signals, and the METHODS a connection handler can name — plus the machine-readable scene JSON Schema. Use when checking exact prop names, defaults, what you can call on a node, or which node type to use.
---

# Node Reference

> Shipped inside the `incanto` npm package — this document always matches the
> installed engine version. Sibling skills live in `node_modules/incanto/skills/`.

> GENERATED from the engine source by `pnpm generate:reference` — do not edit by hand.
> **Methods** are what a connection's `handler` can name and what your behaviour can
> call; a `param?` is optional. **Reads** are read-only accessors — the questions you
> can ASK a node, which is what a headless harness is usually after. Each entry lists
> the type's OWN methods and reads — every node also has `Node`'s (see its section).
> Every node also accepts the structural fields: `name`, `uid`, `groups`, `tags`, `script`,
> `network`, `children` (see `incanto-scene-json-authoring.md`).
> Machine contract: `node_modules/incanto/schemas/scene.schema.json` — a JSON Schema for
> whole `*.scene.json` files (validate scenes before loading; remember props are
> delta-only: write only non-default values).

## `AnimatedSprite2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `texture` | `""` | string |
| `anchor` | `[0.5,0.5]` | array |
| `flipX` | `false` | boolean |
| `flipY` | `false` | boolean |
| `tint` | `"#ffffff"` | string |
| `opacity` | `1` | number |
| `sheet` | `""` | string |
| `animations` | `{}` | object |
| `autoplay` | `""` | string |

Signals: `animationFinished(name)`

Methods: `play(name)` · `stop()`

## `AnimatedSprite3D` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `texture` | `""` | string |
| `size` | `[1,1]` | array |
| `billboard` | `"y"` | one of: `y` `full` `none` |
| `anchor` | `[0.5,0]` | array |
| `tint` | `"#ffffff"` | string |
| `opacity` | `1` | number |
| `flipX` | `false` | boolean |
| `pixelArt` | `true` | boolean |
| `alphaTest` | `0.5` | number |
| `castShadow` | `false` | boolean |
| `shadowMode` | `"silhouette"` | one of: `silhouette` `blob` |
| `sheet` | `""` | string |
| `frameWidth` | `0` | number |
| `frameHeight` | `0` | number |
| `animations` | `{}` | object |
| `autoplay` | `""` | string |

Signals: `animationFinished(name)`

Methods: `play(name)` · `stop()` · `free()`

## `Area2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `collider` | `{}` | object |
| `enabled` | `true` | boolean |

Signals: `triggerEnter(other)` · `triggerExit(other)`

Methods: `overlapping(group?)`

## `Area3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `collider` | `{}` | object |
| `enabled` | `true` | boolean |

Signals: `triggerEnter(other)` · `triggerExit(other)`

Methods: `overlapping(group?)`

## `AudioPlayer` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `src` | `""` | string |
| `preset` | `"custom"` | one of: `custom` `coin` `pickup` `jump` `hurt` `hit` `explosion` `powerup` `laser` `shoot` `blip` `select` `step` `win` `lose` |
| `volume` | `1` | number |
| `pitch` | `1` | number |
| `seed` | `0` | number |
| `bus` | `"sfx"` | one of: `sfx` `music` |
| `loop` | `false` | boolean |
| `autoplay` | `false` | boolean |
| `spatial` | `false` | boolean |
| `refDistance` | `1` | number |
| `maxDistance` | `50` | number |
| `rolloff` | `"inverse"` | one of: `inverse` `linear` `exponential` |

Signals: `finished`

Methods: `playAt(when)` · `play()` · `free()` · `stop()` · `retryPending()`

Reads: `playing: boolean`

## `Billboard3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `mode` | `"screen"` | one of: `screen` `y` `none` |

## `BoneAttachment3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `target` | `""` | node path · **required** |
| `bone` | `""` | string |

Methods: `free()`

Reads: `attachedBone: Object3D | null`

## `BoneLookAt3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `target` | `""` | node path · **required** |
| `bone` | `"Head"` | string |
| `lookAt` | `""` | node path |
| `maxAngleDeg` | `75` | number |
| `weight` | `0.85` | number |
| `forwardAxis` | `"+z"` | one of: `+x` `-x` `+y` `-y` `+z` `-z` |

Reads: `engaged: number` · `attachedBone: Object3D | null`

## `Camera2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `follow` | `""` | node path |
| `smoothing` | `0` | number |
| `zoom` | `1` | number |
| `limits` | `[]` | array |
| `current` | `false` | boolean |
| `blendSeconds` | `0` | number |

Methods: `makeCurrent(blendSeconds?)` · `clampedCenter(vw, vh)`

Reads: `effectiveZoom: number`

## `Camera3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `fov` | `60` | number |
| `minHorizontalFov` | `0` | number |
| `near` | `0.1` | number |
| `far` | `1000` | number |
| `current` | `false` | boolean |
| `lookAt` | `""` | node path |
| `blendSeconds` | `0` | number |

Methods: `makeCurrent(blendSeconds?)` · `viewFov(aspect)`

## `CharacterBody2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `collider` | `{}` | object |
| `enabled` | `true` | boolean |
| `velocity` | `[0,0]` | array |
| `stickToGround` | `true` | boolean |
| `slopeLimitDeg` | `45` | number |
| `stepHeight` | `35` | number |
| `collideWithCharacters` | `true` | boolean |
| `pushes` | `0` | number |

Signals: `triggerEnter(other)` · `triggerExit(other)`

Methods: `moveAndSlide()` · `isOnWall()` · `wallSide()` · `isOnCeiling()` · `isOnFloor()`

## `CharacterBody3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `collider` | `{}` | object |
| `enabled` | `true` | boolean |
| `velocity` | `[0,0,0]` | array |
| `stickToGround` | `true` | boolean |
| `slopeLimitDeg` | `45` | number |
| `stepHeight` | `0.35` | number |
| `collideWithCharacters` | `true` | boolean |
| `pushes` | `0` | number |

Signals: `triggerEnter(other)` · `triggerExit(other)`

Methods: `moveAndSlide()` · `isOnWall()` · `wallNormal()` · `isOnCeiling()` · `isOnFloor()`

## `CharacterController2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `mode` | `"platformer"` | one of: `platformer` `topDown` |
| `maxSpeed` | `220` | number |
| `jumpHeight` | `64` | number |
| `moveAction` | `"move"` | string |
| `jumpAction` | `"jump"` | string |
| `coyoteSeconds` | `0` | number |
| `jumpBufferSeconds` | `0` | number |
| `jumpCutMultiplier` | `1` | number |
| `maxJumps` | `1` | number |
| `dashSpeed` | `0` | number |
| `dashSeconds` | `0.15` | number |
| `dashAction` | `"dash"` | string |
| `wallSlideSpeed` | `0` | number |
| `wallJumpImpulse` | `[0,0]` | array |
| `crouchHeight` | `0` | number |
| `crouchSpeedMultiplier` | `0.5` | number |
| `crouchAction` | `"crouch"` | string |

Signals: `movementStateChanged(state)`

## `CharacterController3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `enabled` | `true` | boolean |
| `view` | `"free"` | one of: `free` `firstPerson` `quarter` `side` |
| `camDistance` | `4` | number |
| `eyeHeight` | `0.64` | number |
| `maxSpeed` | `2.5` | number |
| `sprintMultiplier` | `2` | number |
| `jumpVelocity` | `4` | number |
| `sprintJumpMultiplier` | `1.2` | number |
| `coyoteSeconds` | `0` | number |
| `jumpBufferSeconds` | `0` | number |
| `jumpCutMultiplier` | `1` | number |
| `maxJumps` | `1` | number |
| `airControl` | `0.2` | number |
| `wallJumpImpulse` | `[0,0]` | array |
| `wallSlideSpeed` | `0` | number |
| `fallGravity` | `2.5` | number |
| `floatHeight` | `0.01` | number |
| `stepHeight` | `0.35` | number |
| `slopeLimitDeg` | `55` | number |
| `swimSpeed` | `1.6` | number |
| `swimDepth` | `null` | any JSON — see the skill for the accepted shapes, or number |
| `diveAction` | `"dive"` | string |
| `climbSpeed` | `1.5` | number |
| `ladderGroup` | `"ladder"` | string |
| `mantleHeight` | `0` | number |
| `crouchHeight` | `0` | number |
| `crouchSpeedMultiplier` | `0.5` | number |
| `crouchAction` | `"crouch"` | string |
| `dashSpeed` | `0` | number |
| `dashSeconds` | `0.25` | number |
| `dashCooldown` | `0` | number |
| `dashAction` | `"dash"` | string |
| `dashBackstep` | `false` | boolean |
| `mouseLook` | `true` | boolean |
| `zoomMin` | `0` | number |
| `zoomMax` | `0` | number |
| `pitchMin` | `-1.3` | number |
| `pitchMax` | `1.5` | number |
| `pitchStart` | `0` | number |
| `cameraCollision` | `true` | boolean |
| `camera` | `"drive"` | one of: `drive` `none` |
| `platformCarry` | `true` | boolean |
| `turnSpeed` | `100` | number |
| `camLerp` | `25` | number |
| `moveAction` | `"move"` | string |
| `jumpAction` | `"jump"` | string |
| `sprintAction` | `"sprint"` | string |
| `skinPath` | `"../Skin"` | node path |
| `skinYawOffset` | `0` | number |
| `lockOnAction` | `""` | string |
| `lockGroup` | `"enemy"` | string |
| `lockRange` | `12` | number |
| `animations` | `{}` | object |

Signals: `movementStateChanged(state)` · `wallJumped` · `lockChanged` · `dashed`

Methods: `lock(node)` · `unlock()` · `toggleLock()`

## `ColorRect2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `size` | `[100,100]` | array |
| `color` | `"#ffffff"` | string |
| `opacity` | `1` | number |
| `anchor` | `[0.5,0.5]` | array |

Methods: `free()`

## `DirectionalLight3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `color` | `"#ffffff"` | string |
| `intensity` | `1` | number |
| `castShadow` | `false` | boolean |
| `shadowArea` | `75` | number |
| `shadowMapSize` | `2048` | number |
| `shadowFollowsCamera` | `false` | boolean |

## `Flock3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `mesh` | `"box"` | one of: `box` `sphere` `capsule` `plane` `cylinder` `gem` |
| `size` | `[1,1,1]` | array |
| `material` | `{}` | object |
| `transforms` | `[]` | array |
| `castShadow` | `false` | boolean |
| `receiveShadow` | `false` | boolean |
| `collider` | `null` | any JSON — see the skill for the accepted shapes, or object |
| `count` | `30` | number |
| `radius` | `20` | number |
| `height` | `8` | number |
| `speed` | `6` | number |
| `turn` | `2.5` | number |
| `separation` | `1.5` | number |
| `sight` | `5` | number |
| `alignment` | `1` | number |
| `cohesion` | `1` | number |
| `follow` | `""` | node path |

Methods: `boids()`

## `Flowers3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `density` | `"sparse"` | one of: `lush` `sparse` `none`, or number |
| `area` | `[20,20]` | array |
| `seed` | `1` | number |
| `varieties` | `[]` | array |
| `palette` | `[]` | array |
| `height` | `0.45` | number |
| `clustering` | `0.6` | number |
| `sway` | `0.5` | number |
| `drape` | `null` | any JSON — see the skill for the accepted shapes, or boolean |
| `avoidWater` | `true` | boolean |
| `terrain` | `""` | node path |

Methods: `free()`

## `Foliage3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `2` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `kind` | `"grass"` | one of: `grass` `flowers` `reeds` |
| `style` | `"mesh"` | one of: `blades` `simple` `mesh` `tufts` |
| `tuftStyle` | `"grass"` | one of: `grass` `fern` |
| `area` | `[20,20]` | array |
| `density` | `12` | number |
| `maxInstances` | `50000` | number |
| `height` | `0.25` | number |
| `colorA` | `"#4d7232"` | string |
| `colorB` | `"#9aab55"` | string |
| `groundColor` | `"#1f3015"` | string |
| `sunDirection` | `[0.5,0.8,0.3]` | array |
| `fadeStart` | `60` | number |
| `fadeEnd` | `90` | number |
| `sway` | `0.6` | number |
| `interaction` | `true` | boolean |
| `coverage` | `0.85` | number |
| `flowers` | `0` | number |
| `seed` | `1` | number |
| `drape` | `null` | any JSON — see the skill for the accepted shapes, or boolean |
| `avoidWater` | `true` | boolean |
| `terrain` | `""` | node path |

Methods: `free()`

## `HudLayer` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `zIndex` | `100` | number |
| `visible` | `true` | boolean |
| `focusNavigation` | `false` | boolean |
| `letterbox` | `0` | number |

Methods: `focusables()` · `focus(widget)`

## `InstancedMesh3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `mesh` | `"box"` | one of: `box` `sphere` `capsule` `plane` `cylinder` `gem` |
| `size` | `[1,1,1]` | array |
| `material` | `{}` | object |
| `transforms` | `[]` | array |
| `castShadow` | `false` | boolean |
| `receiveShadow` | `false` | boolean |
| `collider` | `null` | any JSON — see the skill for the accepted shapes, or object |

Methods: `free()`

Reads: `instanceCount: number`

## `Joint2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `type` | `"revolute"` | one of: `fixed` `revolute` `prismatic` `rope` `spring` |
| `target` | `""` | node path · **required** |
| `anchor` | `[0,0]` | array |
| `targetAnchor` | `[0,0]` | array |
| `axis` | `[0,1]` | array |
| `limits` | `[]` | array |
| `motorSpeed` | `0` | number |
| `motorStrength` | `20` | number |
| `length` | `0` | number |
| `stiffness` | `50` | number |
| `damping` | `5` | number |
| `collide` | `null` | any JSON — see the skill for the accepted shapes, or boolean |

## `Joint3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `type` | `"spherical"` | one of: `fixed` `spherical` `revolute` `prismatic` `rope` `spring` |
| `target` | `""` | node path · **required** |
| `anchor` | `[0,0,0]` | array |
| `targetAnchor` | `[0,0,0]` | array |
| `axis` | `[0,1,0]` | array |
| `limits` | `[]` | array |
| `motorSpeed` | `0` | number |
| `motorStrength` | `20` | number |
| `length` | `0` | number |
| `stiffness` | `50` | number |
| `damping` | `5` | number |
| `collide` | `null` | any JSON — see the skill for the accepted shapes, or boolean |

## `Label` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `text` | `""` | string |
| `fontSize` | `16` | number |
| `color` | `"#ffffff"` | string |
| `font` | `"monospace"` | string |
| `align` | `"left"` | string |
| `opacity` | `1` | number |

Methods: `free()`

## `Label3D` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `texture` | `""` | string |
| `size` | `[1,1]` | array |
| `billboard` | `"full"` | one of: `y` `full` `none` |
| `anchor` | `[0.5,0]` | array |
| `tint` | `"#ffffff"` | string |
| `opacity` | `1` | number |
| `flipX` | `false` | boolean |
| `pixelArt` | `true` | boolean |
| `alphaTest` | `0.5` | number |
| `castShadow` | `false` | boolean |
| `shadowMode` | `"silhouette"` | one of: `silhouette` `blob` |
| `text` | `""` | string |
| `height` | `0.3` | number |
| `color` | `"#ffffff"` | string |
| `font` | `"sans-serif"` | string |
| `outline` | `"#000000"` | string |

Methods: `free()`

## `LoftMesh3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `sections` | `[]` | array |
| `slices` | `24` | number |
| `smooth` | `4` | number |
| `material` | `{}` | object |
| `castShadow` | `false` | boolean |
| `receiveShadow` | `false` | boolean |

Methods: `free()`

## `MeshInstance3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `mesh` | `"box"` | one of: `box` `sphere` `capsule` `plane` `cylinder` `gem` |
| `size` | `[1,1,1]` | array |
| `material` | `{}` | object |
| `castShadow` | `false` | boolean |
| `receiveShadow` | `false` | boolean |

Methods: `free()`

## `ModelInstance3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `model` | `""` | string |
| `animation` | `""` | string |
| `targetHeight` | `0` | number |
| `castShadow` | `false` | boolean |
| `animationLoop` | `true` | boolean |
| `animationSpeed` | `1` | number |
| `animationOffset` | `0` | number |
| `animationUpper` | `""` | string |
| `animationUpperLoop` | `false` | boolean |
| `upperBodyRoot` | `"Spine"` | string |
| `receiveShadow` | `false` | boolean |
| `tint` | `""` | string |
| `metalness` | `-1` | number |
| `roughness` | `-1` | number |

Signals: `animationFinished(name)`

Methods: `poseNode(name, rotation)` · `findBone(name)` · `boneNames()` · `availableAnimations()`

## `NetworkSpawner` — `incanto/net`

| Prop | Default | Kind |
|---|---|---|
| `source` | `"users"` | string |
| `scene` | `""` | string · **required** |
| `interpolate` | `true` | boolean |

Signals: `spawned(node, key)` · `despawned(node, key)`

Methods: `replicatedPosition(node)`

## `Node` — `incanto`

_No props (structural fields only)._

Methods: `addChild(child)` · `removeChild(child)` · `reparent(newParent)` · `findChild(name, recursive?)` · `getRoot()` · `getNodeByUid(uid)` · `getNodesByName(name)` · `getPath()` · `wiringPath()` · `getNode(path)` · `getNodeOrNull(path)` · `addToGroup(group)` · `removeFromGroup(group)` · `isInGroup(group)` · `declareSignal(name)` · `declaredSignalNames()` · `signal(name)` · `on(signal, fn, opts?)` · `off(signal, fn)` · `listenerCount(signal)` · `emit(signal, ...args)` · `queueFree()` · `free()`

Reads: `uid: string | null` · `name: string` · `parent: Node | null` · `children: readonly Node[]` · `groups: ReadonlySet<string>` · `tree: SceneTree | null` · `isReady: boolean` · `freed: boolean`

## `Node2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |

Methods: `free()`

Reads: `effectiveRenderOrder: number`

## `Node3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |

Methods: `applyGroundSnap()` · `free()`

Reads: `effectiveRenderOrder: number`

## `OmniLight3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `color` | `"#ffffff"` | string |
| `intensity` | `1` | number |
| `range` | `0` | number |

## `Particles2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"effects"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `preset` | `"custom"` | one of: `custom` `fire` `smoke` `sparks` `fireworks` `explosion` `flash` `lightning` `rain` `snow` `magic` |
| `emitting` | `true` | boolean |
| `worldSpace` | `false` | boolean |
| `rate` | `40` | number |
| `burst` | `0` | number |
| `lifetime` | `[0.6,1.2]` | array |
| `speed` | `[40,120]` | array |
| `directionDeg` | `-90` | number |
| `spreadDeg` | `30` | number |
| `gravity` | `[0,0]` | array |
| `drag` | `0` | number |
| `sizeStart` | `8` | number |
| `sizeEnd` | `2` | number |
| `colorStart` | `"#ffffff"` | string |
| `colorEnd` | `"#ffffff"` | string |
| `paletteColors` | `[]` | array |
| `alphaStart` | `1` | number |
| `alphaEnd` | `0` | number |
| `shimmer` | `0` | number |
| `blend` | `"add"` | one of: `add` `normal` |
| `maxParticles` | `256` | number |
| `emitBox` | `[0,0]` | array |
| `drift` | `[0,0]` | array |

Signals: `finished`

Methods: `particles()` · `free()` · `replay()`

Reads: `aliveCount: number`

## `Particles3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"effects"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `preset` | `"custom"` | one of: `custom` `fire` `smoke` `sparks` `fireworks` `explosion` `flash` `lightning` `rain` `snow` `magic` |
| `emitting` | `true` | boolean |
| `worldSpace` | `false` | boolean |
| `rate` | `40` | number |
| `burst` | `0` | number |
| `lifetime` | `[0.6,1.2]` | array |
| `speed` | `[40,120]` | array |
| `directionDeg` | `-90` | number |
| `spreadDeg` | `30` | number |
| `gravity` | `[0,0]` | array |
| `drag` | `0` | number |
| `sizeStart` | `8` | number |
| `sizeEnd` | `2` | number |
| `colorStart` | `"#ffffff"` | string |
| `colorEnd` | `"#ffffff"` | string |
| `paletteColors` | `[]` | array |
| `alphaStart` | `1` | number |
| `alphaEnd` | `0` | number |
| `shimmer` | `0` | number |
| `blend` | `"add"` | one of: `add` `normal` |
| `depthTest` | `true` | boolean |
| `maxParticles` | `256` | number |
| `emitBox` | `[0,0,0]` | array |
| `drift` | `[0,0,0]` | array |

Signals: `finished`

Methods: `particles()` · `replay()` · `free()`

Reads: `aliveCount: number`

## `Ragdoll3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `target` | `"../Skin"` | node path |
| `mass` | `70` | number |
| `damping` | `3` | number |
| `lifetime` | `0` | number |
| `collide` | `true` | boolean |

Signals: `activated` · `reset`

Methods: `limbs()` · `activate(pose?)` · `reset()` · `free()`

## `Respawn` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `target` | `".."` | node path |
| `below` | `null` | any JSON — see the skill for the accepted shapes, or number |
| `to` | `[]` | array |
| `resetVelocity` | `true` | boolean |

Signals: `respawned`

## `RigidBody2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `collider` | `{}` | object |
| `enabled` | `true` | boolean |
| `mass` | `1` | number |
| `gravityScale` | `1` | number |
| `fixedRotation` | `false` | boolean |
| `friction` | `0.5` | number |
| `restitution` | `0` | number |
| `linearVelocity` | `[0,0]` | array |
| `angularVelocity` | `0` | number |
| `linearDamping` | `0` | number |
| `angularDamping` | `0` | number |

Signals: `triggerEnter(other)` · `triggerExit(other)`

Methods: `applyImpulse(impulse)`

Reads: `velocity: number[]`

## `RigidBody3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `collider` | `{}` | object |
| `enabled` | `true` | boolean |
| `mass` | `1` | number |
| `gravityScale` | `1` | number |
| `fixedRotation` | `false` | boolean |
| `friction` | `0.5` | number |
| `restitution` | `0` | number |
| `linearVelocity` | `[0,0,0]` | array |
| `angularVelocity` | `[0,0,0]` | array |
| `linearDamping` | `0` | number |
| `angularDamping` | `0` | number |
| `buoyancy` | `0` | number |

Signals: `triggerEnter(other)` · `triggerExit(other)`

Methods: `applyImpulse(impulse)`

Reads: `velocity: number[]`

## `River3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `path` | `[]` | array |
| `width` | `6` | number |
| `widths` | `[]` | array |
| `depth` | `0.8` | number |
| `flowSpeed` | `1.6` | number |
| `colors` | `{}` | object |
| `absorption` | `0.5` | number |
| `opacity` | `0.85` | number |
| `foam` | `1` | number |
| `ripples` | `1` | number |
| `sunDirection` | `[0.5,0.8,0.3]` | array |
| `sunColor` | `"#fff6e0"` | string |
| `sunIntensity` | `1` | number |
| `terrain` | `""` | node path |
| `carve` | `true` | boolean |
| `flowForce` | `1` | number |
| `spray` | `1` | number |

Methods: `sampleAt(x, z)` · `fallsAt()` · `free()`

## `SpotLight3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `color` | `"#ffffff"` | string |
| `intensity` | `1` | number |
| `range` | `0` | number |
| `coneDeg` | `60` | number |
| `penumbra` | `0.3` | number |
| `castShadow` | `false` | boolean |
| `shadowMapSize` | `1024` | number |
| `lookAt` | `""` | node path |

## `Sprite2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `texture` | `""` | string |
| `anchor` | `[0.5,0.5]` | array |
| `flipX` | `false` | boolean |
| `flipY` | `false` | boolean |
| `tint` | `"#ffffff"` | string |
| `opacity` | `1` | number |

Methods: `free()`

## `Sprite3D` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `texture` | `""` | string |
| `size` | `[1,1]` | array |
| `billboard` | `"y"` | one of: `y` `full` `none` |
| `anchor` | `[0.5,0]` | array |
| `tint` | `"#ffffff"` | string |
| `opacity` | `1` | number |
| `flipX` | `false` | boolean |
| `pixelArt` | `true` | boolean |
| `alphaTest` | `0.5` | number |
| `castShadow` | `false` | boolean |
| `shadowMode` | `"silhouette"` | one of: `silhouette` `blob` |

Methods: `free()`

## `StaticBody2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `collider` | `{}` | object |
| `enabled` | `true` | boolean |
| `friction` | `0.5` | number |
| `restitution` | `0` | number |

Signals: `triggerEnter(other)` · `triggerExit(other)`

## `StaticBody3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `collider` | `{}` | object |
| `enabled` | `true` | boolean |
| `friction` | `0.5` | number |
| `restitution` | `0` | number |

Signals: `triggerEnter(other)` · `triggerExit(other)`

## `Terrain3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"terrain"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `size` | `[200,200]` | array |
| `maxHeight` | `28` | number |
| `seed` | `1` | number |
| `resolution` | `128` | number |
| `theme` | `"island"` | one of: `island` `alpine` `plains` `desert` `grassland` `forest` `savanna` `snow` `wetland` `volcanic` `custom` |
| `roughness` | `0.5` | number |
| `detail` | `4` | number |
| `flatThreshold` | `0.95` | number |
| `islandEdge` | `null` | any JSON — see the skill for the accepted shapes, or boolean |
| `layers` | `[]` | array |
| `textureBase` | `"https://agent8-games.verse8.io/assets/3D/default/textures/terrain"` | string |
| `basins` | `[]` | array |
| `channels` | `[]` | array |
| `wetline` | `null` | any JSON — see the skill for the accepted shapes, or object |

Methods: `heightAt(x, z)` · `resolvedLayers()` · `free()`

## `TileMap2D` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0]` | array |
| `rotation` | `0` | number |
| `static` | `false` | boolean |
| `scale` | `[1,1]` | array |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `visible` | `true` | boolean |
| `texture` | `""` | string |
| `tileSize` | `32` | number |
| `columns` | `0` | number |
| `cells` | `[]` | array |
| `legend` | `{}` | object |
| `colors` | `{}` | object |
| `solid` | `[]` | array |
| `opacity` | `1` | number |

Methods: `grid()` · `cellAt(worldX, worldY)` · `tileAt(cx, cy)` · `worldAt(cx, cy)` · `setTile(cx, cy, char)` · `free()`

Reads: `renderedTileCount: number`

## `Timer` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `waitTime` | `1` | number |
| `oneShot` | `false` | boolean |
| `autostart` | `false` | boolean |

Signals: `timeout`

Methods: `start(time?)` · `stop()`

Reads: `timeLeft: number`

## `Trail3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `width` | `0.3` | number |
| `color` | `"#ffffff"` | string |
| `opacity` | `0.8` | number |
| `seconds` | `0.6` | number |
| `emitting` | `true` | boolean |
| `additive` | `false` | boolean |
| `minDistance` | `0.05` | number |

Methods: `free()`

Reads: `pointCount: number`

## `Tree3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `tier` | `"medium"` | one of: `simple` `medium` `high` |
| `type` | `"conifer"` | one of: `conifer` `broadleaf` `dead` `bush` |
| `seed` | `1` | number |
| `height` | `6` | number |
| `count` | `1` | number |
| `area` | `[10,10]` | array |
| `trunkColor` | `"#7a5a3a"` | string |
| `canopyColor` | `"#4a7c3f"` | string |
| `leafTexture` | `""` | string |
| `leafFadeStart` | `0` | number |
| `leafFadeEnd` | `0` | number |
| `leafShadows` | `true` | boolean |
| `drape` | `null` | any JSON — see the skill for the accepted shapes, or boolean |
| `avoidWater` | `true` | boolean |
| `terrain` | `""` | node path |

Methods: `trunks()` · `free()`

## `UILayer` — `incanto/2d`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"top-left"` | one of: `top-left` `top` `top-right` `left` `center` `right` `bottom-left` `bottom` `bottom-right` |

## `UiBanner` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"center"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `false` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `size` | `42` | number |
| `seconds` | `2` | number |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `bannerShown`

Methods: `show(text, opts?)` · `clear()`

Reads: `showing: string`

## `UiBar` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `false` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `value` | `100` | number |
| `max` | `100` | number |
| `width` | `180` | number |
| `height` | `14` | number |
| `color` | `"#4ade80"` | string |
| `lowColor` | `"#ef4444"` | string |
| `lowThreshold` | `0.3` | number |
| `background` | `"rgba(0,0,0,0.5)"` | string |
| `label` | `""` | string |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped`

Methods: `setValue(value, max?)` · `setMax(max)`

Reads: `ratio: number`

## `UiButton` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `text` | `"OK"` | string |
| `size` | `16` | number |
| `color` | `"#ffffff"` | string |
| `background` | `"rgba(255,255,255,0.14)"` | string |
| `disabled` | `false` | boolean |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `pressed`

Methods: `press()`

## `UiDialogue` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"bottom"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `charsPerSecond` | `40` | number |
| `autoAdvanceSeconds` | `0` | number |
| `width` | `520` | number |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `lineShown` · `choiceMade` · `dialogueFinished`

Methods: `say(speaker, text, choices?)` · `advance()` · `choose(index)` · `clear()`

Reads: `active: boolean` · `showing: string`

## `UiFrameCapSelect` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `label` | `"Frame rate"` | string |
| `options` | `"30,60,120,0"` | string |
| `value` | `""` | string |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `changed`

## `UiImage` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `false` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `src` | `""` | string |
| `width` | `48` | number |
| `height` | `48` | number |
| `fit` | `"contain"` | one of: `contain` `cover` `fill` |
| `tint` | `""` | string |
| `opacity` | `1` | number |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped`

## `UiLanguageSelect` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `label` | `"Language"` | string |
| `options` | `""` | string |
| `value` | `""` | string |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `changed`

## `UiMinimap` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `false` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `size` | `160` | number |
| `radius` | `40` | number |
| `follow` | `""` | node path |
| `dots` | `{}` | object |
| `heading` | `""` | node path |
| `self` | `"#ffffff"` | string |
| `dotSize` | `6` | number |
| `background` | `"rgba(0,0,0,0.45)"` | string |
| `shape` | `"circle"` | one of: `circle` `square` |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped`

Methods: `centre()` · `markers()`

## `UiMuteToggle` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `label` | `""` | string |
| `value` | `false` | boolean |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `changed`

## `UiPanel` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `false` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `layout` | `"column"` | one of: `column` `row` `grid` |
| `columns` | `4` | number |
| `gap` | `8` | number |
| `padding` | `12` | number |
| `background` | `"rgba(0,0,0,0.55)"` | string |
| `radius` | `10` | number |
| `width` | `0` | number |
| `height` | `0` | number |
| `border` | `""` | string |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped`

## `UiQualitySelect` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `label` | `"Quality"` | string |
| `options` | `"low,medium,high"` | string |
| `value` | `""` | string |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `changed`

## `UiRenderScaleSelect` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `label` | `"Resolution"` | string |
| `options` | `"0.5,0.75,1"` | string |
| `value` | `""` | string |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `changed`

## `UiSelect` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `label` | `""` | string |
| `options` | `""` | string |
| `value` | `""` | string |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `changed`

Methods: `choose(value)`

## `UiSlider` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `label` | `""` | string |
| `value` | `0.5` | number |
| `min` | `0` | number |
| `max` | `1` | number |
| `step` | `0.01` | number |
| `width` | `180` | number |
| `color` | `"#6ee7dc"` | string |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `changed`

Methods: `choose(value)`

## `UiText` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `false` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `text` | `""` | string |
| `format` | `""` | string |
| `size` | `16` | number |
| `color` | `"#ffffff"` | string |
| `shadow` | `true` | boolean |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped`

Methods: `setText(value)`

Reads: `shown: string`

## `UiToggle` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `label` | `""` | string |
| `value` | `false` | boolean |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `changed`

Methods: `choose(value)`

## `UiVolumeSlider` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `true` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `label` | `""` | string |
| `value` | `0.5` | number |
| `min` | `0` | number |
| `max` | `1` | number |
| `step` | `0.01` | number |
| `width` | `180` | number |
| `color` | `"#6ee7dc"` | string |
| `bus` | `"master"` | one of: `master` `sfx` `music` |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `changed`

## `UiWaypoint` — `incanto`

| Prop | Default | Kind |
|---|---|---|
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
| `visible` | `true` | boolean |
| `focusable` | `false` | boolean |
| `draggable` | `false` | boolean |
| `dropTarget` | `false` | boolean |
| `target` | `""` | node path |
| `label` | `""` | string |
| `color` | `"#ffd54f"` | string |
| `size` | `22` | number |
| `distance` | `true` | boolean |
| `clamp` | `true` | boolean |
| `margin` | `40` | number |
| `hideWithin` | `0` | number |
| `arriveWithin` | `0` | number |
| `from` | `""` | node path |

Signals: `dragStarted` · `dragCancelled` · `droppedOn` · `dropped` · `arrived`

Methods: `distanceNow()` · `screen(view?)`

## `Vehicle3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `wheels` | `[]` | array |
| `suspensionStiffness` | `30` | number |
| `suspensionCompression` | `2.3` | number |
| `suspensionRelaxation` | `3.5` | number |
| `maxTravel` | `0.3` | number |
| `friction` | `2.5` | number |
| `sideFriction` | `1` | number |
| `maxSteerDeg` | `32` | number |
| `engineForce` | `1500` | number |
| `brakeForce` | `40` | number |
| `moveAction` | `"move"` | string |
| `brakeAction` | `"brake"` | string |
| `enabled` | `true` | boolean |

Methods: `wheel(i)` · `specs()`

Reads: `body: RigidBody3D` · `maxSteer: number`

## `VoxelGrid3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `voxels` | `[]` | array |

Signals: `blocksChanged`

Methods: `blockCount()` · `tileAt(x, y, z)` · `setBlocks(blocks)` · `addBlock(b)` · `removeBlockAt(x, y, z)` · `blocks()` · `free()`

## `Water3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `1` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `size` | `[40,40]` | array |
| `color` | `"#2a6fbe"` | string |
| `opacity` | `0.8` | number |
| `waveHeight` | `0.04` | number |
| `waveSpeed` | `1` | number |
| `drag` | `1.5` | number |
| `quality` | `"fancy"` | one of: `fancy` `simple` |
| `colors` | `{}` | object |
| `reflection` | `true` | boolean |
| `reflectionInterval` | `1000` | number |
| `mirror` | `false` | boolean |
| `mirrorInterval` | `33` | number |
| `ssr` | `true` | boolean |
| `swellSteepness` | `0.35` | number |
| `foam` | `true` | boolean |
| `reflectivity` | `null` | any JSON — see the skill for the accepted shapes, or number |
| `interaction` | `true` | boolean |
| `splash` | `true` | boolean |
| `sunDirection` | `[0.5,0.8,0.3]` | array |
| `sunColor` | `"#fff5d6"` | string |
| `sunIntensity` | `1` | number |
| `detailStrength` | `0.26` | number |
| `absorption` | `0.15` | number |
| `refraction` | `true` | boolean |
| `underwater` | `true` | boolean, or object |
| `swell` | `0` | number |
| `swellDirectionDeg` | `0` | number |
| `swellWavelength` | `30` | number |
| `whitecaps` | `0` | number |
| `bed` | `""` | node path |
| `wind` | `0` | number |
| `choppiness` | `0.85` | number |
| `preset` | `"custom"` | one of: `custom` `ocean` `pool` `lake` `pond` |
| `causticsAbove` | `0` | number |
| `shoreWaves` | `0` | number |

Signals: `entered(body)` · `exited(body)`

Methods: `underwaterAt(camX, camY, camZ)` · `free()` · `heightAt(x, z)` · `depthAt(x, y, z)`

## `WaterCutout3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `size` | `[2,1,1]` | array |
| `enabled` | `true` | boolean |

## `Weather3D` — `incanto/3d`

| Prop | Default | Kind |
|---|---|---|
| `position` | `[0,0,0]` | array |
| `rotation` | `[0,0,0]` | array |
| `static` | `false` | boolean |
| `scale` | `[1,1,1]` | array |
| `visible` | `true` | boolean |
| `renderOrder` | `0` | number |
| `orderGroup` | `"effects"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
| `snapToGround` | `null` | any JSON — see the skill for the accepted shapes, or boolean or number |
| `preset` | `"custom"` | one of: `custom` `fire` `smoke` `sparks` `fireworks` `explosion` `flash` `lightning` `rain` `snow` `magic` |
| `emitting` | `true` | boolean |
| `worldSpace` | `false` | boolean |
| `rate` | `40` | number |
| `burst` | `0` | number |
| `lifetime` | `[0.6,1.2]` | array |
| `speed` | `[40,120]` | array |
| `directionDeg` | `-90` | number |
| `spreadDeg` | `30` | number |
| `gravity` | `[0,0]` | array |
| `drag` | `0` | number |
| `sizeStart` | `8` | number |
| `sizeEnd` | `2` | number |
| `colorStart` | `"#ffffff"` | string |
| `colorEnd` | `"#ffffff"` | string |
| `paletteColors` | `[]` | array |
| `alphaStart` | `1` | number |
| `alphaEnd` | `0` | number |
| `shimmer` | `0` | number |
| `blend` | `"add"` | one of: `add` `normal` |
| `depthTest` | `true` | boolean |
| `maxParticles` | `256` | number |
| `emitBox` | `[0,0,0]` | array |
| `drift` | `[0,0,0]` | array |
| `kind` | `"rain"` | one of: `rain` `snow` |
| `intensity` | `0.6` | number |
| `radius` | `20` | number |
| `height` | `12` | number |
| `wind` | `[0,0]` | array |
| `follow` | `""` | node path |

Signals: `finished`

## Gameplay behaviors — `incanto/gameplay`

Ready-made `Behavior`s auto-registered by `createGame2D`/`createGame3D` (opt out
with `gameplay: false`). Attach via `"script": {"name": "...", "props": {...}}` and
wire their signals through scene `connections`. Full guide: `incanto-gameplay-behaviors.md`.

### `Blast`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `radius` | `4` | number |
| `damage` | `40` | number |
| `falloff` | `"linear"` | one of: `linear` `none` |
| `groups` | `""` | string |
| `when` | `"died"` | string |
| `self` | `false` | boolean |
| `throughWalls` | `true` | boolean |

Signals: `blasted`

Methods: `blast()`

Reads: `spent: boolean`

### `Buoyancy`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `water` | `""` | node path |
| `draft` | `0.35` | number |
| `stiffness` | `3` | number |
| `damping` | `3.5` | number |
| `drift` | `0.6` | number |
| `drag` | `0.9` | number |
| `samples` | `4` | number |
| `size` | `[1,1]` | array |

Signals: `submerged` · `surfaced`

### `CameraShake`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `falloff` | `0.28` | number |

Methods: `shake(magnitude, seconds?)`

### `Carry`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `action` | `"grab"` | string |
| `throwAction` | `"throw"` | string |
| `range` | `2.2` | number |
| `group` | `"carryable"` | string |
| `maxMass` | `30` | number |
| `holdDistance` | `1.2` | number |
| `holdHeight` | `0.5` | number |
| `throwSpeed` | `9` | number |
| `gain` | `14` | number |
| `inheritMotion` | `1` | number |
| `facePath` | `"../Skin"` | node path |

Signals: `grabbed` · `dropped` · `thrown`

Methods: `grab()` · `drop()` · `throw()`

### `Chase`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `target` | `""` | node path |
| `targetGroup` | `""` | string |
| `retargetEvery` | `0.25` | number |
| `speed` | `60` | number |
| `stopRange` | `0` | number |
| `loseRange` | `0` | number |
| `moveParent` | `false` | boolean |
| `requireSight` | `false` | boolean |
| `ground` | `null` | any JSON — see the skill for the accepted shapes, or boolean |
| `facePath` | `""` | node path |
| `turnSpeed` | `100` | number |

Signals: `reachedTarget` · `lostTarget`

Reads: `chasing: Node | null`

### `ChaseCamera`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `target` | `""` | node path · **required** |
| `back` | `8` | number |
| `up` | `3` | number |
| `smoothing` | `0.85` | number |

Methods: `snap()`

### `Checkpoint`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `respawn` | `""` | node path · **required** |
| `group` | `"player"` | string |
| `once` | `true` | boolean |
| `dropBelow` | `0` | number |

Signals: `activated`

Methods: `announce()`

### `Clickable`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `button` | `0` | number |
| `maxDistance` | `0` | number |

Signals: `clicked` · `hovered` · `unhovered`

### `Collector`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `group` | `"player"` | string |

Signals: `totalChanged(total)`

Methods: `collect(value)` · `announce()`

### `Currency`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `amount` | `0` | number |
| `max` | `0` | number |

Signals: `changed` · `earned` · `spent` · `refused`

Methods: `canAfford(cost)` · `spend(cost)` · `earn(gain)` · `setAmount(next)` · `announce()`

Reads: `room: number`

### `DamageOnContact`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `amount` | `10` | number |
| `targetGroup` | `""` | string |
| `oncePerTarget` | `true` | boolean |
| `repeatEvery` | `0` | number |
| `destroySelf` | `false` | boolean |
| `freeParent` | `false` | boolean |

Signals: `dealtDamage(amount, target)`

### `DayNight`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `daySeconds` | `240` | number |
| `startHour` | `10` | number |
| `maxSunElevationDeg` | `55` | number |
| `nightDarkness` | `0.75` | number |
| `paused` | `false` | boolean |

Signals: `dayPhaseChanged`

### `FaceTarget`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `targetGroup` | `""` | string · **required** |
| `range` | `0` | number |
| `facePath` | `""` | node path |
| `turnSpeed` | `6` | number |
| `aimTolerance` | `6` | number |

Signals: `acquired` · `lostTarget` · `aimed` · `lostAim`

### `FloatAway`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `rise` | `1` | number |
| `seconds` | `0.7` | number |
| `hold` | `0.3` | number |
| `drift` | `0` | number |
| `freeOnEnd` | `true` | boolean |

### `FollowCamera`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `target` | `""` | node path · **required** |
| `offset` | `[]` | array |
| `smoothing` | `0` | number |
| `deadzone` | `0` | number |

Methods: `shake(magnitude, seconds?)`

### `GameFlow`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `restartAction` | `"restart"` | string |
| `pauseAction` | `"pause"` | string |
| `freezeOnEnd` | `true` | boolean |
| `bannerPath` | `"%Banner"` | node path |
| `pausePanelPath` | `"%PauseMenu"` | node path |
| `titlePanelPath` | `""` | node path |
| `saveSlots` | `""` | string |

Signals: `flowChanged`

Methods: `save(slot?)` · `hasSave(slot?)` · `continueFrom(slot?)` · `screen(path)` · `back()` · `gameOver(text?, color?)` · `win(text?, color?)` · `pause()` · `resume()` · `restart()` · `goToScene(sceneJson, opts?)`

### `GroupCamera`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `targets` | `"player"` | string |
| `offset` | `[0,12,14]` | array |
| `minZoom` | `1` | number |
| `maxZoom` | `2.5` | number |
| `padding` | `0.25` | number |
| `smoothing` | `0.15` | number |
| `lookAtGroup` | `true` | boolean |

Methods: `members()` · `snap()`

### `Health`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `max` | `100` | number |
| `regenPerSec` | `0` | number |
| `invulnerableFor` | `0` | number |
| `freeOnDeath` | `false` | boolean |
| `knockback` | `0` | number |
| `knockbackSeconds` | `0.15` | number |
| `knockUp` | `0` | number |
| `staggerSeconds` | `0` | number |
| `applyKnockback` | `true` | boolean |
| `freeParent` | `false` | boolean |

Signals: `damaged(amount, current)` · `healed(amount, current)` · `died` · `revived` · `healthChanged` · `staggerEnded`

Methods: `takeLift()` · `damage(n, from?)` · `protect(seconds)` · `heal(n)` · `revive(hp?)` · `reviveFull()` · `kill()` · `announce()`

Reads: `staggered: boolean` · `knocked: boolean` · `kickVelocity: number[]` · `isDead: boolean` · `invulnerableRemaining: number`

### `Interactable`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `action` | `"interact"` | string |
| `range` | `2` | number |
| `actorGroup` | `"player"` | string |
| `prompt` | `""` | string |
| `focus` | `"any"` | one of: `any` `nearest` `facing` |
| `coneDeg` | `40` | number |

Signals: `interacted(actor)` · `focused` · `unfocused`

### `Lifetime`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `seconds` | `1` | number |
| `startOnSignal` | `false` | boolean |
| `freeParent` | `false` | boolean |

Signals: `expired`

Methods: `startTimer()`

### `Mount`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `rider` | `""` | node path · **required** |
| `steed` | `".."` | node path |
| `drive` | `""` | node path |
| `walk` | `""` | node path |
| `skin` | `"Skin"` | string |
| `saddle` | `""` | node path |
| `skinOnSaddle` | `[0,0,0]` | array |
| `skinOnRider` | `[0,0,0]` | array |
| `dismountAt` | `[1.8,0.3,0]` | array |

Signals: `mounted` · `dismounted`

Methods: `mount()` · `dismount()` · `toggle()`

### `MoveTo`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `to` | `[]` | array · **required** |
| `duration` | `1` | number |
| `ease` | `"easeInOut"` | one of: `linear` `easeIn` `easeOut` `easeInOut` |
| `startOnSignal` | `false` | boolean |

Signals: `arrived`

Methods: `start()` · `finish()`

### `Oscillate`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `axis` | `"y"` | one of: `x` `y` `z` |
| `amplitude` | `1` | number |
| `frequency` | `1` | number |
| `mode` | `"position"` | one of: `position` `rotation` `scale` |

### `PathFollow`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `speed` | `120` | number |
| `loop` | `false` | boolean |
| `moveParent` | `false` | boolean |
| `path` | `""` | node path |
| `autoStart` | `true` | boolean |
| `facePath` | `""` | node path |
| `turnSpeed` | `100` | number |

Signals: `waypointReached` · `arrived`

Methods: `setPath(waypoints)` · `start()` · `stop()`

Reads: `moving: boolean`

### `Patrol`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `points` | `[]` | array · **required** |
| `speed` | `60` | number |
| `loop` | `true` | boolean |
| `mode` | `"loop"` | one of: `loop` `pingpong` |
| `pauseAt` | `0` | number |
| `moveParent` | `false` | boolean |
| `facePath` | `""` | node path |
| `turnSpeed` | `100` | number |

Signals: `reachedPoint(index)`

### `Phases`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `at` | `[]` | array |
| `health` | `""` | node path |

Signals: `phaseChanged` · `phase2` · `phase3` · `phase4` · `phase5`

Methods: `read(current, max)` · `announce()`

### `Pickup`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `value` | `1` | number |
| `kind` | `"coin"` | string |
| `collectorGroup` | `"player"` | string |

Signals: `collected(value, other)`

### `PrefabShelf`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `prefabs` | `""` | string |

Methods: `names()` · `template(name)` · `make(name)`

### `Projectile`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `speed` | `300` | number |
| `direction` | `null` | any JSON — see the skill for the accepted shapes, or array or string |
| `gravity` | `0` | number |

Methods: `aim(direction?, carry?)`

### `SavePoint`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `game` | `"game"` | string |
| `slot` | `"1"` | string |
| `label` | `""` | string |
| `scene` | `""` | string |
| `restoreOnReady` | `false` | boolean |
| `probeOnReady` | `false` | boolean |
| `keep` | `[]` | node path |

Signals: `saved` · `saveFailed` · `restored` · `noSave` · `hasSave`

Methods: `probe()` · `slotScene()` · `save()` · `restore()` · `clear()` · `announce()`

Reads: `playtime: number`

### `ScoreKeeper`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `score` | `0` | number |
| `lives` | `0` | number |
| `scoreToWin` | `0` | number |

Signals: `scoreChanged(score)` · `won` · `lost` · `lifeLost(lives)` · `livesChanged`

Methods: `addScore(n)` · `setScore(value)` · `loseLife()` · `announce()`

Reads: `won: boolean` · `lost: boolean`

### `Shatter`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `pieces` | `8` | number |
| `impulse` | `4` | number |
| `spin` | `6` | number |
| `lifetime` | `2.5` | number |
| `when` | `"died"` | string |
| `mesh` | `""` | node path |
| `free` | `true` | boolean |

Signals: `shattered`

Methods: `break()`

### `Sight`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `range` | `12` | number |
| `coneDeg` | `70` | number |
| `targetGroup` | `"player"` | string |
| `facingPath` | `"../Skin"` | node path |
| `eyeHeight` | `0.6` | number |
| `chestHeight` | `0.3` | number |
| `fillSeconds` | `0` | number |
| `los` | `true` | boolean |

Signals: `spotted` · `lost`

Methods: `sees(node)` · `seen()`

### `Spawner`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `prefab` | `""` | node path · **required** |
| `interval` | `1` | number |
| `max` | `0` | number |
| `at` | `[]` | array |
| `autoStart` | `true` | boolean |
| `total` | `0` | number |
| `into` | `""` | node path |

Signals: `spawned(node)` · `finished`

Methods: `start()` · `stop()` · `spawn()`

Reads: `liveCount: number`

### `Turret`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `targetGroup` | `"enemy"` | string |
| `requireSight` | `false` | boolean |
| `range` | `6` | number |
| `damage` | `10` | number |
| `cooldown` | `0.6` | number |
| `shelf` | `""` | node path |
| `prefab` | `""` | string |
| `muzzle` | `[]` | array |
| `arc` | `"flat"` | one of: `flat` `low` `high` |
| `into` | `""` | node path |
| `facePath` | `""` | node path |
| `turnSpeed` | `100` | number |

Signals: `acquired` · `fired` · `lost`

### `Wander`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `speed` | `40` | number |
| `radius` | `50` | number |
| `changeEvery` | `2` | number |

### `WaveSpawner`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `waves` | `[]` | array · **required** |
| `autoStart` | `true` | boolean |

Signals: `spawned(node)` · `waveStarted(index)` · `waveCleared(index)` · `allCleared`

Methods: `start()`

Reads: `wave: number` · `waveCount: number`

### `ZombieAI`

| Prop | Default | Kind |
|---|---|---|
| `enabled` | `true` | boolean |
| `aggroTarget` | `""` | node path |
| `aggroRange` | `12` | number |
| `deAggroRange` | `0` | number |
| `chaseSpeed` | `4` | number |
| `wanderSpeed` | `1.4` | number |
| `wanderRadius` | `8` | number |
| `wanderChangeEvery` | `3` | number |
| `goalTarget` | `""` | node path |
| `stopRange` | `1.2` | number |
| `moveParent` | `false` | boolean |

Signals: `enteredAggro` · `exitedAggro` · `movementStateChanged`

