incanto 0.3.2 → 0.3.4

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/3d.d.ts CHANGED
@@ -962,6 +962,14 @@ interface MeshMaterialProps {
962
962
  flatShading?: boolean;
963
963
  /** 0..1 surface opacity; below 1 turns on transparency (glassy gems, etc.). */
964
964
  opacity?: number;
965
+ /** Depth-test against the scene (default true). Set false so the mesh ALWAYS
966
+ * draws on top of geometry behind it — the standard trick for flat ground
967
+ * decals (AoE telegraphs, selection rings) that must never z-fight with or be
968
+ * occluded by bumpy terrain. Pair with a high `renderOrder`. */
969
+ depthTest?: boolean;
970
+ /** Write to the depth buffer (default true). Set false for additive/overlay
971
+ * decals so they don't occlude effects drawn after them. */
972
+ depthWrite?: boolean;
965
973
  /** Color texture URL (sampled sRGB, tinted by `color`). */
966
974
  map?: string;
967
975
  /** Tangent-space normal map URL (sampled linear). */
@@ -978,10 +986,12 @@ interface MeshMaterialProps {
978
986
  * - `size [x,y,z]`: box extents; sphere/gem radius = x; capsule radius = x,
979
987
  * height = y; plane = x·z ground plane (laid flat); cylinder radius = x, height = y
980
988
  * - `material`: `{color, metalness, roughness, wireframe, flatShading, opacity,
981
- * emissive, emissiveIntensity, map, normalMap, repeat}` — `map`/`normalMap` are
982
- * texture URLs loaded lazily (headless-safe: geometry and physics never
983
- * wait on them), tiled by `repeat: [u, v]`. `gem` + `flatShading: true` + a low
984
- * `roughness` reads as a sparkling faceted jewel (spin it for the sparkle).
989
+ * depthTest, depthWrite, emissive, emissiveIntensity, map, normalMap, repeat}` —
990
+ * `map`/`normalMap` are texture URLs loaded lazily (headless-safe: geometry and
991
+ * physics never wait on them), tiled by `repeat: [u, v]`. `gem` + `flatShading:
992
+ * true` + a low `roughness` reads as a sparkling faceted jewel (spin it for the
993
+ * sparkle). `depthTest: false` makes a flat `plane`/`cylinder` an always-on-top
994
+ * ground decal (AoE telegraph, selection ring) — no z-fighting with terrain.
985
995
  */
986
996
  declare class MeshInstance3D extends Node3D {
987
997
  static override readonly typeName: string;
package/dist/3d.js CHANGED
@@ -1,5 +1,5 @@
1
- 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-BM7BffzK.js";
2
- import { A as QUARTER_PITCH, C as Area3D, D as StaticBody3D, E as RigidBody3D, M as keyboardIntensity, N as movementState, O as Node3D, P as rigPose, S as terrainThemeLayers, T as PhysicsBody3D, _ as CharacterController3D, a as VoxelGrid3D, b as DEFAULT_TERRAIN_TEXTURE_BASE, c as ModelInstance3D, d as OmniLight3D, f as Foliage3D, g as FLOWER_VARIETIES, h as resolveFlowerDensity, i as VOXEL_PALETTE, j as cameraRelative, l as MeshInstance3D, m as Flowers3D, n as Water3D, o as Tree3D, p as DENSITY_PRESETS, r as WATER_MAX_RIPPLES, s as Particles3D, t as registerNodes3D, u as DirectionalLight3D, v as Camera3D, w as CharacterBody3D, x as TERRAIN_THEMES, y as Terrain3D } from "./register-QFuyOugX.js";
1
+ 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-BNFl50Kg.js";
2
+ import { A as QUARTER_PITCH, C as Area3D, D as StaticBody3D, E as RigidBody3D, M as keyboardIntensity, N as movementState, O as Node3D, P as rigPose, S as terrainThemeLayers, T as PhysicsBody3D, _ as CharacterController3D, a as VoxelGrid3D, b as DEFAULT_TERRAIN_TEXTURE_BASE, c as ModelInstance3D, d as OmniLight3D, f as Foliage3D, g as FLOWER_VARIETIES, h as resolveFlowerDensity, i as VOXEL_PALETTE, j as cameraRelative, l as MeshInstance3D, m as Flowers3D, n as Water3D, o as Tree3D, p as DENSITY_PRESETS, r as WATER_MAX_RIPPLES, s as Particles3D, t as registerNodes3D, u as DirectionalLight3D, v as Camera3D, w as CharacterBody3D, x as TERRAIN_THEMES, y as Terrain3D } from "./register-BMFZKPOq.js";
3
3
  import { n as splatWeights, t as buildHeightmap } from "./heightmap-CroQPEER.js";
4
- import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-DNYm3rQz.js";
4
+ import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-B4L2IlFd.js";
5
5
  export { Area3D, AssetStore3D, Camera3D, CharacterBody3D, CharacterController3D, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, Environment3D, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, Flowers3D, Foliage3D, MeshInstance3D, ModelInstance3D, Node3D, OmniLight3D, Particles3D, Physics3D, PhysicsBody3D, QUARTER_PITCH, Renderer3D, RigidBody3D, StaticBody3D, TERRAIN_THEMES, Terrain3D, Tree3D, VOXEL_PALETTE, VoxelGrid3D, WATER_MAX_RIPPLES, Water3D, buildHeightmap, cameraRelative, createGame3D, enablePhysics3D, horizonColorFromSky, keyboardIntensity, movementState, parseEnvironment3D, registerNodes3D, resolveFlowerDensity, rigPose, splatWeights, sunDirectionFromElevationAzimuth, sunDirectionFromSky, syncTree, terrainThemeLayers };
@@ -6,8 +6,8 @@ import { r as AudioPlayer } from "./register-BuUV1_KB.js";
6
6
  import { i as resolveRendering, n as attachTouchControls } from "./touch-031PxtCR.js";
7
7
  import { n as registerGameplayBehaviors } from "./gameplay-Ccruc3Wd.js";
8
8
  import { t as debugSources } from "./debug-draw-CZmOYjL2.js";
9
- import { O as Node3D, T as PhysicsBody3D, c as ModelInstance3D, t as registerNodes3D, u as DirectionalLight3D, v as Camera3D } from "./register-QFuyOugX.js";
10
- import { n as enablePhysics3D } from "./physics-3d-DNYm3rQz.js";
9
+ import { O as Node3D, T as PhysicsBody3D, c as ModelInstance3D, t as registerNodes3D, u as DirectionalLight3D, v as Camera3D } from "./register-BMFZKPOq.js";
10
+ import { n as enablePhysics3D } from "./physics-3d-B4L2IlFd.js";
11
11
  import { ACESFilmicToneMapping, AmbientLight, BufferAttribute, BufferGeometry, Color, DepthTexture, EquirectangularReflectionMapping, FloatType, Fog, LineBasicMaterial, LineSegments, Matrix4, Mesh, PCFShadowMap, PMREMGenerator, PerspectiveCamera, PlaneGeometry, Quaternion, Raycaster, Scene, ShaderMaterial, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer } from "three";
12
12
  import { VRMLoaderPlugin, VRMUtils } from "@pixiv/three-vrm";
13
13
  import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
package/dist/index.js CHANGED
@@ -57,6 +57,6 @@ function newUid() {
57
57
  //#endregion
58
58
  //#region src/index.ts
59
59
  /** Engine version. Kept in sync with package.json by the release pipeline. */
60
- const VERSION = "0.3.2";
60
+ const VERSION = "0.3.4";
61
61
  //#endregion
62
62
  export { AudioBuses, AudioPlayer, Behavior, CONST_REF_KEY, Engine, IncantoError, InputMap, LogManager, MusicManager, Node, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, Scene, SceneTree, SfxEngine, Signal, Timer, TouchControls, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, crossfadeGains, duplicateNode, fadeGain, getBehavior, getNodeSchema, getNodeSignals, getNodeType, isAudioContextAvailable, isConstRef, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, mergeStaticSignals, newUid, parseNodePath, preloadUrls, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, resolveConstants, resolveRendering, resolveViewport, serializeNode, spatialGain, spatialPan, 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 { C as Area3D, E as RigidBody3D, O as Node3D, T as PhysicsBody3D, k as validateCollider3D, w as CharacterBody3D, y as Terrain3D } from "./register-QFuyOugX.js";
4
+ import { C as Area3D, E as RigidBody3D, O as Node3D, T as PhysicsBody3D, k as validateCollider3D, w as CharacterBody3D, y as Terrain3D } from "./register-BMFZKPOq.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-BM7BffzK.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-CZHROKcT.js").then((n) => n.n)).createGame2D(o)))(opts);
159
+ const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-BNFl50Kg.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-CZHROKcT.js").then((n) => n.n)).createGame2D(o)))(opts);
160
160
  if (disposed) {
161
161
  next.dispose();
162
162
  return;
@@ -1344,6 +1344,15 @@ const _spritePos = new Vector3();
1344
1344
  const _dir = new Vector3();
1345
1345
  const _target = new Quaternion();
1346
1346
  const _parent = new Quaternion();
1347
+ const _sunLocal = new Vector3();
1348
+ /** Slide the silhouette shadow caster this many world-units TOWARD the light,
1349
+ * ALONG the light direction. Moving along the light is projection-invariant
1350
+ * (the shadow's shape/position is unchanged), but it lowers the caster's depth
1351
+ * in the shadow map — so the light's anti-acne bias can no longer eat the
1352
+ * near-ground contact (feet/legs). The terrain keeps its own bias untouched, so
1353
+ * terrain self-shadow acne prevention is unaffected. Tune if the foot still
1354
+ * detaches (raise) or over-darkens (lower). */
1355
+ const SHADOW_CONTACT_PUSH = .5;
1347
1356
  /**
1348
1357
  * Sprite3D — a 2D texture drawn as a camera-facing billboard quad inside a 3D
1349
1358
  * scene (the 2.5D look: Octopath, Don't Starve). The visual is an inner quad
@@ -1530,7 +1539,13 @@ var Sprite3D = class extends Node3D {
1530
1539
  * plain trees pay nothing. */
1531
1540
  _onRender3D(ctx) {
1532
1541
  if (this.billboard !== "none") this._faceToward(this._quad(), ctx.camera.position);
1533
- if (this.shadowMesh?.castShadow && ctx.sunDir) this._faceDir(this.shadowMesh, ctx.sunDir);
1542
+ const caster = this.shadowMesh;
1543
+ if (caster?.castShadow && ctx.sunDir) {
1544
+ this._faceDir(caster, ctx.sunDir);
1545
+ caster.parent?.getWorldQuaternion(_parent);
1546
+ _sunLocal.copy(ctx.sunDir).applyQuaternion(_parent.invert());
1547
+ caster.position.addScaledVector(_sunLocal, SHADOW_CONTACT_PUSH);
1548
+ }
1534
1549
  }
1535
1550
  /** @internal Aim the quad's +Z at a world point, honoring billboard mode. */
1536
1551
  _faceToward(quad, targetWorld) {
@@ -4782,6 +4797,8 @@ const MATERIAL_KEYS = [
4782
4797
  "wireframe",
4783
4798
  "flatShading",
4784
4799
  "opacity",
4800
+ "depthTest",
4801
+ "depthWrite",
4785
4802
  "map",
4786
4803
  "normalMap",
4787
4804
  "repeat"
@@ -4792,10 +4809,12 @@ const MATERIAL_KEYS = [
4792
4809
  * - `size [x,y,z]`: box extents; sphere/gem radius = x; capsule radius = x,
4793
4810
  * height = y; plane = x·z ground plane (laid flat); cylinder radius = x, height = y
4794
4811
  * - `material`: `{color, metalness, roughness, wireframe, flatShading, opacity,
4795
- * emissive, emissiveIntensity, map, normalMap, repeat}` — `map`/`normalMap` are
4796
- * texture URLs loaded lazily (headless-safe: geometry and physics never
4797
- * wait on them), tiled by `repeat: [u, v]`. `gem` + `flatShading: true` + a low
4798
- * `roughness` reads as a sparkling faceted jewel (spin it for the sparkle).
4812
+ * depthTest, depthWrite, emissive, emissiveIntensity, map, normalMap, repeat}` —
4813
+ * `map`/`normalMap` are texture URLs loaded lazily (headless-safe: geometry and
4814
+ * physics never wait on them), tiled by `repeat: [u, v]`. `gem` + `flatShading:
4815
+ * true` + a low `roughness` reads as a sparkling faceted jewel (spin it for the
4816
+ * sparkle). `depthTest: false` makes a flat `plane`/`cylinder` an always-on-top
4817
+ * ground decal (AoE telegraph, selection ring) — no z-fighting with terrain.
4799
4818
  */
4800
4819
  var MeshInstance3D = class extends Node3D {
4801
4820
  static typeName = "MeshInstance3D";
@@ -4858,6 +4877,8 @@ var MeshInstance3D = class extends Node3D {
4858
4877
  const opacity = this.material.opacity ?? 1;
4859
4878
  mat.opacity = opacity;
4860
4879
  mat.transparent = opacity < 1;
4880
+ mat.depthTest = this.material.depthTest ?? true;
4881
+ mat.depthWrite = this.material.depthWrite ?? true;
4861
4882
  const flat = this.material.flatShading ?? false;
4862
4883
  if (mat.flatShading !== flat) {
4863
4884
  mat.flatShading = flat;
@@ -4933,7 +4954,12 @@ function validateMaterial(material, name) {
4933
4954
  const value = material[key];
4934
4955
  if (value !== void 0 && !(typeof value === "number" && value >= 0 && value <= 1)) fail(`material.${key} must be a number in 0..1, got ${JSON.stringify(value)}.`);
4935
4956
  }
4936
- for (const key of ["wireframe", "flatShading"]) {
4957
+ for (const key of [
4958
+ "wireframe",
4959
+ "flatShading",
4960
+ "depthTest",
4961
+ "depthWrite"
4962
+ ]) {
4937
4963
  const value = material[key];
4938
4964
  if (value !== void 0 && typeof value !== "boolean") fail(`material.${key} must be a boolean, got ${JSON.stringify(value)}.`);
4939
4965
  }
package/dist/test.js CHANGED
@@ -5,7 +5,7 @@ import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
5
5
  import { i as getNodeSchema, s as mergeStaticProps } from "./registry-BVJ2HbCn.js";
6
6
  import { n as registerGameplayBehaviors } from "./gameplay-Ccruc3Wd.js";
7
7
  import { t as registerNodes2D } from "./register-DPEV9_9t.js";
8
- import { t as registerNodes3D } from "./register-QFuyOugX.js";
8
+ import { t as registerNodes3D } from "./register-BMFZKPOq.js";
9
9
  import { t as registerNodesNet } from "./register-Dasmnurl.js";
10
10
  //#region src/test/index.ts
11
11
  /**
@@ -132,7 +132,7 @@ async function runScript(json, opts) {
132
132
  const { enablePhysics2D } = await import("./physics-2d-KuMWPTf6.js").then((n) => n.r);
133
133
  await enablePhysics2D(engine);
134
134
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
135
- const { enablePhysics3D } = await import("./physics-3d-DNYm3rQz.js").then((n) => n.r);
135
+ const { enablePhysics3D } = await import("./physics-3d-B4L2IlFd.js").then((n) => n.r);
136
136
  await enablePhysics3D(engine);
137
137
  }
138
138
  const failures = [];
@@ -237,7 +237,7 @@ async function createPlaySession(json, opts = {}) {
237
237
  const { enablePhysics2D } = await import("./physics-2d-KuMWPTf6.js").then((n) => n.r);
238
238
  await enablePhysics2D(engine);
239
239
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
240
- const { enablePhysics3D } = await import("./physics-3d-DNYm3rQz.js").then((n) => n.r);
240
+ const { enablePhysics3D } = await import("./physics-3d-B4L2IlFd.js").then((n) => n.r);
241
241
  await enablePhysics3D(engine);
242
242
  }
243
243
  const stepMs = 1e3 / (opts.fixedHz ?? 60);
@@ -1 +1 @@
1
- import{t as e}from"./index-CXElxUZa.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;constructor(e,t){this.raw=new e({...t})}get account(){return this.raw.account}get connected(){return this.raw.connected}connect(){return this.rawConnect()}rawConnect(){return this.raw.connect({onDisconnect:()=>void this.reconnect()})}disconnect(){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(){await this.rawConnect();for(let e of this.active.values())e.off(),e.off=e.make()}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-BfXcog9m.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;constructor(e,t){this.raw=new e({...t})}get account(){return this.raw.account}get connected(){return this.raw.connected}connect(){return this.rawConnect()}rawConnect(){return this.raw.connect({onDisconnect:()=>void this.reconnect()})}disconnect(){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(){await this.rawConnect();for(let e of this.active.values())e.off(),e.off=e.make()}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};