incanto 0.11.0 → 0.12.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/editor/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Incanto Scene Editor</title>
7
7
  <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><rect width='16' height='16' rx='3' fill='%236ee7dc'/><text x='8' y='12' text-anchor='middle' font-size='11' font-family='monospace' fill='%230e1018'>i</text></svg>" />
8
- <script type="module" crossorigin src="./assets/index-DMCQXowF.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-s0DZuroe.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="./assets/GameServer-C56iOUgF.js">
10
10
  <link rel="stylesheet" crossorigin href="./assets/index-D8QvwvOm.css">
11
11
  </head>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incanto",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Vibe-coding-first web game engine SDK — JSON-driven scenes on three.js",
5
5
  "keywords": [
6
6
  "game-engine",
@@ -146,7 +146,8 @@ A sword in the hand, a hat on the head, sparks on a wingtip — parent them to a
146
146
  - Purely VISUAL: it follows the rendered skeleton, so headless the node stays
147
147
  at its prop transform — keep hit checks range-based from the body, never
148
148
  bone-based.
149
- - `model.boneNames()` lists every bone at runtime when you need to hunt one.
149
+ - `model.boneNames()` lists every bone at runtime when you need to hunt one
150
+ (the editor's inspector offers the same list as a dropdown on the `bone` prop).
150
151
 
151
152
  ## Facing a direction in 3D — the +Z-FORWARD rule (read before turning ANY skin)
152
153
 
@@ -283,6 +283,14 @@ demo into a commercial-looking outdoor scene:
283
283
  dreamier), `strength` how strongly the blurred glow is added back (default
284
284
  0.85; ~1.2 = neon night). One extra half-res blur pass per frame — cheap.
285
285
  Caustics/clouds composites take precedence (pipelines don't stack yet).
286
+ - `post`: the color-grade tail — `{ "vignette"?, "saturation"?, "contrast"? }`.
287
+ `vignette` 0..1 darkens the corners (0.3 = cinematic, 0.6 = heavy mood);
288
+ `saturation` 0..4 (0 = grayscale, 1 = neutral, 1.2 = vivid); `contrast`
289
+ 0.2..3 around mid-gray (1 = neutral). Applied after tone mapping on the same
290
+ composite pass as bloom — declaring `post` WITHOUT `bloom` costs just one
291
+ offscreen pass. The fastest way to give a scene a LOOK: dusk = vignette 0.35
292
+ + saturation 0.85, candy = saturation 1.25 + contrast 1.08. Caustics/clouds
293
+ composites take precedence (pipelines don't stack yet).
286
294
  - `shadows`: `true` | `false` | `{ "mapSize": 1024|2048, "radius": n }`.
287
295
  Truthy makes the main DirectionalLight cast (PCF soft, terrain + trees +
288
296
  meshes cast/receive, mesh grass RECEIVES only). One static ortho box (±75 m
@@ -388,6 +396,33 @@ from a `seed`, with `heightAt(x, z)` for spawning/placement and a
388
396
  `StaticBody3D`). Full themes table, custom layer format and the water/beach
389
397
  pairing live in the **incanto-environment** skill.
390
398
 
399
+ ### Navigation on terrain (`buildTerrainNav` + findPath)
400
+
401
+ Enemies that chase across an open world need paths that respect the surface —
402
+ `buildTerrainNav` samples the heightfield into a walkable grid for the core
403
+ A* (`findPath`), and lifts waypoints back ONTO the surface:
404
+
405
+ ```ts
406
+ import { buildTerrainNav } from 'incanto/3d';
407
+ import { findPath } from 'incanto';
408
+
409
+ const nav = buildTerrainNav(terrain, {
410
+ cellSize: 2, // meters per cell (character-scale corridors)
411
+ maxSlopeDeg: 40, // steeper cells are unwalkable
412
+ minHeight: 0.5, // below sea level = unwalkable (pair with your Water3D y)
413
+ });
414
+ const cells = findPath(nav.grid, nav.toCell(ex, ez), nav.toCell(px, pz));
415
+ if (cells) follow.setPath(cells.map(([cx, cy]) => nav.toWorld(cx, cy)));
416
+ // nav.toWorld's y IS the terrain height — PathFollow rides the surface.
417
+ ```
418
+
419
+ - Build it ONCE per scene (onReady) — sampling is O(cells); re-pathing with
420
+ `findPath` per second is cheap (binary-heap A*).
421
+ - Trees/rocks/buildings aren't in the heightfield: stamp them out with
422
+ `nav.setSolid(...nav.toCell(x, z))` after building.
423
+ - Walkability is judged inside each cell (corner samples), so a flat trail
424
+ beside a cliff stays walkable — only genuinely steep cells go solid.
425
+
391
426
  ## Performance levers for big scenes
392
427
 
393
428
  - **`static: true`** (any Node3D): the renderer syncs that subtree ONCE and
@@ -119,9 +119,9 @@ active brush. The palette chips offer every char already used in `cells`, the
119
119
  single char (digits map straight to atlas tile indices, other chars need a
120
120
  `legend` entry). The grid grows right/down automatically when you paint past
121
121
  the edge — to grow left/up, move the node instead (cell (0,0) hangs on the
122
- node origin). Merged solid colliders re-derive live as you paint. Each painted
123
- cell is one undo step; toggle paint off (or select another node) to get normal
124
- click-select back.
122
+ node origin). Merged solid colliders re-derive live as you paint. A whole
123
+ drag stroke is ONE undo step; toggle paint off (or select another node) to
124
+ get normal click-select back.
125
125
 
126
126
  ## Generate environments
127
127