incanto 0.19.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-B7gj1VII.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.19.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",
@@ -277,6 +277,9 @@
277
277
  {
278
278
  "$ref": "#/$defs/RigidBody3D"
279
279
  },
280
+ {
281
+ "$ref": "#/$defs/River3D"
282
+ },
280
283
  {
281
284
  "$ref": "#/$defs/Sprite2D"
282
285
  },
@@ -4600,6 +4603,170 @@
4600
4603
  },
4601
4604
  "required": ["name", "type"]
4602
4605
  },
4606
+ "River3D": {
4607
+ "type": "object",
4608
+ "properties": {
4609
+ "name": {
4610
+ "type": "string"
4611
+ },
4612
+ "uid": {
4613
+ "type": "string"
4614
+ },
4615
+ "type": {
4616
+ "const": "River3D"
4617
+ },
4618
+ "groups": {
4619
+ "type": "array",
4620
+ "items": {
4621
+ "type": "string"
4622
+ }
4623
+ },
4624
+ "tags": {
4625
+ "type": "object"
4626
+ },
4627
+ "props": {
4628
+ "type": "object",
4629
+ "properties": {
4630
+ "position": {
4631
+ "type": "array",
4632
+ "items": {
4633
+ "type": "number"
4634
+ },
4635
+ "minItems": 3,
4636
+ "maxItems": 3,
4637
+ "default": [0, 0, 0]
4638
+ },
4639
+ "rotation": {
4640
+ "type": "array",
4641
+ "items": {
4642
+ "type": "number"
4643
+ },
4644
+ "minItems": 3,
4645
+ "maxItems": 3,
4646
+ "default": [0, 0, 0]
4647
+ },
4648
+ "static": {
4649
+ "type": "boolean",
4650
+ "default": false
4651
+ },
4652
+ "scale": {
4653
+ "type": "array",
4654
+ "items": {
4655
+ "type": "number"
4656
+ },
4657
+ "minItems": 3,
4658
+ "maxItems": 3,
4659
+ "default": [1, 1, 1]
4660
+ },
4661
+ "visible": {
4662
+ "type": "boolean",
4663
+ "default": true
4664
+ },
4665
+ "renderOrder": {
4666
+ "type": "number",
4667
+ "default": 0
4668
+ },
4669
+ "orderGroup": {
4670
+ "type": "string",
4671
+ "enum": ["background", "terrain", "default", "characters", "effects", "overlay"],
4672
+ "default": "default"
4673
+ },
4674
+ "path": {
4675
+ "type": "array",
4676
+ "default": []
4677
+ },
4678
+ "width": {
4679
+ "type": "number",
4680
+ "default": 6
4681
+ },
4682
+ "widths": {
4683
+ "type": "array",
4684
+ "default": []
4685
+ },
4686
+ "depth": {
4687
+ "type": "number",
4688
+ "default": 0.8
4689
+ },
4690
+ "flowSpeed": {
4691
+ "type": "number",
4692
+ "default": 1.6
4693
+ },
4694
+ "colors": {
4695
+ "type": "object",
4696
+ "default": {}
4697
+ },
4698
+ "absorption": {
4699
+ "type": "number",
4700
+ "default": 0.5
4701
+ },
4702
+ "opacity": {
4703
+ "type": "number",
4704
+ "default": 0.85
4705
+ },
4706
+ "foam": {
4707
+ "type": "number",
4708
+ "default": 1
4709
+ },
4710
+ "ripples": {
4711
+ "type": "number",
4712
+ "default": 1
4713
+ },
4714
+ "sunDirection": {
4715
+ "type": "array",
4716
+ "items": {
4717
+ "type": "number"
4718
+ },
4719
+ "minItems": 3,
4720
+ "maxItems": 3,
4721
+ "default": [0.5, 0.8, 0.3]
4722
+ },
4723
+ "sunColor": {
4724
+ "type": "string",
4725
+ "default": "#fff6e0"
4726
+ },
4727
+ "sunIntensity": {
4728
+ "type": "number",
4729
+ "default": 1
4730
+ },
4731
+ "terrain": {
4732
+ "type": "string",
4733
+ "default": ""
4734
+ },
4735
+ "flowForce": {
4736
+ "type": "number",
4737
+ "default": 1
4738
+ },
4739
+ "spray": {
4740
+ "type": "number",
4741
+ "default": 1
4742
+ }
4743
+ },
4744
+ "additionalProperties": false
4745
+ },
4746
+ "script": {
4747
+ "type": "object",
4748
+ "properties": {
4749
+ "name": {
4750
+ "type": "string"
4751
+ },
4752
+ "props": {
4753
+ "type": "object"
4754
+ }
4755
+ },
4756
+ "required": ["name"]
4757
+ },
4758
+ "network": {
4759
+ "type": "object"
4760
+ },
4761
+ "children": {
4762
+ "type": "array",
4763
+ "items": {
4764
+ "$ref": "#/$defs/node"
4765
+ }
4766
+ }
4767
+ },
4768
+ "required": ["name", "type"]
4769
+ },
4603
4770
  "Sprite2D": {
4604
4771
  "type": "object",
4605
4772
  "properties": {
@@ -5198,6 +5365,10 @@
5198
5365
  "type": "array",
5199
5366
  "default": []
5200
5367
  },
5368
+ "channels": {
5369
+ "type": "array",
5370
+ "default": []
5371
+ },
5201
5372
  "wetline": {
5202
5373
  "default": null
5203
5374
  }
@@ -6408,6 +6579,14 @@
6408
6579
  "type": "number",
6409
6580
  "default": 1000
6410
6581
  },
6582
+ "mirror": {
6583
+ "type": "boolean",
6584
+ "default": false
6585
+ },
6586
+ "swellSteepness": {
6587
+ "type": "number",
6588
+ "default": 0.35
6589
+ },
6411
6590
  "foam": {
6412
6591
  "type": "boolean",
6413
6592
  "default": true
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: incanto-environment
3
- description: Generating game environments in Incanto — the deterministic `incanto-env` CLI and `incanto/env` library. EXACTLY three themed 3D generators (arena with boxes/ruins/garden, Terrain3D heightfield worlds with island/alpine/plains/desert/meadow/forest/savanna/snow/wetland/volcanic themes, maze with stone/hedge/canyon) plus 2D mazes, roguelike dungeons and platform courses; insertIntoScene, the GENERATORS catalog + runGenerator; and the environment nodes — Terrain3D (biome texture splatting, heightAt, heightfield collider), shader-water Water3D (FBM waves, anisotropic wind ripple, sparse sun glints, crystal shallows, refraction + depth absorption, reflections, shoreline foam, splash signals + ripples), shader-grass Foliage3D (real curved blade meshes, clumps, rolling wind, distance LOD, character bend), Flowers3D flower plants (lush/sparse/none density dial, daisy/cosmos/bellflower varieties, Voronoi patches, head-bob sway) and ez-tree Tree3D groves (branchy trunks, textured wind-swayed leaves, budget-checked tiers). Use when a game needs a level, stage, arena, terrain, heightfield, island, meadow, grass field, flowers, flower bed, forest, trees, mountain, desert, savanna, snow, tundra, swamp, wetland, marsh, volcano, lava field, maze, dungeon, platform course, scattered props, clouds, water, or a splash effect.
3
+ description: Generating game environments in Incanto — the deterministic `incanto-env` CLI and `incanto/env` library. EXACTLY three themed 3D generators (arena with boxes/ruins/garden, Terrain3D heightfield worlds with island/alpine/plains/desert/meadow/forest/savanna/snow/wetland/volcanic themes, maze with stone/hedge/canyon) plus 2D mazes, roguelike dungeons and platform courses; insertIntoScene, the GENERATORS catalog + runGenerator; and the environment nodes — Terrain3D (biome texture splatting, heightAt, heightfield collider), shader-water Water3D (FBM waves, anisotropic wind ripple, sparse sun glints, crystal shallows, refraction + depth absorption, reflections, shoreline foam, splash signals + ripples), River3D running water (path-derived course, terrain-cut banks, derived rapids/riffles, a current that sweeps bodies), shader-grass Foliage3D (real curved blade meshes, clumps, rolling wind, distance LOD, character bend), Flowers3D flower plants (lush/sparse/none density dial, daisy/cosmos/bellflower varieties, Voronoi patches, head-bob sway) and ez-tree Tree3D groves (branchy trunks, textured wind-swayed leaves, budget-checked tiers). Use when a game needs a level, stage, arena, terrain, heightfield, island, meadow, grass field, flowers, flower bed, forest, trees, mountain, desert, savanna, snow, tundra, swamp, wetland, marsh, volcano, lava field, maze, dungeon, platform course, scattered props, clouds, water, a river, stream, creek, brook, rapids, a ford, or a splash effect.
4
4
  ---
5
5
 
6
6
  # Environment generation — levels from a seed
@@ -554,6 +554,7 @@ is radians of `atan(|∇h|)`. Default textures stream from the live agent8 CDN
554
554
  | `layers` | `[]` | custom splat layers (theme `custom` only) |
555
555
  | `textureBase` | agent8 CDN | base URL: `<base>/<name>.png` + `<base>/<name>_normal.png` |
556
556
  | `basins` | `[]` | lake/pond bowls — `[{ x, z, radius, depth }]` (centered meters) carved into the surface (smooth, 0-slope rim); **negative `depth` RAISES a smooth dome mound instead** (a hill, an islet); `heightAt`, the collider AND draped grass all see them |
557
+ | `channels` | `[]` | river/road TRENCHES carved along polylines — `[{ path, width, depth, taper? }]` (the line counterpart of `basins`). This is what gives a `River3D` a bed to sit in; `heightAt`, the collider and draped vegetation all see it |
557
558
  | `wetline` | `null` | WET SAND band — `{ y, band? }` darkens + glosses the splat in a noisy, breathing band just above height `y` (a waterline): the trace of the last swash runup. `band` (default `1.1` m) caps how high above `y` reads wet. `null` = off |
558
559
 
559
560
  **Wet sand at a shoreline.** Set `wetline.y` to the SAME world height as the
@@ -697,6 +698,8 @@ hue reads grey.
697
698
  | `colors` | `{}` | fancy ramp overrides: `{"trough", "surface", "peak"}` hex strings |
698
699
  | `reflection` | `true` | live CubeCamera reflections (fancy only; needs a renderer) |
699
700
  | `reflectionInterval` | `1000` | ms between CubeCamera reflection re-renders |
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 |
700
703
  | `foam` | `true` | noise-broken shoreline foam band + crest foam near shores |
701
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`) |
702
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 |
@@ -737,6 +740,32 @@ Two placement rules keep the surface artifact-free:
737
740
  intentionally does not — its submerged hull shows through `refraction`
738
741
  instead.
739
742
 
743
+ ### `mirror` — a TRUE planar reflection
744
+
745
+ The default reflection is a CubeCamera env map: it carries the sky and the far
746
+ shore, and it deliberately near-clips everything inside the water's own
747
+ footprint (a nearby crate sampled as an infinite environment smears across the
748
+ whole surface). So the boat, the dock, the pier lamp and the player standing at
749
+ the edge are exactly what it CANNOT show.
750
+
751
+ `mirror: true` re-renders the scene from the camera mirrored across the water
752
+ plane and samples it per fragment, so those things appear in the water:
753
+
754
+ ```json
755
+ { "type": "Water3D", "props": { "preset": "lake", "mirror": true,
756
+ "waveHeight": 0.012, "detailStrength": 0.07 } }
757
+ ```
758
+
759
+ - Costs **one extra scene render per frame** (half the drawing buffer, clamped)
760
+ — off by default; a still lake or a pool earns it, open ocean rarely does.
761
+ - A mirror needs a CALM surface to read: chop that shatters the reflection is
762
+ what makes game lakes look like blue plastic. Pair it with a low `waveHeight`
763
+ and a gentle `detailStrength`.
764
+ - Rays that leave the screen have no planar sample; those fragments fall back to
765
+ the cube map (keep `reflection: true`), so there is no hard cut at the edges.
766
+ - Geometry below the waterline is clipped out of the mirror pass, and the whole
767
+ pass is skipped while the camera is submerged.
768
+
740
769
  ### Character interaction — `entered(body)` / `exited(body)`
741
770
 
742
771
  With `interaction: true` the water scans the tree each frame for
@@ -779,6 +808,132 @@ emitter only when you want a specific custom burst:
779
808
  emitter to the body first — the signal hands you the node:
780
809
  `onEntered(body) { splash.position = body.position; splash.replay(); }`.)
781
810
 
811
+ ## River3D — running water
812
+
813
+ `Water3D` is a *surface*; `River3D` is a *current*. A river is authored as a
814
+ line, not a shape: give it a centerline `path` and a width, and the terrain
815
+ underneath decides everything else.
816
+
817
+ ```json
818
+ { "name": "Creek", "type": "River3D", "props": {
819
+ "path": [[-80, -30], [-20, 5], [30, 10], [90, -10]],
820
+ "widths": [2.5, 5, 9],
821
+ "depth": 1,
822
+ "flowSpeed": 1.6,
823
+ "colors": { "shallow": "#79b6a4", "deep": "#103c49", "bank": "#39472f" }
824
+ } }
825
+ ```
826
+
827
+ | prop | default | meaning |
828
+ |---|---|---|
829
+ | `path` | `[]` | centerline `[[x, z], …]` in NODE-LOCAL meters, Catmull-Rom smoothed (2+ points) |
830
+ | `width` | `6` | channel width in meters |
831
+ | `widths` | `[]` | width profile lerped source→mouth (e.g. `[2.5, 5, 9]`); empty = constant `width` |
832
+ | `depth` | `0.8` | water column at the centerline — also the scale foam thresholds read as "shallow" |
833
+ | `flowSpeed` | `1.6` | reference current in m/s (the mean; reaches speed up and slow down) |
834
+ | `colors` | `{}` | `{ shallow, deep, sky, horizon, bank }` — the body ramp plus what the surface mirrors |
835
+ | `absorption` | `0.5` | how fast the water hides its bed (Beer's law) |
836
+ | `opacity` | `0.85` | upper bound on the body's opacity |
837
+ | `foam` | `1` | whitewater dial — 0 = a glassy canal, 2 = raging |
838
+ | `ripples` | `1` | surface-detail dial (ripple relief + glitter) |
839
+ | `terrain` | `''` | drape target path; empty = auto-find the first Terrain3D (a wrong path fails at load) |
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) |
842
+ | `sunDirection` / `sunColor` / `sunIntensity` | sky / `#fff6e0` / `1` | glint (the environment sun wins while `sunDirection` is default) |
843
+
844
+ **What the node derives for you**, all from `path` + the ground:
845
+
846
+ - a surface that follows the bed's DESCENDING envelope — water pours over a lip
847
+ and never climbs one (a rising bed dams it into a still pool);
848
+ - **the visible width**: every vertex carries its own water column
849
+ (`surfaceY − bed`) and the shader stops drawing where that runs out, so
850
+ banks, gravel bars and half-drowned boulders cut the ribbon;
851
+ - **the current**: continuity (a pinched channel runs faster) × grade (a chute
852
+ runs faster), which is what puts rapids where a real river has them;
853
+ - **whitewater**: grade × speed makes rapids, the bank shear line makes edge
854
+ froth, a thinning column riffles over rock. Foam then rides downstream.
855
+
856
+ It costs NO extra render passes (unlike fancy `Water3D`), so a map can carry a
857
+ dozen rivers.
858
+
859
+ ### Cut the bed first
860
+
861
+ Water needs somewhere to be. Give the same path to the terrain as a `channels`
862
+ carve, or the creek will lie on top of the ground as a thin film and read as
863
+ riffle everywhere:
864
+
865
+ ```ts
866
+ const path = traceDownhillPath(terrain.heightAt, { x: peakX, z: peakZ, step: 7 });
867
+ // terrain prop — the trench (collider + heightAt + drape all see it)
868
+ "channels": [{ "path": path, "width": 7, "depth": 2.2, "taper": 9 }]
869
+ // river prop — the water in it
870
+ "path": path, "widths": [2.4, 4.5, 7, 9], "depth": 1
871
+ ```
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
+
905
+ ### Let the terrain choose the course — `traceDownhillPath`
906
+
907
+ ```ts
908
+ import { traceDownhillPath } from 'incanto/3d';
909
+ const path = traceDownhillPath((x, z) => terrain.heightAt(x, z), {
910
+ x: sourceX, z: sourceZ, // start high
911
+ step: 7, // meters per step (also the gradient probe radius)
912
+ bounds: 100, // stay inside ±100 m
913
+ maxPoints: 46,
914
+ });
915
+ ```
916
+
917
+ Steepest descent with momentum and a thalweg snap, so the line follows the
918
+ valley floor instead of rattling between its walls. It ends in a pool, at the
919
+ map edge or at `maxPoints`; `[]` means the start was flat.
920
+
921
+ ### The current is gameplay
922
+
923
+ `flowForce` drags bodies toward the water's own velocity — drag, never thrust,
924
+ so a raft accelerates until it matches the current and then coasts, and a
925
+ character can fight across a slow ford but loses ground in a fast one. For
926
+ scripts, `sampleAt(x, z)` (WORLD coords) answers where a point sits:
927
+
928
+ ```ts
929
+ const hit = creek.sampleAt(player.position[0], player.position[2]);
930
+ if (hit?.inside && hit.speed > 3) hud.warn('too fast to ford here');
931
+ // hit: { inside, across (±1 = banks), along, surfaceY, dirX, dirZ, speed, halfWidth }
932
+ ```
933
+
934
+ The course is derived on the CPU in `update()`, so `sampleAt` works headlessly
935
+ (servers, `bun verify.ts`) before anything has ever been rendered.
936
+
782
937
  ## Determinism, verified
783
938
 
784
939
  `--seed` makes every run reproducible — keep the seed in your scene comments
@@ -670,6 +670,34 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
670
670
 
671
671
  Signals: `triggerEnter(other)` · `triggerExit(other)`
672
672
 
673
+ ## `River3D` — `incanto/3d`
674
+
675
+ | Prop | Default | Kind |
676
+ |---|---|---|
677
+ | `position` | `[0,0,0]` | array |
678
+ | `rotation` | `[0,0,0]` | array |
679
+ | `static` | `false` | boolean |
680
+ | `scale` | `[1,1,1]` | array |
681
+ | `visible` | `true` | boolean |
682
+ | `renderOrder` | `0` | number |
683
+ | `orderGroup` | `"default"` | one of: `background` `terrain` `default` `characters` `effects` `overlay` |
684
+ | `path` | `[]` | array |
685
+ | `width` | `6` | number |
686
+ | `widths` | `[]` | array |
687
+ | `depth` | `0.8` | number |
688
+ | `flowSpeed` | `1.6` | number |
689
+ | `colors` | `{}` | object |
690
+ | `absorption` | `0.5` | number |
691
+ | `opacity` | `0.85` | number |
692
+ | `foam` | `1` | number |
693
+ | `ripples` | `1` | number |
694
+ | `sunDirection` | `[0.5,0.8,0.3]` | array |
695
+ | `sunColor` | `"#fff6e0"` | string |
696
+ | `sunIntensity` | `1` | number |
697
+ | `terrain` | `""` | string |
698
+ | `flowForce` | `1` | number |
699
+ | `spray` | `1` | number |
700
+
673
701
  ## `Sprite2D` — `incanto/2d`
674
702
 
675
703
  | Prop | Default | Kind |
@@ -764,6 +792,7 @@ Signals: `triggerEnter(other)` · `triggerExit(other)`
764
792
  | `layers` | `[]` | array |
765
793
  | `textureBase` | `"https://agent8-games.verse8.io/assets/3D/default/textures/terrain"` | string |
766
794
  | `basins` | `[]` | array |
795
+ | `channels` | `[]` | array |
767
796
  | `wetline` | `null` | null |
768
797
 
769
798
  ## `TileMap2D` — `incanto/2d`
@@ -944,6 +973,8 @@ Signals: `blocksChanged`
944
973
  | `colors` | `{}` | object |
945
974
  | `reflection` | `true` | boolean |
946
975
  | `reflectionInterval` | `1000` | number |
976
+ | `mirror` | `false` | boolean |
977
+ | `swellSteepness` | `0.35` | number |
947
978
  | `foam` | `true` | boolean |
948
979
  | `interaction` | `true` | boolean |
949
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.19.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.19.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.19.0",
16
+ "incanto": "^0.21.0",
17
17
  "three": "^0.184.0"
18
18
  },
19
19
  "devDependencies": {