incanto 0.4.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/2d.d.ts +80 -6
- package/dist/2d.js +4 -4
- package/dist/3d.d.ts +200 -15
- package/dist/3d.js +4 -4
- package/dist/{audio-player-DqUR3XFs.d.ts → audio-player-DkBqRTs4.d.ts} +1 -1
- package/dist/{behavior-BAQq7HGM.d.ts → behavior-CWhW3oa6.d.ts} +54 -0
- package/dist/{create-game-CZHROKcT.js → create-game-B_sW_eiE.js} +59 -27
- package/dist/{create-game-DiTq3-fQ.js → create-game-DkbZCNaV.js} +292 -14
- package/dist/debug.d.ts +1 -1
- package/dist/{duplicate-DP2WPYom.js → duplicate-BEvGBtb_.js} +1 -1
- package/dist/{gameplay-Ccruc3Wd.js → gameplay-CDFgSG6z.js} +293 -24
- package/dist/gameplay.d.ts +113 -2
- package/dist/gameplay.js +2 -2
- package/dist/index.d.ts +139 -5
- package/dist/index.js +59 -6
- package/dist/{loader-CGs_G-r0.js → loader-B4OEXDZ8.js} +60 -0
- package/dist/{loader-Mo0KghCv.d.ts → loader-D2u0fVW2.d.ts} +1 -1
- package/dist/net.d.ts +1 -1
- package/dist/net.js +1 -1
- package/dist/{particle-sim-DYuSUxvK.js → particle-sim-CFkILGwh.js} +84 -3
- package/dist/{particle-sim-CbN4YUuH.d.ts → particle-sim-CwJ5rI_P.d.ts} +3 -0
- package/dist/{physics-2d-KuMWPTf6.js → physics-2d-Cgli1aju.js} +95 -10
- package/dist/{physics-3d-DmNCeh58.js → physics-3d-CBAQ12LY.js} +121 -43
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-DPEV9_9t.js → register-BJCfuuZ2.js} +79 -5
- package/dist/{register-B0gq63VW.js → register-C35HDZpm.js} +2 -2
- package/dist/{register-BRy8FNox.js → register-Dd7Juujf.js} +389 -49
- package/dist/{register-BuUV1_KB.js → register-Dl_ixIJe.js} +275 -2
- package/dist/test.d.ts +2 -2
- package/dist/test.js +10 -10
- package/editor/assets/{agent8-DryTXVd4.js → agent8-MciFwn0v.js} +1 -1
- package/editor/assets/index-mofVSmuA.js +7417 -0
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +980 -126
- package/skills/incanto-3d-models.md +24 -1
- package/skills/incanto-building-2d-games.md +6 -0
- package/skills/incanto-building-3d-games.md +46 -1
- package/skills/incanto-gameplay-behaviors.md +60 -0
- package/skills/incanto-hud.md +58 -0
- package/skills/incanto-node-reference.md +148 -0
- package/skills/incanto-physics-and-input.md +47 -0
- package/editor/assets/index-N8se-PhP.js +0 -7365
|
@@ -53,7 +53,30 @@ scales so the bounding box stands that many units tall — composes with the nod
|
|
|
53
53
|
reactive at runtime), `animation` (see below), `tint` (hex; `""`=off — multiplies into
|
|
54
54
|
every material to RESKIN one shared GLB into many variants, e.g. base human → green
|
|
55
55
|
zombie; clones materials per instance so other instances are untouched),
|
|
56
|
-
`
|
|
56
|
+
`metalness`/`roughness` (0..1 overrides applied to EVERY material; `-1`=keep authored —
|
|
57
|
+
low-poly kits usually ship fully rough, so `metalness: 0.6, roughness: 0.25` turns flat
|
|
58
|
+
paint into a glinting clear-coat under the scene's sky IBL; per-instance clones like
|
|
59
|
+
tint), `castShadow`/`receiveShadow`, plus the usual Node3D transform.
|
|
60
|
+
|
|
61
|
+
## Animating named sub-nodes (wheels, turrets, doors) — `poseNode`
|
|
62
|
+
|
|
63
|
+
Many GLBs ship articulated parts as NAMED nodes (`bunx incanto-model <file>` lists them —
|
|
64
|
+
e.g. the Kenney vehicles have `wheel-front-left` … `wheel-back-right`). From a behavior,
|
|
65
|
+
rotate one per frame with `poseNode(name, [rxDeg, ryDeg, rzDeg])` (local Euler XYZ):
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
// spin the wheels by travel + steer the fronts (Kenney car GLB)
|
|
69
|
+
const model = car.getNodesByName('CarModel')[0] as ModelInstance3D;
|
|
70
|
+
this.spin += this.speed * dt * 60; // degrees of roll
|
|
71
|
+
for (const w of ['wheel-back-left', 'wheel-back-right'])
|
|
72
|
+
model.poseNode(w, [this.spin, 0, 0]);
|
|
73
|
+
for (const w of ['wheel-front-left', 'wheel-front-right'])
|
|
74
|
+
model.poseNode(w, [this.spin, steerDeg, 0]);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Poses are queued if the model hasn't finished loading, re-applied every sync, and
|
|
78
|
+
unknown names are ignored (no throw). This is intent-level articulation — for full
|
|
79
|
+
skeletal animation use `animation` clips instead.
|
|
57
80
|
|
|
58
81
|
**`targetHeight` + skinned rigs (the implausible-scale warning).** Mixamo-style humanoid
|
|
59
82
|
rigs hide their true size behind a ~0.01 armature scale + bone-driven vertex scaling, so
|
|
@@ -240,3 +240,9 @@ solid core carries the colour). `rate: 0` +
|
|
|
240
240
|
|
|
241
241
|
`node.replay()` re-arms a one-shot. Simulation is deterministic under the
|
|
242
242
|
engine seed — runScript verifies particle gameplay reproducibly.
|
|
243
|
+
|
|
244
|
+
## `static: true` for big scenes
|
|
245
|
+
|
|
246
|
+
Mark unchanging subtrees (tile decor, backgrounds) `static: true` — the
|
|
247
|
+
renderer syncs them once and skips them every frame. Flip to `false` to
|
|
248
|
+
resume live syncing.
|
|
@@ -62,9 +62,34 @@ All 3D nodes extend `Node3D` and therefore have the transform props:
|
|
|
62
62
|
|---|---|---|
|
|
63
63
|
| `mesh` | `"box"` | `box \| sphere \| capsule \| plane \| cylinder \| gem` — `gem` is a faceted crystal (icosahedron); with `material.flatShading: true` + low `roughness` it reads as a sparkling jewel (spin/tumble it for the sparkle) |
|
|
64
64
|
| `size` | `[1,1,1]` | box: extents · sphere/gem: radius = x · capsule: radius = x, height = y · plane: x·z ground (laid FLAT on XZ) · cylinder: radius = x, height = y |
|
|
65
|
-
| `material` | `{}` | `{color: '#hex', metalness: 0..1, roughness: 0..1, opacity: 0..1, wireframe, flatShading, depthTest, depthWrite, emissive, emissiveIntensity, map, normalMap, repeat: [u,v]}` — the object IS the material state: omitted keys reset to defaults (`#ffffff`, 0, 1, 1, false, false, depthTest/Write true). `opacity < 1` turns on transparency; `flatShading` gives faceted per-face glints (the gem sparkle). `depthTest: false` (+ a high `renderOrder`) makes a flat `plane`/`cylinder` an ALWAYS-ON-TOP ground decal — AoE telegraphs, selection/spawn rings — that never z-fights with or is hidden by bumpy terrain (`depthWrite: false` keeps it from occluding later effects). `map`/`normalMap` are texture URLs (lazy-loaded, headless-safe; map samples sRGB, normalMap linear), tiled `repeat` times across each face — box/plane UVs span 0..1 per face, so for worldspace density use `repeat: [length/tile, height/tile]` (e.g. a 6×2.5 m brick wall at one tile per 2 m → `[3, 1.25]`). `color` tints the map (near-white keeps the texture's own color). NB: under ACES a very bright `emissiveIntensity` blows out to white — keep it modest (~1–2) + a saturated color for a vivid GLOWING look. Unknown keys, malformed `repeat`, or `repeat` without a map hard-fail at load |
|
|
65
|
+
| `material` | `{}` | `{color: '#hex', metalness: 0..1, roughness: 0..1, opacity: 0..1, clearcoat: 0..1, clearcoatRoughness: 0..1, envMapIntensity: >=0, wireframe, flatShading, depthTest, depthWrite, emissive, emissiveIntensity, map, normalMap, repeat: [u,v]}` — the object IS the material state: omitted keys reset to defaults (`#ffffff`, 0, 1, 1, false, false, depthTest/Write true). `opacity < 1` turns on transparency; `flatShading` gives faceted per-face glints (the gem sparkle). `depthTest: false` (+ a high `renderOrder`) makes a flat `plane`/`cylinder` an ALWAYS-ON-TOP ground decal — AoE telegraphs, selection/spawn rings — that never z-fights with or is hidden by bumpy terrain (`depthWrite: false` keeps it from occluding later effects). `map`/`normalMap` are texture URLs (lazy-loaded, headless-safe; map samples sRGB, normalMap linear), tiled `repeat` times across each face — box/plane UVs span 0..1 per face, so for worldspace density use `repeat: [length/tile, height/tile]` (e.g. a 6×2.5 m brick wall at one tile per 2 m → `[3, 1.25]`). `color` tints the map (near-white keeps the texture's own color). CAR PAINT: `clearcoat: 1` adds a glossy lacquer layer with its own reflection over a metallic base (`clearcoatRoughness` ~0.05-0.1 = mirror lacquer) — THE premium vehicle-paint look; `envMapIntensity` scales how strongly the surface mirrors the scene's sky/HDRI (glass windows want ~2, matte surfaces <1; needs a `sky`/`hdri` environment to reflect — at night with no sky there is nothing to mirror). NB: under ACES a very bright `emissiveIntensity` blows out to white — keep it modest (~1–2) + a saturated color for a vivid GLOWING look. Unknown keys, malformed `repeat`, or `repeat` without a map hard-fail at load |
|
|
66
66
|
| `castShadow` / `receiveShadow` | `false` | |
|
|
67
67
|
|
|
68
|
+
### `LoftMesh3D` (smooth swept hulls — vehicle bodies, canopies)
|
|
69
|
+
|
|
70
|
+
A SMOOTH curved surface swept through cross-sections — what box/capsule assemblies can
|
|
71
|
+
never give you. Superellipse sections are Catmull-Rom-interpolated along Z with per-vertex
|
|
72
|
+
normals, so highlights and sky reflections SWEEP across it like sheet metal. Use it for car
|
|
73
|
+
bodies, glass canopies, boat hulls, fuselages, submarines.
|
|
74
|
+
|
|
75
|
+
| Prop | Default | Notes |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| `sections` | `[]` | ≥2 stations, ascending `z`: `{z, width, height, y, corner?}` — `width`/`height` are the full cross-section extents, `y` is the section CENTRE height, `corner` 0 = boxy slab … 1 = full ellipse (default 0.7; the lower half always stays flatter — vehicle floors are flat). Malformed sections hard-fail at load |
|
|
78
|
+
| `slices` | `24` | vertices around each ring (8..64) |
|
|
79
|
+
| `smooth` | `4` | interpolated rings per section gap (1..16) |
|
|
80
|
+
| `material` | `{}` | same object as MeshInstance3D **minus textures** (`map`/`normalMap`/`repeat` hard-fail — a loft has no UVs) |
|
|
81
|
+
| `castShadow` / `receiveShadow` | `false` | |
|
|
82
|
+
|
|
83
|
+
Supercar recipe (hand-tuned against McLaren F1 proportions — see `examples/racing-3d`):
|
|
84
|
+
one hull loft (low rounded nose ~`corner 0.9` → wide fender-crown stations at the axles →
|
|
85
|
+
coke-bottle waist pinch → tall rear haunches → squared kamm tail `corner ~0.25`), plus a
|
|
86
|
+
second small loft as the GLASS bubble canopy (`metalness 1, roughness 0.03,
|
|
87
|
+
envMapIntensity ~1.7`), plus a dark interior loft inside it, with rectilinear
|
|
88
|
+
`MeshInstance3D` details (splitter, wing, light bars, mirrors) on top. Paint that stays
|
|
89
|
+
saturated in sunlight: `metalness ~0.45, roughness ~0.35, clearcoat 1,
|
|
90
|
+
clearcoatRoughness 0.06, envMapIntensity ~0.9` — high metalness washes the base colour
|
|
91
|
+
out into the sky reflection.
|
|
92
|
+
|
|
68
93
|
### `Sprite3D` / `AnimatedSprite3D` (2D billboard sprites — the 2.5D look)
|
|
69
94
|
A 2D image drawn as a camera-facing quad inside the 3D world (Octopath / Don't
|
|
70
95
|
Starve / classic MapleStory in a 3D scene). Unlit — the art shows as-is. The
|
|
@@ -251,6 +276,13 @@ demo into a commercial-looking outdoor scene:
|
|
|
251
276
|
one extra fullscreen pass per frame — keep `Water3D` at `quality:"simple"`
|
|
252
277
|
(zero re-renders) when pairing with clouds to hold 60fps. Absent = zero cost.
|
|
253
278
|
Ideal for flight/sky scenes; see `examples/dogfight-3d`.
|
|
279
|
+
- `bloom`: a glow post pass — bright pixels bleed light, so emissive
|
|
280
|
+
materials (tail-lights, neon, lava, muzzle flashes) and sun glints actually
|
|
281
|
+
GLOW. `{ threshold?, strength? }`: `threshold` 0..1 post-tonemap brightness
|
|
282
|
+
above which pixels bloom (default 0.75 — keeps it to lights/glints; lower =
|
|
283
|
+
dreamier), `strength` how strongly the blurred glow is added back (default
|
|
284
|
+
0.85; ~1.2 = neon night). One extra half-res blur pass per frame — cheap.
|
|
285
|
+
Caustics/clouds composites take precedence (pipelines don't stack yet).
|
|
254
286
|
- `shadows`: `true` | `false` | `{ "mapSize": 1024|2048, "radius": n }`.
|
|
255
287
|
Truthy makes the main DirectionalLight cast (PCF soft, terrain + trees +
|
|
256
288
|
meshes cast/receive, mesh grass RECEIVES only). One static ortho box (±75 m
|
|
@@ -334,3 +366,16 @@ from a `seed`, with `heightAt(x, z)` for spawning/placement and a
|
|
|
334
366
|
`{shape: 'heightfield'}` collider recipe (Terrain3D as the CHILD of a
|
|
335
367
|
`StaticBody3D`). Full themes table, custom layer format and the water/beach
|
|
336
368
|
pairing live in the **incanto-environment** skill.
|
|
369
|
+
|
|
370
|
+
## Performance levers for big scenes
|
|
371
|
+
|
|
372
|
+
- **`static: true`** (any Node3D): the renderer syncs that subtree ONCE and
|
|
373
|
+
skips it every frame after — mark terrain, buildings, rocks, fences,
|
|
374
|
+
whole decor groups. Do NOT mark animated nodes (Water3D, Particles3D,
|
|
375
|
+
animated models, cameras): they freeze (the engine warns once). Set
|
|
376
|
+
`static = false` at runtime to resume live syncing after an edit.
|
|
377
|
+
- **`environment.shadows.static: true`**: the shadow pass renders once per
|
|
378
|
+
scene/environment change instead of every frame (measured ~42% of a
|
|
379
|
+
dense-forest frame). Use when shadow CASTERS don't move — pair moving
|
|
380
|
+
characters with sprite/blob shadows. After a one-off world edit call
|
|
381
|
+
`renderer.refreshShadows()`.
|
|
@@ -705,3 +705,63 @@ signal into a built-in's method through a `connection`).
|
|
|
705
705
|
Generated, always-current prop/signal tables for every behavior live in
|
|
706
706
|
`incanto-node-reference.md` (the "Gameplay behaviors" section).
|
|
707
707
|
```
|
|
708
|
+
|
|
709
|
+
## Game feel ("juice")
|
|
710
|
+
|
|
711
|
+
```ts
|
|
712
|
+
import { CameraShake, Cooldown, hitStop, screenFlash } from 'incanto/gameplay';
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
- **Cooldown** — fire-rate gate, replaces hand-rolled clock math:
|
|
716
|
+
`private gun = new Cooldown(0.2);` then per update `this.gun.tick(dt);
|
|
717
|
+
if (firing && this.gun.tryUse()) shoot();`. `progress` (0..1) drives a
|
|
718
|
+
UiBar reload indicator; `reset()` for reload pickups.
|
|
719
|
+
- **Camera shake** — `FollowCamera` has it built in:
|
|
720
|
+
`(cam.behavior as FollowCamera).shake(8)` (2D pixels; use ~0.2 in 3D
|
|
721
|
+
meters). For cameras WITHOUT a follow script attach the standalone
|
|
722
|
+
`CameraShake` behavior — it composes with any other position writer and
|
|
723
|
+
returns the camera exactly to base.
|
|
724
|
+
- **screenFlash(color?, opacity?, seconds?)** — full-screen damage/pickup
|
|
725
|
+
flash (DOM, headless no-op).
|
|
726
|
+
- **hitStop(engine, seconds?)** — freezes `engine.timeScale` for REAL
|
|
727
|
+
seconds then restores; stacked calls extend. Sells melee impacts.
|
|
728
|
+
- **engine.timeScale** — 1 realtime, 0.5 slow motion, 0 pause: scales
|
|
729
|
+
variable AND fixed updates together (physics, timers, behaviors).
|
|
730
|
+
|
|
731
|
+
## Game flow (win / lose / restart)
|
|
732
|
+
|
|
733
|
+
Attach `GameFlow` to the scene root (`"script": { "name": "GameFlow" }`),
|
|
734
|
+
declare a `restart` input action, and put a `%Banner` UiBanner in your HUD:
|
|
735
|
+
|
|
736
|
+
```ts
|
|
737
|
+
const flow = this.node.getRoot().behavior as GameFlow;
|
|
738
|
+
flow.gameOver('YOU DIED'); // freezes engine.timeScale, sticky banner, waits for restart
|
|
739
|
+
flow.win('AREA CLEAR');
|
|
740
|
+
flow.pause(); flow.resume();
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
Terminal states ignore further transitions; the restart action (or
|
|
744
|
+
`flow.restart()`) reloads the scene from its source JSON — fresh nodes,
|
|
745
|
+
physics, input. Listen to the `flowChanged(state)` signal for custom UI.
|
|
746
|
+
`restartScene(engine)` is exported standalone.
|
|
747
|
+
|
|
748
|
+
## Boot loading overlay
|
|
749
|
+
|
|
750
|
+
```ts
|
|
751
|
+
import { preloadSceneAssets } from 'incanto';
|
|
752
|
+
await preloadSceneAssets(sceneJson.assets); // black screen + bar + %, auto-removes
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
Replaces the ~125-line hand-rolled loading screen; `createLoadingOverlay()`
|
|
756
|
+
gives you the raw overlay when you preload something else.
|
|
757
|
+
|
|
758
|
+
## Persistence (high scores, unlocks, settings)
|
|
759
|
+
|
|
760
|
+
```ts
|
|
761
|
+
import { createSaveStore } from 'incanto';
|
|
762
|
+
const save = createSaveStore('my-game'); // namespaced localStorage
|
|
763
|
+
save.set('highScore', Math.max(score, save.get('highScore', 0)));
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
JSON round-tripped; headless/private-mode falls back to in-memory (never
|
|
767
|
+
throws). `clear()` wipes only your namespace.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: incanto-hud
|
|
3
|
+
description: Screen-space HUD widgets (HudLayer + UiText / UiBar / UiBanner) — health bars, score text, wave banners declared in scene JSON, no hand-rolled DOM or CSS. Use for any in-game UI overlay in 2D or 3D games.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# HUD widgets
|
|
7
|
+
|
|
8
|
+
Declare your HUD in the scene JSON — no `index.html` markup, no CSS, no
|
|
9
|
+
`document.querySelector` in behaviors:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"name": "HUD", "type": "HudLayer",
|
|
14
|
+
"children": [
|
|
15
|
+
{ "name": "Health", "type": "UiBar",
|
|
16
|
+
"props": { "anchor": "topLeft", "value": 100, "max": 100, "label": "HP" } },
|
|
17
|
+
{ "name": "Score", "type": "UiText",
|
|
18
|
+
"props": { "anchor": "topRight", "text": "Score: 0", "size": 20 } },
|
|
19
|
+
{ "name": "Banner", "type": "UiBanner" }
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`HudLayer` is a fixed, pointer-transparent DOM overlay above the canvas — it
|
|
25
|
+
works identically over the 2D and 3D renderers and is a silent no-op in
|
|
26
|
+
headless tests (core nodes, no three.js). Widgets pick one of 9 anchors:
|
|
27
|
+
`topLeft top topRight left center right bottomLeft bottom bottomRight`.
|
|
28
|
+
Widgets stacked on the same anchor form a column.
|
|
29
|
+
|
|
30
|
+
## Driving widgets from behaviors
|
|
31
|
+
|
|
32
|
+
Plain node access — same as everything else:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import type { UiBanner, UiBar, UiText } from 'incanto';
|
|
36
|
+
|
|
37
|
+
const hp = this.node.getNode('%Health') as UiBar;
|
|
38
|
+
hp.value = health.current; // fill animates; turns red below 30%
|
|
39
|
+
|
|
40
|
+
(this.node.getNode('%Score') as UiText).text = `Score: ${score}`;
|
|
41
|
+
|
|
42
|
+
const banner = this.node.getNode('%Banner') as UiBanner;
|
|
43
|
+
banner.show('WAVE 2', { color: '#f87171', seconds: 2 }); // queued, fades
|
|
44
|
+
banner.show('YOU DIED', { color: '#ef4444', seconds: 0 }); // sticky until next show()
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Widget reference
|
|
48
|
+
|
|
49
|
+
- **UiText** — `text`, `size` (px), `color`, `shadow` (readability outline).
|
|
50
|
+
- **UiBar** — `value`/`max` (ratio clamped 0..1), `width`/`height`, `color`,
|
|
51
|
+
`lowColor` + `lowThreshold` (default 0.3), `background`, `label` caption.
|
|
52
|
+
- **UiBanner** — `show(text, {color, seconds})` queues center-screen
|
|
53
|
+
announcements with fade in/out; `seconds: 0` = sticky; `clear()` empties
|
|
54
|
+
the queue; signal `bannerShown(text)`. Props: `size` (font px), `seconds`
|
|
55
|
+
(default duration).
|
|
56
|
+
|
|
57
|
+
Pair with the `Health` / `ScoreKeeper` gameplay behaviors: listen to their
|
|
58
|
+
signals and write the widget props — that is the whole HUD wiring.
|
|
@@ -21,6 +21,7 @@ description: GENERATED complete reference of every Incanto node type — props,
|
|
|
21
21
|
|---|---|---|
|
|
22
22
|
| `position` | `[0,0]` | array |
|
|
23
23
|
| `rotation` | `0` | number |
|
|
24
|
+
| `static` | `false` | boolean |
|
|
24
25
|
| `scale` | `[1,1]` | array |
|
|
25
26
|
| `renderOrder` | `0` | number |
|
|
26
27
|
| `visible` | `true` | boolean |
|
|
@@ -42,6 +43,7 @@ Signals: `animationFinished(name)`
|
|
|
42
43
|
|---|---|---|
|
|
43
44
|
| `position` | `[0,0,0]` | array |
|
|
44
45
|
| `rotation` | `[0,0,0]` | array |
|
|
46
|
+
| `static` | `false` | boolean |
|
|
45
47
|
| `scale` | `[1,1,1]` | array |
|
|
46
48
|
| `visible` | `true` | boolean |
|
|
47
49
|
| `renderOrder` | `0` | number |
|
|
@@ -70,6 +72,7 @@ Signals: `animationFinished(name)`
|
|
|
70
72
|
|---|---|---|
|
|
71
73
|
| `position` | `[0,0]` | array |
|
|
72
74
|
| `rotation` | `0` | number |
|
|
75
|
+
| `static` | `false` | boolean |
|
|
73
76
|
| `scale` | `[1,1]` | array |
|
|
74
77
|
| `renderOrder` | `0` | number |
|
|
75
78
|
| `visible` | `true` | boolean |
|
|
@@ -83,6 +86,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
|
|
|
83
86
|
|---|---|---|
|
|
84
87
|
| `position` | `[0,0,0]` | array |
|
|
85
88
|
| `rotation` | `[0,0,0]` | array |
|
|
89
|
+
| `static` | `false` | boolean |
|
|
86
90
|
| `scale` | `[1,1,1]` | array |
|
|
87
91
|
| `visible` | `true` | boolean |
|
|
88
92
|
| `renderOrder` | `0` | number |
|
|
@@ -115,6 +119,7 @@ Signals: `finished`
|
|
|
115
119
|
|---|---|---|
|
|
116
120
|
| `position` | `[0,0,0]` | array |
|
|
117
121
|
| `rotation` | `[0,0,0]` | array |
|
|
122
|
+
| `static` | `false` | boolean |
|
|
118
123
|
| `scale` | `[1,1,1]` | array |
|
|
119
124
|
| `visible` | `true` | boolean |
|
|
120
125
|
| `renderOrder` | `0` | number |
|
|
@@ -126,6 +131,7 @@ Signals: `finished`
|
|
|
126
131
|
|---|---|---|
|
|
127
132
|
| `position` | `[0,0]` | array |
|
|
128
133
|
| `rotation` | `0` | number |
|
|
134
|
+
| `static` | `false` | boolean |
|
|
129
135
|
| `scale` | `[1,1]` | array |
|
|
130
136
|
| `renderOrder` | `0` | number |
|
|
131
137
|
| `visible` | `true` | boolean |
|
|
@@ -141,6 +147,7 @@ Signals: `finished`
|
|
|
141
147
|
|---|---|---|
|
|
142
148
|
| `position` | `[0,0,0]` | array |
|
|
143
149
|
| `rotation` | `[0,0,0]` | array |
|
|
150
|
+
| `static` | `false` | boolean |
|
|
144
151
|
| `scale` | `[1,1,1]` | array |
|
|
145
152
|
| `visible` | `true` | boolean |
|
|
146
153
|
| `renderOrder` | `0` | number |
|
|
@@ -155,6 +162,7 @@ Signals: `finished`
|
|
|
155
162
|
|---|---|---|
|
|
156
163
|
| `position` | `[0,0]` | array |
|
|
157
164
|
| `rotation` | `0` | number |
|
|
165
|
+
| `static` | `false` | boolean |
|
|
158
166
|
| `scale` | `[1,1]` | array |
|
|
159
167
|
| `renderOrder` | `0` | number |
|
|
160
168
|
| `visible` | `true` | boolean |
|
|
@@ -171,6 +179,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
|
|
|
171
179
|
|---|---|---|
|
|
172
180
|
| `position` | `[0,0,0]` | array |
|
|
173
181
|
| `rotation` | `[0,0,0]` | array |
|
|
182
|
+
| `static` | `false` | boolean |
|
|
174
183
|
| `scale` | `[1,1,1]` | array |
|
|
175
184
|
| `visible` | `true` | boolean |
|
|
176
185
|
| `renderOrder` | `0` | number |
|
|
@@ -197,6 +206,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
|
|
|
197
206
|
|---|---|---|
|
|
198
207
|
| `position` | `[0,0,0]` | array |
|
|
199
208
|
| `rotation` | `[0,0,0]` | array |
|
|
209
|
+
| `static` | `false` | boolean |
|
|
200
210
|
| `scale` | `[1,1,1]` | array |
|
|
201
211
|
| `visible` | `true` | boolean |
|
|
202
212
|
| `renderOrder` | `0` | number |
|
|
@@ -230,6 +240,7 @@ Signals: `movementStateChanged(state)`
|
|
|
230
240
|
|---|---|---|
|
|
231
241
|
| `position` | `[0,0]` | array |
|
|
232
242
|
| `rotation` | `0` | number |
|
|
243
|
+
| `static` | `false` | boolean |
|
|
233
244
|
| `scale` | `[1,1]` | array |
|
|
234
245
|
| `renderOrder` | `0` | number |
|
|
235
246
|
| `visible` | `true` | boolean |
|
|
@@ -244,6 +255,7 @@ Signals: `movementStateChanged(state)`
|
|
|
244
255
|
|---|---|---|
|
|
245
256
|
| `position` | `[0,0,0]` | array |
|
|
246
257
|
| `rotation` | `[0,0,0]` | array |
|
|
258
|
+
| `static` | `false` | boolean |
|
|
247
259
|
| `scale` | `[1,1,1]` | array |
|
|
248
260
|
| `visible` | `true` | boolean |
|
|
249
261
|
| `renderOrder` | `0` | number |
|
|
@@ -260,6 +272,7 @@ Signals: `movementStateChanged(state)`
|
|
|
260
272
|
|---|---|---|
|
|
261
273
|
| `position` | `[0,0,0]` | array |
|
|
262
274
|
| `rotation` | `[0,0,0]` | array |
|
|
275
|
+
| `static` | `false` | boolean |
|
|
263
276
|
| `scale` | `[1,1,1]` | array |
|
|
264
277
|
| `visible` | `true` | boolean |
|
|
265
278
|
| `renderOrder` | `0` | number |
|
|
@@ -280,6 +293,7 @@ Signals: `movementStateChanged(state)`
|
|
|
280
293
|
|---|---|---|
|
|
281
294
|
| `position` | `[0,0,0]` | array |
|
|
282
295
|
| `rotation` | `[0,0,0]` | array |
|
|
296
|
+
| `static` | `false` | boolean |
|
|
283
297
|
| `scale` | `[1,1,1]` | array |
|
|
284
298
|
| `visible` | `true` | boolean |
|
|
285
299
|
| `renderOrder` | `2` | number |
|
|
@@ -304,12 +318,56 @@ Signals: `movementStateChanged(state)`
|
|
|
304
318
|
| `drape` | `false` | boolean |
|
|
305
319
|
| `terrain` | `""` | string |
|
|
306
320
|
|
|
321
|
+
## `HudLayer` — `incanto`
|
|
322
|
+
|
|
323
|
+
| Prop | Default | Kind |
|
|
324
|
+
|---|---|---|
|
|
325
|
+
| `zIndex` | `100` | number |
|
|
326
|
+
| `visible` | `true` | boolean |
|
|
327
|
+
|
|
328
|
+
## `Joint2D` — `incanto/2d`
|
|
329
|
+
|
|
330
|
+
| Prop | Default | Kind |
|
|
331
|
+
|---|---|---|
|
|
332
|
+
| `position` | `[0,0]` | array |
|
|
333
|
+
| `rotation` | `0` | number |
|
|
334
|
+
| `static` | `false` | boolean |
|
|
335
|
+
| `scale` | `[1,1]` | array |
|
|
336
|
+
| `renderOrder` | `0` | number |
|
|
337
|
+
| `visible` | `true` | boolean |
|
|
338
|
+
| `type` | `"revolute"` | one of: `fixed` `revolute` `rope` `spring` |
|
|
339
|
+
| `target` | `""` | string |
|
|
340
|
+
| `anchor` | `[0,0]` | array |
|
|
341
|
+
| `targetAnchor` | `[0,0]` | array |
|
|
342
|
+
| `length` | `0` | number |
|
|
343
|
+
| `stiffness` | `50` | number |
|
|
344
|
+
| `damping` | `5` | number |
|
|
345
|
+
|
|
346
|
+
## `Joint3D` — `incanto/3d`
|
|
347
|
+
|
|
348
|
+
| Prop | Default | Kind |
|
|
349
|
+
|---|---|---|
|
|
350
|
+
| `position` | `[0,0,0]` | array |
|
|
351
|
+
| `rotation` | `[0,0,0]` | array |
|
|
352
|
+
| `static` | `false` | boolean |
|
|
353
|
+
| `scale` | `[1,1,1]` | array |
|
|
354
|
+
| `visible` | `true` | boolean |
|
|
355
|
+
| `renderOrder` | `0` | number |
|
|
356
|
+
| `type` | `"spherical"` | one of: `fixed` `spherical` `rope` `spring` |
|
|
357
|
+
| `target` | `""` | string |
|
|
358
|
+
| `anchor` | `[0,0,0]` | array |
|
|
359
|
+
| `targetAnchor` | `[0,0,0]` | array |
|
|
360
|
+
| `length` | `0` | number |
|
|
361
|
+
| `stiffness` | `50` | number |
|
|
362
|
+
| `damping` | `5` | number |
|
|
363
|
+
|
|
307
364
|
## `Label` — `incanto/2d`
|
|
308
365
|
|
|
309
366
|
| Prop | Default | Kind |
|
|
310
367
|
|---|---|---|
|
|
311
368
|
| `position` | `[0,0]` | array |
|
|
312
369
|
| `rotation` | `0` | number |
|
|
370
|
+
| `static` | `false` | boolean |
|
|
313
371
|
| `scale` | `[1,1]` | array |
|
|
314
372
|
| `renderOrder` | `0` | number |
|
|
315
373
|
| `visible` | `true` | boolean |
|
|
@@ -319,12 +377,30 @@ Signals: `movementStateChanged(state)`
|
|
|
319
377
|
| `font` | `"monospace"` | string |
|
|
320
378
|
| `align` | `"left"` | string |
|
|
321
379
|
|
|
380
|
+
## `LoftMesh3D` — `incanto/3d`
|
|
381
|
+
|
|
382
|
+
| Prop | Default | Kind |
|
|
383
|
+
|---|---|---|
|
|
384
|
+
| `position` | `[0,0,0]` | array |
|
|
385
|
+
| `rotation` | `[0,0,0]` | array |
|
|
386
|
+
| `static` | `false` | boolean |
|
|
387
|
+
| `scale` | `[1,1,1]` | array |
|
|
388
|
+
| `visible` | `true` | boolean |
|
|
389
|
+
| `renderOrder` | `0` | number |
|
|
390
|
+
| `sections` | `[]` | array |
|
|
391
|
+
| `slices` | `24` | number |
|
|
392
|
+
| `smooth` | `4` | number |
|
|
393
|
+
| `material` | `{}` | object |
|
|
394
|
+
| `castShadow` | `false` | boolean |
|
|
395
|
+
| `receiveShadow` | `false` | boolean |
|
|
396
|
+
|
|
322
397
|
## `MeshInstance3D` — `incanto/3d`
|
|
323
398
|
|
|
324
399
|
| Prop | Default | Kind |
|
|
325
400
|
|---|---|---|
|
|
326
401
|
| `position` | `[0,0,0]` | array |
|
|
327
402
|
| `rotation` | `[0,0,0]` | array |
|
|
403
|
+
| `static` | `false` | boolean |
|
|
328
404
|
| `scale` | `[1,1,1]` | array |
|
|
329
405
|
| `visible` | `true` | boolean |
|
|
330
406
|
| `renderOrder` | `0` | number |
|
|
@@ -340,6 +416,7 @@ Signals: `movementStateChanged(state)`
|
|
|
340
416
|
|---|---|---|
|
|
341
417
|
| `position` | `[0,0,0]` | array |
|
|
342
418
|
| `rotation` | `[0,0,0]` | array |
|
|
419
|
+
| `static` | `false` | boolean |
|
|
343
420
|
| `scale` | `[1,1,1]` | array |
|
|
344
421
|
| `visible` | `true` | boolean |
|
|
345
422
|
| `renderOrder` | `0` | number |
|
|
@@ -350,6 +427,8 @@ Signals: `movementStateChanged(state)`
|
|
|
350
427
|
| `animationLoop` | `true` | boolean |
|
|
351
428
|
| `receiveShadow` | `false` | boolean |
|
|
352
429
|
| `tint` | `""` | string |
|
|
430
|
+
| `metalness` | `-1` | number |
|
|
431
|
+
| `roughness` | `-1` | number |
|
|
353
432
|
|
|
354
433
|
Signals: `animationFinished(name)`
|
|
355
434
|
|
|
@@ -373,6 +452,7 @@ _No props (structural fields only)._
|
|
|
373
452
|
|---|---|---|
|
|
374
453
|
| `position` | `[0,0]` | array |
|
|
375
454
|
| `rotation` | `0` | number |
|
|
455
|
+
| `static` | `false` | boolean |
|
|
376
456
|
| `scale` | `[1,1]` | array |
|
|
377
457
|
| `renderOrder` | `0` | number |
|
|
378
458
|
| `visible` | `true` | boolean |
|
|
@@ -383,6 +463,7 @@ _No props (structural fields only)._
|
|
|
383
463
|
|---|---|---|
|
|
384
464
|
| `position` | `[0,0,0]` | array |
|
|
385
465
|
| `rotation` | `[0,0,0]` | array |
|
|
466
|
+
| `static` | `false` | boolean |
|
|
386
467
|
| `scale` | `[1,1,1]` | array |
|
|
387
468
|
| `visible` | `true` | boolean |
|
|
388
469
|
| `renderOrder` | `0` | number |
|
|
@@ -393,6 +474,7 @@ _No props (structural fields only)._
|
|
|
393
474
|
|---|---|---|
|
|
394
475
|
| `position` | `[0,0,0]` | array |
|
|
395
476
|
| `rotation` | `[0,0,0]` | array |
|
|
477
|
+
| `static` | `false` | boolean |
|
|
396
478
|
| `scale` | `[1,1,1]` | array |
|
|
397
479
|
| `visible` | `true` | boolean |
|
|
398
480
|
| `renderOrder` | `0` | number |
|
|
@@ -406,6 +488,7 @@ _No props (structural fields only)._
|
|
|
406
488
|
|---|---|---|
|
|
407
489
|
| `position` | `[0,0]` | array |
|
|
408
490
|
| `rotation` | `0` | number |
|
|
491
|
+
| `static` | `false` | boolean |
|
|
409
492
|
| `scale` | `[1,1]` | array |
|
|
410
493
|
| `renderOrder` | `0` | number |
|
|
411
494
|
| `visible` | `true` | boolean |
|
|
@@ -438,6 +521,7 @@ Signals: `finished`
|
|
|
438
521
|
|---|---|---|
|
|
439
522
|
| `position` | `[0,0,0]` | array |
|
|
440
523
|
| `rotation` | `[0,0,0]` | array |
|
|
524
|
+
| `static` | `false` | boolean |
|
|
441
525
|
| `scale` | `[1,1,1]` | array |
|
|
442
526
|
| `visible` | `true` | boolean |
|
|
443
527
|
| `renderOrder` | `0` | number |
|
|
@@ -471,6 +555,7 @@ Signals: `finished`
|
|
|
471
555
|
|---|---|---|
|
|
472
556
|
| `position` | `[0,0]` | array |
|
|
473
557
|
| `rotation` | `0` | number |
|
|
558
|
+
| `static` | `false` | boolean |
|
|
474
559
|
| `scale` | `[1,1]` | array |
|
|
475
560
|
| `renderOrder` | `0` | number |
|
|
476
561
|
| `visible` | `true` | boolean |
|
|
@@ -490,6 +575,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
|
|
|
490
575
|
|---|---|---|
|
|
491
576
|
| `position` | `[0,0,0]` | array |
|
|
492
577
|
| `rotation` | `[0,0,0]` | array |
|
|
578
|
+
| `static` | `false` | boolean |
|
|
493
579
|
| `scale` | `[1,1,1]` | array |
|
|
494
580
|
| `visible` | `true` | boolean |
|
|
495
581
|
| `renderOrder` | `0` | number |
|
|
@@ -509,6 +595,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
|
|
|
509
595
|
|---|---|---|
|
|
510
596
|
| `position` | `[0,0]` | array |
|
|
511
597
|
| `rotation` | `0` | number |
|
|
598
|
+
| `static` | `false` | boolean |
|
|
512
599
|
| `scale` | `[1,1]` | array |
|
|
513
600
|
| `renderOrder` | `0` | number |
|
|
514
601
|
| `visible` | `true` | boolean |
|
|
@@ -525,6 +612,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
|
|
|
525
612
|
|---|---|---|
|
|
526
613
|
| `position` | `[0,0,0]` | array |
|
|
527
614
|
| `rotation` | `[0,0,0]` | array |
|
|
615
|
+
| `static` | `false` | boolean |
|
|
528
616
|
| `scale` | `[1,1,1]` | array |
|
|
529
617
|
| `visible` | `true` | boolean |
|
|
530
618
|
| `renderOrder` | `0` | number |
|
|
@@ -546,6 +634,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
|
|
|
546
634
|
|---|---|---|
|
|
547
635
|
| `position` | `[0,0]` | array |
|
|
548
636
|
| `rotation` | `0` | number |
|
|
637
|
+
| `static` | `false` | boolean |
|
|
549
638
|
| `scale` | `[1,1]` | array |
|
|
550
639
|
| `renderOrder` | `0` | number |
|
|
551
640
|
| `visible` | `true` | boolean |
|
|
@@ -559,6 +648,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
|
|
|
559
648
|
|---|---|---|
|
|
560
649
|
| `position` | `[0,0,0]` | array |
|
|
561
650
|
| `rotation` | `[0,0,0]` | array |
|
|
651
|
+
| `static` | `false` | boolean |
|
|
562
652
|
| `scale` | `[1,1,1]` | array |
|
|
563
653
|
| `visible` | `true` | boolean |
|
|
564
654
|
| `renderOrder` | `0` | number |
|
|
@@ -572,6 +662,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
|
|
|
572
662
|
|---|---|---|
|
|
573
663
|
| `position` | `[0,0,0]` | array |
|
|
574
664
|
| `rotation` | `[0,0,0]` | array |
|
|
665
|
+
| `static` | `false` | boolean |
|
|
575
666
|
| `scale` | `[1,1,1]` | array |
|
|
576
667
|
| `visible` | `true` | boolean |
|
|
577
668
|
| `renderOrder` | `0` | number |
|
|
@@ -604,6 +695,7 @@ Signals: `timeout`
|
|
|
604
695
|
|---|---|---|
|
|
605
696
|
| `position` | `[0,0,0]` | array |
|
|
606
697
|
| `rotation` | `[0,0,0]` | array |
|
|
698
|
+
| `static` | `false` | boolean |
|
|
607
699
|
| `scale` | `[1,1,1]` | array |
|
|
608
700
|
| `visible` | `true` | boolean |
|
|
609
701
|
| `renderOrder` | `0` | number |
|
|
@@ -628,12 +720,51 @@ Signals: `timeout`
|
|
|
628
720
|
|---|---|---|
|
|
629
721
|
| `anchor` | `"top-left"` | one of: `top-left` `top` `top-right` `left` `center` `right` `bottom-left` `bottom` `bottom-right` |
|
|
630
722
|
|
|
723
|
+
## `UiBanner` — `incanto`
|
|
724
|
+
|
|
725
|
+
| Prop | Default | Kind |
|
|
726
|
+
|---|---|---|
|
|
727
|
+
| `anchor` | `"center"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
|
|
728
|
+
| `visible` | `true` | boolean |
|
|
729
|
+
| `size` | `42` | number |
|
|
730
|
+
| `seconds` | `2` | number |
|
|
731
|
+
|
|
732
|
+
Signals: `bannerShown`
|
|
733
|
+
|
|
734
|
+
## `UiBar` — `incanto`
|
|
735
|
+
|
|
736
|
+
| Prop | Default | Kind |
|
|
737
|
+
|---|---|---|
|
|
738
|
+
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
|
|
739
|
+
| `visible` | `true` | boolean |
|
|
740
|
+
| `value` | `100` | number |
|
|
741
|
+
| `max` | `100` | number |
|
|
742
|
+
| `width` | `180` | number |
|
|
743
|
+
| `height` | `14` | number |
|
|
744
|
+
| `color` | `"#4ade80"` | string |
|
|
745
|
+
| `lowColor` | `"#ef4444"` | string |
|
|
746
|
+
| `lowThreshold` | `0.3` | number |
|
|
747
|
+
| `background` | `"rgba(0,0,0,0.5)"` | string |
|
|
748
|
+
| `label` | `""` | string |
|
|
749
|
+
|
|
750
|
+
## `UiText` — `incanto`
|
|
751
|
+
|
|
752
|
+
| Prop | Default | Kind |
|
|
753
|
+
|---|---|---|
|
|
754
|
+
| `anchor` | `"topLeft"` | one of: `topLeft` `top` `topRight` `left` `center` `right` `bottomLeft` `bottom` `bottomRight` |
|
|
755
|
+
| `visible` | `true` | boolean |
|
|
756
|
+
| `text` | `""` | string |
|
|
757
|
+
| `size` | `16` | number |
|
|
758
|
+
| `color` | `"#ffffff"` | string |
|
|
759
|
+
| `shadow` | `true` | boolean |
|
|
760
|
+
|
|
631
761
|
## `VoxelGrid3D` — `incanto/3d`
|
|
632
762
|
|
|
633
763
|
| Prop | Default | Kind |
|
|
634
764
|
|---|---|---|
|
|
635
765
|
| `position` | `[0,0,0]` | array |
|
|
636
766
|
| `rotation` | `[0,0,0]` | array |
|
|
767
|
+
| `static` | `false` | boolean |
|
|
637
768
|
| `scale` | `[1,1,1]` | array |
|
|
638
769
|
| `visible` | `true` | boolean |
|
|
639
770
|
| `renderOrder` | `0` | number |
|
|
@@ -647,6 +778,7 @@ Signals: `blocksChanged`
|
|
|
647
778
|
|---|---|---|
|
|
648
779
|
| `position` | `[0,0,0]` | array |
|
|
649
780
|
| `rotation` | `[0,0,0]` | array |
|
|
781
|
+
| `static` | `false` | boolean |
|
|
650
782
|
| `scale` | `[1,1,1]` | array |
|
|
651
783
|
| `visible` | `true` | boolean |
|
|
652
784
|
| `renderOrder` | `1` | number |
|
|
@@ -678,6 +810,12 @@ Ready-made `Behavior`s auto-registered by `createGame2D`/`createGame3D` (opt out
|
|
|
678
810
|
with `gameplay: false`). Attach via `"script": {"name": "...", "props": {...}}` and
|
|
679
811
|
wire their signals through scene `connections`. Full guide: `incanto-gameplay-behaviors.md`.
|
|
680
812
|
|
|
813
|
+
### `CameraShake`
|
|
814
|
+
|
|
815
|
+
| Prop | Default | Kind |
|
|
816
|
+
|---|---|---|
|
|
817
|
+
| `falloff` | `0.28` | number |
|
|
818
|
+
|
|
681
819
|
### `Chase`
|
|
682
820
|
|
|
683
821
|
| Prop | Default | Kind |
|
|
@@ -718,6 +856,16 @@ Signals: `dealtDamage(amount, target)`
|
|
|
718
856
|
| `smoothing` | `0` | number |
|
|
719
857
|
| `deadzone` | `0` | number |
|
|
720
858
|
|
|
859
|
+
### `GameFlow`
|
|
860
|
+
|
|
861
|
+
| Prop | Default | Kind |
|
|
862
|
+
|---|---|---|
|
|
863
|
+
| `restartAction` | `"restart"` | string |
|
|
864
|
+
| `freezeOnEnd` | `true` | boolean |
|
|
865
|
+
| `bannerPath` | `"%Banner"` | string |
|
|
866
|
+
|
|
867
|
+
Signals: `flowChanged`
|
|
868
|
+
|
|
721
869
|
### `Health`
|
|
722
870
|
|
|
723
871
|
| Prop | Default | Kind |
|
|
@@ -133,6 +133,53 @@ Injected state combines with key state (vectors clamped to unit length).
|
|
|
133
133
|
- Reference: [examples/2d-phaser-sprite-character-gravity](https://github.com/rareboe/Incanto/tree/main/examples/2d-phaser-sprite-character-gravity) — gravity, jump, attack lockout, custom
|
|
134
134
|
`Player` node type. Verified in Chromium end-to-end.
|
|
135
135
|
|
|
136
|
+
## Joints (Joint2D / Joint3D)
|
|
137
|
+
|
|
138
|
+
Link two bodies: put the joint node as a CHILD of body A, point `target` at
|
|
139
|
+
body B (any node path — `%Name` is typical):
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{ "name": "Ball", "type": "RigidBody2D",
|
|
143
|
+
"props": { "collider": { "shape": "circle", "radius": 10 } },
|
|
144
|
+
"children": [
|
|
145
|
+
{ "name": "Rope", "type": "Joint2D",
|
|
146
|
+
"props": { "type": "rope", "target": "%Anchor", "length": 100 } }
|
|
147
|
+
]}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Types — 2D: `fixed` (weld) · `revolute` (pin/hinge) · `rope` (max distance)
|
|
151
|
+
· `spring` (pull toward `length` with `stiffness`/`damping`). 3D swaps
|
|
152
|
+
`revolute` for `spherical` (ball joint). `length: 0` measures the body
|
|
153
|
+
distance at creation. `anchor`/`targetAnchor` are local offsets (px / m).
|
|
154
|
+
Chains work (pendulums, bridges: each link a body + joint to the previous).
|
|
155
|
+
|
|
156
|
+
## Raycasts
|
|
157
|
+
|
|
158
|
+
Both runtimes expose the same query (2D in PIXELS y-down, 3D in meters):
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
const hit = physics.castRay(origin, dir, maxLen, excludeBody?, { staticOnly?: true });
|
|
162
|
+
// → { distance, normal, node } | null (sensors never block rays)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Exclude the shooter's own body when casting from inside it.
|
|
166
|
+
|
|
167
|
+
## Gamepad
|
|
168
|
+
|
|
169
|
+
`engine.input.attachGamepad(engine)` polls the first connected pad every
|
|
170
|
+
frame (headless no-op). Buttons are codes `Pad0`..`Pad16` in the SAME space
|
|
171
|
+
as keys — declare them in actions: `"jump": { "keys": ["Space", "Pad0"] }`
|
|
172
|
+
(standard mapping: Pad0=A/×, Pad1=B/○, Pad9=Start). Sticks:
|
|
173
|
+
`input.padAxes(0)` / `padAxes(1)` → deadzoned `{x, y}`. Unplugging releases
|
|
174
|
+
everything (no stuck inputs).
|
|
175
|
+
|
|
176
|
+
## Changing colliders at runtime
|
|
177
|
+
|
|
178
|
+
REPLACE the object — `body.collider = { shape: 'rect', size: [w, 60] }` —
|
|
179
|
+
and physics rebuilds the body that step. In-place mutation of the existing
|
|
180
|
+
collider object (`body.collider.size[0] = w`) is NOT watched (the per-step
|
|
181
|
+
change scan was removed for performance).
|
|
182
|
+
|
|
136
183
|
## Debug drawing
|
|
137
184
|
|
|
138
185
|
`physics.debugDraw = true` (the instance `enablePhysics2D/3D` returns) renders
|