incanto 0.42.0 → 0.43.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/incanto-feel.mjs +20 -1
- package/dist/2d.js +1 -1
- package/dist/3d.js +4 -4
- package/dist/{create-game-DItIRyXH.js → create-game-B3vBWgVD.js} +5 -4
- package/dist/{create-game-9KPppR0L.js → create-game-DFRbG0Bj.js} +3 -2
- package/dist/{environment-presets-Vl5xBsXp.js → environment-presets-Ds5kXLoF.js} +1 -1
- package/dist/{gameplay-DRi9524r.js → gameplay-BQOeAid6.js} +37 -0
- package/dist/gameplay.d.ts +17 -0
- package/dist/gameplay.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{physics-3d-C2G604O1.js → physics-3d-CLPFv99o.js} +2 -2
- package/dist/react.js +1 -1
- package/dist/{src-cU57Uwdw.js → src-CwYxzZKl.js} +1 -1
- package/dist/{teardown-CCtAMDLB.js → teardown-yePMOE1K.js} +32 -1
- package/dist/{test-DuOD1DO8.js → test-BMgiiD5i.js} +117 -5
- package/dist/test.d.ts +35 -1
- package/dist/test.js +2 -2
- package/dist/vite.js +2 -2
- package/editor/assets/{agent8-Csw0T7jh.js → agent8-Cl3qFuBB.js} +1 -1
- package/editor/assets/{debug-C3qeBD4X.js → debug-u3yLCciO.js} +1 -1
- package/editor/assets/{index-B1rUkWxB.js → index-Dk2ZlO68.js} +60 -60
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/skills/incanto-3d-character.md +19 -0
- package/skills/incanto-gameplay-behaviors.md +27 -0
- package/skills/incanto-node-reference.md +2 -0
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/beacon-isle-3d/src/game.scene.json +47 -0
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/tps-3d/src/game.scene.json +53 -0
- package/templates-app/village-quest-3d/package.json +1 -1
- package/templates-app/village-quest-3d/src/grove.scene.json +43 -0
package/bin/incanto-feel.mjs
CHANGED
|
@@ -52,7 +52,9 @@ if (args.help || !args.scene) {
|
|
|
52
52
|
process.exit(args.help && args.scene !== undefined ? 0 : 1);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const { feelReport, feelText } = await import(
|
|
55
|
+
const { facingReport, facingText, feelReport, feelText } = await import(
|
|
56
|
+
pathToFileURL(join(PKG, 'dist', 'test.js')).href
|
|
57
|
+
);
|
|
56
58
|
const incanto = await import(pathToFileURL(join(PKG, 'dist', 'index.js')).href);
|
|
57
59
|
|
|
58
60
|
const behaviors = {};
|
|
@@ -90,4 +92,21 @@ try {
|
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
process.stdout.write(args.json ? `${JSON.stringify(report, null, 2)}\n` : `${feelText(report)}\n`);
|
|
95
|
+
|
|
96
|
+
// "It runs backwards" is this repo's most repeated 3D bug and the check is one
|
|
97
|
+
// dot product — which nobody runs by hand. It rides along here because this is
|
|
98
|
+
// already the command that drives the character.
|
|
99
|
+
if (!args.json) {
|
|
100
|
+
try {
|
|
101
|
+
const facing = await facingReport(sceneJson, {
|
|
102
|
+
behaviors,
|
|
103
|
+
stubMissingBehaviors: !args.behaviors,
|
|
104
|
+
resolveScene: (p) => JSON.parse(readFileSync(resolve(sceneDir, p), 'utf-8')),
|
|
105
|
+
});
|
|
106
|
+
if (facing.skin) process.stdout.write(`${facingText(facing)}\n`);
|
|
107
|
+
} catch {
|
|
108
|
+
// a scene this probe cannot drive is not a failing scene
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
93
112
|
process.exit(report.player ? 0 : 1);
|
package/dist/2d.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
2
|
-
import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-
|
|
2
|
+
import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-DFRbG0Bj.js";
|
|
3
3
|
import { _ as RigidBody2D, a as parseCells, c as ColorRect2D, d as AnimatedSprite2D, f as Sprite2D, g as PhysicsBody2D, h as CharacterBody2D, i as mergeSolidRects, l as CharacterController2D, m as Area2D, n as UILayer, o as Particles2D, p as Joint2D, r as TileMap2D, s as Label, t as registerNodes2D, u as Camera2D, v as StaticBody2D, y as Node2D } from "./register-R2JTnIMw.js";
|
|
4
4
|
import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-BmgXBNDB.js";
|
|
5
5
|
//#region src/2d/library-sprite.ts
|
package/dist/3d.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { A as Water3D, F as PhysicsBody3D, I as RigidBody3D, L as StaticBody3D, M as WaterCutout3D, N as Area3D, P as CharacterBody3D, R as Node3D, V as WATER_MAX_RIPPLES, j as WATER_CUTOUT_MAX } from "./gameplay-
|
|
2
|
-
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-
|
|
3
|
-
import { a as Environment3D, c as setEnvironment3D, d as sunDirectionFromElevationAzimuth, f as sunDirectionFromSky, i as syncTree, l as horizonColorFromSky, o as frameStats, p as AssetStore3D, r as Renderer3D, s as frameText, t as createGame3D, u as parseEnvironment3D } from "./create-game-
|
|
1
|
+
import { A as Water3D, F as PhysicsBody3D, I as RigidBody3D, L as StaticBody3D, M as WaterCutout3D, N as Area3D, P as CharacterBody3D, R as Node3D, V as WATER_MAX_RIPPLES, j as WATER_CUTOUT_MAX } from "./gameplay-BQOeAid6.js";
|
|
2
|
+
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-Ds5kXLoF.js";
|
|
3
|
+
import { a as Environment3D, c as setEnvironment3D, d as sunDirectionFromElevationAzimuth, f as sunDirectionFromSky, i as syncTree, l as horizonColorFromSky, o as frameStats, p as AssetStore3D, r as Renderer3D, s as frameText, t as createGame3D, u as parseEnvironment3D } from "./create-game-B3vBWgVD.js";
|
|
4
4
|
import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
|
|
5
|
-
import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-
|
|
5
|
+
import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-CLPFv99o.js";
|
|
6
6
|
//#region src/3d/terrain-nav.ts
|
|
7
7
|
function buildTerrainNav(terrain, opts) {
|
|
8
8
|
const cellSize = opts?.cellSize ?? 2;
|
|
@@ -3,11 +3,11 @@ import { n as loadScene, v as diagnose, w as registerBehavior } from "./loader-r
|
|
|
3
3
|
import { _ as qualityCaps, h as Engine, m as AudioPlayer, y as qualityRendering } from "./register-BSXV8T9F.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
5
|
import { i as resolveRendering, n as attachTouchControls } from "./touch-BoNg_MnF.js";
|
|
6
|
-
import { a as
|
|
7
|
-
import { B as createCausticsQuad, F as PhysicsBody3D, R as Node3D, n as registerGameplayBehaviors } from "./gameplay-
|
|
6
|
+
import { a as openBundledEditor, i as devServerLibrary, n as pauseWhenHidden, o as poseFromRenderer, r as crossFade, t as teardown } from "./teardown-yePMOE1K.js";
|
|
7
|
+
import { B as createCausticsQuad, F as PhysicsBody3D, R as Node3D, n as registerGameplayBehaviors } from "./gameplay-BQOeAid6.js";
|
|
8
8
|
import { t as debugSources } from "./debug-draw-BM3DsvtT.js";
|
|
9
|
-
import { E as Camera3D, U as TextureCache3D, g as ModelInstance3D, n as registerNodes3D, t as resolveEnvironmentHdri, v as DirectionalLight3D } from "./environment-presets-
|
|
10
|
-
import { n as enablePhysics3D } from "./physics-3d-
|
|
9
|
+
import { E as Camera3D, U as TextureCache3D, g as ModelInstance3D, n as registerNodes3D, t as resolveEnvironmentHdri, v as DirectionalLight3D } from "./environment-presets-Ds5kXLoF.js";
|
|
10
|
+
import { n as enablePhysics3D } from "./physics-3d-CLPFv99o.js";
|
|
11
11
|
import { ACESFilmicToneMapping, AmbientLight, Box3, BufferAttribute, BufferGeometry, Color, DepthTexture, EquirectangularReflectionMapping, FloatType, Fog, HalfFloatType, LineBasicMaterial, LineSegments, Matrix4, Mesh, PCFShadowMap, PMREMGenerator, PerspectiveCamera, PlaneGeometry, Quaternion, Raycaster, Scene, ShaderMaterial, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer } from "three";
|
|
12
12
|
import { VRMLoaderPlugin, VRMUtils } from "@pixiv/three-vrm";
|
|
13
13
|
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
|
|
@@ -2525,6 +2525,7 @@ async function createGame3D(opts) {
|
|
|
2525
2525
|
hot.on("incanto:frame-request", onFrameRequest);
|
|
2526
2526
|
cleanups.push(() => hot.off?.("incanto:frame-request", onFrameRequest));
|
|
2527
2527
|
}
|
|
2528
|
+
cleanups.push(pauseWhenHidden(engine));
|
|
2528
2529
|
await report(1, "ready");
|
|
2529
2530
|
function disposeGame() {
|
|
2530
2531
|
teardown([
|
|
@@ -3,8 +3,8 @@ import { n as loadScene, o as computeViewport, s as resolveViewport, v as diagno
|
|
|
3
3
|
import { h as Engine, m as AudioPlayer } from "./register-BSXV8T9F.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
5
|
import { i as resolveRendering, n as attachTouchControls } from "./touch-BoNg_MnF.js";
|
|
6
|
-
import {
|
|
7
|
-
import { n as registerGameplayBehaviors } from "./gameplay-
|
|
6
|
+
import { a as openBundledEditor, i as devServerLibrary, n as pauseWhenHidden, r as crossFade, t as teardown } from "./teardown-yePMOE1K.js";
|
|
7
|
+
import { n as registerGameplayBehaviors } from "./gameplay-BQOeAid6.js";
|
|
8
8
|
import { g as PhysicsBody2D, n as UILayer, t as registerNodes2D, u as Camera2D, y as Node2D } from "./register-R2JTnIMw.js";
|
|
9
9
|
import { t as debugSources } from "./debug-draw-BM3DsvtT.js";
|
|
10
10
|
import { n as enablePhysics2D } from "./physics-2d-BmgXBNDB.js";
|
|
@@ -545,6 +545,7 @@ async function createGame2D(opts) {
|
|
|
545
545
|
if (keyboard) engine.input.attachKeyboard(keyboard);
|
|
546
546
|
cleanups.push(wireAudioUnlock(engine, scene.root, opts.canvas));
|
|
547
547
|
cleanups.push(engine.settings.bindAudio(engine.audio));
|
|
548
|
+
cleanups.push(pauseWhenHidden(engine));
|
|
548
549
|
cleanups.push(engine.settings.bindLocale(engine.locale));
|
|
549
550
|
const touchMode = opts.touch ?? "auto";
|
|
550
551
|
if (touchMode !== false) {
|
|
@@ -4,7 +4,7 @@ import { t as Rng } from "./rng-DP-SR7eg.js";
|
|
|
4
4
|
import { i as getNodeSchema, l as registerNode } from "./registry-IyWCGe4q.js";
|
|
5
5
|
import { t as createNoise2D } from "./noise-CGUMx44x.js";
|
|
6
6
|
import { i as applyParticlePreset, r as PARTICLE_PRESET_NAMES, t as ParticleSim } from "./particle-sim-Bw7hB93B.js";
|
|
7
|
-
import { A as Water3D, F as PhysicsBody3D, H as colliderFootDrop, I as RigidBody3D, L as StaticBody3D, M as WaterCutout3D, N as Area3D, P as CharacterBody3D, R as Node3D } from "./gameplay-
|
|
7
|
+
import { A as Water3D, F as PhysicsBody3D, H as colliderFootDrop, I as RigidBody3D, L as StaticBody3D, M as WaterCutout3D, N as Area3D, P as CharacterBody3D, R as Node3D } from "./gameplay-BQOeAid6.js";
|
|
8
8
|
import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
|
|
9
9
|
import { AdditiveBlending, AnimationClip, AnimationMixer, Box3, BoxGeometry, BufferAttribute, BufferGeometry, CanvasTexture, CapsuleGeometry, ClampToEdgeWrapping, Color, ConeGeometry, CylinderGeometry, DataTexture, DirectionalLight, DoubleSide, DynamicDrawUsage, Euler, Group, IcosahedronGeometry, ImageBitmapLoader, InstancedBufferAttribute, InstancedMesh, LinearFilter, LinearMipmapLinearFilter, LoopOnce, LoopRepeat, Matrix4, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshPhysicalMaterial, MeshStandardMaterial, NearestFilter, NoBlending, NoColorSpace, NormalBlending, PerspectiveCamera, PlaneGeometry, PointLight, Points, PointsMaterial, Quaternion, QuaternionKeyframeTrack, RGBADepthPacking, RGBAFormat, RepeatWrapping, SRGBColorSpace, ShaderChunk, ShaderMaterial, SphereGeometry, Texture, TextureLoader, UniformsLib, UniformsUtils, Vector3, Vector4, VectorKeyframeTrack } from "three";
|
|
10
10
|
import { clone } from "three/addons/utils/SkeletonUtils.js";
|
|
@@ -4973,10 +4973,15 @@ var GameFlow = class extends Behavior {
|
|
|
4973
4973
|
static signals = ["flowChanged"];
|
|
4974
4974
|
static props = {
|
|
4975
4975
|
restartAction: { default: "restart" },
|
|
4976
|
+
pauseAction: { default: "pause" },
|
|
4976
4977
|
freezeOnEnd: { default: true },
|
|
4977
4978
|
bannerPath: {
|
|
4978
4979
|
default: "%Banner",
|
|
4979
4980
|
nodePath: true
|
|
4981
|
+
},
|
|
4982
|
+
pausePanelPath: {
|
|
4983
|
+
default: "%PauseMenu",
|
|
4984
|
+
nodePath: true
|
|
4980
4985
|
}
|
|
4981
4986
|
};
|
|
4982
4987
|
/** Input action that restarts from gameover/won (declare it in `input{}`). */
|
|
@@ -4985,8 +4990,31 @@ var GameFlow = class extends Behavior {
|
|
|
4985
4990
|
freezeOnEnd = true;
|
|
4986
4991
|
/** Where the flow looks for a UiBanner ('' = never). */
|
|
4987
4992
|
bannerPath = "%Banner";
|
|
4993
|
+
/**
|
|
4994
|
+
* Input action that toggles pause (declare it in `input{}`; undeclared is
|
|
4995
|
+
* fine and means pause is API-only).
|
|
4996
|
+
*/
|
|
4997
|
+
pauseAction = "pause";
|
|
4998
|
+
/**
|
|
4999
|
+
* A node shown while paused and hidden otherwise — a `UiPanel` of buttons in
|
|
5000
|
+
* practice. '' turns the whole thing off.
|
|
5001
|
+
*
|
|
5002
|
+
* This lives here rather than in each game because it is identical in all of
|
|
5003
|
+
* them, and a pause menu that costs a script is a pause menu no generated
|
|
5004
|
+
* game will have. `UiPanel` appeared in zero template scenes before this.
|
|
5005
|
+
*/
|
|
5006
|
+
pausePanelPath = "%PauseMenu";
|
|
4988
5007
|
state = "playing";
|
|
4989
5008
|
frozeScale = false;
|
|
5009
|
+
onReady() {
|
|
5010
|
+
this.syncPausePanel();
|
|
5011
|
+
}
|
|
5012
|
+
/** The panel follows the state; nothing else may own its visibility. */
|
|
5013
|
+
syncPausePanel() {
|
|
5014
|
+
if (this.pausePanelPath === "") return;
|
|
5015
|
+
const panel = this.node.getNodeOrNull(this.pausePanelPath);
|
|
5016
|
+
if (panel && "visible" in panel) panel.visible = this.state === "paused";
|
|
5017
|
+
}
|
|
4990
5018
|
gameOver(text = "GAME OVER", color = "#ef4444") {
|
|
4991
5019
|
this.transition("gameover", text, color);
|
|
4992
5020
|
}
|
|
@@ -4997,12 +5025,14 @@ var GameFlow = class extends Behavior {
|
|
|
4997
5025
|
if (this.state !== "playing") return;
|
|
4998
5026
|
this.state = "paused";
|
|
4999
5027
|
this.freeze();
|
|
5028
|
+
this.syncPausePanel();
|
|
5000
5029
|
this.node.emit("flowChanged", this.state);
|
|
5001
5030
|
}
|
|
5002
5031
|
resume() {
|
|
5003
5032
|
if (this.state !== "paused") return;
|
|
5004
5033
|
this.state = "playing";
|
|
5005
5034
|
this.thaw();
|
|
5035
|
+
this.syncPausePanel();
|
|
5006
5036
|
this.node.emit("flowChanged", this.state);
|
|
5007
5037
|
}
|
|
5008
5038
|
restart() {
|
|
@@ -5035,6 +5065,13 @@ var GameFlow = class extends Behavior {
|
|
|
5035
5065
|
this.engine.timeScale = 1;
|
|
5036
5066
|
}
|
|
5037
5067
|
update() {
|
|
5068
|
+
if (this.state === "playing" || this.state === "paused") {
|
|
5069
|
+
try {
|
|
5070
|
+
if (this.engine.input.justPressed(this.pauseAction)) if (this.state === "playing") this.pause();
|
|
5071
|
+
else this.resume();
|
|
5072
|
+
} catch {}
|
|
5073
|
+
return;
|
|
5074
|
+
}
|
|
5038
5075
|
if (this.state !== "gameover" && this.state !== "won") return;
|
|
5039
5076
|
try {
|
|
5040
5077
|
if (this.engine.input.justPressed(this.restartAction)) this.restart();
|
package/dist/gameplay.d.ts
CHANGED
|
@@ -622,8 +622,25 @@ declare class GameFlow extends Behavior {
|
|
|
622
622
|
freezeOnEnd: boolean;
|
|
623
623
|
/** Where the flow looks for a UiBanner ('' = never). */
|
|
624
624
|
bannerPath: string;
|
|
625
|
+
/**
|
|
626
|
+
* Input action that toggles pause (declare it in `input{}`; undeclared is
|
|
627
|
+
* fine and means pause is API-only).
|
|
628
|
+
*/
|
|
629
|
+
pauseAction: string;
|
|
630
|
+
/**
|
|
631
|
+
* A node shown while paused and hidden otherwise — a `UiPanel` of buttons in
|
|
632
|
+
* practice. '' turns the whole thing off.
|
|
633
|
+
*
|
|
634
|
+
* This lives here rather than in each game because it is identical in all of
|
|
635
|
+
* them, and a pause menu that costs a script is a pause menu no generated
|
|
636
|
+
* game will have. `UiPanel` appeared in zero template scenes before this.
|
|
637
|
+
*/
|
|
638
|
+
pausePanelPath: string;
|
|
625
639
|
state: GameFlowState;
|
|
626
640
|
private frozeScale;
|
|
641
|
+
override onReady(): void;
|
|
642
|
+
/** The panel follows the state; nothing else may own its visibility. */
|
|
643
|
+
private syncPausePanel;
|
|
627
644
|
gameOver(text?: string, color?: string): void;
|
|
628
645
|
win(text?: string, color?: string): void;
|
|
629
646
|
pause(): void;
|
package/dist/gameplay.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as FollowCamera, D as Health, E as DamageOnContact, O as Collector, S as restartScene, T as phaseOf, _ as hitStop, a as Wander, b as GameFlow, c as Projectile, d as PathFollow, f as Oscillate, g as Cooldown, h as CameraShake, i as WaveSpawner, k as Chase, l as Pickup, m as Lifetime, n as registerGameplayBehaviors, o as Spawner, p as MoveTo, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Patrol, v as screenFlash, w as DayNight, x as goToScene, y as Interactable } from "./gameplay-
|
|
1
|
+
import { C as FollowCamera, D as Health, E as DamageOnContact, O as Collector, S as restartScene, T as phaseOf, _ as hitStop, a as Wander, b as GameFlow, c as Projectile, d as PathFollow, f as Oscillate, g as Cooldown, h as CameraShake, i as WaveSpawner, k as Chase, l as Pickup, m as Lifetime, n as registerGameplayBehaviors, o as Spawner, p as MoveTo, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Patrol, v as screenFlash, w as DayNight, x as goToScene, y as Interactable } from "./gameplay-BQOeAid6.js";
|
|
2
2
|
export { CameraShake, Chase, Collector, Cooldown, DamageOnContact, DayNight, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, Projectile, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, phaseOf, registerGameplayBehaviors, restartScene, screenFlash };
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-BLk7H2Qa.
|
|
|
7
7
|
import { a as getNodeSignals, c as mergeStaticSignals, i as getNodeSchema, l as registerNode, n as clearRegistry, o as getNodeType, r as createNode, u as registeredTypes } from "./registry-IyWCGe4q.js";
|
|
8
8
|
import { t as createNoise2D } from "./noise-CGUMx44x.js";
|
|
9
9
|
import { i as applyParticlePreset, n as PARTICLE_PRESETS, r as PARTICLE_PRESET_NAMES, t as ParticleSim } from "./particle-sim-Bw7hB93B.js";
|
|
10
|
-
import { a as findPath, i as preloadUrls, n as newUid, o as gridFromRows, r as assetUrls, t as VERSION } from "./src-
|
|
10
|
+
import { a as findPath, i as preloadUrls, n as newUid, o as gridFromRows, r as assetUrls, t as VERSION } from "./src-CwYxzZKl.js";
|
|
11
11
|
import { i as resolveRendering, n as attachTouchControls, r as joystickVector, t as TouchControls } from "./touch-BoNg_MnF.js";
|
|
12
12
|
import { t as duplicateNode } from "./duplicate-CRtihGmC.js";
|
|
13
13
|
export { AudioBuses, AudioPlayer, BASE_LOCALE, Behavior, CONST_REF_KEY, Engine, HudLayer, IncantoError, InputMap, Localization, LogManager, MusicManager, Node, ORDER_GROUP_BASE, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, SaveSlots, Scene, SceneTree, Settings, SfxEngine, Signal, T_PREFIX, Timer, TouchControls, UiBanner, UiBar, UiButton, UiDialogue, UiImage, UiPanel, UiSelect, UiSlider, UiText, UiToggle, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, mergeStaticSignals, newUid, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveConstants, resolveOrderGroups, resolveRendering, resolveViewport, restoreBehaviors, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { v as diagnose } from "./loader-r49nDwB4.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
|
-
import { F as PhysicsBody3D, I as RigidBody3D, N as Area3D, P as CharacterBody3D, R as Node3D, z as validateCollider3D } from "./gameplay-
|
|
4
|
+
import { F as PhysicsBody3D, I as RigidBody3D, N as Area3D, P as CharacterBody3D, R as Node3D, z as validateCollider3D } from "./gameplay-BQOeAid6.js";
|
|
5
5
|
import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
|
|
6
|
-
import { A as Terrain3D, F as InstancedMesh3D, L as buildMeshGeometry, P as Joint3D } from "./environment-presets-
|
|
6
|
+
import { A as Terrain3D, F as InstancedMesh3D, L as buildMeshGeometry, P as Joint3D } from "./environment-presets-Ds5kXLoF.js";
|
|
7
7
|
import { Euler, Matrix4, Quaternion, Vector3 } from "three";
|
|
8
8
|
//#region src/3d/physics/collider-lines.ts
|
|
9
9
|
/**
|
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-B3vBWgVD.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-DFRbG0Bj.js").then((n) => n.n)).createGame2D(o)))(opts);
|
|
160
160
|
if (disposed) {
|
|
161
161
|
next.dispose();
|
|
162
162
|
return;
|
|
@@ -161,6 +161,6 @@ function newUid() {
|
|
|
161
161
|
//#endregion
|
|
162
162
|
//#region src/index.ts
|
|
163
163
|
/** Engine version. Kept in sync with package.json by the release pipeline. */
|
|
164
|
-
const VERSION = "0.
|
|
164
|
+
const VERSION = "0.43.0";
|
|
165
165
|
//#endregion
|
|
166
166
|
export { findPath as a, preloadUrls as i, newUid as n, gridFromRows as o, assetUrls as r, VERSION as t };
|
|
@@ -238,6 +238,37 @@ function poseFromRenderer(renderer, fallbackDistance = 8) {
|
|
|
238
238
|
};
|
|
239
239
|
}
|
|
240
240
|
//#endregion
|
|
241
|
+
//#region src/core/pause-when-hidden.ts
|
|
242
|
+
function pauseWhenHidden(engine, doc = typeof document === "undefined" ? null : document) {
|
|
243
|
+
if (!doc) return () => {};
|
|
244
|
+
/** The scale to come back to — null when we did not pause anything. */
|
|
245
|
+
let heldScale = null;
|
|
246
|
+
let mutedByUs = false;
|
|
247
|
+
const onChange = () => {
|
|
248
|
+
if (doc.hidden) {
|
|
249
|
+
if (heldScale === null && engine.timeScale > 0) {
|
|
250
|
+
heldScale = engine.timeScale;
|
|
251
|
+
engine.timeScale = 0;
|
|
252
|
+
}
|
|
253
|
+
if (!engine.audio.muted) {
|
|
254
|
+
engine.audio.muted = true;
|
|
255
|
+
mutedByUs = true;
|
|
256
|
+
}
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (heldScale !== null) {
|
|
260
|
+
if (engine.timeScale === 0) engine.timeScale = heldScale;
|
|
261
|
+
heldScale = null;
|
|
262
|
+
}
|
|
263
|
+
if (mutedByUs) {
|
|
264
|
+
engine.audio.muted = false;
|
|
265
|
+
mutedByUs = false;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
doc.addEventListener("visibilitychange", onChange);
|
|
269
|
+
return () => doc.removeEventListener("visibilitychange", onChange);
|
|
270
|
+
}
|
|
271
|
+
//#endregion
|
|
241
272
|
//#region src/core/teardown.ts
|
|
242
273
|
function teardown(steps, onError = defaultReport) {
|
|
243
274
|
const failures = [];
|
|
@@ -262,4 +293,4 @@ function defaultReport(what, error) {
|
|
|
262
293
|
console.error(`[incanto] teardown: ${what} failed (continuing)`, error);
|
|
263
294
|
}
|
|
264
295
|
//#endregion
|
|
265
|
-
export {
|
|
296
|
+
export { openBundledEditor as a, devServerLibrary as i, pauseWhenHidden as n, poseFromRenderer as o, crossFade as r, teardown as t };
|
|
@@ -4,9 +4,9 @@ import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
|
4
4
|
import { n as startRecording } from "./replay-DilbZgQI.js";
|
|
5
5
|
import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
|
|
6
6
|
import { i as getNodeSchema, s as mergeStaticProps } from "./registry-IyWCGe4q.js";
|
|
7
|
-
import { n as registerGameplayBehaviors } from "./gameplay-
|
|
7
|
+
import { n as registerGameplayBehaviors } from "./gameplay-BQOeAid6.js";
|
|
8
8
|
import { t as registerNodes2D } from "./register-R2JTnIMw.js";
|
|
9
|
-
import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-
|
|
9
|
+
import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-Ds5kXLoF.js";
|
|
10
10
|
import { t as registerNodesNet } from "./register-D651it1J.js";
|
|
11
11
|
import { Box3, Euler, Matrix4, PerspectiveCamera, Quaternion, Vector3 } from "three";
|
|
12
12
|
//#region src/test/framing.ts
|
|
@@ -651,6 +651,118 @@ function failingReplays(report) {
|
|
|
651
651
|
}));
|
|
652
652
|
}
|
|
653
653
|
//#endregion
|
|
654
|
+
//#region src/test/facing.ts
|
|
655
|
+
const DEG2RAD = Math.PI / 180;
|
|
656
|
+
/** The forward vector of a yaw (degrees) for a given art convention. */
|
|
657
|
+
function forwardOf(yawDeg, axis) {
|
|
658
|
+
const yaw = yawDeg * DEG2RAD;
|
|
659
|
+
const base = [Math.sin(yaw), Math.cos(yaw)];
|
|
660
|
+
switch (axis) {
|
|
661
|
+
case "-z": return [-base[0], -base[1]];
|
|
662
|
+
case "+x": return [base[1], -base[0]];
|
|
663
|
+
case "-x": return [-base[1], base[0]];
|
|
664
|
+
default: return base;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* The skin, and the yaw the art is DECLARED to be rotated by.
|
|
669
|
+
*
|
|
670
|
+
* `skinYawOffset` is how a model that does not face +Z says so, and it is the
|
|
671
|
+
* supported fix rather than a bug. Subtracting it is what stops this check
|
|
672
|
+
* crying wolf on every correctly-configured non-+Z model.
|
|
673
|
+
*/
|
|
674
|
+
function findSkin(player, explicit) {
|
|
675
|
+
if (explicit) return {
|
|
676
|
+
skin: player.getNodeOrNull(explicit) ?? null,
|
|
677
|
+
declaredOffset: 0
|
|
678
|
+
};
|
|
679
|
+
for (const child of player.children) {
|
|
680
|
+
const ctl = child;
|
|
681
|
+
if (typeof ctl.skinPath === "string" && ctl.skinPath !== "") {
|
|
682
|
+
const skin = child.getNodeOrNull(ctl.skinPath);
|
|
683
|
+
if (skin) return {
|
|
684
|
+
skin,
|
|
685
|
+
declaredOffset: ctl.skinYawOffset ?? 0
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return {
|
|
690
|
+
skin: player.getNodeOrNull("%Skin") ?? null,
|
|
691
|
+
declaredOffset: 0
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Drive the player forward and compare where the skin points with where it went.
|
|
696
|
+
*
|
|
697
|
+
* The travel direction is measured, not assumed: whatever the input map means by
|
|
698
|
+
* "up", the character ends up going somewhere, and that somewhere is the truth
|
|
699
|
+
* the art has to agree with.
|
|
700
|
+
*/
|
|
701
|
+
async function facingReport(json, opts = {}) {
|
|
702
|
+
const session = await createPlaySession(json, {
|
|
703
|
+
seed: opts.seed ?? 1,
|
|
704
|
+
...opts.behaviors ? { behaviors: opts.behaviors } : {},
|
|
705
|
+
stubMissingBehaviors: opts.stubMissingBehaviors ?? true,
|
|
706
|
+
...opts.resolveScene ? { resolveScene: opts.resolveScene } : {}
|
|
707
|
+
});
|
|
708
|
+
const player = findPlayer(session.scene.root);
|
|
709
|
+
if (!player) {
|
|
710
|
+
session.dispose();
|
|
711
|
+
return {
|
|
712
|
+
player: null,
|
|
713
|
+
skin: null,
|
|
714
|
+
dot: null,
|
|
715
|
+
backwards: false,
|
|
716
|
+
travelled: 0
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
const declared = session.engine.input.declaredActions();
|
|
720
|
+
const move = opts.moveAction ?? declared.find((a) => a.type === "vector2")?.name ?? null;
|
|
721
|
+
const posOf = () => {
|
|
722
|
+
const p = player.position;
|
|
723
|
+
return [p[0] ?? 0, p[2] ?? 0];
|
|
724
|
+
};
|
|
725
|
+
session.step(500);
|
|
726
|
+
const from = posOf();
|
|
727
|
+
if (move) session.engine.input.setActionVector(move, 1, 0);
|
|
728
|
+
session.step(700);
|
|
729
|
+
const to = posOf();
|
|
730
|
+
if (move) session.engine.input.setActionVector(move, 0, 0);
|
|
731
|
+
const dx = to[0] - from[0];
|
|
732
|
+
const dz = to[1] - from[1];
|
|
733
|
+
const travelled = Math.hypot(dx, dz);
|
|
734
|
+
const { skin, declaredOffset } = findSkin(player, opts.skinPath);
|
|
735
|
+
const skinPath = skin ? skin.getPath() : null;
|
|
736
|
+
if (!skin || travelled < .05) {
|
|
737
|
+
session.dispose();
|
|
738
|
+
return {
|
|
739
|
+
player: player.getPath(),
|
|
740
|
+
skin: skinPath,
|
|
741
|
+
dot: null,
|
|
742
|
+
backwards: false,
|
|
743
|
+
travelled
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
const [fx, fz] = forwardOf((skin.rotation?.[1] ?? 0) - declaredOffset, opts.forwardAxis ?? "+z");
|
|
747
|
+
const dot = (fx * dx + fz * dz) / travelled;
|
|
748
|
+
session.dispose();
|
|
749
|
+
return {
|
|
750
|
+
player: player.getPath(),
|
|
751
|
+
skin: skinPath,
|
|
752
|
+
dot: Math.round(dot * 1e3) / 1e3,
|
|
753
|
+
backwards: dot < -.5,
|
|
754
|
+
travelled: Math.round(travelled * 1e3) / 1e3
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
/** One line for a report, or the failure spelled out. */
|
|
758
|
+
function facingText(report) {
|
|
759
|
+
if (!report.player) return "facing: no player to drive";
|
|
760
|
+
if (report.skin === null) return `facing: ${report.player} has no skin to check`;
|
|
761
|
+
if (report.dot === null) return `facing: ${report.player} did not move — nothing to compare`;
|
|
762
|
+
if (report.backwards) return `facing: ${report.skin} RUNS BACKWARDS (dot ${report.dot.toFixed(2)}) — the skin points away from the direction of travel. The rule is +Z forward, yaw = atan2(dx, dz), with NO +180; for art that faces another way set skinYawOffset rather than adding to the yaw.`;
|
|
763
|
+
return `facing: ${report.skin} faces its travel (dot ${report.dot.toFixed(2)})`;
|
|
764
|
+
}
|
|
765
|
+
//#endregion
|
|
654
766
|
//#region src/test/feel.ts
|
|
655
767
|
const STEP_MS = 1e3 / 60;
|
|
656
768
|
/** Drop height for the buffer probe — long enough to outlast a coyote window. */
|
|
@@ -1258,7 +1370,7 @@ async function runScript(json, opts) {
|
|
|
1258
1370
|
const { enablePhysics2D } = await import("./physics-2d-BmgXBNDB.js").then((n) => n.r);
|
|
1259
1371
|
await enablePhysics2D(engine);
|
|
1260
1372
|
} else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
|
|
1261
|
-
const { enablePhysics3D } = await import("./physics-3d-
|
|
1373
|
+
const { enablePhysics3D } = await import("./physics-3d-CLPFv99o.js").then((n) => n.r);
|
|
1262
1374
|
await enablePhysics3D(engine);
|
|
1263
1375
|
}
|
|
1264
1376
|
const failures = [];
|
|
@@ -1374,7 +1486,7 @@ async function createPlaySession(json, opts = {}) {
|
|
|
1374
1486
|
const { enablePhysics2D } = await import("./physics-2d-BmgXBNDB.js").then((n) => n.r);
|
|
1375
1487
|
await enablePhysics2D(engine);
|
|
1376
1488
|
} else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
|
|
1377
|
-
const { enablePhysics3D } = await import("./physics-3d-
|
|
1489
|
+
const { enablePhysics3D } = await import("./physics-3d-CLPFv99o.js").then((n) => n.r);
|
|
1378
1490
|
await enablePhysics3D(engine);
|
|
1379
1491
|
}
|
|
1380
1492
|
const stepMs = 1e3 / (opts.fixedHz ?? 60);
|
|
@@ -1412,4 +1524,4 @@ async function createPlaySession(json, opts = {}) {
|
|
|
1412
1524
|
};
|
|
1413
1525
|
}
|
|
1414
1526
|
//#endregion
|
|
1415
|
-
export { registerAllNodes as a, feelReport as c,
|
|
1527
|
+
export { framingText as _, registerAllNodes as a, feelReport as c, facingText as d, failingReplays as f, describeFraming as g, playtestText as h, findFloatingProps as i, feelText as l, playtest as m, createPlaySession as n, runScript as o, findPlayer as p, describeCapture as r, validateScene as s, captureScene as t, facingReport as u };
|
package/dist/test.d.ts
CHANGED
|
@@ -3,6 +3,40 @@ import { c as JsonValue, i as SceneJson } from "./schema-CFeioQRE.js";
|
|
|
3
3
|
import { t as LoadSceneOptions } from "./loader-CeyU_bm1.js";
|
|
4
4
|
import { l as auditScene, o as IncantoError, r as ReplayJson } from "./replay-CAphXMyM.js";
|
|
5
5
|
|
|
6
|
+
//#region src/test/facing.d.ts
|
|
7
|
+
interface FacingOptions {
|
|
8
|
+
behaviors?: Record<string, BehaviorCtor>;
|
|
9
|
+
stubMissingBehaviors?: boolean;
|
|
10
|
+
resolveScene?: LoadSceneOptions["resolveScene"];
|
|
11
|
+
seed?: number;
|
|
12
|
+
moveAction?: string;
|
|
13
|
+
/** Which local axis the ART faces. Default `+z`, the engine's convention. */
|
|
14
|
+
forwardAxis?: "+z" | "-z" | "+x" | "-x";
|
|
15
|
+
/** Where the visual skin is, relative to the player. Default: found by name. */
|
|
16
|
+
skinPath?: string;
|
|
17
|
+
}
|
|
18
|
+
interface FacingReport {
|
|
19
|
+
player: string | null;
|
|
20
|
+
/** The node whose rotation was measured, or null when the player has no skin. */
|
|
21
|
+
skin: string | null;
|
|
22
|
+
/** Skin forward · travel direction. +1 faces forward, −1 runs backwards. */
|
|
23
|
+
dot: number | null;
|
|
24
|
+
/** True only when the two genuinely oppose — the reportable failure. */
|
|
25
|
+
backwards: boolean;
|
|
26
|
+
/** How far it actually moved, so a report on a stuck character is not trusted. */
|
|
27
|
+
travelled: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Drive the player forward and compare where the skin points with where it went.
|
|
31
|
+
*
|
|
32
|
+
* The travel direction is measured, not assumed: whatever the input map means by
|
|
33
|
+
* "up", the character ends up going somewhere, and that somewhere is the truth
|
|
34
|
+
* the art has to agree with.
|
|
35
|
+
*/
|
|
36
|
+
declare function facingReport(json: unknown, opts?: FacingOptions): Promise<FacingReport>;
|
|
37
|
+
/** One line for a report, or the failure spelled out. */
|
|
38
|
+
declare function facingText(report: FacingReport): string;
|
|
39
|
+
//#endregion
|
|
6
40
|
//#region src/test/framing.d.ts
|
|
7
41
|
/** Where a node's origin sits relative to the current camera. */
|
|
8
42
|
type Where = "onScreen" | "offscreen" | "behind";
|
|
@@ -337,4 +371,4 @@ interface PlaySession {
|
|
|
337
371
|
*/
|
|
338
372
|
declare function createPlaySession(json: unknown, opts?: PlaySessionOptions): Promise<PlaySession>;
|
|
339
373
|
//#endregion
|
|
340
|
-
export { type FeelOptions, type FeelReport, type FramingEntry, type FramingOptions, type FramingReport, GroundingIssue, GroundingOptions, NodeCapture, type Outcome, PlaySession, PlaySessionOptions, type PlaytestOptions, type PlaytestReport, type PlaytestRun, RunContext, RunFailure, RunResult, RunScriptOptions, SceneCapture, ScriptStep, ValidateSceneOptions, ValidationResult, type Where, auditScene, captureScene, createPlaySession, describeCapture, describeFraming, failingReplays, feelReport, feelText, findFloatingProps, findPlayer, framingText, playtest, playtestText, registerAllNodes, runScript, validateScene };
|
|
374
|
+
export { type FacingOptions, type FacingReport, type FeelOptions, type FeelReport, type FramingEntry, type FramingOptions, type FramingReport, GroundingIssue, GroundingOptions, NodeCapture, type Outcome, PlaySession, PlaySessionOptions, type PlaytestOptions, type PlaytestReport, type PlaytestRun, RunContext, RunFailure, RunResult, RunScriptOptions, SceneCapture, ScriptStep, ValidateSceneOptions, ValidationResult, type Where, auditScene, captureScene, createPlaySession, describeCapture, describeFraming, facingReport, facingText, failingReplays, feelReport, feelText, findFloatingProps, findPlayer, framingText, playtest, playtestText, registerAllNodes, runScript, validateScene };
|
package/dist/test.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { r as auditScene } from "./replay-DilbZgQI.js";
|
|
2
|
-
import { a as registerAllNodes, c as feelReport, d as
|
|
3
|
-
export { auditScene, captureScene, createPlaySession, describeCapture, describeFraming, failingReplays, feelReport, feelText, findFloatingProps, findPlayer, framingText, playtest, playtestText, registerAllNodes, runScript, validateScene };
|
|
2
|
+
import { _ as framingText, a as registerAllNodes, c as feelReport, d as facingText, f as failingReplays, g as describeFraming, h as playtestText, i as findFloatingProps, l as feelText, m as playtest, n as createPlaySession, o as runScript, p as findPlayer, r as describeCapture, s as validateScene, t as captureScene, u as facingReport } from "./test-BMgiiD5i.js";
|
|
3
|
+
export { auditScene, captureScene, createPlaySession, describeCapture, describeFraming, facingReport, facingText, failingReplays, feelReport, feelText, findFloatingProps, findPlayer, framingText, playtest, playtestText, registerAllNodes, runScript, validateScene };
|
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as VERSION } from "./src-
|
|
2
|
-
import { s as validateScene } from "./test-
|
|
1
|
+
import { t as VERSION } from "./src-CwYxzZKl.js";
|
|
2
|
+
import { s as validateScene } from "./test-BMgiiD5i.js";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { basename, dirname, join, normalize, relative, resolve, sep } from "node:path";
|
|
5
5
|
//#region src/vite/frame-endpoint.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./index-
|
|
1
|
+
import{n as e}from"./index-Dk2ZlO68.js";async function t(t){return new n((await e(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,t)}var n=class{raw;active=new Map;reconnecting=!1;disposed=!1;constructor(e,t){this.raw=new e({...t})}get account(){return this.raw.account}get connected(){return this.raw.connected}connect(){return this.raw.connected?Promise.resolve(!0):(this.disposed=!1,this.rawConnect())}rawConnect(){return this.raw.connect({onDisconnect:()=>void this.reconnect()})}disconnect(){this.disposed=!0;for(let e of this.active.values())e.off();return this.active.clear(),this.raw.disconnect()}remoteFunction(e,t,n){return this.raw.remoteFunction(e,t,n)}track(e){let t=Symbol(`sub`),n={make:e,off:e()};return this.active.set(t,n),()=>{n.off(),this.active.delete(t)}}async reconnect(){if(!this.disposed&&!this.reconnecting){this.reconnecting=!0;try{await this.rawConnect();for(let e of this.active.values())e.off(),e.off=e.make()}finally{this.reconnecting=!1}}}subscribeRoomState(e,t){return this.track(()=>this.raw.subscribeRoomState(e,t))}subscribeRoomMyState(e,t){return this.track(()=>this.raw.subscribeRoomMyState(e,t))}subscribeRoomAllUserStates(e,t){return this.track(()=>this.raw.subscribeRoomAllUserStates(e,e=>{let n={};for(let t of e??[]){if(!t||typeof t.account!=`string`||t.__leaved)continue;let{account:e,__updated:r,__leaved:i,...a}=t;n[e]=a}t(n)}))}subscribeRoomCollection(e,t,n){return this.track(()=>this.raw.subscribeRoomCollection(e,t,({items:e})=>{let t={};for(let n of e??[])n&&typeof n.__id==`string`&&(t[n.__id]=n);n(t)}))}onRoomMessage(e,t,n){return this.track(()=>this.raw.onRoomMessage(e,t,n))}onRoomUserJoin(e,t){return this.track(()=>this.raw.onRoomUserJoin(e,t))}onRoomUserLeave(e,t){return this.track(()=>this.raw.onRoomUserLeave(e,t))}subscribeGlobalState(e){return this.track(()=>this.raw.subscribeGlobalState(e))}subscribeGlobalMyState(e){return this.track(()=>this.raw.subscribeGlobalMyState(e))}subscribeGlobalUserState(e,t){return this.track(()=>this.raw.subscribeGlobalUserState(e,t))}subscribeGlobalCollection(e,t){return this.track(()=>this.raw.subscribeGlobalCollection(e,({items:e})=>{let n={};for(let t of e??[])t&&typeof t.__id==`string`&&(n[t.__id]=t);t(n)}))}subscribeAsset(e,t){return this.track(()=>this.raw.subscribeAsset(e,t))}onGlobalMessage(e,t){return this.track(()=>this.raw.onGlobalMessage(e,t))}};export{t as createAgent8Server};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{i as e,r as t,t as n}from"./index-
|
|
1
|
+
import{i as e,r as t,t as n}from"./index-Dk2ZlO68.js";function r(e,t,n,r,i,a,o=180,s=120){let c=Math.max(o,n),l=Math.max(s,r);return{x:Math.min(Math.max(0,e),Math.max(0,i-c)),y:Math.min(Math.max(0,t),Math.max(0,a-l)),w:c,h:l}}function i(e,t){for(let[n,r]of Object.entries(t))e.style[n]=r}var a=`rgba(18, 20, 26, 0.92)`,o=`1px solid rgba(255,255,255,0.14)`,s=`12px ui-monospace, SFMono-Regular, Menlo, monospace`,c=class{host;el;body;onClose=()=>{};x;y;w;h;constructor(e,t,n,r){this.host=t,this.x=r.x,this.y=r.y,this.w=r.w,this.h=r.h,this.el=e.createElement(`div`),i(this.el,{position:`absolute`,background:a,border:o,borderRadius:`8px`,color:`rgba(255,255,255,0.88)`,font:s,display:`flex`,flexDirection:`column`,overflow:`hidden`,zIndex:`40`,pointerEvents:`auto`,boxShadow:`0 8px 28px rgba(0,0,0,0.45)`});let c=e.createElement(`div`);c.textContent=n,i(c,{padding:`6px 28px 6px 10px`,background:`rgba(255,255,255,0.07)`,cursor:`move`,userSelect:`none`,touchAction:`none`,fontWeight:`700`}),this.el.appendChild(c);let l=e.createElement(`div`);l.textContent=`×`,l.title=`close`,i(l,{position:`absolute`,top:`2px`,right:`8px`,cursor:`pointer`,fontSize:`16px`,lineHeight:`20px`,opacity:`0.7`}),l.addEventListener(`click`,()=>this.onClose()),this.el.appendChild(l),this.body=e.createElement(`div`),i(this.body,{flex:`1`,overflow:`auto`,padding:`8px 10px`}),this.el.appendChild(this.body);let u=e.createElement(`div`);u.textContent=`◢`,i(u,{position:`absolute`,right:`2px`,bottom:`0`,cursor:`nwse-resize`,opacity:`0.5`,userSelect:`none`,touchAction:`none`}),this.el.appendChild(u),this.wireDrag(c,(e,t)=>{this.x+=e,this.y+=t,this.layout()}),this.wireDrag(u,(e,t)=>{this.w+=e,this.h+=t,this.layout()}),this.layout(),t.appendChild(this.el)}remove(){this.el.remove()}layout(){let e=this.host.getBoundingClientRect(),t=r(this.x,this.y,this.w,this.h,e.width,e.height);this.x=t.x,this.y=t.y,this.w=t.w,this.h=t.h,i(this.el,{left:`${t.x}px`,top:`${t.y}px`,width:`${t.w}px`,height:`${t.h}px`})}wireDrag(e,t){let n=null,r=0,i=0;e.addEventListener(`pointerdown`,t=>{n=t.pointerId,r=t.clientX,i=t.clientY,e.setPointerCapture?.(t.pointerId)}),e.addEventListener(`pointermove`,e=>{e.pointerId===n&&(t(e.clientX-r,e.clientY-i),r=e.clientX,i=e.clientY)});let a=e=>{e.pointerId===n&&(n=null)};e.addEventListener(`pointerup`,a),e.addEventListener(`pointercancel`,a)}},l=96,u=200,d=8192;function f(e){return Array.isArray(e)?`Array(${e.length})`:`Object(${Object.keys(e).length} keys)`}function p(e,t){if(Array.isArray(e)&&e.some(e=>typeof e==`object`&&!!e)){let t=e.slice(0,u).map(e=>JSON.stringify(e)),n=e.length-u;return t.join(`
|
|
2
2
|
`)+(n>0?`\n… ${n} more`:``)}return t.length>d?`${t.slice(0,d)} … (${t.length-d} more chars)`:t}function m(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}var h=2;function g(e,t={}){let n=t.doc??(typeof document<`u`?document:null);if(!n)return null;let r=t.container??(typeof document<`u`?document.body:null);return!r||typeof r.appendChild!=`function`?null:new y(e,r,n,t.statsSource,t.actions)}var _=300,v=[`log`,`info`,`warn`,`error`,`debug`],y=class{engine;container;doc;statsSource;actions;panels=new Map;cleanups=[];menuButton;dropdown=null;selected=null;collapsedFlags=new Map;statsChip=null;logRows=[];levelEnabled={debug:!0,info:!0,warn:!0,error:!0};consoleCapture=!1;consolePatched=[];frame=0;editing=0;detailOpen=new WeakMap;resumeScale=1;timeEls=null;hovering=!1;constructor(e,t,n,r,a=[]){this.engine=e,this.container=t,this.doc=n,this.statsSource=r,this.actions=a,this.menuButton=n.createElement(`div`),this.menuButton.textContent=`☰ debug`,i(this.menuButton,{position:`absolute`,top:`8px`,left:`8px`,padding:`4px 10px`,background:`rgba(18,20,26,0.85)`,border:`1px solid rgba(255,255,255,0.18)`,borderRadius:`6px`,color:`rgba(255,255,255,0.85)`,font:`12px ui-monospace, Menlo, monospace`,cursor:`pointer`,userSelect:`none`,zIndex:`50`,pointerEvents:`auto`}),this.menuButton.addEventListener(`click`,()=>this.toggleDropdown()),t.style.position||(t.style.position=`relative`),t.appendChild(this.menuButton),this.cleanups.push(e.log.added.connect(e=>{this.pushLog({level:e.level,source:`engine`,text:e.parts.map(S).join(` `)})})),this.cleanups.push(e.sceneChanged.connect(()=>{this.selected=null,this.applyColliderScope(),this.renderExplorer(),this.renderInspector()})),this.cleanups.push(e.updated.connect(()=>{this.frame+=1,this.frame%30==0&&(this.renderExplorer(),this.renderStats(),this.editing===0&&!this.hovering&&this.renderInspector(),this.syncTime())}))}isOpen(e){return e===`colliders`?this.colliderMode!==`off`:e===`stats`?this.statsChip!==null:this.panels.has(e)}colliderMode=`off`;setColliders(e){this.colliderMode=e,this.applyColliderScope()}applyColliderScope(){let e=this.colliderMode;for(let t of n(`2d`).concat(n(`3d`)))t.debugDraw=e!==`off`,t.debugScope=e===`selected`?this.selected:null}open(e){if(e===`stats`){this.openStatsChip();return}if(this.panels.has(e)){e===`explorer`&&this.renderExplorer(),e===`inspector`&&this.renderInspector(),e===`logs`&&this.renderLogs(),e===`time`&&this.renderTime();return}let t=new c(this.doc,this.container,{explorer:`Explorer`,inspector:`Inspector`,logs:`Logs`,time:`Time`}[e],{explorer:{x:12,y:44,w:240,h:320},inspector:{x:264,y:44,w:280,h:320},logs:{x:12,y:380,w:532,h:200},time:{x:556,y:44,w:260,h:150}}[e]);t.onClose=()=>this.close(e),e===`inspector`&&(t.body.addEventListener(`pointerenter`,()=>{this.hovering=!0}),t.body.addEventListener(`pointerleave`,()=>{this.hovering=!1})),this.panels.set(e,t),e===`explorer`&&this.renderExplorer(),e===`inspector`&&this.renderInspector(),e===`logs`&&this.renderLogs(),e===`time`&&this.renderTime()}close(e){if(e===`inspector`&&(this.hovering=!1),e===`stats`){this.statsChip?.remove(),this.statsChip=null;return}let t=this.panels.get(e);t&&(t.remove(),this.panels.delete(e))}toggle(e){if(e===`colliders`){this.setColliders({off:`all`,all:`selected`,selected:`off`}[this.colliderMode]);return}this.isOpen(e)?this.close(e):this.open(e)}setLevelEnabled(e,t){this.levelEnabled[e]=t,this.renderLogs()}setConsoleCapture(e){if(e!==this.consoleCapture)if(this.consoleCapture=e,e){this.renderLogs();let e=console;for(let t of v){let n=e[t];e[t]=(...e)=>{n.apply(console,e);let r=t===`log`?`info`:t;this.pushLog({level:r,source:`console`,text:e.map(S).join(` `)})},this.consolePatched.push(()=>{e[t]=n})}}else{for(let e of this.consolePatched)e();this.consolePatched=[],this.renderLogs()}}dispose(){this.engine.debugSelection=null,this.setColliders(`off`),this.setConsoleCapture(!1);for(let e of this.cleanups)e();for(let e of[...this.panels.keys()])this.close(e);this.close(`stats`),this.dropdown?.remove(),this.dropdown=null,this.menuButton.remove()}menuLabel(e,t){let n=e===`colliders`&&this.colliderMode!==`off`?` · ${this.colliderMode}`:``;return`${this.isOpen(e)?`✓ `:``}${t}${n}`}toggleDropdown(){if(this.dropdown){this.dropdown.remove(),this.dropdown=null;return}let e=this.doc.createElement(`div`);i(e,{position:`absolute`,top:`34px`,left:`8px`,background:`rgba(18,20,26,0.95)`,border:`1px solid rgba(255,255,255,0.18)`,borderRadius:`6px`,font:`12px ui-monospace, Menlo, monospace`,color:`rgba(255,255,255,0.85)`,zIndex:`60`,pointerEvents:`auto`,overflow:`hidden`});for(let[t,n]of[[`explorer`,`Explorer`],[`inspector`,`Inspector`],[`logs`,`Logs`],[`time`,`Time`],[`stats`,`Stats`],[`colliders`,`Colliders`]]){let r=this.doc.createElement(`div`);r.textContent=this.menuLabel(t,n),i(r,{padding:`6px 14px`,cursor:`pointer`,userSelect:`none`}),r.addEventListener(`click`,()=>{if(this.toggle(t),t===`colliders`){r.textContent=this.menuLabel(t,n);return}this.dropdown?.remove(),this.dropdown=null}),e.appendChild(r)}for(let t of this.actions){let n=this.doc.createElement(`div`);n.textContent=t.label,i(n,{padding:`6px 14px`,cursor:`pointer`,userSelect:`none`,borderTop:`1px solid rgba(255,255,255,0.14)`,color:`rgba(158,232,220,0.95)`}),n.addEventListener(`click`,()=>{this.dropdown?.remove(),this.dropdown=null,t.run()}),e.appendChild(n)}this.container.appendChild(e),this.dropdown=e}openStatsChip(){if(this.statsChip)return;let e=this.doc.createElement(`div`);i(e,{position:`absolute`,top:`8px`,right:`8px`,padding:`4px 10px`,background:`rgba(18,20,26,0.85)`,border:`1px solid rgba(255,255,255,0.18)`,borderRadius:`6px`,color:`rgba(255,255,255,0.85)`,font:`12px ui-monospace, Menlo, monospace`,textAlign:`right`,whiteSpace:`pre`,userSelect:`none`,pointerEvents:`none`,zIndex:`70`}),this.container.appendChild(e),this.statsChip=e,this.renderStats()}renderStats(){let e=this.statsChip;if(!e)return;let t=this.engine.stats(),n=this.statsSource?.()??{},r=[`nodes ${t.nodes}`,...n.triangles===void 0?[]:[`tris ${x(n.triangles)}`],...n.drawCalls===void 0?[]:[`calls ${n.drawCalls}`]].join(` · `);e.textContent=`${Math.round(t.fps)} fps · ${t.frameMs.toFixed(1)} ms\n${r}`}renderExplorer(){let e=this.panels.get(`explorer`);if(!e)return;let t=e.body.scrollTop;b(e.body);let n=this.engine.scene?.root;if(!n){e.body.scrollTop=t;return}let r=(e,t)=>{let n=e.constructor,a=e.children.length>0,o=this.collapsedFlags.get(e)===!0,s=this.doc.createElement(`div`);i(s,{display:`flex`,alignItems:`center`,cursor:`pointer`,padding:`1px 2px`,borderRadius:`3px`,background:e===this.selected?`rgba(110,160,255,0.25)`:`transparent`});let c=this.doc.createElement(`span`);c.textContent=a?o?`▸`:`▾`:`·`,i(c,{width:`14px`,flex:`none`,textAlign:`center`,opacity:a?`0.85`:`0.25`,userSelect:`none`}),a&&c.addEventListener(`click`,t=>{t.stopPropagation?.(),this.collapsedFlags.set(e,!o),this.renderExplorer()}),s.appendChild(c);let l=this.doc.createElement(`span`);l.textContent=e.name,i(l,{whiteSpace:`nowrap`}),s.appendChild(l);let u=this.doc.createElement(`span`);if(u.textContent=` ${n.typeName}`,i(u,{opacity:`0.45`,whiteSpace:`nowrap`,fontSize:`10px`}),s.appendChild(u),a&&o){let t=this.doc.createElement(`span`);t.textContent=` (${e.children.length})`,i(t,{opacity:`0.35`,fontSize:`10px`}),s.appendChild(t)}if(s.addEventListener(`click`,()=>{this.selected=e,this.engine.debugSelection=e,this.applyColliderScope(),this.open(`inspector`),this.renderExplorer(),this.renderInspector()}),t.appendChild(s),a&&!o){let n=this.doc.createElement(`div`);i(n,{marginLeft:`8px`,paddingLeft:`8px`,borderLeft:`1px solid rgba(255,255,255,0.14)`});for(let t of e.children)r(t,n);t.appendChild(n)}};r(n,e.body),e.body.scrollTop=t}renderInspector(){let e=this.panels.get(`inspector`);if(!e)return;let n=e.body.scrollTop;b(e.body);let r=this.selected;if(r&&r.tree===null&&(this.selected=null,this.engine.debugSelection=null,this.applyColliderScope(),r=null),!r){let t=this.doc.createElement(`div`);t.textContent=`select a node in the Explorer`,i(t,{opacity:`0.6`}),e.body.appendChild(t);return}let a=r.constructor,o=this.doc.createElement(`div`);if(o.textContent=`${r.getPath()} · ${a.typeName}${r.uid?` · ${r.uid}`:``}`,i(o,{fontWeight:`700`,marginBottom:`6px`,whiteSpace:`pre-wrap`}),e.body.appendChild(o),r.groups.size>0){let t=this.doc.createElement(`div`);t.textContent=`groups: ${[...r.groups].join(`, `)}`,i(t,{opacity:`0.7`,marginBottom:`6px`}),e.body.appendChild(t)}let s=t(a),c=r;for(let t of Object.keys(s)){let n=s[t];this.renderValueRow(e.body,r,t,{read:()=>c[t],write:e=>{c[t]=e},options:n?.options,variants:n?.variants})}e.body.scrollTop=n}renderValueRow(t,n,r,a){let o=a.read(),s=a.options,c={get[r](){return a.read()},set[r](e){a.write(e)}},u=this.doc.createElement(`div`);i(u,{display:`flex`,gap:`6px`,alignItems:`center`,margin:`2px 0`});let d=this.doc.createElement(`div`);d.textContent=r,i(d,{minWidth:`84px`,opacity:`0.75`}),u.appendChild(d);let h=(e,t)=>{let a=this.doc.createElement(`input`);return a.type=`number`,a.value=String(e),i(a,w(`70px`)),this.trackEditing(a),a.addEventListener(`change`,()=>{let e=Number(a.value);Number.isFinite(e)?t(e):a.value=String(n[r])}),a};if(typeof o==`number`)u.appendChild(h(o,e=>{c[r]=e}));else if(typeof o==`boolean`){let e=this.doc.createElement(`input`);e.type=`checkbox`,e.checked=o,this.trackEditing(e),e.addEventListener(`change`,()=>{c[r]=e.checked}),u.appendChild(e)}else if(typeof o==`string`&&s&&s.length>0){let e=this.doc.createElement(`select`);for(let t of s.includes(o)?s:[o,...s]){let n=this.doc.createElement(`option`);n.value=t,n.textContent=t,t===o&&(n.selected=!0),e.appendChild(n)}e.value=o,this.trackEditing(e),e.addEventListener(`change`,()=>{c[r]=e.value}),i(e,w(`110px`)),u.appendChild(e)}else if(typeof o==`string`){let e=this.doc.createElement(`input`);e.type=`text`,e.value=o,this.trackEditing(e),i(e,w(`140px`)),e.addEventListener(`change`,()=>{c[r]=e.value}),u.appendChild(e)}else if(Array.isArray(o)&&o.length<=8&&o.every(e=>typeof e==`number`))for(let e=0;e<o.length;e++)u.appendChild(h(o[e],t=>{let n=[...c[r]];n[e]=t,c[r]=n}));else if(m(o)){let s=this.doc.createElement(`div`);i(s,{marginLeft:`10px`,paddingLeft:`8px`,borderLeft:`1px solid rgba(255,255,255,0.14)`});let c=a.variants?.tag,l=Object.keys(o);c&&!l.includes(c)&&l.unshift(c);let d=a.path??r;for(let t of l){let r=t===c;this.renderValueRow(s,n,t,{path:`${d}.${t}`,read:()=>a.read()[t]??(r?``:null),write:n=>{if(r&&a.variants){let t=a.variants.byTag[String(n)];if(t!==void 0){a.write(e(t));return}}a.write({...a.read(),[t]:n})},options:r&&a.variants?Object.keys(a.variants.byTag):void 0})}t.appendChild(u),t.appendChild(s);return}else{let s=JSON.stringify(e(o));if(s.length<=l){let e=this.doc.createElement(`div`);e.textContent=s,i(e,{opacity:`0.65`,whiteSpace:`pre-wrap`,wordBreak:`break-all`}),u.appendChild(e)}else{let e=a.path??r,c=this.detailOpen.get(n)?.has(e)??!1,l=this.doc.createElement(`div`);if(l.textContent=`${c?`▾`:`▸`} ${f(o)}`,i(l,{opacity:`0.75`,cursor:`pointer`,userSelect:`none`}),l.addEventListener(`click`,()=>{let t=this.detailOpen.get(n);t||(t=new Set,this.detailOpen.set(n,t)),c?t.delete(e):t.add(e),this.renderInspector()}),u.appendChild(l),t.appendChild(u),c){let e=this.doc.createElement(`div`);e.textContent=p(o,s),i(e,{opacity:`0.6`,whiteSpace:`pre-wrap`,wordBreak:`break-all`,marginLeft:`10px`,paddingLeft:`8px`,borderLeft:`1px solid rgba(255,255,255,0.14)`}),t.appendChild(e)}return}}t.appendChild(u)}trackEditing(e){e.addEventListener(`focus`,()=>{this.editing+=1}),e.addEventListener(`blur`,()=>{this.editing=Math.max(0,this.editing-1)})}pushLog(e){this.logRows.push(e),this.logRows.length>_&&this.logRows.splice(0,this.logRows.length-_),this.renderLogs()}setTimeScale(e){Number.isFinite(e)&&(this.engine.timeScale=Math.max(0,e),this.syncTime())}setPaused(e){e?(this.engine.timeScale>0&&(this.resumeScale=this.engine.timeScale),this.engine.timeScale=0):this.engine.timeScale=this.resumeScale>0?this.resumeScale:1,this.syncTime()}get paused(){return this.engine.timeScale===0}nextFrame(){this.paused||this.setPaused(!0),this.engine.step(),this.syncTime()}syncTime(){let e=this.timeEls;if(!e)return;let t=this.engine.timeScale,n=String(Math.round(t*1e3)/1e3);this.editing===0&&(e.slider.value=String(Math.min(t,h)),e.box.value=n),e.readout.textContent=`timeScale ${n}${this.paused?` · paused`:``}`,e.pause.textContent=this.paused?`▶ Resume`:`⏸ Pause`}renderTime(){let e=this.panels.get(`time`);if(!e)return;b(e.body),this.timeEls=null;let t=this.doc.createElement(`div`);i(t,{marginBottom:`6px`,opacity:`0.85`}),e.body.appendChild(t);let n=this.doc.createElement(`input`);n.type=`range`,n.min=`0`,n.max=String(h),n.step=`0.05`,n.value=String(Math.min(this.engine.timeScale,h)),i(n,{width:`100%`,marginBottom:`6px`}),this.trackEditing(n),n.addEventListener(`input`,()=>this.setTimeScale(Number(n.value))),e.body.appendChild(n);let r=this.doc.createElement(`div`);i(r,{display:`flex`,gap:`6px`,alignItems:`center`,marginBottom:`8px`});let a=this.doc.createElement(`input`);a.type=`number`,a.min=`0`,a.step=`0.05`,a.value=String(this.engine.timeScale),i(a,w(`72px`)),this.trackEditing(a),a.addEventListener(`change`,()=>{let e=Number(a.value);Number.isFinite(e)&&this.setTimeScale(e),this.syncTimeAfterEdit()}),r.appendChild(a);for(let e of[.25,.5,1,2]){let t=this.doc.createElement(`div`);t.textContent=`${e}×`,i(t,{cursor:`pointer`,opacity:`0.7`,padding:`2px 4px`}),t.addEventListener(`click`,()=>this.setTimeScale(e)),r.appendChild(t)}e.body.appendChild(r);let o=this.doc.createElement(`div`);i(o,{display:`flex`,gap:`8px`});let s=this.doc.createElement(`div`);i(s,C()),s.addEventListener(`click`,()=>this.setPaused(!this.paused)),o.appendChild(s);let c=this.doc.createElement(`div`);c.textContent=`⏭ Next frame`,c.title=`Pauses, then advances one fixed step`,i(c,C()),c.addEventListener(`click`,()=>this.nextFrame()),o.appendChild(c),e.body.appendChild(o),this.timeEls={slider:n,box:a,readout:t,pause:s},this.syncTime()}syncTimeAfterEdit(){let e=this.timeEls;if(!e)return;let t=this.engine.timeScale;e.slider.value=String(Math.min(t,h)),e.box.value=String(Math.round(t*1e3)/1e3)}renderLogs(){let e=this.panels.get(`logs`);if(!e)return;b(e.body);let t=this.doc.createElement(`div`);i(t,{display:`flex`,gap:`8px`,marginBottom:`4px`,flexWrap:`wrap`});for(let e of[`debug`,`info`,`warn`,`error`]){let n=this.doc.createElement(`div`);n.textContent=`${this.levelEnabled[e]?`✓`:`·`}${e}`,i(n,{cursor:`pointer`,opacity:this.levelEnabled[e]?`1`:`0.45`}),n.addEventListener(`click`,()=>this.setLevelEnabled(e,!this.levelEnabled[e])),t.appendChild(n)}let n=this.doc.createElement(`div`);n.textContent=`${this.consoleCapture?`✓`:`·`}console`,i(n,{cursor:`pointer`,marginLeft:`auto`}),n.addEventListener(`click`,()=>this.setConsoleCapture(!this.consoleCapture)),t.appendChild(n),e.body.appendChild(t);let r={debug:`rgba(255,255,255,0.5)`,info:`rgba(255,255,255,0.85)`,warn:`#ffc861`,error:`#ff6b6b`};for(let t of this.logRows){if(!this.levelEnabled[t.level])continue;let n=this.doc.createElement(`div`);n.textContent=`[${t.source===`console`?`console`:t.level}] ${t.text}`,i(n,{color:r[t.level],whiteSpace:`pre-wrap`}),e.body.appendChild(n)}}};function b(e){for(let t of[...e.children])t.remove()}function x(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function S(e){if(typeof e==`string`)return e;if(e instanceof Error){let t=e.stack?.split(`
|
|
3
3
|
`)[1]?.trim();return`${e.name}: ${e.message}${t?` (${t})`:``}`}try{let t=JSON.stringify(e);return t===`{}`||t===void 0?String(e):t}catch{return String(e)}}function C(){return{background:`rgba(255,255,255,0.08)`,border:`1px solid rgba(255,255,255,0.2)`,borderRadius:`4px`,padding:`4px 8px`,cursor:`pointer`,userSelect:`none`}}function w(e){return{width:e,background:`rgba(255,255,255,0.08)`,border:`1px solid rgba(255,255,255,0.2)`,borderRadius:`4px`,color:`inherit`,font:`inherit`,padding:`2px 4px`}}export{g as attachDebugOverlay};
|