incanto 0.26.0 → 0.27.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-D4_I76v2.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-BrneVqN0.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.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "Vibe-coding-first web game engine SDK — JSON-driven scenes on three.js",
5
5
  "keywords": [
6
6
  "game-engine",
@@ -4735,6 +4735,10 @@
4735
4735
  "type": "string",
4736
4736
  "default": ""
4737
4737
  },
4738
+ "carve": {
4739
+ "type": "boolean",
4740
+ "default": true
4741
+ },
4738
4742
  "flowForce": {
4739
4743
  "type": "number",
4740
4744
  "default": 1
@@ -545,7 +545,7 @@ is radians of `atan(|∇h|)`. Default textures stream from the live agent8 CDN
545
545
  | `size` | `[200, 200]` | [width, depth] meters, centered on the node |
546
546
  | `maxHeight` | `28` | height SCALE — realized heights land at ~3.5–8× this (the ported pipeline sums positive noise octaves); read real numbers off `heightAt` |
547
547
  | `seed` | `1` | integer seed — deterministic terrain |
548
- | `resolution` | `128` | grid segments per side (2–128, load-time check) |
548
+ | `resolution` | `128` | grid segments per side (2–256, load-time check). 128 ≈ 2 m cells on a 260 m map; raise to 256 when the map carries something finer, e.g. a creek bed |
549
549
  | `theme` | `"island"` | see table — `custom` requires `layers` |
550
550
  | `roughness` | `0.5` | detail-octave persistence (higher = more rugged) |
551
551
  | `detail` | `4` | detail octave count |
@@ -975,6 +975,7 @@ underneath decides everything else.
975
975
  | `foam` | `1` | whitewater dial — 0 = a glassy canal, 2 = raging |
976
976
  | `ripples` | `1` | surface-detail dial (ripple relief + glitter) |
977
977
  | `terrain` | `''` | drape target path; empty = auto-find the first Terrain3D (a wrong path fails at load) |
978
+ | `carve` | `true` | cut the bed. The river trenches its own channel into the terrain it drapes on — see below |
978
979
  | `flowForce` | `1` | how hard the current sweeps bodies downstream (0 = visual only) |
979
980
  | `spray` | `1` | mist at the foot of every waterfall the course turns out to contain — the node finds the drops and hangs a Particles3D plume on each (0 = off) |
980
981
  | `sunDirection` / `sunColor` / `sunIntensity` | sky / `#fff6e0` / `1` | glint (the environment sun wins while `sunDirection` is default) |
@@ -990,24 +991,64 @@ underneath decides everything else.
990
991
  runs faster), which is what puts rapids where a real river has them;
991
992
  - **whitewater**: grade × speed makes rapids, the bank shear line makes edge
992
993
  froth, a thinning column riffles over rock. Foam then rides downstream.
994
+ - **what stands in the water**: drop boulders in the channel and the current
995
+ answers them — a cushion of white piled on the upstream face, a torn wake
996
+ opening downstream, and the surface sheen bending around the stone. Nothing
997
+ is wired: the node scans the tree for `MeshInstance3D` and `InstancedMesh3D`
998
+ footprints (a rock scatter is one node with fifty stones in it), keeps the
999
+ ones whose body actually intersects the water column — a footbridge deck
1000
+ three metres up is not a boulder — and writes the eight nearest the camera
1001
+ each frame, ramped in by distance so nothing pops. A drowned stone still
1002
+ bends the flow; only one standing proud tears it white.
993
1003
 
994
1004
  It costs NO extra render passes (unlike fancy `Water3D`), so a map can carry a
995
1005
  dozen rivers.
996
1006
 
997
- ### Cut the bed first
1007
+ ### The bed digs itself, and the water can never hang in the air
998
1008
 
999
- Water needs somewhere to be. Give the same path to the terrain as a `channels`
1000
- carve, or the creek will lie on top of the ground as a thin film and read as
1001
- riffle everywhere:
1009
+ Two promises hold a river to the ground, and both are automatic:
1010
+
1011
+ **1. It carves its own bed** (`carve`, on by default). Real water erodes a
1012
+ channel; a ribbon laid on raw ground has nothing holding it and reads as a
1013
+ strip of blue hovering over the grass. So the node cuts one — a trench per
1014
+ reach, as wide as the creek is there, with banks that stand above the water.
1015
+ `heightAt`, the heightfield collider, the splat and draped vegetation all see
1016
+ it, because it IS the terrain. The floor it cuts only ever FALLS: where the
1017
+ path crosses a rise the bed digs through it (up to 7 water columns deep) so the
1018
+ water keeps running instead of burying itself.
1019
+
1020
+ ```json
1021
+ { "name": "Creek", "type": "River3D", "props": {
1022
+ "path": [[-80, -30], [-20, 5], [30, 10], [90, -10]],
1023
+ "widths": [2.4, 4.5, 7, 9], "depth": 1 } }
1024
+ ```
1025
+
1026
+ That is the whole scene. No `channels` on the terrain, no bank meshes.
1027
+
1028
+ **2. Its surface is FITTED to the ground it finds.** Each station reads its own
1029
+ cross-section: the water stands no higher than the lowest rim holding it, ends
1030
+ where the ground comes up to meet it (so the ribbon is asymmetric on a sloping
1031
+ reach — a near bank and a far one), and where a bank has fallen away entirely
1032
+ the ribbon lies DOWN on the slope as a film instead of hanging off it. Authored
1033
+ width is how much water there is; the ground decides where it goes.
1034
+
1035
+ Carve it yourself with `Terrain3D.channels` when you want a bed the river does
1036
+ not own — a stone aqueduct, a canal with masonry sides, a dry wash that only
1037
+ floods in a cutscene — and set `"carve": false`.
1038
+
1039
+ **Terrain resolution is the one thing that can defeat this.** A trench thinner
1040
+ than a grid cell smooths away to nothing. 128 segments on a 260 m map is ~2 m
1041
+ per cell, so a 2.4 m headwater creek needs `"resolution": 256` (~1 m cells) on
1042
+ the Terrain3D. The node widens its cut to survive the grid rather than cutting
1043
+ nothing, so a too-coarse terrain shows up as a creek in a bed wider than it
1044
+ should be.
1002
1045
 
1003
1046
  ```ts
1047
+ // the classic setup: let the terrain choose the line, then pour water on it
1004
1048
  const path = traceDownhillPath(terrain.heightAt, { x: peakX, z: peakZ, step: 7 });
1005
- // terrain prop — the trench (collider + heightAt + drape all see it)
1006
- "channels": [{ "path": path, "width": 7, "depth": 2.2, "taper": 9 }]
1007
- // river prop — the water in it
1008
- "path": path, "widths": [2.4, 4.5, 7, 9], "depth": 1
1009
1049
  ```
1010
1050
 
1051
+
1011
1052
  ### Waterfalls happen — you do not author them
1012
1053
 
1013
1054
  Nothing in a scene says "waterfall". Where the ground gives way the surface
@@ -695,6 +695,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
695
695
  | `sunColor` | `"#fff6e0"` | string |
696
696
  | `sunIntensity` | `1` | number |
697
697
  | `terrain` | `""` | string |
698
+ | `carve` | `true` | boolean |
698
699
  | `flowForce` | `1` | number |
699
700
  | `spray` | `1` | number |
700
701
 
@@ -14,7 +14,7 @@
14
14
  "@dimforge/rapier2d-compat": "0.19.3",
15
15
  "@dimforge/rapier3d-compat": "0.19.3",
16
16
  "@pixiv/three-vrm": "^3.5.3",
17
- "incanto": "^0.26.0",
17
+ "incanto": "^0.27.0",
18
18
  "three": "^0.184.0"
19
19
  },
20
20
  "devDependencies": {
@@ -13,7 +13,7 @@
13
13
  "@dimforge/rapier2d-compat": "0.19.3",
14
14
  "@dimforge/rapier3d-compat": "0.19.3",
15
15
  "@pixiv/three-vrm": "^3.5.3",
16
- "incanto": "^0.26.0",
16
+ "incanto": "^0.27.0",
17
17
  "three": "^0.184.0"
18
18
  },
19
19
  "devDependencies": {
@@ -13,7 +13,7 @@
13
13
  "@dimforge/rapier2d-compat": "0.19.3",
14
14
  "@dimforge/rapier3d-compat": "0.19.3",
15
15
  "@pixiv/three-vrm": "^3.5.3",
16
- "incanto": "^0.26.0",
16
+ "incanto": "^0.27.0",
17
17
  "three": "^0.184.0"
18
18
  },
19
19
  "devDependencies": {