incanto 0.65.0 → 0.67.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/bin/_behaviors-loader.mjs +87 -0
- package/bin/incanto-editor.mjs +39 -2
- package/bin/incanto-feel.mjs +4 -1
- package/bin/incanto-frame.mjs +52 -3
- package/bin/incanto-logs.mjs +33 -3
- package/bin/incanto-multiplay.mjs +50 -1
- package/bin/incanto-play.mjs +3 -1
- package/bin/incanto-playtest.mjs +3 -25
- package/bin/incanto-verify.mjs +15 -2
- package/dist/2d.d.ts +76 -4
- package/dist/2d.js +3 -3
- package/dist/3d.d.ts +213 -14
- package/dist/3d.js +6 -6
- package/dist/{audio-player-BrEHwbK1.d.ts → audio-player-BNUHo0JF.d.ts} +1 -1
- package/dist/{behavior-CmMuQ6CL.d.ts → behavior-ZnfzKDo3.d.ts} +58 -1
- package/dist/{create-game-DIyh5Zy9.js → create-game-DMetd3vR.js} +14 -8
- package/dist/{create-game-W2xzTJhs.js → create-game-FAXdHta3.js} +138 -11
- package/dist/debug.d.ts +1 -1
- package/dist/debug.js +3 -2
- package/dist/{duplicate-CqSAtdrh.js → duplicate-B8QnX2-r.js} +1 -1
- package/dist/editor.js +7 -2
- package/dist/{environment-presets-BvHs6HEk.js → environment-presets-C-5g2pMh.js} +113 -9
- package/dist/{gameplay-D-H986A4.js → gameplay-CGSv-9XR.js} +295 -12
- package/dist/gameplay.d.ts +102 -6
- package/dist/gameplay.js +2 -2
- package/dist/index.d.ts +50 -6
- package/dist/index.js +7 -6
- package/dist/{loader-CTB441z4.d.ts → loader-DyT30ArB.d.ts} +1 -1
- package/dist/{loader-lQDCwNag.js → loader-KZESOZmE.js} +148 -1
- package/dist/net.d.ts +2 -2
- package/dist/net.js +1 -1
- package/dist/{physics-2d-CmnunaR2.js → physics-2d-_B6zj3zU.js} +57 -4
- package/dist/{physics-3d-DULB1lD1.js → physics-3d-i1IeAY0F.js} +74 -5
- package/dist/{quiet-rapier-BAJ4K94N.js → quiet-rapier-C6fW4zcW.js} +14 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-CgeR4ckF.js → register-Cs53CY7s.js} +110 -16
- package/dist/{register-DO5_Qp0Q.js → register-vIxU3Xbv.js} +38 -4
- package/dist/rendering-options-ByAdi8PF.js +184 -0
- package/dist/{replay-CEw2xAhG.js → replay-BkpDV51O.js} +4 -3
- package/dist/{replay-CThvwkcQ.d.ts → replay-D0GcEHYU.d.ts} +1 -1
- package/dist/{split-screen-DxZzC1nm.d.ts → split-screen-DD5eYIgW.d.ts} +2 -2
- package/dist/{split-screen-gb0c3xdb.js → split-screen-DS8RaUV_.js} +2 -2
- package/dist/{src-DYffzHbd.js → src-BLlsGJW9.js} +1 -1
- package/dist/{teardown-BordHL9o.js → teardown-LB9cTnXJ.js} +2 -2
- package/dist/{test-CXZuXs8k.js → test-81uZ967a.js} +127 -24
- package/dist/test.d.ts +7 -5
- package/dist/test.js +2 -2
- package/dist/{touch-DESwnpOc.js → touch-DEAmqGdf.js} +30 -186
- package/dist/vite.d.ts +0 -7
- package/dist/vite.js +13 -3
- package/editor/assets/{agent8-DO5qzIOD.js → agent8-C2jtNKbx.js} +1 -1
- package/editor/assets/debug-DoU3KeqS.js +3 -0
- package/editor/assets/{index-CqEUVaPN.js → index-CNqHojcC.js} +92 -92
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +20 -1
- package/skills/incanto-building-3d-games.md +19 -0
- package/skills/incanto-editor.md +5 -1
- package/skills/incanto-environment.md +2 -2
- package/skills/incanto-gameplay-behaviors.md +86 -7
- package/skills/incanto-hud.md +14 -1
- package/skills/incanto-multiplayer.md +14 -0
- package/skills/incanto-node-reference.md +60 -2
- package/skills/incanto-performance.md +35 -0
- package/skills/incanto-physics-and-input.md +69 -0
- package/skills/incanto-playtesting.md +15 -1
- package/skills/incanto-save-slots.md +21 -1
- package/skills/incanto-verifying-your-game.md +19 -0
- package/skills/incanto-web-integration.md +24 -3
- package/skills/incanto-your-first-game.md +4 -4
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/beacon-isle-3d/src/game.scene.json +38 -19
- package/templates-app/platformer-2d/package.json +1 -1
- package/templates-app/platformer-2d/src/game.scene.json +99 -53
- package/templates-app/star-survivor/package.json +1 -1
- package/templates-app/star-survivor/src/game.scene.json +31 -17
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/tps-3d/src/game.scene.json +14 -8
- package/templates-app/village-quest-3d/package.json +1 -1
- package/templates-app/village-quest-3d/src/grove.scene.json +20 -11
- package/templates-app/village-quest-3d/src/village.scene.json +10 -7
- package/editor/assets/debug-DntG9CVD.js +0 -3
- package/templates-app/beacon-isle-3d/coverage.json +0 -9
- package/templates-app/platformer-2d/coverage.json +0 -5
- package/templates-app/star-survivor/coverage.json +0 -5
- package/templates-app/tps-3d/coverage.json +0 -5
- package/templates-app/village-quest-3d/coverage.json +0 -9
package/dist/3d.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { D as QualityCaps, P as Scene$1, S as Scheduler, T as RendererStats, b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, w as GameStats } from "./behavior-
|
|
1
|
+
import { D as QualityCaps, P as Scene$1, S as Scheduler, T as RendererStats, b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, w as GameStats, x as EngineOptions } from "./behavior-ZnfzKDo3.js";
|
|
2
2
|
import { n as DiagnosticSink, t as EditorSwitchOptions } from "./editor-switch-DAvWQeld.js";
|
|
3
3
|
import { i as SceneJson$1, s as JsonObject } from "./schema-CFeioQRE.js";
|
|
4
4
|
import { a as GridCell, c as diffText, d as frameText, i as FrameStatsOptions, l as frameSignature, n as FrameSignature, o as SIGNATURE_GRID, r as FrameStats, s as diffSignatures, t as FrameDiff, u as frameStats } from "./frame-report-DCnHFmto.js";
|
|
5
|
-
import { t as LoadSceneOptions } from "./loader-
|
|
6
|
-
import { i as ParticleSim, o as ParticleView, r as SpatialPose } from "./audio-player-
|
|
5
|
+
import { t as LoadSceneOptions } from "./loader-DyT30ArB.js";
|
|
6
|
+
import { i as ParticleSim, o as ParticleView, r as SpatialPose } from "./audio-player-BNUHo0JF.js";
|
|
7
7
|
import { n as PathGrid } from "./pathfinding-_fGrCFmH.js";
|
|
8
8
|
import { AnimationClip, AnimationMixer, BufferGeometry, Color, DirectionalLight, Group, InstancedMesh, Mesh, MeshPhysicalMaterial, Object3D, PerspectiveCamera, Scene, ShaderMaterial, Texture, Vector3, WebGLRenderer } from "three";
|
|
9
9
|
import { VRM } from "@pixiv/three-vrm";
|
|
@@ -133,6 +133,31 @@ interface AnimationEntry {
|
|
|
133
133
|
*/
|
|
134
134
|
declare class AssetStore3D {
|
|
135
135
|
private readonly engine;
|
|
136
|
+
/**
|
|
137
|
+
* One geometry and one material per distinct SHAPE and per distinct look.
|
|
138
|
+
*
|
|
139
|
+
* `MeshInstance3D._createObject3D` used to `new BoxGeometry()` and
|
|
140
|
+
* `new MeshPhysicalMaterial()` for every node, even when byte-identical.
|
|
141
|
+
* Three identical nodes reported `geometry shared? false false / material
|
|
142
|
+
* shared? false false`, with distinct uuids. Measured at 3,200 units, all
|
|
143
|
+
* three runs at identical 3,209 draw calls / 1,741,932 triangles and an
|
|
144
|
+
* identical screenshot:
|
|
145
|
+
*
|
|
146
|
+
* ```
|
|
147
|
+
* per-node geometry + material 31.0 ms wall (renderMs 27.3)
|
|
148
|
+
* share one geometry 27.0 ms
|
|
149
|
+
* + share two materials 15.4 ms <- 2x the headroom
|
|
150
|
+
* ```
|
|
151
|
+
*
|
|
152
|
+
* 13.1 ms of that 26.5 ms cliff was GPU state churn from per-node objects,
|
|
153
|
+
* and none of it was visible headlessly: with no renderer `_syncObject3D`
|
|
154
|
+
* never runs, so the bench measured 55 ns/node instead of ~2,000.
|
|
155
|
+
*
|
|
156
|
+
* Renderer-scoped, deliberately — module-level state is the predecessor's
|
|
157
|
+
* fatal flaw and two games in one page must not share a cache.
|
|
158
|
+
*/
|
|
159
|
+
readonly meshGeometries: Map<string, unknown>;
|
|
160
|
+
readonly meshMaterials: Map<string, unknown>;
|
|
136
161
|
private readonly models;
|
|
137
162
|
private readonly animations;
|
|
138
163
|
private readonly modelKeys;
|
|
@@ -358,6 +383,33 @@ declare class StaticBody3D extends PhysicsBody3D {
|
|
|
358
383
|
/** Sensor volume emitting `triggerEnter(other)` / `triggerExit(other)`. */
|
|
359
384
|
declare class Area3D extends PhysicsBody3D {
|
|
360
385
|
static override readonly typeName: string;
|
|
386
|
+
/**
|
|
387
|
+
* Who is inside RIGHT NOW — the standing answer behind the enter/exit pair.
|
|
388
|
+
*
|
|
389
|
+
* Enter and exit tell you about crossings; a pressure plate, a capture point,
|
|
390
|
+
* a "how many enemies are in the blast" count and a shop trigger all want
|
|
391
|
+
* OCCUPANCY. Without this every one of them kept a private `Set` fed by the
|
|
392
|
+
* two signals, and had to guard it, because a body that is teleported or
|
|
393
|
+
* freed inside a sensor does not reliably announce its exit. Physics already
|
|
394
|
+
* knows; now it says.
|
|
395
|
+
*
|
|
396
|
+
* ```ts
|
|
397
|
+
* const load = this.area.overlapping()
|
|
398
|
+
* .reduce((kg, b) => kg + ((b as RigidBody3D).mass ?? 0), 0);
|
|
399
|
+
* door.open = load >= 60;
|
|
400
|
+
* ```
|
|
401
|
+
*
|
|
402
|
+
* It reports everything the solver says is inside, STATIC WORLD INCLUDED — a
|
|
403
|
+
* plate laid into the floor genuinely contains the floor. Pass a group to ask
|
|
404
|
+
* the question you usually mean:
|
|
405
|
+
*
|
|
406
|
+
* ```ts
|
|
407
|
+
* area.overlapping('crate') // only things tagged `crate`
|
|
408
|
+
* ```
|
|
409
|
+
*
|
|
410
|
+
* Empty in a scene with no physics world.
|
|
411
|
+
*/
|
|
412
|
+
overlapping(group?: string): PhysicsBody3D[];
|
|
361
413
|
}
|
|
362
414
|
/** Dynamic simulated body. */
|
|
363
415
|
declare class RigidBody3D extends PhysicsBody3D {
|
|
@@ -370,6 +422,14 @@ declare class RigidBody3D extends PhysicsBody3D {
|
|
|
370
422
|
restitution: number;
|
|
371
423
|
/** m/s, y-up. Read back every step; write to launch. */
|
|
372
424
|
linearVelocity: number[];
|
|
425
|
+
/**
|
|
426
|
+
* rad/s about each world axis. Read back every step; write to spin.
|
|
427
|
+
*
|
|
428
|
+
* A puzzle builder could neither launch a spinning body nor read how fast a
|
|
429
|
+
* lever was swinging — only its angle, differenced by hand — because this had
|
|
430
|
+
* no counterpart to `linearVelocity`. `fixedRotation` pins it at zero.
|
|
431
|
+
*/
|
|
432
|
+
angularVelocity: number[];
|
|
373
433
|
/** @internal set by Physics3D */
|
|
374
434
|
_physics3d: Physics3D | null;
|
|
375
435
|
/** World-space impulse (kg·m/s) — the floating-capsule controller's verb. */
|
|
@@ -539,6 +599,27 @@ declare class Physics3D {
|
|
|
539
599
|
velocityOf(node: PhysicsBody3D): [number, number, number];
|
|
540
600
|
/** Create newly-arrived joints; tear down departed ones. */
|
|
541
601
|
private syncJoints;
|
|
602
|
+
/** Who is currently inside each sensor/body, maintained from the event drain. */
|
|
603
|
+
private readonly overlaps;
|
|
604
|
+
private trackOverlap;
|
|
605
|
+
/**
|
|
606
|
+
* Forget every overlap whose node has left the tree.
|
|
607
|
+
*
|
|
608
|
+
* The lazy drop inside `overlapping()` only cleans the SETS of a key someone
|
|
609
|
+
* asks about, and only when they ask. This clears the KEYS, which is where the
|
|
610
|
+
* dead nodes were pinned.
|
|
611
|
+
*/
|
|
612
|
+
/** Drop one node from the overlap map, both as a key and as a member. */
|
|
613
|
+
private forgetOverlaps;
|
|
614
|
+
private pruneOverlaps;
|
|
615
|
+
/**
|
|
616
|
+
* The bodies currently overlapping `node` — the standing answer behind
|
|
617
|
+
* `triggerEnter`/`triggerExit`.
|
|
618
|
+
*
|
|
619
|
+
* Freed nodes are dropped on read rather than tracked, so a hazard that
|
|
620
|
+
* despawns inside a plate cannot leave a ghost holding a door open.
|
|
621
|
+
*/
|
|
622
|
+
overlapping(node: PhysicsBody3D): PhysicsBody3D[];
|
|
542
623
|
/**
|
|
543
624
|
* World-space raycast (meters). `exclude` skips that body's collider —
|
|
544
625
|
* ground probes from inside a capsule need it. `opts.staticOnly` hits ONLY the
|
|
@@ -637,6 +718,18 @@ interface CreateGame3DOptions {
|
|
|
637
718
|
*/
|
|
638
719
|
editor?: boolean | EditorSwitchOptions;
|
|
639
720
|
seed?: number;
|
|
721
|
+
/**
|
|
722
|
+
* Namespace this game's persisted settings — volume, language, quality tier.
|
|
723
|
+
*
|
|
724
|
+
* They are keyed `incanto:<namespace>:<key>` in the browser's storage and
|
|
725
|
+
* defaulted to `settings` for everyone, so two Incanto games on one domain
|
|
726
|
+
* shared one options screen. Measured: game A's player sets `renderScale
|
|
727
|
+
* 0.25, muted, quality low`; game B, whose source never mentions settings,
|
|
728
|
+
* boots at a 480x232 drawing buffer and silent.
|
|
729
|
+
*
|
|
730
|
+
* `SaveSlots(namespace)` already takes one for exactly this reason.
|
|
731
|
+
*/
|
|
732
|
+
settings?: EngineOptions["settings"];
|
|
640
733
|
fixedHz?: number;
|
|
641
734
|
pixelRatio?: number;
|
|
642
735
|
/** Keep the frame rate by rendering fewer pixels while frames run slow
|
|
@@ -686,7 +779,22 @@ interface GameRenderer {
|
|
|
686
779
|
}
|
|
687
780
|
interface Game3D {
|
|
688
781
|
engine: Engine;
|
|
689
|
-
|
|
782
|
+
/**
|
|
783
|
+
* The LIVE scene — a getter over `engine.scene`, not a snapshot.
|
|
784
|
+
*
|
|
785
|
+
* This used to be the scene captured at boot. `Engine.setScene` calls
|
|
786
|
+
* `this._scene?.root.free()`, so after any swap the old handle was not merely
|
|
787
|
+
* stale, it was EMPTIED — and a single-scene game reaches that through
|
|
788
|
+
* `flow.restart()`, which `incanto-hud.md` wires to a Start button. Measured:
|
|
789
|
+
*
|
|
790
|
+
* before swap game.scene.root.children = 2 engine.scene = 2
|
|
791
|
+
* after swap game.scene.root.children = 0 engine.scene = 2
|
|
792
|
+
* game.scene.root.getNode('Flow') -> No node at 'Flow'. Children here: [].
|
|
793
|
+
*
|
|
794
|
+
* `game.engine.scene` always worked and three skills use it, so there were
|
|
795
|
+
* two handles with one name and no note saying which was which.
|
|
796
|
+
*/
|
|
797
|
+
get scene(): Scene$1;
|
|
690
798
|
/**
|
|
691
799
|
* The AUTHORED scene this game booted from — the JSON, not the live tree.
|
|
692
800
|
*
|
|
@@ -982,19 +1090,25 @@ declare class Environment3D {
|
|
|
982
1090
|
}
|
|
983
1091
|
//#endregion
|
|
984
1092
|
//#region src/3d/environment-runtime.d.ts
|
|
1093
|
+
declare function setEnvironment3D(engine: Engine, patch: JsonObject, opts?: {
|
|
1094
|
+
rebaseTierKeys?: boolean;
|
|
1095
|
+
}): void;
|
|
985
1096
|
/**
|
|
986
|
-
*
|
|
987
|
-
* every frame (cheap when unchanged), so changing the LOOK at runtime is
|
|
988
|
-
* just writing that object. This helper does it safely:
|
|
1097
|
+
* Apply a quality tier — the only caller that may RESET as well as patch.
|
|
989
1098
|
*
|
|
990
|
-
*
|
|
991
|
-
*
|
|
1099
|
+
* A tier is re-applied every time the player moves the slider, so it cannot
|
|
1100
|
+
* compose with what the last one left behind: `low` strips the author's bloom,
|
|
1101
|
+
* and `high` then has nothing to put back. This re-derives the four tier-owned
|
|
1102
|
+
* stages from the scene FILE first, so every tier is reversible, and so a stage
|
|
1103
|
+
* the author never wrote can never appear — the contract `settings.ts` states
|
|
1104
|
+
* and `incanto-performance.md` promises: *the tier can only take things away.*
|
|
992
1105
|
*
|
|
993
|
-
*
|
|
994
|
-
*
|
|
995
|
-
*
|
|
1106
|
+
* Measured before this, on a scene with no `bloom` and no `post` in its JSON:
|
|
1107
|
+
* `high` and `medium` both rendered five GL passes at 3.3 ms where `low`
|
|
1108
|
+
* rendered one at 1.24 ms — 62% of the frame on a chain the game never asked
|
|
1109
|
+
* for, and `environment.bloom` read back `{strength: 0.8, threshold: 1}`.
|
|
996
1110
|
*/
|
|
997
|
-
declare function
|
|
1111
|
+
declare function applyQualityTier3D(engine: Engine, patch: JsonObject): void;
|
|
998
1112
|
//#endregion
|
|
999
1113
|
//#region src/3d/model-verdict.d.ts
|
|
1000
1114
|
/**
|
|
@@ -1264,6 +1378,25 @@ declare class CharacterController3D extends Node3D {
|
|
|
1264
1378
|
airControl: number;
|
|
1265
1379
|
fallGravity: number;
|
|
1266
1380
|
floatHeight: number;
|
|
1381
|
+
/**
|
|
1382
|
+
* How high a step the PLAYER walks up without jumping (0 = off).
|
|
1383
|
+
*
|
|
1384
|
+
* The hover spring holds the capsule a fixed distance above whatever is
|
|
1385
|
+
* DIRECTLY below it, so a vertical face stopped the player dead at about
|
|
1386
|
+
* 0.2 m — while `CharacterBody3D.stepHeight` let every enemy climb 0.35 m.
|
|
1387
|
+
* The docs said the player did not need this ("it floats over small ledges
|
|
1388
|
+
* already"); it floats over 18 cm ones.
|
|
1389
|
+
*
|
|
1390
|
+
* This probes just AHEAD of the capsule in the direction of travel: if the
|
|
1391
|
+
* ground there is higher, but by no more than `stepHeight`, the spring aims
|
|
1392
|
+
* at THAT surface and lifts the character onto it. A wall taller than the
|
|
1393
|
+
* step is not a step and still stops you.
|
|
1394
|
+
*
|
|
1395
|
+
* Do not reach for `floatHeight` instead. It does raise the character over
|
|
1396
|
+
* ledges, and it silently makes it WEIGHTLESS: at `floatHeight: 0.28` a
|
|
1397
|
+
* 200 kg character does not move a seesaw a 70 kg crate tips.
|
|
1398
|
+
*/
|
|
1399
|
+
stepHeight: number;
|
|
1267
1400
|
mouseLook: boolean;
|
|
1268
1401
|
zoomMin: number;
|
|
1269
1402
|
zoomMax: number;
|
|
@@ -1727,6 +1860,10 @@ declare class MeshInstance3D extends Node3D {
|
|
|
1727
1860
|
/** Loader hook: malformed materials fail at LOAD time, not at render. */
|
|
1728
1861
|
static validateJson(node: Node): void;
|
|
1729
1862
|
private geometryKey;
|
|
1863
|
+
private materialKey;
|
|
1864
|
+
/** True while this node is using a cache entry it must not dispose. */
|
|
1865
|
+
private sharedGeometry;
|
|
1866
|
+
private sharedMaterial;
|
|
1730
1867
|
private textureKey;
|
|
1731
1868
|
private loadedTextures;
|
|
1732
1869
|
protected override _createObject3D(): Object3D;
|
|
@@ -1836,6 +1973,31 @@ declare class Joint3D extends Node3D {
|
|
|
1836
1973
|
length: number;
|
|
1837
1974
|
stiffness: number;
|
|
1838
1975
|
damping: number;
|
|
1976
|
+
/**
|
|
1977
|
+
* Do the two linked bodies still collide with EACH OTHER?
|
|
1978
|
+
*
|
|
1979
|
+
* `null` (default) decides from the joint type, because the two families want
|
|
1980
|
+
* opposite answers:
|
|
1981
|
+
*
|
|
1982
|
+
* - **pivots** (`fixed`, `spherical`, `revolute`) → **off**. A hinge's bodies
|
|
1983
|
+
* overlap at the pivot by construction, so the contact solver fights the
|
|
1984
|
+
* joint and flings them. A puzzle builder's first hinge produced a bar that
|
|
1985
|
+
* spun chaotically forever and threw a 40 kg box thirty metres, and they
|
|
1986
|
+
* nearly filed "spherical joints inject energy":
|
|
1987
|
+
*
|
|
1988
|
+
* ```
|
|
1989
|
+
* t= 0 Plank r=[0,0,0] Box [ 0.00, 5.50, 2.40]
|
|
1990
|
+
* t=3000 Plank r=[-66,24,64] Box [-29.70, 0.40, -4.91]
|
|
1991
|
+
* ```
|
|
1992
|
+
*
|
|
1993
|
+
* - **tethers** (`rope`, `spring`) → **on**. These anchor a thing to the world,
|
|
1994
|
+
* and the thing has to rest on what it is tethered to. Defaulting these off
|
|
1995
|
+
* drops a barrel roped to the floor straight through it — measured, in this
|
|
1996
|
+
* repo's own conformance room.
|
|
1997
|
+
*
|
|
1998
|
+
* Set `true`/`false` to say it outright.
|
|
1999
|
+
*/
|
|
2000
|
+
collide: boolean | null;
|
|
1839
2001
|
override onEnterTree(): void;
|
|
1840
2002
|
/** @internal The two bodies, resolved (throws on a bad target at step time). */
|
|
1841
2003
|
_resolveBodies(): {
|
|
@@ -3719,6 +3881,43 @@ declare class Renderer3D {
|
|
|
3719
3881
|
behind: boolean;
|
|
3720
3882
|
};
|
|
3721
3883
|
/**
|
|
3884
|
+
* The WORLD POINT under canvas pixel (sx, sy) — the other half of
|
|
3885
|
+
* `screenFromWorld`, and the call `incanto-web-integration.md` has always
|
|
3886
|
+
* offered "for taps and clicks".
|
|
3887
|
+
*
|
|
3888
|
+
* It did not exist in 3D. `Renderer2D` has had it since the beginning, the
|
|
3889
|
+
* doc covers both runtimes, and an agent building a tower defense went looking
|
|
3890
|
+
* for it and measured `typeof game.renderer.worldFromScreen === "undefined"`.
|
|
3891
|
+
* `pick()` gives you the NODE under a pixel but never the POINT, so "put the
|
|
3892
|
+
* thing where the player clicked on the ground" was not expressible and that
|
|
3893
|
+
* game discretised its whole map into clickable pads instead.
|
|
3894
|
+
*
|
|
3895
|
+
* A pixel in 3D is a RAY, not a point, so this needs a surface to land on and
|
|
3896
|
+
* takes the horizontal plane at `planeY` (default 0 — the ground). Returns
|
|
3897
|
+
* null when the ray runs parallel to that plane or would only meet it behind
|
|
3898
|
+
* the camera, which is what "the sky" looks like from here.
|
|
3899
|
+
*
|
|
3900
|
+
* For anything not flat — terrain, a hillside, a stack of crates — raycast
|
|
3901
|
+
* physics instead: `rayFromScreen` gives you the origin and direction to feed
|
|
3902
|
+
* `physics.castRay`.
|
|
3903
|
+
*/
|
|
3904
|
+
worldFromScreen(sx: number, sy: number, planeY?: number): {
|
|
3905
|
+
x: number;
|
|
3906
|
+
y: number;
|
|
3907
|
+
z: number;
|
|
3908
|
+
} | null;
|
|
3909
|
+
/**
|
|
3910
|
+
* The camera ray through canvas pixel (sx, sy) — origin and unit direction,
|
|
3911
|
+
* ready for `physics.castRay(origin, dir, maxLen)`.
|
|
3912
|
+
*
|
|
3913
|
+
* This is the honest 3D answer to "where did the player click": on uneven
|
|
3914
|
+
* ground the only thing that knows is the collision world.
|
|
3915
|
+
*/
|
|
3916
|
+
rayFromScreen(sx: number, sy: number): {
|
|
3917
|
+
origin: [number, number, number];
|
|
3918
|
+
dir: [number, number, number];
|
|
3919
|
+
} | null;
|
|
3920
|
+
/**
|
|
3722
3921
|
* The node rendered under canvas pixel (sx, sy), or null — raycasts the last
|
|
3723
3922
|
* rendered camera into the scene and resolves the hit up to its `incantoNode`
|
|
3724
3923
|
* (every Node3D stamps that in `_ensureObject3D`). 3D depth-sorts, so the
|
|
@@ -3907,4 +4106,4 @@ declare function createNavDebugNode(nav: TerrainNav, opts?: {
|
|
|
3907
4106
|
name?: string;
|
|
3908
4107
|
}): InstancedMesh3D;
|
|
3909
4108
|
//#endregion
|
|
3910
|
-
export { Area3D, AssetStore3D, type BedSampler, Billboard3D, type BillboardGroupMode, BoneAttachment3D, BoneLookAt3D, Camera3D, CharacterBody3D, CharacterController3D, type CreateGame3DOptions, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, type DownhillTraceOptions, Environment3D, type Environment3DConfig, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, type FlowerVariety, Flowers3D, type FogEnvironment, Foliage3D, type FoliageKind, type FoliageStyle, type FrameDiff, type FrameSignature, type FrameStats, type FrameStatsOptions, type Game3D, type GridCell, type HeightSampler, type Heightmap, type HeightmapOptions, InstancedMesh3D, Joint3D, type JointType3D, LoftMesh3D, type LoftSection, MeshInstance3D, type MeshKind, type MeshMaterialProps, type ModelEntry, type ModelFacts, ModelInstance3D, type ModelVerdict, Node3D, OmniLight3D, Particles3D, Physics3D, type Physics3DOptions, PhysicsBody3D, QUARTER_PITCH, type RenderContext3D, type RenderHook3D, Renderer3D, type Renderer3DOptions, type Rig, type RigView, RigidBody3D, type Ripple, River3D, type RiverCarveOptions, type RiverCoverageGap, type RiverHit, type RiverRing, type RiverRingOptions, SIGNATURE_GRID, type SceneJson, type ShadowsEnvironment, type SkyEnvironment, StaticBody3D, type SunConsumer3D, type SyncOptions, type SyncResult, TERRAIN_THEMES, Terrain3D, type TerrainLayer, type TerrainNav, type TerrainNavOptions, type TerrainTheme, TextureCache3D, type TextureSpec, Trail3D, Tree3D, type TreeTier, type TreeType, VOXEL_PALETTE, type VoxelBlock, VoxelGrid3D, WATER_CUTOUT_MAX, WATER_MAX_RIPPLES, Water3D, WaterCutout3D, acquireOwnTexture, acquireTexture, buildHeightmap, buildRiverRings, buildTerrainNav, cameraRelative, createGame3D, createNavDebugNode, diffSignatures, diffText, enablePhysics3D, findRiverCoverageGaps, frameSignature, frameStats, frameText, horizonColorFromSky, keyboardIntensity, modelVerdict, movementState, parseEnvironment3D, projectToRiver, registerNodes3D, resolveFlowerDensity, rigPose, riverCarveChannels, riverStepFor, setEnvironment3D, smoothCourse, splatWeights, sunDirectionFromElevationAzimuth, sunDirectionFromSky, syncTree, terrainThemeLayers, traceDownhillPath, verdictText };
|
|
4109
|
+
export { Area3D, AssetStore3D, type BedSampler, Billboard3D, type BillboardGroupMode, BoneAttachment3D, BoneLookAt3D, Camera3D, CharacterBody3D, CharacterController3D, type CreateGame3DOptions, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, type DownhillTraceOptions, Environment3D, type Environment3DConfig, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, type FlowerVariety, Flowers3D, type FogEnvironment, Foliage3D, type FoliageKind, type FoliageStyle, type FrameDiff, type FrameSignature, type FrameStats, type FrameStatsOptions, type Game3D, type GridCell, type HeightSampler, type Heightmap, type HeightmapOptions, InstancedMesh3D, Joint3D, type JointType3D, LoftMesh3D, type LoftSection, MeshInstance3D, type MeshKind, type MeshMaterialProps, type ModelEntry, type ModelFacts, ModelInstance3D, type ModelVerdict, Node3D, OmniLight3D, Particles3D, Physics3D, type Physics3DOptions, PhysicsBody3D, QUARTER_PITCH, type RenderContext3D, type RenderHook3D, Renderer3D, type Renderer3DOptions, type Rig, type RigView, RigidBody3D, type Ripple, River3D, type RiverCarveOptions, type RiverCoverageGap, type RiverHit, type RiverRing, type RiverRingOptions, SIGNATURE_GRID, type SceneJson, type ShadowsEnvironment, type SkyEnvironment, StaticBody3D, type SunConsumer3D, type SyncOptions, type SyncResult, TERRAIN_THEMES, Terrain3D, type TerrainLayer, type TerrainNav, type TerrainNavOptions, type TerrainTheme, TextureCache3D, type TextureSpec, Trail3D, Tree3D, type TreeTier, type TreeType, VOXEL_PALETTE, type VoxelBlock, VoxelGrid3D, WATER_CUTOUT_MAX, WATER_MAX_RIPPLES, Water3D, WaterCutout3D, acquireOwnTexture, acquireTexture, applyQualityTier3D, buildHeightmap, buildRiverRings, buildTerrainNav, cameraRelative, createGame3D, createNavDebugNode, diffSignatures, diffText, enablePhysics3D, findRiverCoverageGaps, frameSignature, frameStats, frameText, horizonColorFromSky, keyboardIntensity, modelVerdict, movementState, parseEnvironment3D, projectToRiver, registerNodes3D, resolveFlowerDensity, rigPose, riverCarveChannels, riverStepFor, setEnvironment3D, smoothCourse, splatWeights, sunDirectionFromElevationAzimuth, sunDirectionFromSky, syncTree, terrainThemeLayers, traceDownhillPath, verdictText };
|
package/dist/3d.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { c as parseEnvironment3D, l as sunDirectionFromElevationAzimuth, s as horizonColorFromSky, u as sunDirectionFromSky } from "./loader-
|
|
1
|
+
import { c as parseEnvironment3D, l as sunDirectionFromElevationAzimuth, s as horizonColorFromSky, u as sunDirectionFromSky } from "./loader-KZESOZmE.js";
|
|
2
2
|
import { a as frameSignature, n as diffSignatures, o as frameStats, r as diffText, s as frameText, t as SIGNATURE_GRID } from "./frame-report-BSMny7oe.js";
|
|
3
|
-
import {
|
|
4
|
-
import { A as Terrain3D, B as keyboardIntensity, C as resolveFlowerDensity, D as BoneLookAt3D, E as Camera3D, F as InstancedMesh3D, G as acquireTexture, H as rigPose, I as MeshInstance3D, M as TERRAIN_THEMES, N as terrainThemeLayers, O as BoneAttachment3D, P as Joint3D, R as QUARTER_PITCH, S as Flowers3D, T as CharacterController3D, U as TextureCache3D, V as movementState, W as acquireOwnTexture, _ as LoftMesh3D, a as Tree3D, b as Foliage3D, c as buildRiverRings, d as riverCarveChannels, f as riverStepFor, g as ModelInstance3D, h as Particles3D, i as VoxelGrid3D, j as DEFAULT_TERRAIN_TEXTURE_BASE, k as Billboard3D, l as findRiverCoverageGaps, m as traceDownhillPath, n as registerNodes3D, o as Trail3D, p as smoothCourse, r as VOXEL_PALETTE, s as River3D, u as projectToRiver, v as DirectionalLight3D, w as FLOWER_VARIETIES, x as DENSITY_PRESETS, y as OmniLight3D, z as cameraRelative } from "./environment-presets-
|
|
5
|
-
import { a as Environment3D, i as syncTree, o as
|
|
3
|
+
import { G as StaticBody3D, H as CharacterBody3D, K as Node3D, L as Water3D, R as WATER_CUTOUT_MAX, U as PhysicsBody3D, V as Area3D, W as RigidBody3D, Y as WATER_MAX_RIPPLES, z as WaterCutout3D } from "./gameplay-CGSv-9XR.js";
|
|
4
|
+
import { A as Terrain3D, B as keyboardIntensity, C as resolveFlowerDensity, D as BoneLookAt3D, E as Camera3D, F as InstancedMesh3D, G as acquireTexture, H as rigPose, I as MeshInstance3D, M as TERRAIN_THEMES, N as terrainThemeLayers, O as BoneAttachment3D, P as Joint3D, R as QUARTER_PITCH, S as Flowers3D, T as CharacterController3D, U as TextureCache3D, V as movementState, W as acquireOwnTexture, _ as LoftMesh3D, a as Tree3D, b as Foliage3D, c as buildRiverRings, d as riverCarveChannels, f as riverStepFor, g as ModelInstance3D, h as Particles3D, i as VoxelGrid3D, j as DEFAULT_TERRAIN_TEXTURE_BASE, k as Billboard3D, l as findRiverCoverageGaps, m as traceDownhillPath, n as registerNodes3D, o as Trail3D, p as smoothCourse, r as VOXEL_PALETTE, s as River3D, u as projectToRiver, v as DirectionalLight3D, w as FLOWER_VARIETIES, x as DENSITY_PRESETS, y as OmniLight3D, z as cameraRelative } from "./environment-presets-C-5g2pMh.js";
|
|
5
|
+
import { a as Environment3D, c as AssetStore3D, i as syncTree, o as applyQualityTier3D, r as Renderer3D, s as setEnvironment3D, t as createGame3D } from "./create-game-FAXdHta3.js";
|
|
6
6
|
import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
|
|
7
|
-
import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-
|
|
7
|
+
import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-i1IeAY0F.js";
|
|
8
8
|
//#region src/3d/model-verdict.ts
|
|
9
9
|
/** Mixamo exports every bone as `mixamorigX`; the retargeter binds by that name. */
|
|
10
10
|
const MIXAMO = /^mixamorig[:_]?/i;
|
|
@@ -317,4 +317,4 @@ function createNavDebugNode(nav, opts) {
|
|
|
317
317
|
return node;
|
|
318
318
|
}
|
|
319
319
|
//#endregion
|
|
320
|
-
export { Area3D, AssetStore3D, Billboard3D, BoneAttachment3D, BoneLookAt3D, Camera3D, CharacterBody3D, CharacterController3D, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, Environment3D, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, Flowers3D, Foliage3D, InstancedMesh3D, Joint3D, LoftMesh3D, MeshInstance3D, ModelInstance3D, Node3D, OmniLight3D, Particles3D, Physics3D, PhysicsBody3D, QUARTER_PITCH, Renderer3D, RigidBody3D, River3D, SIGNATURE_GRID, StaticBody3D, TERRAIN_THEMES, Terrain3D, TextureCache3D, Trail3D, Tree3D, VOXEL_PALETTE, VoxelGrid3D, WATER_CUTOUT_MAX, WATER_MAX_RIPPLES, Water3D, WaterCutout3D, acquireOwnTexture, acquireTexture, buildHeightmap, buildRiverRings, buildTerrainNav, cameraRelative, createGame3D, createNavDebugNode, diffSignatures, diffText, enablePhysics3D, findRiverCoverageGaps, frameSignature, frameStats, frameText, horizonColorFromSky, keyboardIntensity, modelVerdict, movementState, parseEnvironment3D, projectToRiver, registerNodes3D, resolveFlowerDensity, rigPose, riverCarveChannels, riverStepFor, setEnvironment3D, smoothCourse, splatWeights, sunDirectionFromElevationAzimuth, sunDirectionFromSky, syncTree, terrainThemeLayers, traceDownhillPath, verdictText };
|
|
320
|
+
export { Area3D, AssetStore3D, Billboard3D, BoneAttachment3D, BoneLookAt3D, Camera3D, CharacterBody3D, CharacterController3D, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, Environment3D, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, Flowers3D, Foliage3D, InstancedMesh3D, Joint3D, LoftMesh3D, MeshInstance3D, ModelInstance3D, Node3D, OmniLight3D, Particles3D, Physics3D, PhysicsBody3D, QUARTER_PITCH, Renderer3D, RigidBody3D, River3D, SIGNATURE_GRID, StaticBody3D, TERRAIN_THEMES, Terrain3D, TextureCache3D, Trail3D, Tree3D, VOXEL_PALETTE, VoxelGrid3D, WATER_CUTOUT_MAX, WATER_MAX_RIPPLES, Water3D, WaterCutout3D, acquireOwnTexture, acquireTexture, applyQualityTier3D, buildHeightmap, buildRiverRings, buildTerrainNav, cameraRelative, createGame3D, createNavDebugNode, diffSignatures, diffText, enablePhysics3D, findRiverCoverageGaps, frameSignature, frameStats, frameText, horizonColorFromSky, keyboardIntensity, modelVerdict, movementState, parseEnvironment3D, projectToRiver, registerNodes3D, resolveFlowerDensity, rigPose, riverCarveChannels, riverStepFor, setEnvironment3D, smoothCourse, splatWeights, sunDirectionFromElevationAzimuth, sunDirectionFromSky, syncTree, terrainThemeLayers, traceDownhillPath, verdictText };
|
|
@@ -16,6 +16,15 @@ declare class Signal<Args extends unknown[] = unknown[]> {
|
|
|
16
16
|
}): () => void;
|
|
17
17
|
disconnect(fn: SignalListener<Args>): void;
|
|
18
18
|
disconnectAll(): void;
|
|
19
|
+
/**
|
|
20
|
+
* How many listeners are attached.
|
|
21
|
+
*
|
|
22
|
+
* A leak is a SLOPE, and a game had no way to see one: every check in this
|
|
23
|
+
* engine is a snapshot. A handler connected per frame and never disconnected,
|
|
24
|
+
* or a `once` that armed and never fired, accumulates invisibly and is
|
|
25
|
+
* perfectly healthy for the first thirty seconds of every playthrough.
|
|
26
|
+
*/
|
|
27
|
+
get count(): number;
|
|
19
28
|
emit(...args: Args): void;
|
|
20
29
|
get connectionCount(): number;
|
|
21
30
|
}
|
|
@@ -247,6 +256,14 @@ declare class Node implements NodeLifecycle {
|
|
|
247
256
|
once?: boolean;
|
|
248
257
|
}): () => void;
|
|
249
258
|
off(signal: string, fn: SignalListener<unknown[]>): void;
|
|
259
|
+
/**
|
|
260
|
+
* How many listeners this node has on `signal` — 0 for one nobody watches.
|
|
261
|
+
*
|
|
262
|
+
* The engine's own leak test reads it, and so can a game: a handler connected
|
|
263
|
+
* every frame and never disconnected is invisible to every other check here,
|
|
264
|
+
* because every other check is a snapshot and a leak is a slope.
|
|
265
|
+
*/
|
|
266
|
+
listenerCount(signal: string): number;
|
|
250
267
|
emit(signal: string, ...args: unknown[]): void;
|
|
251
268
|
/**
|
|
252
269
|
* Defer destruction to the end of the current update pass (flushed by the
|
|
@@ -1220,7 +1237,8 @@ interface RestoreReport {
|
|
|
1220
1237
|
declare function captureBehaviors(root: Node, source?: JsonValue): {
|
|
1221
1238
|
state: BehaviorState; /** Paths of nodes that had state to save and no uid to save it under. */
|
|
1222
1239
|
unaddressable: string[]; /** Behaviors in this tree that have something to save — addressable or not. */
|
|
1223
|
-
saveable: number;
|
|
1240
|
+
saveable: number; /** Authored nodes this run consumed that the `#freed` ledger cannot record. */
|
|
1241
|
+
unrecordable: string[];
|
|
1224
1242
|
};
|
|
1225
1243
|
/**
|
|
1226
1244
|
* Hand each behavior its state back.
|
|
@@ -1600,6 +1618,26 @@ interface EngineOptions {
|
|
|
1600
1618
|
seed?: number;
|
|
1601
1619
|
/** Frame cap in fps; 0 (default) runs at whatever the display offers. */
|
|
1602
1620
|
maxFps?: number;
|
|
1621
|
+
/**
|
|
1622
|
+
* Which SETTINGS this game owns — its own, or the origin's.
|
|
1623
|
+
*
|
|
1624
|
+
* Persisted settings are keyed `incanto:<namespace>:<key>` in the browser's
|
|
1625
|
+
* storage, and this defaulted to `settings` with no way to change it. So two
|
|
1626
|
+
* Incanto games served from one domain shared one volume slider, one language
|
|
1627
|
+
* and one quality tier. Measured: game A's player sets
|
|
1628
|
+
* `renderScale 0.25, muted, quality low`; game B — whose source never mentions
|
|
1629
|
+
* settings — boots at a 480×232 drawing buffer, silent.
|
|
1630
|
+
*
|
|
1631
|
+
* `SaveSlots(namespace)` and `createSaveStore(namespace)` have always taken
|
|
1632
|
+
* one and document it as "keeps two games on one origin apart". This is the
|
|
1633
|
+
* third sibling finally saying the same thing.
|
|
1634
|
+
*
|
|
1635
|
+
* Pass a `Settings` instance instead when a game wants to share deliberately
|
|
1636
|
+
* (a launcher and its titles), or drive them from its own store.
|
|
1637
|
+
*/
|
|
1638
|
+
settings?: Settings | {
|
|
1639
|
+
namespace: string;
|
|
1640
|
+
};
|
|
1603
1641
|
}
|
|
1604
1642
|
/**
|
|
1605
1643
|
* The game loop: drives a Scene's tree with fixed-timestep `fixedUpdate`
|
|
@@ -1649,6 +1687,25 @@ declare class Engine {
|
|
|
1649
1687
|
* and cleared on dispose; null when nothing renders (headless).
|
|
1650
1688
|
*/
|
|
1651
1689
|
picker: ((x: number, y: number) => Node | null) | null;
|
|
1690
|
+
/** Frames the engine has stepped — monotonic, and the pick cache's key. */
|
|
1691
|
+
frameNumber: number;
|
|
1692
|
+
/** @internal frame number + answer, so N Clickables cost ONE raycast. */
|
|
1693
|
+
private pickCacheFrame;
|
|
1694
|
+
private pickCacheKey;
|
|
1695
|
+
private pickCacheHit;
|
|
1696
|
+
/**
|
|
1697
|
+
* The node under (x, y), answered at most ONCE per frame per cursor position.
|
|
1698
|
+
*
|
|
1699
|
+
* `Clickable` asks every frame, and a board game has one per cell: 42 pads
|
|
1700
|
+
* measured **420 picker calls over ten frames** — one GPU raycast per pad per
|
|
1701
|
+
* frame, all answering the same question about the same pixel. At 60 fps that
|
|
1702
|
+
* is ~2500 raycasts a second to find out what the cursor is on, and a 200-tile
|
|
1703
|
+
* board was unusable.
|
|
1704
|
+
*
|
|
1705
|
+
* Cached on (frame, x, y), so a game that picks at two different points in one
|
|
1706
|
+
* frame still gets two real answers.
|
|
1707
|
+
*/
|
|
1708
|
+
pickAt(x: number, y: number): Node | null;
|
|
1652
1709
|
/** Global volume buses — `master` × `sfx`/`music` gain + `muted`. AudioPlayer
|
|
1653
1710
|
* routes its volume through this; games set it for global volume/mute. */
|
|
1654
1711
|
readonly audio: AudioBuses;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { d as computeViewport, f as resolveViewport, k as diagnose, n as loadScene, z as registerBehavior } from "./loader-
|
|
3
|
-
import { _ as AudioPlayer, v as Engine } from "./register-
|
|
2
|
+
import { d as computeViewport, f as resolveViewport, k as diagnose, n as loadScene, z as registerBehavior } from "./loader-KZESOZmE.js";
|
|
3
|
+
import { _ as AudioPlayer, v as Engine } from "./register-Cs53CY7s.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { n as attachTouchControls } from "./touch-DEAmqGdf.js";
|
|
6
|
+
import { t as resolveRendering } from "./rendering-options-ByAdi8PF.js";
|
|
7
|
+
import { a as openBundledEditor, c as claimCanvasGestures, i as devServerLibrary, l as audioErrors, n as pauseWhenHidden, r as crossFade, s as wireDevChannel, t as teardown } from "./teardown-LB9cTnXJ.js";
|
|
7
8
|
import { o as frameStats } from "./frame-report-BSMny7oe.js";
|
|
8
|
-
import { n as registerGameplayBehaviors } from "./gameplay-
|
|
9
|
-
import { g as PhysicsBody2D, n as UILayer, t as registerNodes2D, u as Camera2D, y as Node2D } from "./register-
|
|
9
|
+
import { n as registerGameplayBehaviors } from "./gameplay-CGSv-9XR.js";
|
|
10
|
+
import { g as PhysicsBody2D, n as UILayer, t as registerNodes2D, u as Camera2D, y as Node2D } from "./register-vIxU3Xbv.js";
|
|
10
11
|
import { t as debugSources } from "./debug-draw-BM3DsvtT.js";
|
|
11
|
-
import { n as enablePhysics2D } from "./physics-2d-
|
|
12
|
+
import { n as enablePhysics2D } from "./physics-2d-_B6zj3zU.js";
|
|
12
13
|
import { Box3, BufferAttribute, BufferGeometry, Color, LineBasicMaterial, LineSegments, LinearFilter, NearestFilter, OrthographicCamera, Raycaster, SRGBColorSpace, Scene, TextureLoader, Vector2, Vector3, WebGLRenderer } from "three";
|
|
13
14
|
//#region src/2d/assets.ts
|
|
14
15
|
/**
|
|
@@ -756,6 +757,7 @@ async function createGame2D(opts) {
|
|
|
756
757
|
const engine = new Engine({
|
|
757
758
|
seed: opts.seed,
|
|
758
759
|
fixedHz: opts.fixedHz,
|
|
760
|
+
...opts.settings ? { settings: opts.settings } : {},
|
|
759
761
|
...opts._scheduler ? { scheduler: opts._scheduler } : {}
|
|
760
762
|
});
|
|
761
763
|
const sourceJson = cloneSceneJson(opts.scene);
|
|
@@ -918,7 +920,11 @@ async function createGame2D(opts) {
|
|
|
918
920
|
}
|
|
919
921
|
return {
|
|
920
922
|
engine,
|
|
921
|
-
scene
|
|
923
|
+
get scene() {
|
|
924
|
+
const live = engine.scene;
|
|
925
|
+
if (!live) throw new IncantoError("TREE_VIOLATION", "game.scene: the engine has no scene.");
|
|
926
|
+
return live;
|
|
927
|
+
},
|
|
922
928
|
sourceJson,
|
|
923
929
|
renderer,
|
|
924
930
|
physics,
|