incanto 0.5.0 → 0.6.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/dist/2d.d.ts +7 -1
- package/dist/2d.js +3 -3
- package/dist/3d.d.ts +27 -0
- package/dist/3d.js +3 -3
- package/dist/{create-game-BFESHv1X.js → create-game-B_sW_eiE.js} +27 -7
- package/dist/{create-game-D8UvwXme.js → create-game-DkbZCNaV.js} +63 -8
- package/dist/index.js +1 -1
- package/dist/{physics-2d-KXn1N1jF.js → physics-2d-Cgli1aju.js} +1 -1
- package/dist/{physics-3d-C58oQzTX.js → physics-3d-CBAQ12LY.js} +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-D71C4rDC.js → register-BJCfuuZ2.js} +3 -0
- package/dist/{register-DvPHJdVj.js → register-Dd7Juujf.js} +10 -0
- package/dist/test.js +6 -6
- package/editor/assets/{agent8-DruKhR22.js → agent8-MciFwn0v.js} +1 -1
- package/editor/assets/{index-D2qufqUo.js → index-mofVSmuA.js} +8 -8
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +140 -0
- package/skills/incanto-building-2d-games.md +6 -0
- package/skills/incanto-building-3d-games.md +13 -0
- package/skills/incanto-node-reference.md +35 -0
package/dist/2d.d.ts
CHANGED
|
@@ -52,6 +52,8 @@ declare class Node2D extends Node {
|
|
|
52
52
|
position: number[];
|
|
53
53
|
/** Degrees, clockwise. */
|
|
54
54
|
rotation: number;
|
|
55
|
+
/** Frozen after first sync — see Node3D.static (same semantics in 2D). */
|
|
56
|
+
static: boolean;
|
|
55
57
|
scale: number[];
|
|
56
58
|
/** Draw order among 2D drawables (higher = on top); matches 3D `renderOrder`. */
|
|
57
59
|
renderOrder: number;
|
|
@@ -636,6 +638,8 @@ declare class Renderer2D {
|
|
|
636
638
|
private readonly webgl;
|
|
637
639
|
private readonly worldScene;
|
|
638
640
|
private readonly syncScratch;
|
|
641
|
+
/** Editors set this: keep syncing `static: true` subtrees every frame. */
|
|
642
|
+
ignoreStatic: boolean;
|
|
639
643
|
private readonly uiScene;
|
|
640
644
|
private readonly worldCam;
|
|
641
645
|
private readonly uiCam;
|
|
@@ -705,6 +709,8 @@ interface Sync2DScratch {
|
|
|
705
709
|
visited: Set<Object3D>;
|
|
706
710
|
cameras: Camera2D[];
|
|
707
711
|
}
|
|
708
|
-
declare function syncTree2D(root: Node, world: Scene, ui: Scene, assets: AssetStore2D | null, uiSize?: UiSize, scratch?: Sync2DScratch
|
|
712
|
+
declare function syncTree2D(root: Node, world: Scene, ui: Scene, assets: AssetStore2D | null, uiSize?: UiSize, scratch?: Sync2DScratch, opts?: {
|
|
713
|
+
ignoreStatic?: boolean;
|
|
714
|
+
}): Sync2DResult;
|
|
709
715
|
//#endregion
|
|
710
716
|
export { AnimatedSprite2D, type AnimationDef, Area2D, type AssetStatus, AssetStore2D, Camera2D, CharacterBody2D, CharacterController2D, ColorRect2D, type CreateGame2DOptions, type Game2D, Joint2D, type JointType2D, Label, Node2D, Particles2D, Physics2D, type Physics2DOptions, PhysicsBody2D, Renderer2D, type Renderer2DOptions, type ResolvedSpriteTexture, RigidBody2D, type SheetInfo, Sprite2D, type SpriteFromLibraryResult, StaticBody2D, type Sync2DResult, type TextureLoadCallbacks, type UIAnchor, UILayer, createGame2D, enablePhysics2D, registerNodes2D, spriteFromLibraryMeta, syncTree2D };
|
package/dist/2d.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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-
|
|
3
|
-
import { a as ColorRect2D, c as AnimatedSprite2D, d as Area2D, f as CharacterBody2D, g as Node2D, h as StaticBody2D, i as Label, l as Sprite2D, m as RigidBody2D, n as UILayer, o as CharacterController2D, p as PhysicsBody2D, r as Particles2D, s as Camera2D, t as registerNodes2D, u as Joint2D } from "./register-
|
|
4
|
-
import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-
|
|
2
|
+
import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-B_sW_eiE.js";
|
|
3
|
+
import { a as ColorRect2D, c as AnimatedSprite2D, d as Area2D, f as CharacterBody2D, g as Node2D, h as StaticBody2D, i as Label, l as Sprite2D, m as RigidBody2D, n as UILayer, o as CharacterController2D, p as PhysicsBody2D, r as Particles2D, s as Camera2D, t as registerNodes2D, u as Joint2D } from "./register-BJCfuuZ2.js";
|
|
4
|
+
import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-Cgli1aju.js";
|
|
5
5
|
//#region src/2d/library-sprite.ts
|
|
6
6
|
/**
|
|
7
7
|
* Turn a library sprite-animation JSON into a scene-ready spritesheet asset
|
package/dist/3d.d.ts
CHANGED
|
@@ -137,6 +137,15 @@ declare class Node3D extends Node {
|
|
|
137
137
|
position: number[];
|
|
138
138
|
/** Euler XYZ in degrees. */
|
|
139
139
|
rotation: number[];
|
|
140
|
+
/**
|
|
141
|
+
* This subtree never changes after load: the renderer syncs it ONCE and
|
|
142
|
+
* skips it every frame after (transforms, materials, animations frozen).
|
|
143
|
+
* The per-frame walk is O(nodes) — marking terrain/buildings/decor static
|
|
144
|
+
* removes most of a big scene from it. Set `static = false` to resume
|
|
145
|
+
* live syncing. Do NOT mark animated nodes (Water3D, Particles3D,
|
|
146
|
+
* AnimatedSprite3D, ModelInstance3D with clips) or cameras static.
|
|
147
|
+
*/
|
|
148
|
+
static: boolean;
|
|
140
149
|
scale: number[];
|
|
141
150
|
visible: boolean;
|
|
142
151
|
/** Draw-order priority (higher = drawn later / on top). Only affects TRANSPARENT
|
|
@@ -412,6 +421,14 @@ interface ShadowsEnvironment {
|
|
|
412
421
|
mapSize: 1024 | 2048;
|
|
413
422
|
/** Shadow edge softening radius (PCF blur, default 1). */
|
|
414
423
|
radius: number;
|
|
424
|
+
/**
|
|
425
|
+
* `true` = shadow casters never move or animate: the shadow pass renders
|
|
426
|
+
* ONCE (and again on scene/environment change) instead of every frame —
|
|
427
|
+
* measured ~42% of a dense-forest frame. Characters under a static-shadow
|
|
428
|
+
* scene should use blob/sprite shadows. `Renderer3D.refreshShadows()`
|
|
429
|
+
* forces a re-render after a one-off world edit.
|
|
430
|
+
*/
|
|
431
|
+
static: boolean;
|
|
415
432
|
}
|
|
416
433
|
interface CloudsEnvironment {
|
|
417
434
|
/** How much of the sky is cloudy, 0..1. */
|
|
@@ -1914,6 +1931,8 @@ declare class Renderer3D {
|
|
|
1914
1931
|
private compiledScene;
|
|
1915
1932
|
/** Reused per-frame walk scratch (instance-scoped — never a module global). */
|
|
1916
1933
|
private readonly syncScratch;
|
|
1934
|
+
/** Editors set this: keep syncing `static: true` subtrees every frame. */
|
|
1935
|
+
ignoreStatic: boolean;
|
|
1917
1936
|
/** Reused render-hook context — gl/scene are stable, camera reassigned/frame. */
|
|
1918
1937
|
private renderCtx;
|
|
1919
1938
|
/** Underwater caustics pass (lazy — only created the first time submerged). */
|
|
@@ -2000,6 +2019,11 @@ declare class Renderer3D {
|
|
|
2000
2019
|
up: Vector3;
|
|
2001
2020
|
forward: Vector3;
|
|
2002
2021
|
};
|
|
2022
|
+
/**
|
|
2023
|
+
* Re-render the shadow pass once (static-shadow scenes,
|
|
2024
|
+
* `environment.shadows.static: true`) after a one-off world edit.
|
|
2025
|
+
*/
|
|
2026
|
+
refreshShadows(): void;
|
|
2003
2027
|
dispose(): void;
|
|
2004
2028
|
}
|
|
2005
2029
|
//#endregion
|
|
@@ -2043,6 +2067,8 @@ interface SyncScratch {
|
|
|
2043
2067
|
}
|
|
2044
2068
|
interface SyncOptions {
|
|
2045
2069
|
assets?: AssetStore3D;
|
|
2070
|
+
/** Sync `static: true` subtrees every frame anyway (the editor's edit mode). */
|
|
2071
|
+
ignoreStatic?: boolean;
|
|
2046
2072
|
/**
|
|
2047
2073
|
* The environment sky's unit sun direction. Pushed to every
|
|
2048
2074
|
* `_applySunDirection` node (Water3D, Foliage3D) right after its own sync —
|
|
@@ -2079,6 +2105,7 @@ interface WalkState {
|
|
|
2079
2105
|
sunDirection: readonly [number, number, number] | null;
|
|
2080
2106
|
sunLight: DirectionalLight3D | null;
|
|
2081
2107
|
alpha: number;
|
|
2108
|
+
ignoreStatic: boolean;
|
|
2082
2109
|
}
|
|
2083
2110
|
//#endregion
|
|
2084
2111
|
export { Area3D, AssetStore3D, Billboard3D, type BillboardGroupMode, Camera3D, CharacterBody3D, CharacterController3D, type CreateGame3DOptions, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, Environment3D, type Environment3DConfig, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, type FlowerVariety, Flowers3D, type FogEnvironment, Foliage3D, type FoliageKind, type FoliageStyle, type Game3D, type Heightmap, type HeightmapOptions, Joint3D, type JointType3D, LoftMesh3D, type LoftSection, MeshInstance3D, type MeshKind, type MeshMaterialProps, type ModelEntry, ModelInstance3D, Node3D, OmniLight3D, Particles3D, Physics3D, type Physics3DOptions, PhysicsBody3D, QUARTER_PITCH, type RenderContext3D, type RenderHook3D, Renderer3D, type Renderer3DOptions, type RigView, RigidBody3D, type Ripple, type ShadowsEnvironment, type SkyEnvironment, StaticBody3D, type SunConsumer3D, type SyncOptions, type SyncResult, TERRAIN_THEMES, Terrain3D, type TerrainLayer, type TerrainTheme, Tree3D, type TreeTier, type TreeType, VOXEL_PALETTE, type VoxelBlock, VoxelGrid3D, WATER_MAX_RIPPLES, Water3D, buildHeightmap, cameraRelative, createGame3D, enablePhysics3D, horizonColorFromSky, keyboardIntensity, movementState, parseEnvironment3D, registerNodes3D, resolveFlowerDensity, rigPose, splatWeights, sunDirectionFromElevationAzimuth, sunDirectionFromSky, syncTree, terrainThemeLayers };
|
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-
|
|
2
|
-
import { A as StaticBody3D, C as TERRAIN_THEMES, D as CharacterBody3D, E as Area3D, F as keyboardIntensity, I as movementState, L as rigPose, N as QUARTER_PITCH, O as PhysicsBody3D, P as cameraRelative, S as DEFAULT_TERRAIN_TEXTURE_BASE, T as Joint3D, _ as FLOWER_VARIETIES, a as VoxelGrid3D, b as Billboard3D, c as ModelInstance3D, d as DirectionalLight3D, f as OmniLight3D, g as resolveFlowerDensity, h as Flowers3D, i as VOXEL_PALETTE, j as Node3D, k as RigidBody3D, l as LoftMesh3D, m as DENSITY_PRESETS, n as Water3D, o as Tree3D, p as Foliage3D, r as WATER_MAX_RIPPLES, s as Particles3D, t as registerNodes3D, u as MeshInstance3D, v as CharacterController3D, w as terrainThemeLayers, x as Terrain3D, y as Camera3D } from "./register-
|
|
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-DkbZCNaV.js";
|
|
2
|
+
import { A as StaticBody3D, C as TERRAIN_THEMES, D as CharacterBody3D, E as Area3D, F as keyboardIntensity, I as movementState, L as rigPose, N as QUARTER_PITCH, O as PhysicsBody3D, P as cameraRelative, S as DEFAULT_TERRAIN_TEXTURE_BASE, T as Joint3D, _ as FLOWER_VARIETIES, a as VoxelGrid3D, b as Billboard3D, c as ModelInstance3D, d as DirectionalLight3D, f as OmniLight3D, g as resolveFlowerDensity, h as Flowers3D, i as VOXEL_PALETTE, j as Node3D, k as RigidBody3D, l as LoftMesh3D, m as DENSITY_PRESETS, n as Water3D, o as Tree3D, p as Foliage3D, r as WATER_MAX_RIPPLES, s as Particles3D, t as registerNodes3D, u as MeshInstance3D, v as CharacterController3D, w as terrainThemeLayers, x as Terrain3D, y as Camera3D } from "./register-Dd7Juujf.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-
|
|
4
|
+
import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-CBAQ12LY.js";
|
|
5
5
|
export { Area3D, AssetStore3D, Billboard3D, Camera3D, CharacterBody3D, CharacterController3D, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, Environment3D, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, Flowers3D, Foliage3D, Joint3D, LoftMesh3D, 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 };
|
|
@@ -5,9 +5,9 @@ import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
|
5
5
|
import { s as AudioPlayer } from "./register-Dl_ixIJe.js";
|
|
6
6
|
import { i as resolveRendering, n as attachTouchControls } from "./touch-031PxtCR.js";
|
|
7
7
|
import { n as registerGameplayBehaviors } from "./gameplay-CDFgSG6z.js";
|
|
8
|
-
import { g as Node2D, n as UILayer, p as PhysicsBody2D, s as Camera2D, t as registerNodes2D } from "./register-
|
|
8
|
+
import { g as Node2D, n as UILayer, p as PhysicsBody2D, s as Camera2D, t as registerNodes2D } from "./register-BJCfuuZ2.js";
|
|
9
9
|
import { t as debugSources } from "./debug-draw-CZmOYjL2.js";
|
|
10
|
-
import { n as enablePhysics2D } from "./physics-2d-
|
|
10
|
+
import { n as enablePhysics2D } from "./physics-2d-Cgli1aju.js";
|
|
11
11
|
import { Box3, BufferAttribute, BufferGeometry, Color, LineBasicMaterial, LineSegments, LinearFilter, NearestFilter, OrthographicCamera, Raycaster, SRGBColorSpace, Scene, TextureLoader, Vector2, Vector3, WebGLRenderer } from "three";
|
|
12
12
|
//#region src/2d/assets.ts
|
|
13
13
|
/**
|
|
@@ -108,11 +108,11 @@ function createSync2DScratch() {
|
|
|
108
108
|
cameras: []
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
|
-
function syncTree2D(root, world, ui, assets, uiSize, scratch) {
|
|
111
|
+
function syncTree2D(root, world, ui, assets, uiSize, scratch, opts) {
|
|
112
112
|
const s = scratch ?? createSync2DScratch();
|
|
113
113
|
s.visited.clear();
|
|
114
114
|
s.cameras.length = 0;
|
|
115
|
-
walk(root, world, ui, false, s.visited, s.cameras, assets, uiSize);
|
|
115
|
+
walk(root, world, ui, false, s.visited, s.cameras, assets, uiSize, opts?.ignoreStatic === true);
|
|
116
116
|
prune(world, s.visited);
|
|
117
117
|
prune(ui, s.visited);
|
|
118
118
|
let current = null;
|
|
@@ -126,9 +126,17 @@ function syncTree2D(root, world, ui, assets, uiSize, scratch) {
|
|
|
126
126
|
if (!current) current = s.cameras[0] ?? null;
|
|
127
127
|
return { activeCamera: current };
|
|
128
128
|
}
|
|
129
|
-
function walk(node, parentObj, ui, inUi, visited, cameras, assets, uiSize) {
|
|
129
|
+
function walk(node, parentObj, ui, inUi, visited, cameras, assets, uiSize, ignoreStatic) {
|
|
130
130
|
let nextParent = parentObj;
|
|
131
131
|
let nextInUi = inUi;
|
|
132
|
+
if (node instanceof Node2D && !(node instanceof UILayer)) {
|
|
133
|
+
const frozen = node._ensureObject2D();
|
|
134
|
+
if (node.static && !ignoreStatic && frozen.userData.incantoStaticSynced === true) {
|
|
135
|
+
frozen.userData.incantoStatic = true;
|
|
136
|
+
visited.add(frozen);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
132
140
|
if (node instanceof UILayer) {
|
|
133
141
|
const group = node._ensureGroup();
|
|
134
142
|
if (group.parent !== ui) ui.add(group);
|
|
@@ -148,14 +156,24 @@ function walk(node, parentObj, ui, inUi, visited, cameras, assets, uiSize) {
|
|
|
148
156
|
if (node instanceof Camera2D && !inUi) cameras.push(node);
|
|
149
157
|
nextParent = obj;
|
|
150
158
|
}
|
|
151
|
-
for (const child of node.children) walk(child, nextParent, ui, nextInUi, visited, cameras, assets, uiSize);
|
|
159
|
+
for (const child of node.children) walk(child, nextParent, ui, nextInUi, visited, cameras, assets, uiSize, ignoreStatic);
|
|
160
|
+
if (node instanceof Node2D && !(node instanceof UILayer)) {
|
|
161
|
+
const obj = node._ensureObject2D();
|
|
162
|
+
if (node.static && !ignoreStatic) {
|
|
163
|
+
obj.userData.incantoStaticSynced = true;
|
|
164
|
+
obj.userData.incantoStatic = true;
|
|
165
|
+
} else if (obj.userData.incantoStaticSynced === true) {
|
|
166
|
+
obj.userData.incantoStaticSynced = false;
|
|
167
|
+
obj.userData.incantoStatic = false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
152
170
|
}
|
|
153
171
|
function prune(obj, visited) {
|
|
154
172
|
const ch = obj.children;
|
|
155
173
|
for (let i = ch.length - 1; i >= 0; i--) {
|
|
156
174
|
const child = ch[i];
|
|
157
175
|
if (child.userData.incantoNode && !visited.has(child)) obj.remove(child);
|
|
158
|
-
else prune(child, visited);
|
|
176
|
+
else if (child.userData.incantoStatic !== true) prune(child, visited);
|
|
159
177
|
}
|
|
160
178
|
}
|
|
161
179
|
//#endregion
|
|
@@ -175,6 +193,8 @@ var Renderer2D = class {
|
|
|
175
193
|
webgl;
|
|
176
194
|
worldScene = new Scene();
|
|
177
195
|
syncScratch = createSync2DScratch();
|
|
196
|
+
/** Editors set this: keep syncing `static: true` subtrees every frame. */
|
|
197
|
+
ignoreStatic = false;
|
|
178
198
|
uiScene = new Scene();
|
|
179
199
|
worldCam = new OrthographicCamera(-1, 1, 1, -1, -1e3, 1e3);
|
|
180
200
|
uiCam = new OrthographicCamera(-1, 1, 1, -1, -1e3, 1e3);
|
|
@@ -6,8 +6,8 @@ import { s as AudioPlayer } from "./register-Dl_ixIJe.js";
|
|
|
6
6
|
import { i as resolveRendering, n as attachTouchControls } from "./touch-031PxtCR.js";
|
|
7
7
|
import { n as registerGameplayBehaviors } from "./gameplay-CDFgSG6z.js";
|
|
8
8
|
import { t as debugSources } from "./debug-draw-CZmOYjL2.js";
|
|
9
|
-
import { O as PhysicsBody3D, c as ModelInstance3D, d as DirectionalLight3D, j as Node3D, t as registerNodes3D, y as Camera3D } from "./register-
|
|
10
|
-
import { n as enablePhysics3D } from "./physics-3d-
|
|
9
|
+
import { O as PhysicsBody3D, c as ModelInstance3D, d as DirectionalLight3D, j as Node3D, t as registerNodes3D, y as Camera3D } from "./register-Dd7Juujf.js";
|
|
10
|
+
import { n as enablePhysics3D } from "./physics-3d-CBAQ12LY.js";
|
|
11
11
|
import { ACESFilmicToneMapping, AmbientLight, 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";
|
|
12
12
|
import { VRMLoaderPlugin, VRMUtils } from "@pixiv/three-vrm";
|
|
13
13
|
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
|
|
@@ -563,7 +563,11 @@ const CLOUD_KEYS = [
|
|
|
563
563
|
"scale"
|
|
564
564
|
];
|
|
565
565
|
const BLOOM_KEYS = ["threshold", "strength"];
|
|
566
|
-
const SHADOW_KEYS = [
|
|
566
|
+
const SHADOW_KEYS = [
|
|
567
|
+
"mapSize",
|
|
568
|
+
"radius",
|
|
569
|
+
"static"
|
|
570
|
+
];
|
|
567
571
|
const SHADOW_MAP_SIZES = [1024, 2048];
|
|
568
572
|
const DEFAULT_TURBIDITY = 2;
|
|
569
573
|
const DEFAULT_RAYLEIGH = 1;
|
|
@@ -756,7 +760,8 @@ function parseShadows(value) {
|
|
|
756
760
|
if (value === false) return false;
|
|
757
761
|
if (value === true) return {
|
|
758
762
|
mapSize: 2048,
|
|
759
|
-
radius: 1
|
|
763
|
+
radius: 1,
|
|
764
|
+
static: false
|
|
760
765
|
};
|
|
761
766
|
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new IncantoError("BAD_FORMAT", `environment.shadows must be true, false or an object ({ mapSize?, radius? }), got ${JSON.stringify(value)}.`, { prop: "shadows" });
|
|
762
767
|
const shadows = value;
|
|
@@ -771,9 +776,12 @@ function parseShadows(value) {
|
|
|
771
776
|
});
|
|
772
777
|
const radius = numberOr(shadows.radius, 1, "shadows.radius");
|
|
773
778
|
if (radius < 0) throw new IncantoError("BAD_FORMAT", `environment.shadows.radius must be >= 0, got ${radius}.`, { prop: "shadows" });
|
|
779
|
+
const staticShadows = shadows.static === void 0 ? false : shadows.static;
|
|
780
|
+
if (typeof staticShadows !== "boolean") throw new IncantoError("BAD_FORMAT", `environment.shadows.static must be a boolean, got ${JSON.stringify(shadows.static)}.`, { prop: "shadows" });
|
|
774
781
|
return {
|
|
775
782
|
mapSize,
|
|
776
|
-
radius
|
|
783
|
+
radius,
|
|
784
|
+
static: staticShadows
|
|
777
785
|
};
|
|
778
786
|
}
|
|
779
787
|
function numberOr(value, fallback, at) {
|
|
@@ -887,6 +895,12 @@ var Environment3D = class {
|
|
|
887
895
|
if (gl) {
|
|
888
896
|
gl.toneMappingExposure = cfg.exposure;
|
|
889
897
|
gl.shadowMap.enabled = cfg.shadows !== false;
|
|
898
|
+
if (cfg.shadows !== false && cfg.shadows !== null && cfg.shadows.static) {
|
|
899
|
+
if (gl.shadowMap.autoUpdate) {
|
|
900
|
+
gl.shadowMap.autoUpdate = false;
|
|
901
|
+
gl.shadowMap.needsUpdate = true;
|
|
902
|
+
}
|
|
903
|
+
} else if (!gl.shadowMap.autoUpdate) gl.shadowMap.autoUpdate = true;
|
|
890
904
|
}
|
|
891
905
|
this.applyHdri(env);
|
|
892
906
|
this.applySky(cfg.sky, gl);
|
|
@@ -1081,7 +1095,8 @@ function createSyncScratch() {
|
|
|
1081
1095
|
assets: void 0,
|
|
1082
1096
|
sunDirection: null,
|
|
1083
1097
|
sunLight: null,
|
|
1084
|
-
alpha: 1
|
|
1098
|
+
alpha: 1,
|
|
1099
|
+
ignoreStatic: false
|
|
1085
1100
|
}
|
|
1086
1101
|
};
|
|
1087
1102
|
}
|
|
@@ -1105,6 +1120,7 @@ function syncTree(root, threeScene, assets, opts, scratch) {
|
|
|
1105
1120
|
const state = s.state;
|
|
1106
1121
|
state.assets = assets;
|
|
1107
1122
|
state.sunDirection = opts?.sunDirection ?? null;
|
|
1123
|
+
state.ignoreStatic = opts?.ignoreStatic === true;
|
|
1108
1124
|
state.sunLight = null;
|
|
1109
1125
|
state.alpha = opts?.alpha ?? 1;
|
|
1110
1126
|
walk(root, threeScene, state);
|
|
@@ -1176,6 +1192,11 @@ function walk(node, parentObj, state) {
|
|
|
1176
1192
|
let nextParent = parentObj;
|
|
1177
1193
|
if (node instanceof Node3D) {
|
|
1178
1194
|
const obj = node._ensureObject3D();
|
|
1195
|
+
if (node.static && !state.ignoreStatic && obj.userData.incantoStaticSynced === true) {
|
|
1196
|
+
obj.userData.incantoStatic = true;
|
|
1197
|
+
state.visited.add(obj);
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1179
1200
|
if (obj.parent !== parentObj) parentObj.add(obj);
|
|
1180
1201
|
node._syncObject3D(state.alpha);
|
|
1181
1202
|
if (state.assets && node instanceof ModelInstance3D) node._syncModel(state.assets);
|
|
@@ -1195,13 +1216,37 @@ function walk(node, parentObj, state) {
|
|
|
1195
1216
|
parent: nextParent
|
|
1196
1217
|
});
|
|
1197
1218
|
for (const child of node.children) walk(child, nextParent, state);
|
|
1219
|
+
if (node instanceof Node3D) {
|
|
1220
|
+
const obj = node._ensureObject3D();
|
|
1221
|
+
if (node.static && !state.ignoreStatic) {
|
|
1222
|
+
obj.userData.incantoStaticSynced = true;
|
|
1223
|
+
obj.userData.incantoStatic = true;
|
|
1224
|
+
warnStaticHazards(node);
|
|
1225
|
+
} else if (obj.userData.incantoStaticSynced === true) {
|
|
1226
|
+
obj.userData.incantoStaticSynced = false;
|
|
1227
|
+
obj.userData.incantoStatic = false;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
const warnedStatic = /* @__PURE__ */ new WeakSet();
|
|
1232
|
+
/** One-time warning when animated machinery is frozen under a static root. */
|
|
1233
|
+
function warnStaticHazards(root) {
|
|
1234
|
+
if (warnedStatic.has(root)) return;
|
|
1235
|
+
warnedStatic.add(root);
|
|
1236
|
+
const hazards = [];
|
|
1237
|
+
const scan = (n) => {
|
|
1238
|
+
if (typeof n._onRender3D === "function" || n instanceof Camera3D) hazards.push(`${n.name} (${n.constructor.typeName ?? "?"})`);
|
|
1239
|
+
for (const c of n.children) scan(c);
|
|
1240
|
+
};
|
|
1241
|
+
scan(root);
|
|
1242
|
+
if (hazards.length > 0) console.warn(`[incanto] static subtree '${root.name}' freezes animated/per-frame nodes: ${hazards.join(", ")} — they will stop updating. Unmark static or move them out.`);
|
|
1198
1243
|
}
|
|
1199
1244
|
function prune(obj, visited) {
|
|
1200
1245
|
const ch = obj.children;
|
|
1201
1246
|
for (let i = ch.length - 1; i >= 0; i--) {
|
|
1202
1247
|
const child = ch[i];
|
|
1203
1248
|
if (child.userData.incantoNode && !visited.has(child)) obj.remove(child);
|
|
1204
|
-
else prune(child, visited);
|
|
1249
|
+
else if (child.userData.incantoStatic !== true) prune(child, visited);
|
|
1205
1250
|
}
|
|
1206
1251
|
}
|
|
1207
1252
|
//#endregion
|
|
@@ -1348,6 +1393,8 @@ var Renderer3D = class {
|
|
|
1348
1393
|
compiledScene = null;
|
|
1349
1394
|
/** Reused per-frame walk scratch (instance-scoped — never a module global). */
|
|
1350
1395
|
syncScratch = createSyncScratch();
|
|
1396
|
+
/** Editors set this: keep syncing `static: true` subtrees every frame. */
|
|
1397
|
+
ignoreStatic = false;
|
|
1351
1398
|
/** Reused render-hook context — gl/scene are stable, camera reassigned/frame. */
|
|
1352
1399
|
renderCtx = null;
|
|
1353
1400
|
/** Underwater caustics pass (lazy — only created the first time submerged). */
|
|
@@ -1425,7 +1472,8 @@ var Renderer3D = class {
|
|
|
1425
1472
|
this.environment.apply(scene.environment, this.webgl);
|
|
1426
1473
|
const { activeCamera: sceneCamera, renderHooks, sunLight } = syncTree(scene.root, this.threeScene, this.assets, {
|
|
1427
1474
|
sunDirection: this.environment.sunDirection,
|
|
1428
|
-
alpha: this.engine.interpolationAlpha
|
|
1475
|
+
alpha: this.engine.interpolationAlpha,
|
|
1476
|
+
ignoreStatic: this.ignoreStatic
|
|
1429
1477
|
}, this.syncScratch);
|
|
1430
1478
|
let activeCamera = sceneCamera;
|
|
1431
1479
|
if (this.viewOverride) {
|
|
@@ -1763,6 +1811,13 @@ var Renderer3D = class {
|
|
|
1763
1811
|
forward: new Vector3(0, 0, -1).applyQuaternion(q)
|
|
1764
1812
|
};
|
|
1765
1813
|
}
|
|
1814
|
+
/**
|
|
1815
|
+
* Re-render the shadow pass once (static-shadow scenes,
|
|
1816
|
+
* `environment.shadows.static: true`) after a one-off world edit.
|
|
1817
|
+
*/
|
|
1818
|
+
refreshShadows() {
|
|
1819
|
+
this.webgl.shadowMap.needsUpdate = true;
|
|
1820
|
+
}
|
|
1766
1821
|
dispose() {
|
|
1767
1822
|
this.disconnect();
|
|
1768
1823
|
this.threeScene.traverse((obj) => {
|
package/dist/index.js
CHANGED
|
@@ -110,6 +110,6 @@ function newUid() {
|
|
|
110
110
|
//#endregion
|
|
111
111
|
//#region src/index.ts
|
|
112
112
|
/** Engine version. Kept in sync with package.json by the release pipeline. */
|
|
113
|
-
const VERSION = "0.
|
|
113
|
+
const VERSION = "0.6.0";
|
|
114
114
|
//#endregion
|
|
115
115
|
export { AudioBuses, AudioPlayer, Behavior, CONST_REF_KEY, Engine, HudLayer, 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, UiBanner, UiBar, UiText, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, 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,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
3
|
-
import { _ as validateCollider2D, d as Area2D, f as CharacterBody2D, g as Node2D, m as RigidBody2D, p as PhysicsBody2D, u as Joint2D } from "./register-
|
|
3
|
+
import { _ as validateCollider2D, d as Area2D, f as CharacterBody2D, g as Node2D, m as RigidBody2D, p as PhysicsBody2D, u as Joint2D } from "./register-BJCfuuZ2.js";
|
|
4
4
|
import { n as registerDebugSource } from "./debug-draw-CZmOYjL2.js";
|
|
5
5
|
//#region src/2d/physics/physics-2d.ts
|
|
6
6
|
var physics_2d_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -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 { D as CharacterBody3D, E as Area3D, M as validateCollider3D, O as PhysicsBody3D, T as Joint3D, j as Node3D, k as RigidBody3D, x as Terrain3D } from "./register-
|
|
4
|
+
import { D as CharacterBody3D, E as Area3D, M as validateCollider3D, O as PhysicsBody3D, T as Joint3D, j as Node3D, k as RigidBody3D, x as Terrain3D } from "./register-Dd7Juujf.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-
|
|
159
|
+
const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-DkbZCNaV.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-B_sW_eiE.js").then((n) => n.n)).createGame2D(o)))(opts);
|
|
160
160
|
if (disposed) {
|
|
161
161
|
next.dispose();
|
|
162
162
|
return;
|
|
@@ -42,6 +42,7 @@ var Node2D = class extends Node {
|
|
|
42
42
|
static props = {
|
|
43
43
|
position: { default: [0, 0] },
|
|
44
44
|
rotation: { default: 0 },
|
|
45
|
+
static: { default: false },
|
|
45
46
|
scale: { default: [1, 1] },
|
|
46
47
|
renderOrder: { default: 0 },
|
|
47
48
|
visible: { default: true }
|
|
@@ -54,6 +55,8 @@ var Node2D = class extends Node {
|
|
|
54
55
|
position = [0, 0];
|
|
55
56
|
/** Degrees, clockwise. */
|
|
56
57
|
rotation = 0;
|
|
58
|
+
/** Frozen after first sync — see Node3D.static (same semantics in 2D). */
|
|
59
|
+
static = false;
|
|
57
60
|
scale = [1, 1];
|
|
58
61
|
/** Draw order among 2D drawables (higher = on top); matches 3D `renderOrder`. */
|
|
59
62
|
renderOrder = 0;
|
|
@@ -203,6 +203,7 @@ var Node3D = class extends Node {
|
|
|
203
203
|
0,
|
|
204
204
|
0
|
|
205
205
|
] },
|
|
206
|
+
static: { default: false },
|
|
206
207
|
scale: { default: [
|
|
207
208
|
1,
|
|
208
209
|
1,
|
|
@@ -222,6 +223,15 @@ var Node3D = class extends Node {
|
|
|
222
223
|
0,
|
|
223
224
|
0
|
|
224
225
|
];
|
|
226
|
+
/**
|
|
227
|
+
* This subtree never changes after load: the renderer syncs it ONCE and
|
|
228
|
+
* skips it every frame after (transforms, materials, animations frozen).
|
|
229
|
+
* The per-frame walk is O(nodes) — marking terrain/buildings/decor static
|
|
230
|
+
* removes most of a big scene from it. Set `static = false` to resume
|
|
231
|
+
* live syncing. Do NOT mark animated nodes (Water3D, Particles3D,
|
|
232
|
+
* AnimatedSprite3D, ModelInstance3D with clips) or cameras static.
|
|
233
|
+
*/
|
|
234
|
+
static = false;
|
|
225
235
|
scale = [
|
|
226
236
|
1,
|
|
227
237
|
1,
|
package/dist/test.js
CHANGED
|
@@ -4,8 +4,8 @@ import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
|
4
4
|
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-CDFgSG6z.js";
|
|
7
|
-
import { t as registerNodes2D } from "./register-
|
|
8
|
-
import { t as registerNodes3D } from "./register-
|
|
7
|
+
import { t as registerNodes2D } from "./register-BJCfuuZ2.js";
|
|
8
|
+
import { t as registerNodes3D } from "./register-Dd7Juujf.js";
|
|
9
9
|
import { t as registerNodesNet } from "./register-C35HDZpm.js";
|
|
10
10
|
//#region src/test/index.ts
|
|
11
11
|
/**
|
|
@@ -129,10 +129,10 @@ async function runScript(json, opts) {
|
|
|
129
129
|
engine.setScene(scene);
|
|
130
130
|
const physics = opts.physics ?? "auto";
|
|
131
131
|
if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
|
|
132
|
-
const { enablePhysics2D } = await import("./physics-2d-
|
|
132
|
+
const { enablePhysics2D } = await import("./physics-2d-Cgli1aju.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-
|
|
135
|
+
const { enablePhysics3D } = await import("./physics-3d-CBAQ12LY.js").then((n) => n.r);
|
|
136
136
|
await enablePhysics3D(engine);
|
|
137
137
|
}
|
|
138
138
|
const failures = [];
|
|
@@ -234,10 +234,10 @@ async function createPlaySession(json, opts = {}) {
|
|
|
234
234
|
engine.setScene(scene);
|
|
235
235
|
const physics = opts.physics ?? "auto";
|
|
236
236
|
if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
|
|
237
|
-
const { enablePhysics2D } = await import("./physics-2d-
|
|
237
|
+
const { enablePhysics2D } = await import("./physics-2d-Cgli1aju.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-
|
|
240
|
+
const { enablePhysics3D } = await import("./physics-3d-CBAQ12LY.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-
|
|
1
|
+
import{t as e}from"./index-mofVSmuA.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};
|