incanto 0.14.0 → 0.15.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.
Files changed (29) hide show
  1. package/dist/3d.d.ts +15 -0
  2. package/dist/3d.js +3 -3
  3. package/dist/{create-game-OSntcIiM.js → create-game-BS-K-GY1.js} +2 -2
  4. package/dist/index.js +1 -1
  5. package/dist/{physics-3d-D_kUdOjr.js → physics-3d-TmOuCy7J.js} +1 -1
  6. package/dist/react.js +1 -1
  7. package/dist/{register-C9-16x_t.js → register-Bh_3Z39N.js} +110 -5
  8. package/dist/test.js +3 -3
  9. package/editor/assets/{agent8-BDC4LhjC.js → agent8-DqQ2CQ5A.js} +1 -1
  10. package/editor/assets/{index-7qOYg7t8.js → index-CofH0yGY.js} +77 -5
  11. package/editor/index.html +1 -1
  12. package/package.json +1 -1
  13. package/schemas/scene.schema.json +16 -0
  14. package/skills/incanto-environment.md +7 -1
  15. package/skills/incanto-node-reference.md +4 -0
  16. package/templates-app/beacon-isle-3d/PROJECT/Status.md +1 -1
  17. package/templates-app/beacon-isle-3d/generate-world.ts +23 -18
  18. package/templates-app/beacon-isle-3d/package.json +1 -1
  19. package/templates-app/beacon-isle-3d/src/behaviors.ts +70 -4
  20. package/templates-app/beacon-isle-3d/src/game.scene.json +20 -21
  21. package/templates-app/tps-3d/package.json +1 -1
  22. package/templates-app/village-quest-3d/PROJECT/Context.md +1 -1
  23. package/templates-app/village-quest-3d/PROJECT/Requirements.md +1 -1
  24. package/templates-app/village-quest-3d/PROJECT/Structure.md +6 -1
  25. package/templates-app/village-quest-3d/generate-dressing.ts +769 -0
  26. package/templates-app/village-quest-3d/package.json +1 -1
  27. package/templates-app/village-quest-3d/src/behaviors.ts +74 -8
  28. package/templates-app/village-quest-3d/src/grove.scene.json +1 -13
  29. package/templates-app/village-quest-3d/src/village.scene.json +2989 -162
package/dist/3d.d.ts CHANGED
@@ -2043,6 +2043,21 @@ declare class Water3D extends Node3D implements RenderHook3D, SunConsumer3D {
2043
2043
  * `{ color?, visibility? }` overrides the fog hue / view distance (meters).
2044
2044
  */
2045
2045
  underwater: boolean | JsonObject;
2046
+ /**
2047
+ * Directional traveling SWELL amplitude in meters (fancy only; 0 = off, the
2048
+ * legacy isotropic look). Three peaked wave trains march across the surface
2049
+ * at real deep-water speeds — THE open-ocean dial: 0.15 = lively lake chop,
2050
+ * 0.4 = coastal sea, 0.8 = heavy weather. Crests feed the color ramp,
2051
+ * `whitecaps` and the shore foam automatically.
2052
+ */
2053
+ swell: number;
2054
+ /** Compass direction the swell TRAVELS toward, degrees (0 = +z, 90 = +x). */
2055
+ swellDirectionDeg: number;
2056
+ /** Primary swell wavelength in meters (the two crossing trains derive). */
2057
+ swellWavelength: number;
2058
+ /** Open-water whitecap foam on the tallest crests, 0–1 (fancy only). Works
2059
+ * best with `swell` — the caps ride the swell's crest lines. */
2060
+ whitecaps: number;
2046
2061
  /** Loader hook: degenerate planes and bad enums fail at LOAD, not at render. */
2047
2062
  static validateJson(node: Node): void;
2048
2063
  private time;
package/dist/3d.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
2
- import { a as Environment3D, c as sunDirectionFromElevationAzimuth, i as syncTree, l as sunDirectionFromSky, o as horizonColorFromSky, r as Renderer3D, s as parseEnvironment3D, t as createGame3D, u as AssetStore3D } from "./create-game-OSntcIiM.js";
3
- import { A as Area3D, B as movementState, C as BoneAttachment3D, D as TERRAIN_THEMES, E as DEFAULT_TERRAIN_TEXTURE_BASE, F as Node3D, L as QUARTER_PITCH, M as PhysicsBody3D, N as RigidBody3D, O as terrainThemeLayers, P as StaticBody3D, R as cameraRelative, S as BoneLookAt3D, T as Terrain3D, V as rigPose, _ as Flowers3D, a as VoxelGrid3D, b as CharacterController3D, c as Particles3D, d as DirectionalLight3D, f as OmniLight3D, g as DENSITY_PRESETS, h as Foliage3D, i as VOXEL_PALETTE, j as CharacterBody3D, k as Joint3D, l as ModelInstance3D, m as MeshInstance3D, n as Water3D, o as Tree3D, p as InstancedMesh3D, r as WATER_MAX_RIPPLES, s as Trail3D, t as registerNodes3D, u as LoftMesh3D, v as resolveFlowerDensity, w as Billboard3D, x as Camera3D, y as FLOWER_VARIETIES, z as keyboardIntensity } from "./register-C9-16x_t.js";
2
+ import { a as Environment3D, c as sunDirectionFromElevationAzimuth, i as syncTree, l as sunDirectionFromSky, o as horizonColorFromSky, r as Renderer3D, s as parseEnvironment3D, t as createGame3D, u as AssetStore3D } from "./create-game-BS-K-GY1.js";
3
+ import { A as Area3D, B as movementState, C as BoneAttachment3D, D as TERRAIN_THEMES, E as DEFAULT_TERRAIN_TEXTURE_BASE, F as Node3D, L as QUARTER_PITCH, M as PhysicsBody3D, N as RigidBody3D, O as terrainThemeLayers, P as StaticBody3D, R as cameraRelative, S as BoneLookAt3D, T as Terrain3D, V as rigPose, _ as Flowers3D, a as VoxelGrid3D, b as CharacterController3D, c as Particles3D, d as DirectionalLight3D, f as OmniLight3D, g as DENSITY_PRESETS, h as Foliage3D, i as VOXEL_PALETTE, j as CharacterBody3D, k as Joint3D, l as ModelInstance3D, m as MeshInstance3D, n as Water3D, o as Tree3D, p as InstancedMesh3D, r as WATER_MAX_RIPPLES, s as Trail3D, t as registerNodes3D, u as LoftMesh3D, v as resolveFlowerDensity, w as Billboard3D, x as Camera3D, y as FLOWER_VARIETIES, z as keyboardIntensity } from "./register-Bh_3Z39N.js";
4
4
  import { n as splatWeights, t as buildHeightmap } from "./heightmap-CroQPEER.js";
5
- import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-D_kUdOjr.js";
5
+ import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-TmOuCy7J.js";
6
6
  //#region src/3d/environment-runtime.ts
7
7
  /**
8
8
  * Live environment editing — the renderer re-applies `scene.environment`
@@ -5,8 +5,8 @@ import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { i as resolveRendering, n as attachTouchControls } from "./touch-031PxtCR.js";
6
6
  import { n as registerGameplayBehaviors } from "./gameplay-sSqrUcnz.js";
7
7
  import { t as debugSources } from "./debug-draw-CZmOYjL2.js";
8
- import { F as Node3D, M as PhysicsBody3D, d as DirectionalLight3D, l as ModelInstance3D, t as registerNodes3D, x as Camera3D } from "./register-C9-16x_t.js";
9
- import { n as enablePhysics3D } from "./physics-3d-D_kUdOjr.js";
8
+ import { F as Node3D, M as PhysicsBody3D, d as DirectionalLight3D, l as ModelInstance3D, t as registerNodes3D, x as Camera3D } from "./register-Bh_3Z39N.js";
9
+ import { n as enablePhysics3D } from "./physics-3d-TmOuCy7J.js";
10
10
  import { ACESFilmicToneMapping, AmbientLight, Box3, BufferAttribute, BufferGeometry, Color, DepthTexture, EquirectangularReflectionMapping, FloatType, Fog, HalfFloatType, LineBasicMaterial, LineSegments, Matrix4, Mesh, PCFShadowMap, PMREMGenerator, PerspectiveCamera, PlaneGeometry, Quaternion, Raycaster, Scene, ShaderMaterial, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer } from "three";
11
11
  import { VRMLoaderPlugin, VRMUtils } from "@pixiv/three-vrm";
12
12
  import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
package/dist/index.js CHANGED
@@ -295,6 +295,6 @@ function newUid() {
295
295
  //#endregion
296
296
  //#region src/index.ts
297
297
  /** Engine version. Kept in sync with package.json by the release pipeline. */
298
- const VERSION = "0.14.0";
298
+ const VERSION = "0.15.0";
299
299
  //#endregion
300
300
  export { AudioBuses, AudioPlayer, Behavior, CONST_REF_KEY, Engine, HudLayer, IncantoError, InputMap, LogManager, MusicManager, Node, ORDER_GROUP_BASE, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, Scene, SceneTree, SfxEngine, Signal, Timer, TouchControls, UiBanner, UiBar, UiButton, UiDialogue, UiText, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, mergeStaticSignals, newUid, parseNodePath, preloadUrls, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveConstants, resolveRendering, resolveViewport, serializeNode, spatialGain, spatialPan, startRecording, synthSfx };
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
3
  import { n as registerDebugSource } from "./debug-draw-CZmOYjL2.js";
4
- import { A as Area3D, F as Node3D, I as validateCollider3D, M as PhysicsBody3D, N as RigidBody3D, T as Terrain3D, j as CharacterBody3D, k as Joint3D } from "./register-C9-16x_t.js";
4
+ import { A as Area3D, F as Node3D, I as validateCollider3D, M as PhysicsBody3D, N as RigidBody3D, T as Terrain3D, j as CharacterBody3D, k as Joint3D } from "./register-Bh_3Z39N.js";
5
5
  import { Euler, Quaternion } from "three";
6
6
  //#region src/3d/physics/physics-3d.ts
7
7
  var physics_3d_exports = /* @__PURE__ */ __exportAll({
package/dist/react.js CHANGED
@@ -156,7 +156,7 @@ function IncantoCanvas(props) {
156
156
  pointer: latest.pointer,
157
157
  ...keyboard !== void 0 ? { keyboard } : {}
158
158
  };
159
- const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-OSntcIiM.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-Ct86zczq.js").then((n) => n.n)).createGame2D(o)))(opts);
159
+ const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-BS-K-GY1.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-Ct86zczq.js").then((n) => n.n)).createGame2D(o)))(opts);
160
160
  if (disposed) {
161
161
  next.dispose();
162
162
  return;
@@ -10344,6 +10344,11 @@ uniform vec3 uScale;
10344
10344
  // incanto: world-anchor + interaction ripples (x, z, age, amplitude)
10345
10345
  uniform vec3 uWaterCenter;
10346
10346
  uniform vec4 uRipples[8];
10347
+ // incanto swell: directional traveling wave trains (0 = off — legacy look).
10348
+ // uSwellDir is a unit XZ vector; amplitude in meters; wavelength in meters.
10349
+ uniform float uSwellAmplitude;
10350
+ uniform vec2 uSwellDir;
10351
+ uniform float uSwellWavelength;
10347
10352
 
10348
10353
  varying vec3 vNormal;
10349
10354
  varying vec3 vWorldPosition;
@@ -10426,10 +10431,34 @@ float getRippleHeight(vec2 p) {
10426
10431
  return h;
10427
10432
  }
10428
10433
 
10429
- // incanto: waves + ripples used for displacement AND the normal samples
10430
- // so interaction rings catch the light like real waves.
10434
+ // incanto swell: one peaked traveling wave train. Deep-water dispersion
10435
+ // (c = sqrt(g/k)) gives each wavelength its REAL speed, so short chop
10436
+ // overtakes long swell exactly like the open sea. The pow-shaped profile
10437
+ // sharpens crests and flattens troughs (a height-only Gerstner stand-in —
10438
+ // no XZ pinch, so the analytic finite-difference normals stay exact).
10439
+ float swellWave(vec2 p, vec2 dir, float lambda, float amp, float sharp) {
10440
+ float k = 6.2831853 / max(lambda, 1.0);
10441
+ float c = sqrt(9.8 / k);
10442
+ float s = 0.5 + 0.5 * sin(dot(p, dir) * k - uTime * c * k);
10443
+ return amp * (pow(s, sharp) * 2.0 - 1.0);
10444
+ }
10445
+
10446
+ // incanto swell: three trains — the primary + two shorter crossing sets
10447
+ // (+25° / −19°) so crest lines stay broken and organic, never a zebra field.
10448
+ float getSwell(vec2 p) {
10449
+ if (uSwellAmplitude <= 0.0) return 0.0;
10450
+ vec2 d1 = uSwellDir;
10451
+ vec2 d2 = normalize(vec2(d1.x * 0.906 - d1.y * 0.423, d1.x * 0.423 + d1.y * 0.906));
10452
+ vec2 d3 = normalize(vec2(d1.x * 0.946 + d1.y * 0.326, -d1.x * 0.326 + d1.y * 0.946));
10453
+ return swellWave(p, d1, uSwellWavelength, uSwellAmplitude * 0.60, 2.6)
10454
+ + swellWave(p, d2, uSwellWavelength * 0.53, uSwellAmplitude * 0.27, 2.2)
10455
+ + swellWave(p, d3, uSwellWavelength * 0.31, uSwellAmplitude * 0.16, 1.8);
10456
+ }
10457
+
10458
+ // incanto: waves + swell + ripples — used for displacement AND the normal
10459
+ // samples so every layer catches the light like real waves.
10431
10460
  float getHeight(float x, float z) {
10432
- return getElevation(x, z) + getRippleHeight(vec2(x, z));
10461
+ return getElevation(x, z) + getSwell(vec2(x, z)) + getRippleHeight(vec2(x, z));
10433
10462
  }
10434
10463
 
10435
10464
  void main() {
@@ -10538,6 +10567,15 @@ uniform vec4 uRipples[8];
10538
10567
  uniform float uRippleFoam[8];
10539
10568
  uniform float uSplashFoam;
10540
10569
 
10570
+ // incanto swell: open-water WHITECAPS — foam breaking on the highest crests,
10571
+ // independent of the shoreline depth mask. uWaveEnvelope is the JS-computed
10572
+ // total wave amplitude (FBM + swell) so the crest mask normalizes by the
10573
+ // actual sea state, not the surface's extent. uSwellAmplitude gates the
10574
+ // swell-only color work (crest banding + wave-face shading).
10575
+ uniform float uWhitecaps;
10576
+ uniform float uWaveEnvelope;
10577
+ uniform float uSwellAmplitude;
10578
+
10541
10579
  // 🎨 Contact surface color customization uniforms
10542
10580
  uniform vec3 uEdgeColor;
10543
10581
  uniform float uEdgeIntensity;
@@ -10924,6 +10962,24 @@ void main() {
10924
10962
  // Mix between surface and peak colors based on peak transition
10925
10963
  vec3 mixedColor2 = mix(mixedColor1, uPeakColor, peakFactor);
10926
10964
 
10965
+ // incanto swell: the legacy ramp normalizes elevation by the surface's
10966
+ // HALF-EXTENT — on a real ocean plane that's hundreds of meters, so the
10967
+ // ramp never sees a wave. When swell is on, re-read the crest height
10968
+ // against the actual sea state (uWaveEnvelope) and (a) lighten crest tops
10969
+ // toward the peak color, (b) shade the wave FACES with a gentle N·L off
10970
+ // the distance-smoothed geometry normal — the lit/shadow lanes are what
10971
+ // make open-ocean swell READ at any distance. Both gated: swell 0 keeps
10972
+ // the legacy look byte-identical.
10973
+ if (uSwellAmplitude > 0.0) {
10974
+ float crestBand = smoothstep(0.3, 0.9,
10975
+ (vWorldPosition.y - uWaterCenter.y) / max(uWaveEnvelope, 0.001));
10976
+ mixedColor2 = mix(mixedColor2, uPeakColor, crestBand * 0.45);
10977
+ float faceShade = clamp(dot(normalize(mix(vec3(0.0, 1.0, 0.0), normalize(vNormal),
10978
+ 1.0 - 0.9 * smoothstep(150.0, 600.0, length(vWorldPosition - cameraPosition)))),
10979
+ normalize(uSunDirection)), 0.0, 1.0);
10980
+ mixedColor2 *= 0.80 + 0.32 * faceShade;
10981
+ }
10982
+
10927
10983
  // incanto v2: Beer's-law depth absorption + screen-space refraction.
10928
10984
  // Shallow water transmits the (refracted) scene almost untouched; depth
10929
10985
  // exponentially absorbs it into the ramp color — clear turquoise edges,
@@ -11060,6 +11116,22 @@ void main() {
11060
11116
  if (uEnableFoam > 0.5) {
11061
11117
  foamAmount = calculateFoam();
11062
11118
  }
11119
+ // incanto swell: whitecaps — foam eats the TOPS of the tallest crests in
11120
+ // open water. The crest mask normalizes elevation by the real wave envelope
11121
+ // (uScale.y is the surface's half-extent — useless as a sea-state yardstick
11122
+ // on a big ocean plane), and a two-octave noise breaks the caps into
11123
+ // patches that live and die with the crests. Distance-faded: far whitecaps
11124
+ // subtend under a pixel and would alias into horizon speckle.
11125
+ if (uWhitecaps > 0.0 && uWaveEnvelope > 0.001) {
11126
+ float crestN = (vWorldPosition.y - uWaterCenter.y) / uWaveEnvelope;
11127
+ float cap = smoothstep(0.5, 0.85, crestN);
11128
+ vec2 capUV = vWorldPosition.xz * 0.3;
11129
+ float capNoise = noise(capUV * 2.2 + uTime * vec2(0.10, 0.06)) * 0.65
11130
+ + noise(capUV * 6.5 - uTime * vec2(0.05, 0.14)) * 0.35;
11131
+ float capFade = 1.0 - smoothstep(220.0, 640.0, camDist);
11132
+ float whitecap = uWhitecaps * cap * smoothstep(0.42, 0.78, capNoise) * capFade;
11133
+ foamAmount = max(foamAmount, whitecap);
11134
+ }
11063
11135
  // incanto: splash/wake whitewater rides the ripple buffer, INDEPENDENT of the
11064
11136
  // depth-foam gate so it works even on shallow ponds / before the first pre-pass
11065
11137
  float splashFoam = rippleFoam(vWorldPosition.xz);
@@ -11469,7 +11541,11 @@ var Water3D = class Water3D extends Node3D {
11469
11541
  detailStrength: { default: .26 },
11470
11542
  absorption: { default: .15 },
11471
11543
  refraction: { default: true },
11472
- underwater: { default: true }
11544
+ underwater: { default: true },
11545
+ swell: { default: 0 },
11546
+ swellDirectionDeg: { default: 0 },
11547
+ swellWavelength: { default: 30 },
11548
+ whitecaps: { default: 0 }
11473
11549
  };
11474
11550
  /** [width, depth] in meters (the surface lies on XZ). */
11475
11551
  size = [40, 40];
@@ -11524,6 +11600,21 @@ var Water3D = class Water3D extends Node3D {
11524
11600
  * `{ color?, visibility? }` overrides the fog hue / view distance (meters).
11525
11601
  */
11526
11602
  underwater = true;
11603
+ /**
11604
+ * Directional traveling SWELL amplitude in meters (fancy only; 0 = off, the
11605
+ * legacy isotropic look). Three peaked wave trains march across the surface
11606
+ * at real deep-water speeds — THE open-ocean dial: 0.15 = lively lake chop,
11607
+ * 0.4 = coastal sea, 0.8 = heavy weather. Crests feed the color ramp,
11608
+ * `whitecaps` and the shore foam automatically.
11609
+ */
11610
+ swell = 0;
11611
+ /** Compass direction the swell TRAVELS toward, degrees (0 = +z, 90 = +x). */
11612
+ swellDirectionDeg = 0;
11613
+ /** Primary swell wavelength in meters (the two crossing trains derive). */
11614
+ swellWavelength = 30;
11615
+ /** Open-water whitecap foam on the tallest crests, 0–1 (fancy only). Works
11616
+ * best with `swell` — the caps ride the swell's crest lines. */
11617
+ whitecaps = 0;
11527
11618
  /** Loader hook: degenerate planes and bad enums fail at LOAD, not at render. */
11528
11619
  static validateJson(node) {
11529
11620
  const w = node;
@@ -11545,6 +11636,9 @@ var Water3D = class Water3D extends Node3D {
11545
11636
  if (!(w.sunIntensity >= 0)) throw new IncantoError("BAD_FORMAT", `Water3D '${node.name}' sunIntensity must be >= 0, got ${w.sunIntensity}.`, { prop: "sunIntensity" });
11546
11637
  if (!(w.detailStrength >= 0)) throw new IncantoError("BAD_FORMAT", `Water3D '${node.name}' detailStrength must be >= 0, got ${w.detailStrength}.`, { prop: "detailStrength" });
11547
11638
  if (!(w.absorption >= 0)) throw new IncantoError("BAD_FORMAT", `Water3D '${node.name}' absorption must be >= 0 (per-meter Beer's-law constant), got ${w.absorption}.`, { prop: "absorption" });
11639
+ if (!(w.swell >= 0) || !Number.isFinite(w.swell)) throw new IncantoError("BAD_FORMAT", `Water3D '${node.name}' swell must be >= 0 meters (0 = off), got ${JSON.stringify(w.swell)}.`, { prop: "swell" });
11640
+ if (!(w.swellWavelength >= 2)) throw new IncantoError("BAD_FORMAT", `Water3D '${node.name}' swellWavelength must be >= 2 meters, got ${JSON.stringify(w.swellWavelength)}.`, { prop: "swellWavelength" });
11641
+ if (!(w.whitecaps >= 0) || !(w.whitecaps <= 1)) throw new IncantoError("BAD_FORMAT", `Water3D '${node.name}' whitecaps must be in [0, 1], got ${JSON.stringify(w.whitecaps)}.`, { prop: "whitecaps" });
11548
11642
  const uw = w.underwater;
11549
11643
  if (typeof uw !== "boolean") {
11550
11644
  if (typeof uw !== "object" || uw === null || Array.isArray(uw)) throw new IncantoError("BAD_FORMAT", `Water3D '${node.name}' underwater must be true, false or an object ({ color?, visibility? }), got ${JSON.stringify(uw)}.`, { prop: "underwater" });
@@ -11798,7 +11892,12 @@ var Water3D = class Water3D extends Node3D {
11798
11892
  uCameraFar: { value: 1e3 },
11799
11893
  uEdgeColor: { value: new Color(FOAM_LOOK.edgeColor) },
11800
11894
  uEdgeIntensity: { value: FOAM_LOOK.edgeIntensity },
11801
- uEdgeWidth: { value: FOAM_LOOK.edgeWidth }
11895
+ uEdgeWidth: { value: FOAM_LOOK.edgeWidth },
11896
+ uSwellAmplitude: { value: this.swell },
11897
+ uSwellDir: { value: new Vector2(0, 1) },
11898
+ uSwellWavelength: { value: this.swellWavelength },
11899
+ uWhitecaps: { value: this.whitecaps },
11900
+ uWaveEnvelope: { value: 0 }
11802
11901
  },
11803
11902
  transparent: true,
11804
11903
  depthTest: true,
@@ -11860,6 +11959,12 @@ var Water3D = class Water3D extends Node3D {
11860
11959
  if (u.uSunIntensity) u.uSunIntensity.value = this.sunIntensity;
11861
11960
  if (u.uDetailStrength) u.uDetailStrength.value = this.detailStrength;
11862
11961
  if (u.uAbsorption) u.uAbsorption.value = this.absorption;
11962
+ if (u.uSwellAmplitude) u.uSwellAmplitude.value = this.swell;
11963
+ if (u.uSwellWavelength) u.uSwellWavelength.value = this.swellWavelength;
11964
+ if (u.uWhitecaps) u.uWhitecaps.value = this.whitecaps;
11965
+ const swellRad = this.swellDirectionDeg * Math.PI / 180;
11966
+ (u.uSwellDir?.value)?.set(Math.sin(swellRad), Math.cos(swellRad));
11967
+ if (u.uWaveEnvelope) u.uWaveEnvelope.value = this.waveHeight * AMPLITUDE_PER_WAVE_HEIGHT * 1.5 + this.swell * 1.03;
11863
11968
  if (!this.reflection && u.uUseEnvironmentMap) u.uUseEnvironmentMap.value = 0;
11864
11969
  if (!this.foam && u.uEnableFoam) u.uEnableFoam.value = 0;
11865
11970
  if (!this.refraction && u.uUseRefraction) u.uUseRefraction.value = 0;
package/dist/test.js CHANGED
@@ -6,7 +6,7 @@ import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
6
6
  import { i as getNodeSchema, s as mergeStaticProps } from "./registry-BVJ2HbCn.js";
7
7
  import { n as registerGameplayBehaviors } from "./gameplay-sSqrUcnz.js";
8
8
  import { t as registerNodes2D } from "./register-Djwckzgx.js";
9
- import { t as registerNodes3D } from "./register-C9-16x_t.js";
9
+ import { t as registerNodes3D } from "./register-Bh_3Z39N.js";
10
10
  import { t as registerNodesNet } from "./register-BFFE1Mh1.js";
11
11
  //#region src/test/index.ts
12
12
  /**
@@ -127,7 +127,7 @@ async function runScript(json, opts) {
127
127
  const { enablePhysics2D } = await import("./physics-2d-BiIdl51r.js").then((n) => n.r);
128
128
  await enablePhysics2D(engine);
129
129
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
130
- const { enablePhysics3D } = await import("./physics-3d-D_kUdOjr.js").then((n) => n.r);
130
+ const { enablePhysics3D } = await import("./physics-3d-TmOuCy7J.js").then((n) => n.r);
131
131
  await enablePhysics3D(engine);
132
132
  }
133
133
  const failures = [];
@@ -232,7 +232,7 @@ async function createPlaySession(json, opts = {}) {
232
232
  const { enablePhysics2D } = await import("./physics-2d-BiIdl51r.js").then((n) => n.r);
233
233
  await enablePhysics2D(engine);
234
234
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
235
- const { enablePhysics3D } = await import("./physics-3d-D_kUdOjr.js").then((n) => n.r);
235
+ const { enablePhysics3D } = await import("./physics-3d-TmOuCy7J.js").then((n) => n.r);
236
236
  await enablePhysics3D(engine);
237
237
  }
238
238
  const stepMs = 1e3 / (opts.fixedHz ?? 60);
@@ -1 +1 @@
1
- import{t as e}from"./index-7qOYg7t8.js";async function t(t){return new n((await e(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,t)}var n=class{raw;active=new Map;reconnecting=!1;disposed=!1;constructor(e,t){this.raw=new e({...t})}get account(){return this.raw.account}get connected(){return this.raw.connected}connect(){return this.raw.connected?Promise.resolve(!0):(this.disposed=!1,this.rawConnect())}rawConnect(){return this.raw.connect({onDisconnect:()=>void this.reconnect()})}disconnect(){this.disposed=!0;for(let e of this.active.values())e.off();return this.active.clear(),this.raw.disconnect()}remoteFunction(e,t,n){return this.raw.remoteFunction(e,t,n)}track(e){let t=Symbol(`sub`),n={make:e,off:e()};return this.active.set(t,n),()=>{n.off(),this.active.delete(t)}}async reconnect(){if(!this.disposed&&!this.reconnecting){this.reconnecting=!0;try{await this.rawConnect();for(let e of this.active.values())e.off(),e.off=e.make()}finally{this.reconnecting=!1}}}subscribeRoomState(e,t){return this.track(()=>this.raw.subscribeRoomState(e,t))}subscribeRoomMyState(e,t){return this.track(()=>this.raw.subscribeRoomMyState(e,t))}subscribeRoomAllUserStates(e,t){return this.track(()=>this.raw.subscribeRoomAllUserStates(e,e=>{let n={};for(let t of e??[]){if(!t||typeof t.account!=`string`||t.__leaved)continue;let{account:e,__updated:r,__leaved:i,...a}=t;n[e]=a}t(n)}))}subscribeRoomCollection(e,t,n){return this.track(()=>this.raw.subscribeRoomCollection(e,t,({items:e})=>{let t={};for(let n of e??[])n&&typeof n.__id==`string`&&(t[n.__id]=n);n(t)}))}onRoomMessage(e,t,n){return this.track(()=>this.raw.onRoomMessage(e,t,n))}onRoomUserJoin(e,t){return this.track(()=>this.raw.onRoomUserJoin(e,t))}onRoomUserLeave(e,t){return this.track(()=>this.raw.onRoomUserLeave(e,t))}subscribeGlobalState(e){return this.track(()=>this.raw.subscribeGlobalState(e))}subscribeGlobalMyState(e){return this.track(()=>this.raw.subscribeGlobalMyState(e))}subscribeGlobalUserState(e,t){return this.track(()=>this.raw.subscribeGlobalUserState(e,t))}subscribeGlobalCollection(e,t){return this.track(()=>this.raw.subscribeGlobalCollection(e,({items:e})=>{let n={};for(let t of e??[])t&&typeof t.__id==`string`&&(n[t.__id]=t);t(n)}))}subscribeAsset(e,t){return this.track(()=>this.raw.subscribeAsset(e,t))}onGlobalMessage(e,t){return this.track(()=>this.raw.onGlobalMessage(e,t))}};export{t as createAgent8Server};
1
+ import{t as e}from"./index-CofH0yGY.js";async function t(t){return new n((await e(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,t)}var n=class{raw;active=new Map;reconnecting=!1;disposed=!1;constructor(e,t){this.raw=new e({...t})}get account(){return this.raw.account}get connected(){return this.raw.connected}connect(){return this.raw.connected?Promise.resolve(!0):(this.disposed=!1,this.rawConnect())}rawConnect(){return this.raw.connect({onDisconnect:()=>void this.reconnect()})}disconnect(){this.disposed=!0;for(let e of this.active.values())e.off();return this.active.clear(),this.raw.disconnect()}remoteFunction(e,t,n){return this.raw.remoteFunction(e,t,n)}track(e){let t=Symbol(`sub`),n={make:e,off:e()};return this.active.set(t,n),()=>{n.off(),this.active.delete(t)}}async reconnect(){if(!this.disposed&&!this.reconnecting){this.reconnecting=!0;try{await this.rawConnect();for(let e of this.active.values())e.off(),e.off=e.make()}finally{this.reconnecting=!1}}}subscribeRoomState(e,t){return this.track(()=>this.raw.subscribeRoomState(e,t))}subscribeRoomMyState(e,t){return this.track(()=>this.raw.subscribeRoomMyState(e,t))}subscribeRoomAllUserStates(e,t){return this.track(()=>this.raw.subscribeRoomAllUserStates(e,e=>{let n={};for(let t of e??[]){if(!t||typeof t.account!=`string`||t.__leaved)continue;let{account:e,__updated:r,__leaved:i,...a}=t;n[e]=a}t(n)}))}subscribeRoomCollection(e,t,n){return this.track(()=>this.raw.subscribeRoomCollection(e,t,({items:e})=>{let t={};for(let n of e??[])n&&typeof n.__id==`string`&&(t[n.__id]=n);n(t)}))}onRoomMessage(e,t,n){return this.track(()=>this.raw.onRoomMessage(e,t,n))}onRoomUserJoin(e,t){return this.track(()=>this.raw.onRoomUserJoin(e,t))}onRoomUserLeave(e,t){return this.track(()=>this.raw.onRoomUserLeave(e,t))}subscribeGlobalState(e){return this.track(()=>this.raw.subscribeGlobalState(e))}subscribeGlobalMyState(e){return this.track(()=>this.raw.subscribeGlobalMyState(e))}subscribeGlobalUserState(e,t){return this.track(()=>this.raw.subscribeGlobalUserState(e,t))}subscribeGlobalCollection(e,t){return this.track(()=>this.raw.subscribeGlobalCollection(e,({items:e})=>{let n={};for(let t of e??[])t&&typeof t.__id==`string`&&(n[t.__id]=t);t(n)}))}subscribeAsset(e,t){return this.track(()=>this.raw.subscribeAsset(e,t))}onGlobalMessage(e,t){return this.track(()=>this.raw.onGlobalMessage(e,t))}};export{t as createAgent8Server};