incanto 0.31.0 → 0.33.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-play.mjs +7 -2
- package/dist/2d.d.ts +59 -2
- package/dist/2d.js +3 -3
- package/dist/3d.d.ts +28 -3
- package/dist/3d.js +4 -4
- package/dist/{behavior-D_jMpFh8.d.ts → behavior-CKwTCjfR.d.ts} +140 -1
- package/dist/{create-game-z5XaB1p5.js → create-game-D2QU5x7S.js} +16 -8
- package/dist/{create-game-DqOjMBUS.js → create-game-sFuTLqjD.js} +22 -10
- package/dist/debug.d.ts +1 -1
- package/dist/{duplicate-KRPtUtzl.js → duplicate-BgnG1Lqz.js} +1 -1
- package/dist/editor.js +35 -0
- package/dist/{environment-presets--DigHNg4.js → environment-presets-CQtEGogB.js} +2 -2
- package/dist/{gameplay-BftxM_It.js → gameplay-BpQCbABv.js} +90 -2
- package/dist/gameplay.d.ts +1 -1
- package/dist/gameplay.js +1 -1
- package/dist/index.d.ts +135 -23
- package/dist/index.js +6 -59
- package/dist/{loader-BlaRQGaA.js → loader-Buk8Bu1h.js} +53 -0
- package/dist/{loader-BYBrqTxP.d.ts → loader-COn5fS0o.d.ts} +1 -1
- package/dist/net.d.ts +1 -1
- package/dist/net.js +3 -3
- package/dist/{pathfinding-BwhqPD3i.d.ts → pathfinding-DUw9mir9.d.ts} +1 -1
- package/dist/{physics-2d-D9wquBvK.js → physics-2d-DjXR5DMu.js} +12 -2
- package/dist/{physics-3d-CnPygVGo.js → physics-3d-DF8npb1O.js} +55 -9
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-Dzkd6-os.js → register-CscIzJEO.js} +551 -13
- package/dist/{register-CUY284Is.js → register-CtI-itec.js} +2 -2
- package/dist/{register-tkR_8tWg.js → register-FIJtNbub.js} +145 -8
- package/dist/test-BRxLd2jH.js +642 -0
- package/dist/test.d.ts +55 -3
- package/dist/test.js +2 -392
- package/dist/{touch-031PxtCR.js → touch-BoNg_MnF.js} +2 -1
- package/dist/vite.js +1 -1
- package/editor/assets/{agent8-o27_Y1xN.js → agent8-BdDP3xKW.js} +1 -1
- package/editor/assets/{debug-DfcWX3uW.js → debug-DbjTyTlC.js} +1 -1
- package/editor/assets/{index-C9fb5QcT.js → index-BWCudoz1.js} +90 -90
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +520 -0
- package/skills/README.md +14 -2
- package/skills/incanto-audio.md +43 -0
- package/skills/incanto-building-2d-games.md +52 -0
- package/skills/incanto-building-3d-games.md +16 -0
- package/skills/incanto-hud.md +41 -0
- package/skills/incanto-node-reference.md +89 -0
- package/skills/incanto-physics-and-input.md +50 -0
- package/skills/incanto-verifying-your-game.md +86 -30
- package/templates-app/beacon-isle-3d/docs/project-3d-rules.md +40 -19
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/tps-3d/docs/project-3d-rules.md +41 -19
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/village-quest-3d/docs/project-3d-rules.md +40 -19
- package/templates-app/village-quest-3d/package.json +1 -1
package/bin/incanto-play.mjs
CHANGED
|
@@ -17,6 +17,7 @@ import { dirname, join, resolve } from 'node:path';
|
|
|
17
17
|
* pointer <dx> <dy> look deltas wheel <dy>
|
|
18
18
|
* capture [file] current state as scene JSON (stdout or file)
|
|
19
19
|
* describe one line per node, non-default props only
|
|
20
|
+
* framing what the camera SEES: on/off screen, lights, overlaps
|
|
20
21
|
* logs engine.log entries since the last call
|
|
21
22
|
* quit
|
|
22
23
|
*
|
|
@@ -56,7 +57,7 @@ if (args.help || !args.scene) {
|
|
|
56
57
|
console.error(`Usage: incanto-play <scene.json> [--behaviors <file.ts|.js>] [--seed N] [--fixed-hz 60] [--commands <file>]
|
|
57
58
|
|
|
58
59
|
Headless play: stdin commands (step/press/release/vector/key/mouse/pointer/
|
|
59
|
-
wheel/capture/describe/logs/quit), JSON-line responses on stdout.`);
|
|
60
|
+
wheel/capture/describe/framing/logs/quit), JSON-line responses on stdout.`);
|
|
60
61
|
process.exit(args.help && args.scene !== undefined ? 0 : 1);
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -175,6 +176,10 @@ function handle(line) {
|
|
|
175
176
|
case 'describe':
|
|
176
177
|
out({ ok: true, cmd, text: session.describe() });
|
|
177
178
|
break;
|
|
179
|
+
case 'framing':
|
|
180
|
+
// what the camera can SEE — on/off screen, lit or black, overlaps
|
|
181
|
+
out({ ok: true, cmd, text: session.framing() });
|
|
182
|
+
break;
|
|
178
183
|
case 'logs':
|
|
179
184
|
out({ ok: true, cmd, entries: session.drainLogs() });
|
|
180
185
|
break;
|
|
@@ -188,7 +193,7 @@ function handle(line) {
|
|
|
188
193
|
cmd,
|
|
189
194
|
error: {
|
|
190
195
|
code: 'UNKNOWN_COMMAND',
|
|
191
|
-
message: `unknown command '${cmd}'. Commands: step press release vector key mouse pointer wheel capture describe logs quit`,
|
|
196
|
+
message: `unknown command '${cmd}'. Commands: step press release vector key mouse pointer wheel capture describe framing logs quit`,
|
|
192
197
|
},
|
|
193
198
|
});
|
|
194
199
|
}
|
package/dist/2d.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { C as RendererStats, S as GameStats,
|
|
1
|
+
import { C as RendererStats, N as Scene$1, S as GameStats, at as Node, b as Scheduler, l as PropSchema, n as BehaviorCtor, v as Engine } from "./behavior-CKwTCjfR.js";
|
|
2
2
|
import { n as DiagnosticSink, t as EditorSwitchOptions } from "./editor-switch-BJb-CWfA.js";
|
|
3
3
|
import { i as SceneJson, s as JsonObject } from "./schema-CcoWb32N.js";
|
|
4
|
-
import { t as LoadSceneOptions } from "./loader-
|
|
4
|
+
import { t as LoadSceneOptions } from "./loader-COn5fS0o.js";
|
|
5
5
|
import { t as ParticleSim } from "./particle-sim-CwJ5rI_P.js";
|
|
6
6
|
import { Group, Mesh, Object3D, Scene, Texture } from "three";
|
|
7
7
|
import * as RapierNs from "@dimforge/rapier2d-compat";
|
|
@@ -144,6 +144,22 @@ declare class CharacterBody2D extends PhysicsBody2D {
|
|
|
144
144
|
/** @internal Updated by Physics2D.moveAndSlide. */
|
|
145
145
|
_grounded: boolean;
|
|
146
146
|
moveAndSlide(): void;
|
|
147
|
+
/** @internal Set by the physics step from the KCC's resolved collisions. */
|
|
148
|
+
_onWall: number;
|
|
149
|
+
/** @internal */
|
|
150
|
+
_onCeiling: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Touching a wall, and which side (-1 left, +1 right, 0 neither).
|
|
153
|
+
*
|
|
154
|
+
* Wall jump and wall slide are unbuildable without it — not awkward to build,
|
|
155
|
+
* impossible: `isOnFloor()` was the only surface a character could report, so
|
|
156
|
+
* even a hand-written behavior had nothing to ask.
|
|
157
|
+
*/
|
|
158
|
+
isOnWall(): boolean;
|
|
159
|
+
/** -1 the wall is to the left, +1 to the right, 0 no wall. */
|
|
160
|
+
wallSide(): number;
|
|
161
|
+
/** Head hit something — cut the jump short, the way every platformer does. */
|
|
162
|
+
isOnCeiling(): boolean;
|
|
147
163
|
isOnFloor(): boolean;
|
|
148
164
|
}
|
|
149
165
|
//#endregion
|
|
@@ -321,6 +337,11 @@ interface Game2D {
|
|
|
321
337
|
sourceJson: SceneJson;
|
|
322
338
|
renderer: GameRenderer;
|
|
323
339
|
physics: Physics2D | null;
|
|
340
|
+
/**
|
|
341
|
+
* The node under a screen pixel, or null. The raycast the renderer already
|
|
342
|
+
* does — reachable now without holding the renderer.
|
|
343
|
+
*/
|
|
344
|
+
pick(x: number, y: number): Node | null;
|
|
324
345
|
/** Engine + renderer perf counters in one read (fps/nodes/triangles/…). */
|
|
325
346
|
stats(): GameStats;
|
|
326
347
|
/**
|
|
@@ -463,18 +484,54 @@ declare class Camera2D extends Node2D {
|
|
|
463
484
|
* - `platformer`: x movement + gravity (from the scene `physics.gravity[1]`,
|
|
464
485
|
* default 980) + jump (`jumpHeight` px → impulse √(2·g·h))
|
|
465
486
|
* - `topDown`: full-axis movement, no gravity
|
|
487
|
+
*
|
|
488
|
+
* ## Why the extra platformer props exist
|
|
489
|
+
*
|
|
490
|
+
* A jump that only works while `isOnFloor()` is true feels BROKEN, and players
|
|
491
|
+
* do not report it as "the coyote time is missing" — they report the game as
|
|
492
|
+
* unresponsive. The whole schema used to be five props, so a JSON-only game got
|
|
493
|
+
* a character that felt wrong and could not drive `AnimatedSprite2D.play('run')`
|
|
494
|
+
* either. `examples/platformer-2d` hand-rolls all of this in a 541-line
|
|
495
|
+
* behavior; these are those constants, as props.
|
|
496
|
+
*
|
|
497
|
+
* Every one defaults to OFF (0 / 1 / false), so an existing scene behaves
|
|
498
|
+
* exactly as before until it asks for something.
|
|
466
499
|
*/
|
|
467
500
|
declare class CharacterController2D extends Node {
|
|
468
501
|
static override readonly typeName: string;
|
|
469
502
|
static readonly props: PropSchema;
|
|
503
|
+
static readonly signals: readonly string[];
|
|
470
504
|
mode: string;
|
|
471
505
|
maxSpeed: number;
|
|
472
506
|
/** Pixels (platformer mode). */
|
|
473
507
|
jumpHeight: number;
|
|
474
508
|
moveAction: string;
|
|
475
509
|
jumpAction: string;
|
|
510
|
+
coyoteSeconds: number;
|
|
511
|
+
jumpBufferSeconds: number;
|
|
512
|
+
jumpCutMultiplier: number;
|
|
513
|
+
maxJumps: number;
|
|
514
|
+
dashSpeed: number;
|
|
515
|
+
dashSeconds: number;
|
|
516
|
+
dashAction: string;
|
|
517
|
+
wallSlideSpeed: number;
|
|
518
|
+
wallJumpImpulse: number[];
|
|
519
|
+
/** What the character is doing — drive `AnimatedSprite2D.play(state)` off it. */
|
|
520
|
+
state: "idle" | "run" | "jump" | "fall" | "wallSlide" | "dash";
|
|
521
|
+
private coyoteLeft;
|
|
522
|
+
private bufferLeft;
|
|
523
|
+
private jumpsUsed;
|
|
524
|
+
private dashLeft;
|
|
525
|
+
private dashDir;
|
|
526
|
+
private rising;
|
|
476
527
|
override onReady(): void;
|
|
477
528
|
override fixedUpdate(dt: number): void;
|
|
529
|
+
/**
|
|
530
|
+
* Emits `movementStateChanged(state)` on a change — the 3D sibling has had
|
|
531
|
+
* this since it shipped, and it is what drives `AnimatedSprite2D.play(...)`
|
|
532
|
+
* from scene JSON instead of a behavior polling velocities.
|
|
533
|
+
*/
|
|
534
|
+
private setState;
|
|
478
535
|
}
|
|
479
536
|
//#endregion
|
|
480
537
|
//#region src/2d/nodes/color-rect-2d.d.ts
|
package/dist/2d.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
2
|
-
import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-
|
|
3
|
-
import { _ 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-
|
|
4
|
-
import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-
|
|
2
|
+
import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-D2QU5x7S.js";
|
|
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-FIJtNbub.js";
|
|
4
|
+
import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-DjXR5DMu.js";
|
|
5
5
|
//#region src/2d/library-sprite.ts
|
|
6
6
|
/**
|
|
7
7
|
* Turn a library sprite-animation JSON into a scene-ready spritesheet asset
|
package/dist/3d.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { C as RendererStats, S as GameStats,
|
|
1
|
+
import { C as RendererStats, N as Scene$1, S as GameStats, at as Node, b as Scheduler, l as PropSchema, n as BehaviorCtor, v as Engine } from "./behavior-CKwTCjfR.js";
|
|
2
2
|
import { n as DiagnosticSink, t as EditorSwitchOptions } from "./editor-switch-BJb-CWfA.js";
|
|
3
3
|
import { i as SceneJson, s as JsonObject } from "./schema-CcoWb32N.js";
|
|
4
|
-
import { t as LoadSceneOptions } from "./loader-
|
|
4
|
+
import { t as LoadSceneOptions } from "./loader-COn5fS0o.js";
|
|
5
5
|
import { t as ParticleSim } from "./particle-sim-CwJ5rI_P.js";
|
|
6
|
-
import { n as PathGrid, s as SpatialPose } from "./pathfinding-
|
|
6
|
+
import { n as PathGrid, s as SpatialPose } from "./pathfinding-DUw9mir9.js";
|
|
7
7
|
import { AnimationClip, AnimationMixer, BufferGeometry, Color, DirectionalLight, Group, InstancedMesh, Mesh, MeshPhysicalMaterial, Object3D, PerspectiveCamera, Scene, ShaderMaterial, Vector3, WebGLRenderer } from "three";
|
|
8
8
|
import { VRM } from "@pixiv/three-vrm";
|
|
9
9
|
import { Sky } from "three/examples/jsm/objects/Sky.js";
|
|
@@ -488,6 +488,16 @@ interface CreateGame3DOptions {
|
|
|
488
488
|
/** Keep the frame rate by rendering fewer pixels while frames run slow
|
|
489
489
|
* (default ON). `false` pins the resolution — screenshots, capture, tests. */
|
|
490
490
|
adaptiveResolution?: boolean;
|
|
491
|
+
/**
|
|
492
|
+
* Keep the drawing buffer readable so the canvas can be screenshot.
|
|
493
|
+
*
|
|
494
|
+
* WebGL clears it the instant a frame composites, so `toDataURL()` — and every
|
|
495
|
+
* screenshot built on it — is BLANK without this. Off by default: it costs a
|
|
496
|
+
* buffer copy per frame and only a run that means to look at the output should
|
|
497
|
+
* pay for it. `environment.rendering.preserveDrawingBuffer` does the same from
|
|
498
|
+
* the scene.
|
|
499
|
+
*/
|
|
500
|
+
preserveDrawingBuffer?: boolean;
|
|
491
501
|
resolveScene?: LoadSceneOptions["resolveScene"];
|
|
492
502
|
/**
|
|
493
503
|
* Boot progress, for the loading screen an app already has.
|
|
@@ -534,6 +544,11 @@ interface Game3D {
|
|
|
534
544
|
sourceJson: SceneJson;
|
|
535
545
|
renderer: GameRenderer;
|
|
536
546
|
physics: Physics3D | null;
|
|
547
|
+
/**
|
|
548
|
+
* The node under a screen pixel, or null. The raycast the renderer already
|
|
549
|
+
* does — reachable now without holding the renderer.
|
|
550
|
+
*/
|
|
551
|
+
pick(x: number, y: number): Node | null;
|
|
537
552
|
/** Engine + renderer perf counters in one read (fps/nodes/triangles/…). */
|
|
538
553
|
stats(): GameStats;
|
|
539
554
|
/**
|
|
@@ -2998,6 +3013,16 @@ interface Renderer3DOptions {
|
|
|
2998
3013
|
* the resolution — for screenshots, video capture and pixel-diff tests.
|
|
2999
3014
|
*/
|
|
3000
3015
|
adaptiveResolution?: boolean;
|
|
3016
|
+
/**
|
|
3017
|
+
* Keep the drawing buffer readable so the canvas can be SCREENSHOT.
|
|
3018
|
+
*
|
|
3019
|
+
* WebGL clears it the moment a frame composites, so `canvas.toDataURL()` and
|
|
3020
|
+
* anything built on it (a Playwright screenshot, a pixel-diff test) comes
|
|
3021
|
+
* back blank without this. Off by default — it costs a buffer copy per frame
|
|
3022
|
+
* and only a run that intends to look at the output should pay it. The scene
|
|
3023
|
+
* can ask for it too: `environment.rendering.preserveDrawingBuffer`.
|
|
3024
|
+
*/
|
|
3025
|
+
preserveDrawingBuffer?: boolean;
|
|
3001
3026
|
}
|
|
3002
3027
|
/**
|
|
3003
3028
|
* WebGL presentation layer: subscribes to `engine.updated`, mirrors the active
|
package/dist/3d.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
2
|
-
import { A as Water3D, F as 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-
|
|
3
|
-
import { a as Environment3D, c as sunDirectionFromElevationAzimuth, i as syncTree, l as sunDirectionFromSky, o as horizonColorFromSky, r as Renderer3D, s as parseEnvironment3D, t as createGame3D, u as AssetStore3D } from "./create-game-
|
|
4
|
-
import { A as Terrain3D, B as keyboardIntensity, C as resolveFlowerDensity, D as BoneLookAt3D, E as Camera3D, F as InstancedMesh3D, 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, V as movementState, _ 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
|
|
2
|
+
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-BpQCbABv.js";
|
|
3
|
+
import { a as Environment3D, c as sunDirectionFromElevationAzimuth, i as syncTree, l as sunDirectionFromSky, o as horizonColorFromSky, r as Renderer3D, s as parseEnvironment3D, t as createGame3D, u as AssetStore3D } from "./create-game-sFuTLqjD.js";
|
|
4
|
+
import { A as Terrain3D, B as keyboardIntensity, C as resolveFlowerDensity, D as BoneLookAt3D, E as Camera3D, F as InstancedMesh3D, 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, V as movementState, _ 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-CQtEGogB.js";
|
|
5
5
|
import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
|
|
6
|
-
import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-
|
|
6
|
+
import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-DF8npb1O.js";
|
|
7
7
|
//#region src/3d/environment-runtime.ts
|
|
8
8
|
/**
|
|
9
9
|
* Live environment editing — the renderer re-applies `scene.environment`
|
|
@@ -298,6 +298,14 @@ declare class AudioBuses {
|
|
|
298
298
|
/** Final gain for a sound on `bus` with its own `sourceVolume` (all clamped). */
|
|
299
299
|
effectiveVolume(bus: BusName, sourceVolume: number): number;
|
|
300
300
|
/** Clamp + finite-guard a new value; emit only on a real change. */
|
|
301
|
+
/**
|
|
302
|
+
* Write THEN emit.
|
|
303
|
+
*
|
|
304
|
+
* This used to emit from inside the expression assigning the field, so every
|
|
305
|
+
* listener of `changed` read the OLD value — including the thing the signal
|
|
306
|
+
* exists for ("live re-gain of playing sounds"), which therefore re-gained to
|
|
307
|
+
* the volume you just left.
|
|
308
|
+
*/
|
|
301
309
|
private assign;
|
|
302
310
|
}
|
|
303
311
|
//#endregion
|
|
@@ -595,6 +603,25 @@ declare class InputMap {
|
|
|
595
603
|
private detach;
|
|
596
604
|
/** Load (or extend with) scene-JSON action declarations. Hard-validates shape. */
|
|
597
605
|
declare(decls: Record<string, unknown>): void;
|
|
606
|
+
/**
|
|
607
|
+
* Where the pointer is, in CANVAS pixels (top-left origin), or null when it
|
|
608
|
+
* has never been over the canvas.
|
|
609
|
+
*
|
|
610
|
+
* This is what a click-driven game asks for. `pointerDelta()` answers "how far
|
|
611
|
+
* did the mouse move" — the mouse-look question — and for a whole class of
|
|
612
|
+
* genres that is the wrong question and the only one the engine could answer.
|
|
613
|
+
* Pair it with `renderer.pick(x, y)` to get the node under the cursor.
|
|
614
|
+
*/
|
|
615
|
+
pointerPosition(): {
|
|
616
|
+
x: number;
|
|
617
|
+
y: number;
|
|
618
|
+
} | null;
|
|
619
|
+
/**
|
|
620
|
+
* @internal Feed a pointer position. `target` scales client → canvas pixels
|
|
621
|
+
* so a CSS-stretched canvas still reports coordinates its renderer can use.
|
|
622
|
+
*/
|
|
623
|
+
setPointerPosition(clientX: number, clientY: number, target?: HTMLElement): void;
|
|
624
|
+
private pointerPos;
|
|
598
625
|
/** Feed a key state change (code = KeyboardEvent.code, e.g. 'Space', 'KeyW'). */
|
|
599
626
|
handleKey(code: string, isDown: boolean): void;
|
|
600
627
|
private readonly injectedDown;
|
|
@@ -699,6 +726,17 @@ declare class InputMap {
|
|
|
699
726
|
isPressed(action: string): boolean;
|
|
700
727
|
justPressed(action: string): boolean;
|
|
701
728
|
justReleased(action: string): boolean;
|
|
729
|
+
/**
|
|
730
|
+
* Mouse button state WITHOUT declaring an action for it.
|
|
731
|
+
*
|
|
732
|
+
* A click on a tile is not a bindable action — there is no key to remap, and
|
|
733
|
+
* asking a match-3 to declare `"click": { "keys": ["Mouse0"] }` in every scene
|
|
734
|
+
* is ceremony. Buttons already live in the key set as `Mouse0`/`Mouse1`/…;
|
|
735
|
+
* these read them directly. 0 left, 1 middle, 2 right.
|
|
736
|
+
*/
|
|
737
|
+
mousePressed(button?: number): boolean;
|
|
738
|
+
mouseJustPressed(button?: number): boolean;
|
|
739
|
+
mouseJustReleased(button?: number): boolean;
|
|
702
740
|
/** Normalized direction for a vector2 action (y-down: up = -y). */
|
|
703
741
|
getVector(action: string): {
|
|
704
742
|
x: number;
|
|
@@ -753,6 +791,89 @@ declare class Scene {
|
|
|
753
791
|
toJSON(): SceneJson;
|
|
754
792
|
}
|
|
755
793
|
//#endregion
|
|
794
|
+
//#region src/core/save.d.ts
|
|
795
|
+
/**
|
|
796
|
+
* Namespaced game persistence — high scores, unlocks, settings. localStorage
|
|
797
|
+
* in the browser, in-memory headless (tests and SSR stay green). Values are
|
|
798
|
+
* JSON round-tripped, so what you get back is what you saved.
|
|
799
|
+
*
|
|
800
|
+
* const save = createSaveStore('my-game');
|
|
801
|
+
* save.set('highScore', 4200);
|
|
802
|
+
* const best = save.get('highScore', 0);
|
|
803
|
+
*/
|
|
804
|
+
interface SaveStore {
|
|
805
|
+
get<T extends JsonValue>(key: string, fallback: T): T;
|
|
806
|
+
set(key: string, value: JsonValue): void;
|
|
807
|
+
remove(key: string): void;
|
|
808
|
+
/** Wipe THIS namespace only. */
|
|
809
|
+
clear(): void;
|
|
810
|
+
}
|
|
811
|
+
declare function createSaveStore(namespace: string): SaveStore;
|
|
812
|
+
//#endregion
|
|
813
|
+
//#region src/core/settings.d.ts
|
|
814
|
+
/** One of three tiers, resolved once at boot and adjustable in an options menu. */
|
|
815
|
+
type QualityTier = "low" | "medium" | "high";
|
|
816
|
+
interface SettingsValues {
|
|
817
|
+
master: number;
|
|
818
|
+
sfx: number;
|
|
819
|
+
music: number;
|
|
820
|
+
muted: boolean;
|
|
821
|
+
quality: QualityTier;
|
|
822
|
+
/** Mouse/stick look sensitivity multiplier. */
|
|
823
|
+
sensitivity: number;
|
|
824
|
+
invertY: boolean;
|
|
825
|
+
/** Reduce camera shake, flashes and other motion. */
|
|
826
|
+
reduceMotion: boolean;
|
|
827
|
+
}
|
|
828
|
+
/** What a device probe can see without a GPU context. */
|
|
829
|
+
interface DeviceHints {
|
|
830
|
+
hardwareConcurrency?: number;
|
|
831
|
+
deviceMemory?: number;
|
|
832
|
+
coarsePointer?: boolean;
|
|
833
|
+
maxTextureSize?: number;
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* A default tier from what the browser will admit to.
|
|
837
|
+
*
|
|
838
|
+
* Deliberately crude: this picks a STARTING point, and the options menu is the
|
|
839
|
+
* real answer. A phone that reports four cores and a coarse pointer should not
|
|
840
|
+
* open on the setting tuned for a desktop GPU.
|
|
841
|
+
*/
|
|
842
|
+
declare function suggestQuality(hints: DeviceHints): QualityTier;
|
|
843
|
+
/** Read what this environment will tell us, safely, without touching WebGL. */
|
|
844
|
+
declare function readDeviceHints(): DeviceHints;
|
|
845
|
+
declare class Settings {
|
|
846
|
+
/** Fires after any change, with the key that changed. */
|
|
847
|
+
readonly changed: Signal<[keyof SettingsValues]>;
|
|
848
|
+
private readonly store;
|
|
849
|
+
private readonly values;
|
|
850
|
+
constructor(namespace?: string, store?: SaveStore);
|
|
851
|
+
get<K extends keyof SettingsValues>(key: K): SettingsValues[K];
|
|
852
|
+
set<K extends keyof SettingsValues>(key: K, value: SettingsValues[K]): void;
|
|
853
|
+
/** Every value at once — for an options screen, or a save-file dump. */
|
|
854
|
+
all(): SettingsValues;
|
|
855
|
+
/** Back to defaults, on disk too. */
|
|
856
|
+
reset(): void;
|
|
857
|
+
/**
|
|
858
|
+
* Push the saved volumes into the engine's buses, and keep writing them back
|
|
859
|
+
* whenever anything changes them.
|
|
860
|
+
*
|
|
861
|
+
* The subscription is the point: a game that sets `engine.audio.music = 0.4`
|
|
862
|
+
* from a slider has already persisted it, without knowing this class exists.
|
|
863
|
+
*/
|
|
864
|
+
bindAudio(audio: AudioBuses): () => void;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* What a quality tier MEANS, as an environment patch.
|
|
868
|
+
*
|
|
869
|
+
* Only the levers that actually cost: shadows, post, clouds, and the resolution
|
|
870
|
+
* the renderer draws at. Deliberately an `environment` patch, because
|
|
871
|
+
* `setEnvironment3D(engine, patch)` already applies one live and validated —
|
|
872
|
+
* this is not a second rendering pipeline, it is three presets for the one that
|
|
873
|
+
* exists.
|
|
874
|
+
*/
|
|
875
|
+
declare function qualityEnvironment(tier: QualityTier): Record<string, JsonValue>;
|
|
876
|
+
//#endregion
|
|
756
877
|
//#region src/core/stats.d.ts
|
|
757
878
|
/**
|
|
758
879
|
* Performance-stats shapes — pure data, importable everywhere (core stays
|
|
@@ -824,9 +945,27 @@ declare class Engine {
|
|
|
824
945
|
readonly rng: Rng;
|
|
825
946
|
/** The engine log channel (debug overlay + headless harness tail this). */
|
|
826
947
|
readonly log: LogManager;
|
|
948
|
+
/**
|
|
949
|
+
* Screen pixel → the node under it, when a renderer has offered one.
|
|
950
|
+
*
|
|
951
|
+
* The raycast has always existed (`Renderer3D.pick` / `Renderer2D.pick`) and
|
|
952
|
+
* was reachable only from whoever held the renderer — so a Behavior, which
|
|
953
|
+
* holds a node, could not use it. Every mouse-driven genre needs exactly this
|
|
954
|
+
* and had no way to ask. Instance-scoped, set by the renderer on construction
|
|
955
|
+
* and cleared on dispose; null when nothing renders (headless).
|
|
956
|
+
*/
|
|
957
|
+
picker: ((x: number, y: number) => Node | null) | null;
|
|
827
958
|
/** Global volume buses — `master` × `sfx`/`music` gain + `muted`. AudioPlayer
|
|
828
959
|
* routes its volume through this; games set it for global volume/mute. */
|
|
829
960
|
readonly audio: AudioBuses;
|
|
961
|
+
/**
|
|
962
|
+
* Persisted player settings — volume, quality, sensitivity.
|
|
963
|
+
*
|
|
964
|
+
* `createSaveStore` was good and had zero callers, so every game's volume
|
|
965
|
+
* reset on reload. Reading it here costs nothing (localStorage, once) and
|
|
966
|
+
* `bindAudio` makes the volumes write themselves.
|
|
967
|
+
*/
|
|
968
|
+
readonly settings: Settings;
|
|
830
969
|
/** Low-latency procedural-SFX player (WebAudio, headless-safe). AudioPlayer
|
|
831
970
|
* presets play through it; games may call `engine.sfx.play(...)` directly. */
|
|
832
971
|
readonly sfx: SfxEngine;
|
|
@@ -1035,4 +1174,4 @@ declare function registeredBehaviors(): string[];
|
|
|
1035
1174
|
/** Test isolation helper. */
|
|
1036
1175
|
declare function clearBehaviors(): void;
|
|
1037
1176
|
//#endregion
|
|
1038
|
-
export {
|
|
1177
|
+
export { MusicBackend as $, suggestQuality as A, Listener as B, RendererStats as C, SettingsValues as D, Settings as E, SfxEngine as F, spatialGain as G, RolloffModel as H, SfxPlayOptions as I, SFX_PRESET_NAMES as J, spatialPan as K, isAudioContextAvailable as L, createSaveStore as M, Scene as N, qualityEnvironment as O, InputMap as P, synthSfx as Q, Voice as R, GameStats as S, QualityTier as T, SpatialParams as U, ROLLOFF_MODELS as V, Vec3 as W, SfxWave as X, SfxParams as Y, SynthOptions as Z, registeredTypes as _, registerBehavior as a, Node as at, Scheduler as b, PropDef as c, LogEntry as ct, createNode as d, Signal as dt, MusicManager as et, getNodeSchema as f, SignalListener as ft, registerNode as g, mergeStaticSignals as h, getBehavior as i, BusName as it, SaveStore as j, readDeviceHints as k, PropSchema as l, LogLevel as lt, getNodeType as m, BehaviorCtor as n, PlayMusicOptions as nt, registeredBehaviors as o, NodeLifecycle as ot, getNodeSignals as p, SFX_PRESETS as q, clearBehaviors as r, AudioBuses as rt, NodeCtor as s, SceneTree as st, Behavior as t, MusicTrack as tt, clearRegistry as u, LogManager as ut, Engine as v, DeviceHints as w, EngineStats as x, EngineOptions as y, VoicePreset as z };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { m as diagnose, n as loadScene, o as computeViewport, s as resolveViewport, y as registerBehavior } from "./loader-
|
|
3
|
-
import {
|
|
2
|
+
import { m as diagnose, n as loadScene, o as computeViewport, s as resolveViewport, y as registerBehavior } from "./loader-Buk8Bu1h.js";
|
|
3
|
+
import { h as Engine, m as AudioPlayer } from "./register-CscIzJEO.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
|
-
import { i as resolveRendering, n as attachTouchControls } from "./touch-
|
|
5
|
+
import { i as resolveRendering, n as attachTouchControls } from "./touch-BoNg_MnF.js";
|
|
6
6
|
import { i as openBundledEditor, n as crossFade, r as devServerLibrary, t as teardown } from "./teardown-ByzfDPyu.js";
|
|
7
|
-
import { n as registerGameplayBehaviors } from "./gameplay-
|
|
8
|
-
import { g as PhysicsBody2D, n as UILayer, t as registerNodes2D, u as Camera2D, y as Node2D } from "./register-
|
|
7
|
+
import { n as registerGameplayBehaviors } from "./gameplay-BpQCbABv.js";
|
|
8
|
+
import { g as PhysicsBody2D, n as UILayer, t as registerNodes2D, u as Camera2D, y as Node2D } from "./register-FIJtNbub.js";
|
|
9
9
|
import { t as debugSources } from "./debug-draw-BM3DsvtT.js";
|
|
10
|
-
import { n as enablePhysics2D } from "./physics-2d-
|
|
10
|
+
import { n as enablePhysics2D } from "./physics-2d-DjXR5DMu.js";
|
|
11
11
|
import { Box3, BufferAttribute, BufferGeometry, Color, LineBasicMaterial, LineSegments, LinearFilter, NearestFilter, OrthographicCamera, Raycaster, SRGBColorSpace, Scene, TextureLoader, Vector2, Vector3, WebGLRenderer } from "three";
|
|
12
12
|
//#region src/2d/assets.ts
|
|
13
13
|
/**
|
|
@@ -269,13 +269,16 @@ var Renderer2D = class {
|
|
|
269
269
|
this.assets = opts.assets ?? new AssetStore2D(void 0, this.engine);
|
|
270
270
|
const rendering = resolveRendering(opts.engine.scene?.environment, {
|
|
271
271
|
antialias: true,
|
|
272
|
-
pixelRatio: 1
|
|
272
|
+
pixelRatio: 1,
|
|
273
|
+
preserveDrawingBuffer: false
|
|
273
274
|
}, globalThis.devicePixelRatio ?? 1, opts);
|
|
274
275
|
this.webgl = new WebGLRenderer({
|
|
275
276
|
canvas: opts.canvas,
|
|
276
|
-
antialias: rendering.antialias
|
|
277
|
+
antialias: rendering.antialias,
|
|
278
|
+
preserveDrawingBuffer: rendering.preserveDrawingBuffer
|
|
277
279
|
});
|
|
278
280
|
this.webgl.info.autoReset = false;
|
|
281
|
+
this.engine.picker = (x, y) => this.pick(x, y);
|
|
279
282
|
this.webgl.setPixelRatio(rendering.pixelRatio);
|
|
280
283
|
this.webgl.info.autoReset = false;
|
|
281
284
|
this.debugLines = new LineSegments(new BufferGeometry(), new LineBasicMaterial({
|
|
@@ -483,6 +486,7 @@ var Renderer2D = class {
|
|
|
483
486
|
};
|
|
484
487
|
}
|
|
485
488
|
dispose() {
|
|
489
|
+
if (this.engine.picker) this.engine.picker = null;
|
|
486
490
|
this.disconnect();
|
|
487
491
|
for (const scene of [this.worldScene, this.uiScene]) scene.traverse((obj) => {
|
|
488
492
|
const mesh = obj;
|
|
@@ -540,6 +544,7 @@ async function createGame2D(opts) {
|
|
|
540
544
|
const keyboard = opts.keyboard ?? (typeof window !== "undefined" ? window : false);
|
|
541
545
|
if (keyboard) engine.input.attachKeyboard(keyboard);
|
|
542
546
|
cleanups.push(wireAudioUnlock(engine, scene.root, opts.canvas));
|
|
547
|
+
cleanups.push(engine.settings.bindAudio(engine.audio));
|
|
543
548
|
const touchMode = opts.touch ?? "auto";
|
|
544
549
|
if (touchMode !== false) {
|
|
545
550
|
const host = opts.touchContainer ?? opts.canvas.parentElement ?? null;
|
|
@@ -626,6 +631,9 @@ async function createGame2D(opts) {
|
|
|
626
631
|
sourceJson,
|
|
627
632
|
renderer,
|
|
628
633
|
physics,
|
|
634
|
+
pick(x, y) {
|
|
635
|
+
return engine.picker?.(x, y) ?? null;
|
|
636
|
+
},
|
|
629
637
|
stats() {
|
|
630
638
|
return {
|
|
631
639
|
triangles: 0,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { m as diagnose, n as loadScene, y as registerBehavior } from "./loader-
|
|
3
|
-
import {
|
|
2
|
+
import { m as diagnose, n as loadScene, y as registerBehavior } from "./loader-Buk8Bu1h.js";
|
|
3
|
+
import { h as Engine, m as AudioPlayer } from "./register-CscIzJEO.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
|
-
import { i as resolveRendering, n as attachTouchControls } from "./touch-
|
|
5
|
+
import { i as resolveRendering, n as attachTouchControls } from "./touch-BoNg_MnF.js";
|
|
6
6
|
import { a as poseFromRenderer, i as openBundledEditor, n as crossFade, r as devServerLibrary, t as teardown } from "./teardown-ByzfDPyu.js";
|
|
7
|
-
import { B as createCausticsQuad, F as PhysicsBody3D, R as Node3D, n as registerGameplayBehaviors } from "./gameplay-
|
|
7
|
+
import { B as createCausticsQuad, F as PhysicsBody3D, R as Node3D, n as registerGameplayBehaviors } from "./gameplay-BpQCbABv.js";
|
|
8
8
|
import { t as debugSources } from "./debug-draw-BM3DsvtT.js";
|
|
9
|
-
import { E as Camera3D, 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, g as ModelInstance3D, n as registerNodes3D, t as resolveEnvironmentHdri, v as DirectionalLight3D } from "./environment-presets-CQtEGogB.js";
|
|
10
|
+
import { n as enablePhysics3D } from "./physics-3d-DF8npb1O.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";
|
|
@@ -1554,13 +1554,19 @@ var Renderer3D = class {
|
|
|
1554
1554
|
this.assets = opts.assets ?? new AssetStore3D(this.engine);
|
|
1555
1555
|
const rendering = resolveRendering(opts.engine.scene?.environment, {
|
|
1556
1556
|
antialias: true,
|
|
1557
|
-
pixelRatio: Math.min(globalThis.devicePixelRatio ?? 1, 2)
|
|
1558
|
-
|
|
1557
|
+
pixelRatio: Math.min(globalThis.devicePixelRatio ?? 1, 2),
|
|
1558
|
+
preserveDrawingBuffer: false
|
|
1559
|
+
}, globalThis.devicePixelRatio ?? 1, {
|
|
1560
|
+
pixelRatio: opts.pixelRatio,
|
|
1561
|
+
preserveDrawingBuffer: opts.preserveDrawingBuffer
|
|
1562
|
+
});
|
|
1559
1563
|
this.webgl = new WebGLRenderer({
|
|
1560
1564
|
canvas: opts.canvas,
|
|
1561
|
-
antialias: rendering.antialias
|
|
1565
|
+
antialias: rendering.antialias,
|
|
1566
|
+
preserveDrawingBuffer: rendering.preserveDrawingBuffer
|
|
1562
1567
|
});
|
|
1563
1568
|
this.webgl.info.autoReset = false;
|
|
1569
|
+
this.engine.picker = (x, y) => this.pick(x, y);
|
|
1564
1570
|
this.basePixelRatio = rendering.pixelRatio;
|
|
1565
1571
|
this.webgl.setPixelRatio(rendering.pixelRatio);
|
|
1566
1572
|
this.adaptive = opts.adaptiveResolution === false ? null : new AdaptiveResolution();
|
|
@@ -2077,6 +2083,7 @@ var Renderer3D = class {
|
|
|
2077
2083
|
this.webgl.shadowMap.needsUpdate = true;
|
|
2078
2084
|
}
|
|
2079
2085
|
dispose() {
|
|
2086
|
+
if (this.engine.picker) this.engine.picker = null;
|
|
2080
2087
|
this.disconnect();
|
|
2081
2088
|
this.threeScene.traverse((obj) => {
|
|
2082
2089
|
const mesh = obj;
|
|
@@ -2194,7 +2201,8 @@ async function createGame3D(opts) {
|
|
|
2194
2201
|
canvas: opts.canvas,
|
|
2195
2202
|
engine,
|
|
2196
2203
|
...opts.pixelRatio !== void 0 ? { pixelRatio: opts.pixelRatio } : {},
|
|
2197
|
-
...opts.adaptiveResolution !== void 0 ? { adaptiveResolution: opts.adaptiveResolution } : {}
|
|
2204
|
+
...opts.adaptiveResolution !== void 0 ? { adaptiveResolution: opts.adaptiveResolution } : {},
|
|
2205
|
+
...opts.preserveDrawingBuffer !== void 0 ? { preserveDrawingBuffer: opts.preserveDrawingBuffer } : {}
|
|
2198
2206
|
});
|
|
2199
2207
|
await report(.14, "renderer");
|
|
2200
2208
|
const wantDebug = opts.debug ?? false;
|
|
@@ -2254,6 +2262,7 @@ async function createGame3D(opts) {
|
|
|
2254
2262
|
opts.onProgress?.(.16 + f * .82, "shaders");
|
|
2255
2263
|
});
|
|
2256
2264
|
} catch {}
|
|
2265
|
+
cleanups.push(engine.settings.bindAudio(engine.audio));
|
|
2257
2266
|
await report(1, "ready");
|
|
2258
2267
|
function disposeGame() {
|
|
2259
2268
|
teardown([
|
|
@@ -2274,6 +2283,9 @@ async function createGame3D(opts) {
|
|
|
2274
2283
|
assetErrors() {
|
|
2275
2284
|
return renderer.assets?.errors() ?? [];
|
|
2276
2285
|
},
|
|
2286
|
+
pick(x, y) {
|
|
2287
|
+
return engine.picker?.(x, y) ?? null;
|
|
2288
|
+
},
|
|
2277
2289
|
stats() {
|
|
2278
2290
|
return {
|
|
2279
2291
|
triangles: 0,
|
package/dist/debug.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as RendererStats,
|
|
1
|
+
import { C as RendererStats, lt as LogLevel, v as Engine } from "./behavior-CKwTCjfR.js";
|
|
2
2
|
|
|
3
3
|
//#region src/debug/panel.d.ts
|
|
4
4
|
/** Minimal document surface the overlay needs (injectable for tests). */
|
package/dist/editor.js
CHANGED
|
@@ -1075,6 +1075,41 @@ var dt = {
|
|
|
1075
1075
|
en: "Child of HudLayer. Set text/size/color/background; disabled greys it out. Emits the 'pressed' signal (behaviors: node.on('pressed', ...)); press() triggers it programmatically (gamepad menus, tests).",
|
|
1076
1076
|
ko: "HudLayer의 자식. text/size/color/background를 설정하고 disabled로 비활성화합니다. 'pressed' 시그널을 내며(비헤이비어에서 node.on('pressed', ...)), press()로 코드에서도 누를 수 있습니다(게임패드 메뉴, 테스트)."
|
|
1077
1077
|
}),
|
|
1078
|
+
F("UiPanel", {
|
|
1079
|
+
en: "A box that holds other widgets — the thing a menu, options screen or inventory actually is.",
|
|
1080
|
+
ko: "다른 위젯을 담는 상자 — 메뉴·설정 화면·인벤토리가 실제로 이것입니다."
|
|
1081
|
+
}, {
|
|
1082
|
+
en: "Child of HudLayer. Widgets under it mount INSIDE it, so tree structure becomes screen structure; panels nest. layout column|row|grid with columns (an inventory is a grid panel, one child per slot), plus gap/padding/background/radius/width/height/border. width or height 0 = size to the contents.",
|
|
1083
|
+
ko: "HudLayer의 자식. 그 아래 위젯들이 이 안에 마운트되어 트리 구조가 화면 구조가 됩니다(중첩 가능). layout은 column|row|grid이고 columns와 함께 씁니다(인벤토리 = grid 패널, 슬롯당 자식 하나). gap/padding/background/radius/width/height/border 지원. width·height가 0이면 내용에 맞춰집니다."
|
|
1084
|
+
}),
|
|
1085
|
+
F("UiImage", {
|
|
1086
|
+
en: "A picture in the HUD — item icons, portraits, a logo.",
|
|
1087
|
+
ko: "HUD 안의 그림 — 아이템 아이콘, 초상화, 로고."
|
|
1088
|
+
}, {
|
|
1089
|
+
en: "src takes a url or a $assetKey (declare the icon once like any other asset). fit contain|cover|fill; tint multiplies through the picture, which is how an unaffordable item greys out in one prop; opacity for disabled states.",
|
|
1090
|
+
ko: "src는 url 또는 $assetKey(아이콘도 다른 에셋처럼 한 번만 선언). fit은 contain|cover|fill, tint는 그림에 곱해져서 살 수 없는 아이템을 프롭 하나로 회색 처리합니다. opacity로 비활성 표현."
|
|
1091
|
+
}),
|
|
1092
|
+
F("UiSlider", {
|
|
1093
|
+
en: "A value the player sets — volume, sensitivity, difficulty.",
|
|
1094
|
+
ko: "플레이어가 조절하는 값 — 볼륨, 감도, 난이도."
|
|
1095
|
+
}, {
|
|
1096
|
+
en: "Emits changed(value). label/value/min/max/step/width/color. Setting .value from a behavior updates the control WITHOUT re-emitting, so restoring a saved setting does not fire the handler that saved it.",
|
|
1097
|
+
ko: "changed(value) 시그널. label/value/min/max/step/width/color. 비헤이비어에서 .value를 설정하면 컨트롤만 갱신되고 changed는 다시 발생하지 않습니다 — 저장된 설정을 복원할 때 저장 핸들러가 다시 도는 것을 막습니다."
|
|
1098
|
+
}),
|
|
1099
|
+
F("UiToggle", {
|
|
1100
|
+
en: "An on/off switch — mute, invert-Y, fullscreen.",
|
|
1101
|
+
ko: "켜기/끄기 스위치 — 음소거, Y축 반전, 전체화면."
|
|
1102
|
+
}, {
|
|
1103
|
+
en: "Emits changed(boolean). label/value. Same no-re-emit rule as UiSlider when set from code.",
|
|
1104
|
+
ko: "changed(boolean) 시그널. label/value. 코드에서 설정할 때 재발생하지 않는 규칙은 UiSlider와 같습니다."
|
|
1105
|
+
}),
|
|
1106
|
+
F("UiSelect", {
|
|
1107
|
+
en: "One of several — quality, resolution, language.",
|
|
1108
|
+
ko: "여러 개 중 하나 — 품질, 해상도, 언어."
|
|
1109
|
+
}, {
|
|
1110
|
+
en: "options is a comma-separated list (\"low,medium,high\"); value is the current one. Emits changed(value).",
|
|
1111
|
+
ko: "options는 쉼표로 구분된 목록(\"low,medium,high\"), value가 현재 선택입니다. changed(value) 시그널."
|
|
1112
|
+
}),
|
|
1078
1113
|
F("UiDialogue", {
|
|
1079
1114
|
en: "A typewriter dialogue box with a queue and choice buttons — the RPG conversation layer.",
|
|
1080
1115
|
ko: "타자기 효과·큐·선택지 버튼을 갖춘 대화창 — RPG 대화 레이어."
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { t as registerCoreNodes } from "./register-
|
|
1
|
+
import { t as registerCoreNodes } from "./register-CscIzJEO.js";
|
|
2
2
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
3
3
|
import { t as Rng } from "./rng-DP-SR7eg.js";
|
|
4
4
|
import { i as getNodeSchema, l as registerNode } from "./registry-CJdGpT2V.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-BpQCbABv.js";
|
|
8
8
|
import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
|
|
9
9
|
import { AdditiveBlending, AnimationClip, AnimationMixer, Box3, BoxGeometry, BufferAttribute, BufferGeometry, CanvasTexture, CapsuleGeometry, Color, ConeGeometry, CylinderGeometry, DataTexture, DirectionalLight, DoubleSide, DynamicDrawUsage, Euler, Group, IcosahedronGeometry, ImageBitmapLoader, InstancedBufferAttribute, InstancedMesh, LinearFilter, LoopOnce, LoopRepeat, Matrix4, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshPhysicalMaterial, MeshStandardMaterial, NearestFilter, NoBlending, NormalBlending, PerspectiveCamera, PlaneGeometry, PointLight, Points, PointsMaterial, Quaternion, QuaternionKeyframeTrack, RGBADepthPacking, RGBAFormat, RepeatWrapping, SRGBColorSpace, ShaderChunk, ShaderMaterial, SphereGeometry, Texture, TextureLoader, UniformsLib, UniformsUtils, Vector3, Vector4, VectorKeyframeTrack } from "three";
|
|
10
10
|
import { clone } from "three/addons/utils/SkeletonUtils.js";
|