incanto 0.20.0 → 0.21.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-CXdpxO_B.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-Dt44Z9ka.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.20.0",
3
+ "version": "0.21.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
  "flowForce": {
4736
4736
  "type": "number",
4737
4737
  "default": 1
4738
+ },
4739
+ "spray": {
4740
+ "type": "number",
4741
+ "default": 1
4738
4742
  }
4739
4743
  },
4740
4744
  "additionalProperties": false
@@ -6579,6 +6583,10 @@
6579
6583
  "type": "boolean",
6580
6584
  "default": false
6581
6585
  },
6586
+ "swellSteepness": {
6587
+ "type": "number",
6588
+ "default": 0.35
6589
+ },
6582
6590
  "foam": {
6583
6591
  "type": "boolean",
6584
6592
  "default": true
@@ -699,6 +699,7 @@ hue reads grey.
699
699
  | `reflection` | `true` | live CubeCamera reflections (fancy only; needs a renderer) |
700
700
  | `reflectionInterval` | `1000` | ms between CubeCamera reflection re-renders |
701
701
  | `mirror` | `false` | TRUE planar reflection (see below) — the only way the dock, the boat and the player appear IN the water. One extra scene render per frame |
702
+ | `swellSteepness` | `0.35` | GERSTNER pinch on the swell: 0 = height-only trains, 1 = maximum trochoid (crests narrow to a peak, troughs broaden). It also decides where whitecaps break — the surface's Jacobian collapses on a folding crest, and that is where foam belongs |
702
703
  | `foam` | `true` | noise-broken shoreline foam band + crest foam near shores |
703
704
  | `interaction` | `true` | character interaction: bodies (CharacterBody3D/RigidBody3D) inside the XZ footprint whose FEET dip below the surface count as in-water — so a WADING character (origin above water, feet below, sized from its collider) splashes, not only a fully-submerged one. Entry/exit emit `entered`/`exited` + a splash ripple; striding through water trails a WAKE (a ripple every ~0.45 m); floating bodies bob gently. Ripples drive both shaders' `uRipples[8]` (fancy) and CPU-displace the mesh (`simple`) |
704
705
  | `splash` | `true` | built-in splash WHITEWATER (needs `interaction`): the shaders paint expanding **surface foam** where bodies interact — a **"풍덩"** froth bloom when a body plunges in (bigger the faster it falls) and a **foam trail ("물살")** behind a body wading/running through. Real frothy whitewater on the surface, not flying droplets; works on both `fancy` and `simple` quality. `false` keeps the ripples/waves but paints no foam. No wiring needed; for an extra custom burst add your own `Particles3D` on the `entered` signal |
@@ -837,6 +838,7 @@ underneath decides everything else.
837
838
  | `ripples` | `1` | surface-detail dial (ripple relief + glitter) |
838
839
  | `terrain` | `''` | drape target path; empty = auto-find the first Terrain3D (a wrong path fails at load) |
839
840
  | `flowForce` | `1` | how hard the current sweeps bodies downstream (0 = visual only) |
841
+ | `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) |
840
842
  | `sunDirection` / `sunColor` / `sunIntensity` | sky / `#fff6e0` / `1` | glint (the environment sun wins while `sunDirection` is default) |
841
843
 
842
844
  **What the node derives for you**, all from `path` + the ground:
@@ -868,6 +870,38 @@ const path = traceDownhillPath(terrain.heightAt, { x: peakX, z: peakZ, step: 7 }
868
870
  "path": path, "widths": [2.4, 4.5, 7, 9], "depth": 1
869
871
  ```
870
872
 
873
+ ### Waterfalls happen — you do not author them
874
+
875
+ Nothing in a scene says "waterfall". Where the ground gives way the surface
876
+ profile falls with it, and past ~20° of grade the shader stops treating the
877
+ sheet as flowing water: it aerates (white, diffuse, no sky reflection), its
878
+ pattern stretches into strands, the standing waves of a rapid switch off, and
879
+ the lip goes glassy-dark for the moment before it breaks. `spray` then hangs a
880
+ mist plume at the foot of each drop, sized by how far the water fell.
881
+
882
+ The cheapest way to put one in a scene is to take the ground away — a
883
+ `basins` pocket on the course, no wider than the creek's own reach:
884
+
885
+ ```ts
886
+ const plungeAt = path[Math.round(path.length * 0.82)];
887
+ "basins": [{ "x": plungeAt[0], "z": plungeAt[1], "radius": 7, "depth": 4.5 }]
888
+ ```
889
+
890
+ Keep it a POCKET: a wide shallow bowl reads as a crater with a puddle, and the
891
+ drop has to be short and sharp for the curtain to read at all. For your own
892
+ effects (sound, a rainbow, a cave behind the water), `river.fallsAt()` returns
893
+ every drop with its plunge point in WORLD coordinates and its height:
894
+
895
+ ```ts
896
+ for (const fall of creek.fallsAt()) {
897
+ if (fall.drop > 4) playAt('$sfx/falls', fall.worldX, fall.worldY, fall.worldZ);
898
+ }
899
+ ```
900
+
901
+ A step shallower than the water's own `depth` is deliberately NOT a fall — the
902
+ surface profile treats it as bed grain, which is what stops every riffle in a
903
+ creek from spawning a spray plume.
904
+
871
905
  ### Let the terrain choose the course — `traceDownhillPath`
872
906
 
873
907
  ```ts
@@ -696,6 +696,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
696
696
  | `sunIntensity` | `1` | number |
697
697
  | `terrain` | `""` | string |
698
698
  | `flowForce` | `1` | number |
699
+ | `spray` | `1` | number |
699
700
 
700
701
  ## `Sprite2D` — `incanto/2d`
701
702
 
@@ -973,6 +974,7 @@ Signals: `blocksChanged`
973
974
  | `reflection` | `true` | boolean |
974
975
  | `reflectionInterval` | `1000` | number |
975
976
  | `mirror` | `false` | boolean |
977
+ | `swellSteepness` | `0.35` | number |
976
978
  | `foam` | `true` | boolean |
977
979
  | `interaction` | `true` | boolean |
978
980
  | `splash` | `true` | boolean |
@@ -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.20.0",
17
+ "incanto": "^0.21.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.20.0",
16
+ "incanto": "^0.21.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.20.0",
16
+ "incanto": "^0.21.0",
17
17
  "three": "^0.184.0"
18
18
  },
19
19
  "devDependencies": {