incanto 0.24.0 → 0.25.1

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/dist/2d.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
2
- import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-DrcEgRup.js";
2
+ import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-BkJ1SLbE.js";
3
3
  import { _ as RigidBody2D, a as parseCells, c as ColorRect2D, d as AnimatedSprite2D, f as Sprite2D, g as PhysicsBody2D, h as CharacterBody2D, i as mergeSolidRects, l as CharacterController2D, m as Area2D, n as UILayer, o as Particles2D, p as Joint2D, r as TileMap2D, s as Label, t as registerNodes2D, u as Camera2D, v as StaticBody2D, y as Node2D } from "./register-CvpSUU3O.js";
4
4
  import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-DiVFFlH3.js";
5
5
  //#region src/2d/library-sprite.ts
package/dist/3d.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
2
- import { A as Water3D, F as StaticBody3D, I as Node3D, M as CharacterBody3D, N as PhysicsBody3D, P as RigidBody3D, j as Area3D, z as WATER_MAX_RIPPLES } from "./gameplay-BJ5gXIks.js";
3
- 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-DjWIgtQ_.js";
4
- import { A as QUARTER_PITCH, C as BoneAttachment3D, D as TERRAIN_THEMES, E as DEFAULT_TERRAIN_TEXTURE_BASE, M as keyboardIntensity, N as movementState, O as terrainThemeLayers, P as rigPose, S as BoneLookAt3D, T as Terrain3D, _ as Flowers3D, a as Trail3D, b as CharacterController3D, c as Particles3D, d as DirectionalLight3D, f as OmniLight3D, g as DENSITY_PRESETS, h as Foliage3D, i as Tree3D, j as cameraRelative, k as Joint3D, l as ModelInstance3D, m as MeshInstance3D, n as VOXEL_PALETTE, o as River3D, p as InstancedMesh3D, r as VoxelGrid3D, s as traceDownhillPath, t as registerNodes3D, u as LoftMesh3D, v as resolveFlowerDensity, w as Billboard3D, x as Camera3D, y as FLOWER_VARIETIES } from "./register-CpJORtm4.js";
2
+ import { A as Water3D, F as StaticBody3D, I as Node3D, M as CharacterBody3D, N as PhysicsBody3D, P as RigidBody3D, j as Area3D, z as WATER_MAX_RIPPLES } from "./gameplay-Cj5Y89Xc.js";
3
+ 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-CCT4p8Qd.js";
4
+ import { A as QUARTER_PITCH, C as BoneAttachment3D, D as TERRAIN_THEMES, E as DEFAULT_TERRAIN_TEXTURE_BASE, M as keyboardIntensity, N as movementState, O as terrainThemeLayers, P as rigPose, S as BoneLookAt3D, T as Terrain3D, _ as Flowers3D, a as Trail3D, b as CharacterController3D, c as Particles3D, d as DirectionalLight3D, f as OmniLight3D, g as DENSITY_PRESETS, h as Foliage3D, i as Tree3D, j as cameraRelative, k as Joint3D, l as ModelInstance3D, m as MeshInstance3D, n as VOXEL_PALETTE, o as River3D, p as InstancedMesh3D, r as VoxelGrid3D, s as traceDownhillPath, t as registerNodes3D, u as LoftMesh3D, v as resolveFlowerDensity, w as Billboard3D, x as Camera3D, y as FLOWER_VARIETIES } from "./register-Bed0raXR.js";
5
5
  import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
6
- import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-CpIB9C-F.js";
6
+ import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-BhH0Uu6c.js";
7
7
  //#region src/3d/environment-runtime.ts
8
8
  /**
9
9
  * Live environment editing — the renderer re-applies `scene.environment`
@@ -3,7 +3,7 @@ import { _ as registerBehavior, n as loadScene, o as computeViewport, s as resol
3
3
  import { l as AudioPlayer, u as Engine } from "./register-nObreUQR.js";
4
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { i as resolveRendering, n as attachTouchControls } from "./touch-031PxtCR.js";
6
- import { n as registerGameplayBehaviors } from "./gameplay-BJ5gXIks.js";
6
+ import { n as registerGameplayBehaviors } from "./gameplay-Cj5Y89Xc.js";
7
7
  import { g as PhysicsBody2D, n as UILayer, t as registerNodes2D, u as Camera2D, y as Node2D } from "./register-CvpSUU3O.js";
8
8
  import { t as debugSources } from "./debug-draw-CZmOYjL2.js";
9
9
  import { n as enablePhysics2D } from "./physics-2d-DiVFFlH3.js";
@@ -3,10 +3,10 @@ import { _ as registerBehavior, n as loadScene } from "./loader-BZqOKfI2.js";
3
3
  import { l as AudioPlayer, u as Engine } from "./register-nObreUQR.js";
4
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { i as resolveRendering, n as attachTouchControls } from "./touch-031PxtCR.js";
6
- import { I as Node3D, N as PhysicsBody3D, R as createCausticsQuad, n as registerGameplayBehaviors } from "./gameplay-BJ5gXIks.js";
6
+ import { I as Node3D, N as PhysicsBody3D, R as createCausticsQuad, n as registerGameplayBehaviors } from "./gameplay-Cj5Y89Xc.js";
7
7
  import { t as debugSources } from "./debug-draw-CZmOYjL2.js";
8
- import { d as DirectionalLight3D, l as ModelInstance3D, t as registerNodes3D, x as Camera3D } from "./register-CpJORtm4.js";
9
- import { n as enablePhysics3D } from "./physics-3d-CpIB9C-F.js";
8
+ import { d as DirectionalLight3D, l as ModelInstance3D, t as registerNodes3D, x as Camera3D } from "./register-Bed0raXR.js";
9
+ import { n as enablePhysics3D } from "./physics-3d-BhH0Uu6c.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";
@@ -1014,6 +1014,18 @@ uniform float uCausticsAbove;
1014
1014
  // incanto presets: per-preset reflection ceiling (the old hard 0.6) — lakes
1015
1015
  // push toward mirror, pools stay glassy-clear.
1016
1016
  uniform float uReflectivityMax;
1017
+ // incanto: the scene pre-pass runs at HALF resolution, so everything read from
1018
+ // its depth texture arrives quantised to those texels. Derivatives of a
1019
+ // quantised signal are garbage (they alternate between ~0 inside a texel and a
1020
+ // spike at its edge — the "barcode" on a shoreline), and a threshold crossed
1021
+ // inside one texel is a STAIRCASE (the sand-coloured line across open water).
1022
+ // Both cures are the same: filter the depth over its own texel footprint and
1023
+ // estimate gradients from those taps instead of from fwidth().
1024
+ uniform vec2 uScenePassTexel;
1025
+ /** Shoreline dissolve width, in DEPTH TEXELS (≈2 screen px each). */
1026
+ const float SHORE_FADE_TEXELS = 11.0;
1027
+ /** Deepest water that can still be a shoreline (m) — past this the fade is off. */
1028
+ const float SHORE_MAX_COLUMN = 2.2;
1017
1029
  // incanto: 1 while the camera EYE is under THIS surface — the underside is a
1018
1030
  // different optical world (Snell's window), not the top shaded darker.
1019
1031
  uniform float uCameraSubmerged;
@@ -1163,11 +1175,16 @@ vec3 detailNormal(vec3 n, vec2 worldXZ, float strength, float camDist) {
1163
1175
  float fadeFine = 1.0 - smoothstep(18.0, 80.0, camDist);
1164
1176
  float fadeMicro = 1.0 - smoothstep(8.0, 34.0, camDist);
1165
1177
  vec2 dMid = normalize(vec2(0.62, 0.78));
1166
- vec2 slope =
1167
- octaveSlope(worldXZ, WIND_DIR, 6.0, uTime) * (0.085 * fadeCoarse)
1168
- + octaveSlope(worldXZ, dMid, 2.2, uTime) * (0.10 * fadeMid)
1169
- + octavePair(worldXZ, WIND_DIR, 0.9, uTime) * (0.055 * fadeFine)
1170
- + octavePair(worldXZ, dMid, 0.38, uTime) * (0.042 * fadeMicro);
1178
+ // LOD: the fades used to scale a result that had already been PAID FOR — a
1179
+ // pixel of horizon water evaluated four noise octaves to multiply three of
1180
+ // them by zero. Branch instead. camDist barely varies across a quad, so
1181
+ // these are warp-coherent: distant water genuinely skips the work, and the
1182
+ // near look is bit-identical because a skipped layer was contributing < 1%.
1183
+ vec2 slope = vec2(0.0);
1184
+ if (fadeCoarse > 0.01) slope += octaveSlope(worldXZ, WIND_DIR, 6.0, uTime) * (0.085 * fadeCoarse);
1185
+ if (fadeMid > 0.01) slope += octaveSlope(worldXZ, dMid, 2.2, uTime) * (0.10 * fadeMid);
1186
+ if (fadeFine > 0.01) slope += octavePair(worldXZ, WIND_DIR, 0.9, uTime) * (0.055 * fadeFine);
1187
+ if (fadeMicro > 0.01) slope += octavePair(worldXZ, dMid, 0.38, uTime) * (0.042 * fadeMicro);
1171
1188
  slope *= strength * 3.0; // spectrum norm: default strength 0.26 ≈ calm-lively
1172
1189
  return normalize(vec3(n.x - slope.x, n.y, n.z - slope.y));
1173
1190
  }
@@ -1181,9 +1198,9 @@ vec3 glossNormal(vec3 n, vec2 worldXZ, float strength, float camDist) {
1181
1198
  float fadeCoarse = 1.0 - smoothstep(90.0, 420.0, camDist);
1182
1199
  float fadeMid = 1.0 - smoothstep(40.0, 170.0, camDist);
1183
1200
  vec2 dMid = normalize(vec2(0.62, 0.78));
1184
- vec2 slope =
1185
- octaveSlope(worldXZ, WIND_DIR, 6.0, uTime) * (0.085 * fadeCoarse)
1186
- + octaveSlope(worldXZ, dMid, 2.2, uTime) * (0.075 * fadeMid);
1201
+ vec2 slope = vec2(0.0);
1202
+ if (fadeCoarse > 0.01) slope += octaveSlope(worldXZ, WIND_DIR, 6.0, uTime) * (0.085 * fadeCoarse);
1203
+ if (fadeMid > 0.01) slope += octaveSlope(worldXZ, dMid, 2.2, uTime) * (0.075 * fadeMid);
1187
1204
  slope *= strength * 3.0;
1188
1205
  return normalize(vec3(n.x - slope.x, n.y, n.z - slope.y));
1189
1206
  }
@@ -1194,6 +1211,17 @@ float linearizeDepth(float depth, float near, float far) {
1194
1211
  return (2.0 * near * far) / (far + near - z * (far - near));
1195
1212
  }
1196
1213
 
1214
+ /**
1215
+ * Vertical water column under a screen point, reconstructed from the scene
1216
+ * depth along the view ray. Split out so the shoreline can sample it in a
1217
+ * cross and filter the half-res quantisation away.
1218
+ */
1219
+ float waterColumnAt(vec2 uv, float linearWaterDepth, float camDist, vec3 viewDir) {
1220
+ float sceneD = linearizeDepth(texture2D(uDepthTexture, uv).r, uCameraNear, uCameraFar);
1221
+ float t = camDist * (sceneD / max(linearWaterDepth, 1e-4));
1222
+ return max(uWaterCenter.y - (cameraPosition.y + viewDir.y * t), 0.0);
1223
+ }
1224
+
1197
1225
  // incanto: splash WHITEWATER. The look that read as FAKE was a clean radial
1198
1226
  // disc/ring × speckle. Real foam is irregular clumps + tendrils that drift with
1199
1227
  // the water and break apart at the edges. So: a soft COVERAGE envelope (where
@@ -1525,7 +1553,13 @@ void main() {
1525
1553
  float refrT = camDist * (refractedSceneDepth / max(linearWaterDepth, 1e-4));
1526
1554
  offsetReject = max(offsetReject, smoothstep(0.02, 0.25,
1527
1555
  cameraPosition.y + viewDirection.y * refrT - uWaterCenter.y));
1528
- refractedUV = mix(refractedUV, screenUV, offsetReject);
1556
+ // SILHOUETTE reject: a refracted sample that lands across a depth cliff
1557
+ // (a bed's rim, a hull, a swimmer's edge) drags that surface's colour
1558
+ // into the water as a hard sliver — and the half-res grab quantises the
1559
+ // sliver into a staircase. Snap those samples back to the straight ray.
1560
+ float silhouette = smoothstep(0.05, 0.22,
1561
+ abs(refractedSceneDepth - linearSceneDepth) / max(linearWaterDepth, 1e-3));
1562
+ refractedUV = mix(refractedUV, screenUV, max(offsetReject, silhouette));
1529
1563
  // mip-biased grab read: the pre-pass target carries mips (see
1530
1564
  // Water3D._onRender3D) — biasing ~1.75 levels samples a pre-blurred
1531
1565
  // underwater scene. Real water blurs what it refracts; the crisp
@@ -1540,9 +1574,11 @@ void main() {
1540
1574
  if (uCausticsAbove > 0.0) {
1541
1575
  vec3 bottomWorld = cameraPosition + viewDirection * refrT;
1542
1576
  float below = uWaterCenter.y - bottomWorld.y;
1543
- if (below > 0.05) {
1577
+ float causticFade = 1.0 - smoothstep(28.0, 90.0, camDist);
1578
+ // LOD: two 5-iteration caustic loops are the most expensive thing in
1579
+ // this shader — never run them for a contribution that has faded out
1580
+ if (below > 0.05 && causticFade > 0.01) {
1544
1581
  float reach = smoothstep(0.05, 0.5, below) * (1.0 - smoothstep(0.2, 9.0, below));
1545
- float causticFade = 1.0 - smoothstep(28.0, 90.0, camDist);
1546
1582
  float cw = caustic(bottomWorld.xz * 0.42, uTime * 0.7) * 0.65
1547
1583
  + caustic(bottomWorld.xz * 0.72 + 30.0, uTime * 0.55) * 0.35;
1548
1584
  sceneColor += vec3(0.87, 0.96, 1.0) * (cw * uCausticsAbove * reach * causticFade);
@@ -1566,9 +1602,21 @@ void main() {
1566
1602
  // shows the occluder behind this fragment, so a translucent ramp tint
1567
1603
  // over it is the honest shallow-water look; compositing the clipped
1568
1604
  // grab instead painted ref-26's background-colored band.
1569
- float sceneT = camDist * (linearSceneDepth / max(linearWaterDepth, 1e-4));
1605
+ // the above-water test crosses inside ONE half-res texel, and a hard
1606
+ // crossing there draws a stepped sand-coloured seam across open water —
1607
+ // average the neighbours so the transition spans the texel instead
1608
+ float aboveC = cameraPosition.y + viewDirection.y *
1609
+ (camDist * (linearSceneDepth / max(linearWaterDepth, 1e-4))) - uWaterCenter.y;
1610
+ float aboveL = -waterColumnAt(screenUV - vec2(uScenePassTexel.x, 0.0),
1611
+ linearWaterDepth, camDist, viewDirection);
1612
+ float aboveR = -waterColumnAt(screenUV + vec2(uScenePassTexel.x, 0.0),
1613
+ linearWaterDepth, camDist, viewDirection);
1614
+ float aboveU = -waterColumnAt(screenUV + vec2(0.0, uScenePassTexel.y),
1615
+ linearWaterDepth, camDist, viewDirection);
1616
+ float aboveD = -waterColumnAt(screenUV - vec2(0.0, uScenePassTexel.y),
1617
+ linearWaterDepth, camDist, viewDirection);
1570
1618
  float sceneAbove = smoothstep(0.02, 0.25,
1571
- cameraPosition.y + viewDirection.y * sceneT - uWaterCenter.y);
1619
+ (aboveC * 2.0 + aboveL + aboveR + aboveU + aboveD) / 6.0);
1572
1620
  float meanAbsorbed = 1.0 - dot(transmittance, vec3(0.299, 0.587, 0.114));
1573
1621
  float alphaOpacity = mix(uOpacity * 0.45, max(uOpacity, 0.95), meanAbsorbed);
1574
1622
  bodyColor = mix(mix(sceneColor, mixedColor2, body), mixedColor2, sceneAbove);
@@ -1683,10 +1731,14 @@ void main() {
1683
1731
  if (uWhitecaps > 0.0 && uWaveEnvelope > 0.001) {
1684
1732
  float crestN = (vWorldPosition.y - uWaterCenter.y) / uWaveEnvelope;
1685
1733
  float cap = smoothstep(0.5, 0.85, crestN);
1686
- vec2 capUV = vWorldPosition.xz * 0.3;
1687
- float capNoise = noise(capUV * 2.2 + uTime * vec2(0.10, 0.06)) * 0.65
1688
- + noise(capUV * 6.5 - uTime * vec2(0.05, 0.14)) * 0.35;
1689
1734
  float capFade = 1.0 - smoothstep(220.0, 640.0, camDist);
1735
+ // LOD: no cap, no distance, no noise — the patch field is two octaves
1736
+ float capNoise = 0.0;
1737
+ if (capFade > 0.01 && max(cap, vFold) > 0.001) {
1738
+ vec2 capUV = vWorldPosition.xz * 0.3;
1739
+ capNoise = noise(capUV * 2.2 + uTime * vec2(0.10, 0.06)) * 0.65
1740
+ + noise(capUV * 6.5 - uTime * vec2(0.05, 0.14)) * 0.35;
1741
+ }
1690
1742
  // height says WHERE the crest is; the Jacobian says where it is actually
1691
1743
  // breaking. Taking the max keeps the tuned height-based caps and adds the
1692
1744
  // ones physics insists on — the pinched crest faces about to spill.
@@ -1755,12 +1807,44 @@ void main() {
1755
1807
  // foam toggle — a beach without foam still has a waterline.
1756
1808
  float shoreDissolve = 1.0;
1757
1809
  if (uUseSceneDepth > 0.5 && waterViewDepth >= 0.0) {
1758
- float shoreT = camDist * (linearSceneDepth / max(linearWaterDepth, 1e-4));
1759
- float bedY = cameraPosition.y + viewDirection.y * shoreT;
1760
- float column = max(uWaterCenter.y - bedY, 0.0);
1761
- // ragged, so the dissolve edge is a wash line and not a contour
1762
- float lacy = noise(vWorldPosition.xz * 1.9) * 0.4 + noise(vWorldPosition.xz * 5.3) * 0.2;
1763
- shoreDissolve = smoothstep(0.0, 0.18 + lacy * 0.12, column);
1810
+ // FIVE taps, one depth texel apart. The centre says how deep the water is;
1811
+ // the cross says how fast that is changing across the screen — a
1812
+ // derivative-free gradient, because fwidth() of a half-res depth read
1813
+ // alternates between nothing and a spike and bars the shoreline like a
1814
+ // barcode. Filtering also dissolves the texel staircase that otherwise
1815
+ // draws a hard sand-coloured line wherever a threshold is crossed inside
1816
+ // one texel.
1817
+ vec2 tx = uScenePassTexel;
1818
+ float cC = waterColumnAt(screenUV, linearWaterDepth, camDist, viewDirection);
1819
+ float cL = waterColumnAt(screenUV - vec2(tx.x, 0.0), linearWaterDepth, camDist, viewDirection);
1820
+ float cR = waterColumnAt(screenUV + vec2(tx.x, 0.0), linearWaterDepth, camDist, viewDirection);
1821
+ float cD = waterColumnAt(screenUV - vec2(0.0, tx.y), linearWaterDepth, camDist, viewDirection);
1822
+ float cU = waterColumnAt(screenUV + vec2(0.0, tx.y), linearWaterDepth, camDist, viewDirection);
1823
+ float column = (cC * 2.0 + cL + cR + cD + cU) / 6.0;
1824
+ float grad = max(max(abs(cR - cL), abs(cU - cD)) * 0.5, 1e-5);
1825
+ float edgeT = clamp(column / (grad * SHORE_FADE_TEXELS), 0.0, 1.0);
1826
+ // A SHORELINE is where the water is ankle-to-knee deep. Any other place
1827
+ // the column changes fast — the seabed's own horizon, a hull's silhouette,
1828
+ // a cliff under water — has a huge gradient too, and without this gate the
1829
+ // fade fired there and drew a frothy translucent band across open sea.
1830
+ float shoreBand = 1.0 - smoothstep(SHORE_MAX_COLUMN * 0.55, SHORE_MAX_COLUMN, column);
1831
+ edgeT = mix(1.0, edgeT, shoreBand);
1832
+
1833
+ // the wash LINE is ragged and it breathes: a still contour reads as a cut
1834
+ // no matter how soft it is
1835
+ float lacy = noise(vWorldPosition.xz * 2.3 + uTime * 0.05) * 0.6
1836
+ + noise(vWorldPosition.xz * 6.1 - uTime * 0.08) * 0.4;
1837
+ float surge = uShoreWaves > 0.0
1838
+ ? (sin(uTime * 0.5) * 0.5 + sin(uTime * 0.31 + 1.7) * 0.5) * 0.22 * uShoreWaves
1839
+ : 0.0;
1840
+ edgeT = clamp(edgeT * (1.0 + surge) + (lacy - 0.5) * 0.45, 0.0, 1.0);
1841
+ shoreDissolve = smoothstep(0.0, 1.0, edgeT);
1842
+
1843
+ // FROTH gathers where the sheet is thinning out — the last band of a wash
1844
+ // is white, and that white is what makes water read as meeting ground
1845
+ // rather than ending at a line.
1846
+ float hem = (1.0 - edgeT) * smoothstep(0.25, 0.75, lacy) * 0.85 * shoreBand;
1847
+ foamAmount = max(foamAmount, hem * shoreDissolve);
1764
1848
  }
1765
1849
 
1766
1850
  // 🔥 Final fundamental solution: Apply depth mask
@@ -2940,6 +3024,7 @@ var Water3D = class Water3D extends Node3D {
2940
3024
  mesh.visible = wasVisible;
2941
3025
  if (u.uDepthTexture && u.uSceneColor && u.uCameraNear && u.uCameraFar && u.uUseSceneDepth) {
2942
3026
  u.uDepthTexture.value = this.scenePassTarget.depthTexture;
3027
+ (u.uScenePassTexel?.value)?.set(1 / passW, 1 / passH);
2943
3028
  u.uSceneColor.value = this.scenePassTarget.texture;
2944
3029
  u.uCameraNear.value = ctx.camera.near;
2945
3030
  u.uCameraFar.value = ctx.camera.far;
@@ -3054,6 +3139,7 @@ var Water3D = class Water3D extends Node3D {
3054
3139
  uFoamRange: { value: foamRangeFor(this.size[0] ?? 1, this.size[1] ?? 1) },
3055
3140
  uFoamScale: { value: FOAM_LOOK.scale },
3056
3141
  uDepthTexture: { value: null },
3142
+ uScenePassTexel: { value: new Vector2(1 / 512, 1 / 512) },
3057
3143
  uCameraNear: { value: .1 },
3058
3144
  uCameraFar: { value: 1e3 },
3059
3145
  uEdgeColor: { value: new Color(FOAM_LOOK.edgeColor) },
package/dist/gameplay.js CHANGED
@@ -1,2 +1,2 @@
1
- import { C as FollowCamera, D as Health, E as DamageOnContact, O as Collector, S as restartScene, T as phaseOf, _ as hitStop, a as Wander, b as GameFlow, c as Projectile, d as PathFollow, f as Oscillate, g as Cooldown, h as CameraShake, i as WaveSpawner, k as Chase, l as Pickup, m as Lifetime, n as registerGameplayBehaviors, o as Spawner, p as MoveTo, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Patrol, v as screenFlash, w as DayNight, x as goToScene, y as Interactable } from "./gameplay-BJ5gXIks.js";
1
+ import { C as FollowCamera, D as Health, E as DamageOnContact, O as Collector, S as restartScene, T as phaseOf, _ as hitStop, a as Wander, b as GameFlow, c as Projectile, d as PathFollow, f as Oscillate, g as Cooldown, h as CameraShake, i as WaveSpawner, k as Chase, l as Pickup, m as Lifetime, n as registerGameplayBehaviors, o as Spawner, p as MoveTo, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Patrol, v as screenFlash, w as DayNight, x as goToScene, y as Interactable } from "./gameplay-Cj5Y89Xc.js";
2
2
  export { CameraShake, Chase, Collector, Cooldown, DamageOnContact, DayNight, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, Projectile, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, phaseOf, registerGameplayBehaviors, restartScene, screenFlash };
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.24.0";
298
+ const VERSION = "0.25.1";
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,8 +1,8 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
- import { I as Node3D, L as validateCollider3D, M as CharacterBody3D, N as PhysicsBody3D, P as RigidBody3D, j as Area3D } from "./gameplay-BJ5gXIks.js";
3
+ import { I as Node3D, L as validateCollider3D, M as CharacterBody3D, N as PhysicsBody3D, P as RigidBody3D, j as Area3D } from "./gameplay-Cj5Y89Xc.js";
4
4
  import { n as registerDebugSource } from "./debug-draw-CZmOYjL2.js";
5
- import { T as Terrain3D, k as Joint3D } from "./register-CpJORtm4.js";
5
+ import { T as Terrain3D, k as Joint3D } from "./register-Bed0raXR.js";
6
6
  import { Euler, Quaternion } from "three";
7
7
  //#region src/3d/physics/physics-3d.ts
8
8
  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-DjWIgtQ_.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-DrcEgRup.js").then((n) => n.n)).createGame2D(o)))(opts);
159
+ const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-CCT4p8Qd.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-BkJ1SLbE.js").then((n) => n.n)).createGame2D(o)))(opts);
160
160
  if (disposed) {
161
161
  next.dispose();
162
162
  return;
@@ -4,7 +4,7 @@ import { t as Rng } from "./rng-DP-SR7eg.js";
4
4
  import { i as getNodeSchema, l as registerNode } from "./registry-BVJ2HbCn.js";
5
5
  import { t as createNoise2D } from "./noise-CGUMx44x.js";
6
6
  import { i as applyParticlePreset, r as PARTICLE_PRESET_NAMES, t as ParticleSim } from "./particle-sim-Bw7hB93B.js";
7
- import { A as Water3D, B as colliderFootDrop, F as StaticBody3D, I as Node3D, M as CharacterBody3D, N as PhysicsBody3D, P as RigidBody3D, j as Area3D } from "./gameplay-BJ5gXIks.js";
7
+ import { A as Water3D, B as colliderFootDrop, F as StaticBody3D, I as Node3D, M as CharacterBody3D, N as PhysicsBody3D, P as RigidBody3D, j as Area3D } from "./gameplay-Cj5Y89Xc.js";
8
8
  import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
9
9
  import { AdditiveBlending, AnimationClip, AnimationMixer, Box3, BoxGeometry, BufferAttribute, BufferGeometry, CanvasTexture, CapsuleGeometry, Color, ConeGeometry, CylinderGeometry, DataTexture, DirectionalLight, DoubleSide, DynamicDrawUsage, Euler, Group, IcosahedronGeometry, ImageBitmapLoader, InstancedBufferAttribute, InstancedMesh, LinearFilter, LoopOnce, LoopRepeat, Matrix4, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshPhysicalMaterial, MeshStandardMaterial, NearestFilter, NoBlending, NormalBlending, PerspectiveCamera, PlaneGeometry, PointLight, Points, PointsMaterial, Quaternion, QuaternionKeyframeTrack, RGBADepthPacking, RGBAFormat, RepeatWrapping, SRGBColorSpace, ShaderChunk, ShaderMaterial, SphereGeometry, Texture, TextureLoader, UniformsLib, UniformsUtils, Vector3, Vector4, VectorKeyframeTrack } from "three";
10
10
  import { clone } from "three/addons/utils/SkeletonUtils.js";
package/dist/test.js CHANGED
@@ -4,9 +4,9 @@ import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { t as auditScene } from "./audit-C6rMyict.js";
5
5
  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
- import { n as registerGameplayBehaviors } from "./gameplay-BJ5gXIks.js";
7
+ import { n as registerGameplayBehaviors } from "./gameplay-Cj5Y89Xc.js";
8
8
  import { t as registerNodes2D } from "./register-CvpSUU3O.js";
9
- import { t as registerNodes3D } from "./register-CpJORtm4.js";
9
+ import { t as registerNodes3D } from "./register-Bed0raXR.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-DiVFFlH3.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-CpIB9C-F.js").then((n) => n.r);
130
+ const { enablePhysics3D } = await import("./physics-3d-BhH0Uu6c.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-DiVFFlH3.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-CpIB9C-F.js").then((n) => n.r);
235
+ const { enablePhysics3D } = await import("./physics-3d-BhH0Uu6c.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-B5y_MdYb.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-COVjwWy3.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};