incanto 0.37.0 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/2d.d.ts +2 -2
- package/dist/2d.js +3 -3
- package/dist/3d.d.ts +33 -3
- package/dist/3d.js +3 -31
- package/dist/{behavior-5o1EkbLD.d.ts → behavior-B5PJ32eu.d.ts} +95 -6
- package/dist/{create-game-DmGc-Mrn.js → create-game-C4t5gVhc.js} +3 -3
- package/dist/{create-game-QqrrK3yr.js → create-game-DqY2lMBc.js} +781 -687
- package/dist/debug.d.ts +1 -1
- package/dist/editor.js +21 -0
- package/dist/{environment-presets-DWHxLHM5.js → environment-presets-C0Axpfth.js} +1 -1
- package/dist/gameplay.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/{loader-iGq2PT_k.d.ts → loader-DSMdqasu.d.ts} +1 -1
- package/dist/net.d.ts +1 -1
- package/dist/net.js +2 -2
- package/dist/{pathfinding-pPrqtlWS.d.ts → pathfinding-BrE5Uec6.d.ts} +1 -1
- package/dist/{physics-2d-C8Hi40qb.js → physics-2d-OfKb0PV_.js} +1 -1
- package/dist/{physics-3d-C0mWoWXC.js → physics-3d-C8242nXr.js} +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-t15rydSm.js → register-B4RRQbyq.js} +1 -1
- package/dist/{register-DOWGnxe1.js → register-Dm7nrd-E.js} +321 -33
- package/dist/{register-DFSW2Y30.js → register-DnB9m7Rl.js} +1 -1
- package/dist/{replay-DGzhZWrM.d.ts → replay-Cxrr-ApH.d.ts} +1 -1
- package/dist/{replay-BuOTl5rM.js → replay-DH0UOuZ-.js} +1 -1
- package/dist/{test-BiIO9ULW.js → test-CoDPWx-m.js} +9 -9
- package/dist/test.d.ts +3 -3
- package/dist/test.js +2 -2
- package/dist/vite.js +1 -1
- package/editor/assets/{agent8-CeeI7P_0.js → agent8-BtIlblPm.js} +1 -1
- package/editor/assets/{debug-DN9X9G6z.js → debug-BvTmHXI7.js} +1 -1
- package/editor/assets/{index-C833FBzB.js → index-BS01WWgM.js} +91 -91
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +294 -0
- package/skills/incanto-node-reference.md +45 -0
- package/skills/incanto-performance.md +212 -0
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/village-quest-3d/package.json +1 -1
package/dist/debug.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as RendererStats, b as Engine, kt as LogLevel } from "./behavior-
|
|
1
|
+
import { T as RendererStats, b as Engine, kt as LogLevel } from "./behavior-B5PJ32eu.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
|
@@ -1121,6 +1121,27 @@ var ht = {
|
|
|
1121
1121
|
en: "Options are the locales the scene declares in \"strings\", each labeled with its own endonym. Picking one switches the game live and persists it. English is the base: any key a locale omits falls back to it, on purpose.",
|
|
1122
1122
|
ko: "옵션은 씬의 \"strings\"가 선언한 로케일이며, 각 언어의 자기 이름으로 표시됩니다. 선택하면 즉시 바뀌고 저장됩니다. 영어가 기준이라 로케일이 빠뜨린 키는 의도적으로 영어로 표시됩니다."
|
|
1123
1123
|
}),
|
|
1124
|
+
R("UiQualitySelect", {
|
|
1125
|
+
en: "Graphics quality — Low, Medium, High. Already wired.",
|
|
1126
|
+
ko: "그래픽 품질 — Low, Medium, High. 이미 연결되어 있습니다."
|
|
1127
|
+
}, {
|
|
1128
|
+
en: "Low turns off shadows, bloom, post and clouds; Medium keeps shadows but makes them static and drops post; High is everything. Applies live and persists. Antialiasing follows the tier on the NEXT launch — it is a WebGL context attribute and cannot change while a context exists. Picking records a human choice, so device detection never overrides it later.",
|
|
1129
|
+
ko: "Low는 그림자·블룸·포스트·구름을 끄고, Medium은 그림자를 정적으로 유지하며 포스트를 끄고, High는 전부 켭니다. 즉시 적용되고 저장됩니다. 안티에일리어싱만 다음 실행부터 반영됩니다(WebGL 컨텍스트 속성이라 생성 후에는 못 바꿉니다). 사람이 고른 값으로 기록되어 이후 자동 감지가 덮어쓰지 않습니다."
|
|
1130
|
+
}),
|
|
1131
|
+
R("UiFrameCapSelect", {
|
|
1132
|
+
en: "Frame rate cap — 30, 60, 120 or Unlimited.",
|
|
1133
|
+
ko: "프레임 제한 — 30, 60, 120 또는 무제한."
|
|
1134
|
+
}, {
|
|
1135
|
+
en: "Gates the whole frame, not just the render, so it saves CPU as well as GPU — a cooler phone and a longer battery. Unlimited (0) is the default. Restrict the list with options, e.g. \"60,120,0\".",
|
|
1136
|
+
ko: "렌더뿐 아니라 프레임 전체를 제한하므로 GPU와 CPU를 함께 아낍니다 — 발열과 배터리에 유리합니다. 기본값은 무제한(0). options로 목록을 줄일 수 있습니다(예: \"60,120,0\")."
|
|
1137
|
+
}),
|
|
1138
|
+
R("UiRenderScaleSelect", {
|
|
1139
|
+
en: "Resolution scale — 50%, 75%, 100%.",
|
|
1140
|
+
ko: "해상도 배율 — 50%, 75%, 100%."
|
|
1141
|
+
}, {
|
|
1142
|
+
en: "The cheapest frames on a weak GPU: at 75% the fragment shaders run over 56% of the pixels for a slightly softer image and nothing else, where dropping a quality tier costs the shadows outright. Multiplies with the engine's automatic resolution governor rather than fighting it.",
|
|
1143
|
+
ko: "저사양 GPU에서 가장 값싼 프레임: 75%면 픽셀의 약 56%만 셰이딩하므로 이미지가 약간 부드러워질 뿐이지만, 품질 단계를 낮추면 그림자가 통째로 사라집니다. 엔진의 자동 해상도 조절과 충돌하지 않고 곱해집니다."
|
|
1144
|
+
}),
|
|
1124
1145
|
R("UiSelect", {
|
|
1125
1146
|
en: "One of several — quality, resolution, language.",
|
|
1126
1147
|
ko: "여러 개 중 하나 — 품질, 해상도, 언어."
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as registerCoreNodes } from "./register-
|
|
1
|
+
import { t as registerCoreNodes } from "./register-Dm7nrd-E.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-IyWCGe4q.js";
|
package/dist/gameplay.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tt as Node, b as Engine, d as PropSchema, n as BehaviorCtor, t as Behavior } from "./behavior-
|
|
1
|
+
import { Tt as Node, b as Engine, d as PropSchema, n as BehaviorCtor, t as Behavior } from "./behavior-B5PJ32eu.js";
|
|
2
2
|
import { c as JsonValue, s as JsonObject } from "./schema-CFeioQRE.js";
|
|
3
3
|
|
|
4
4
|
//#region src/gameplay/chase.d.ts
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { $ as translationKey, A as qualityEnvironment, At as LogManager, B as restoreBehaviors, C as EngineStats, Ct as AudioBuses, D as QualityTier, Dt as SceneTree, E as DeviceHints, Et as NodeLifecycle, F as RestoreReport, G as OrderGroupTable, H as createSaveStore, I as SaveSlot, J as BASE_LOCALE, K as effectiveOrder, L as SaveSlots, M as suggestQuality, Mt as SignalListener, N as Scene, O as Settings, Ot as LogEntry, P as BehaviorState, Q as suggestLocale, R as behaviorsWithoutSave, S as Scheduler, St as PlayMusicOptions, T as RendererStats, Tt as Node, U as ORDER_GROUP_BASE, V as SaveStore, W as OrderGroup, X as Localization, Y as LocaleTables, Z as T_PREFIX, _ as mergeStaticSignals, _t as SynthOptions, a as clearBehaviors, at as VoicePreset, b as Engine, bt as MusicManager, c as registeredBehaviors, ct as RolloffModel, d as PropSchema, dt as spatialGain, et as InputMap, f as clearRegistry, ft as spatialPan, g as getNodeType, gt as SfxWave, h as getNodeSignals, ht as SfxParams, i as behaviorSignals, it as Voice, j as readDeviceHints, jt as Signal, k as SettingsValues, kt as LogLevel, l as NodeCtor, lt as SpatialParams, m as getNodeSchema, mt as SFX_PRESET_NAMES, n as BehaviorCtor, nt as SfxPlayOptions, o as getBehavior, ot as Listener, p as createNode, pt as SFX_PRESETS, q as resolveOrderGroups, r as behaviorSchema, rt as isAudioContextAvailable, s as registerBehavior, st as ROLLOFF_MODELS, t as Behavior, tt as SfxEngine, u as PropDef, ut as Vec3, v as registerNode, vt as synthSfx, w as GameStats, wt as BusName, x as EngineOptions, xt as MusicTrack, y as registeredTypes, yt as MusicBackend, z as captureBehaviors } from "./behavior-
|
|
1
|
+
import { $ as translationKey, A as qualityEnvironment, At as LogManager, B as restoreBehaviors, C as EngineStats, Ct as AudioBuses, D as QualityTier, Dt as SceneTree, E as DeviceHints, Et as NodeLifecycle, F as RestoreReport, G as OrderGroupTable, H as createSaveStore, I as SaveSlot, J as BASE_LOCALE, K as effectiveOrder, L as SaveSlots, M as suggestQuality, Mt as SignalListener, N as Scene, O as Settings, Ot as LogEntry, P as BehaviorState, Q as suggestLocale, R as behaviorsWithoutSave, S as Scheduler, St as PlayMusicOptions, T as RendererStats, Tt as Node, U as ORDER_GROUP_BASE, V as SaveStore, W as OrderGroup, X as Localization, Y as LocaleTables, Z as T_PREFIX, _ as mergeStaticSignals, _t as SynthOptions, a as clearBehaviors, at as VoicePreset, b as Engine, bt as MusicManager, c as registeredBehaviors, ct as RolloffModel, d as PropSchema, dt as spatialGain, et as InputMap, f as clearRegistry, ft as spatialPan, g as getNodeType, gt as SfxWave, h as getNodeSignals, ht as SfxParams, i as behaviorSignals, it as Voice, j as readDeviceHints, jt as Signal, k as SettingsValues, kt as LogLevel, l as NodeCtor, lt as SpatialParams, m as getNodeSchema, mt as SFX_PRESET_NAMES, n as BehaviorCtor, nt as SfxPlayOptions, o as getBehavior, ot as Listener, p as createNode, pt as SFX_PRESETS, q as resolveOrderGroups, r as behaviorSchema, rt as isAudioContextAvailable, s as registerBehavior, st as ROLLOFF_MODELS, t as Behavior, tt as SfxEngine, u as PropDef, ut as Vec3, v as registerNode, vt as synthSfx, w as GameStats, wt as BusName, x as EngineOptions, xt as MusicTrack, y as registeredTypes, yt as MusicBackend, z as captureBehaviors } from "./behavior-B5PJ32eu.js";
|
|
2
2
|
import { a as Rng, c as JsonValue, d as jsonKind, i as SceneJson, l as jsonClone, n as NodeJson, o as JsonKind, r as SCENE_FORMAT, s as JsonObject, t as ConnectionJson, u as jsonEquals } from "./schema-CFeioQRE.js";
|
|
3
|
-
import { n as loadScene, t as LoadSceneOptions } from "./loader-
|
|
3
|
+
import { n as loadScene, t as LoadSceneOptions } from "./loader-DSMdqasu.js";
|
|
4
4
|
import { n as ParticleSimConfig, r as ParticleView, t as ParticleSim } from "./particle-sim-BzJ1yxoE.js";
|
|
5
|
-
import { a as AudioElementLike, i as gridFromRows, n as PathGrid, o as AudioPlayer, r as findPath, t as FindPathOptions } from "./pathfinding-
|
|
6
|
-
import { a as startRecording, c as IncantoErrorDetails, i as replay, l as auditScene, n as ReplayEvent, o as IncantoError, r as ReplayJson, s as IncantoErrorCode, t as Recorder } from "./replay-
|
|
5
|
+
import { a as AudioElementLike, i as gridFromRows, n as PathGrid, o as AudioPlayer, r as findPath, t as FindPathOptions } from "./pathfinding-BrE5Uec6.js";
|
|
6
|
+
import { a as startRecording, c as IncantoErrorDetails, i as replay, l as auditScene, n as ReplayEvent, o as IncantoError, r as ReplayJson, s as IncantoErrorCode, t as Recorder } from "./replay-Cxrr-ApH.js";
|
|
7
7
|
|
|
8
8
|
//#region src/core/audio/crossfade.d.ts
|
|
9
9
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { C as getBehavior, E as Signal, S as clearBehaviors, T as registeredBehaviors, _ as InputMap, a as SCENE_FORMAT, b as behaviorSchema, c as SceneTree, d as resolveConstants, f as Node, g as resolveOrderGroups, h as effectiveOrder, i as serializeNode, l as CONST_REF_KEY, m as ORDER_GROUP_BASE, n as loadScene, o as computeViewport, p as parseNodePath, r as Scene, s as resolveViewport, u as isConstRef, w as registerBehavior, x as behaviorSignals, y as Behavior } from "./loader-r49nDwB4.js";
|
|
2
|
-
import { A as
|
|
2
|
+
import { A as suggestLocale, B as MusicManager, C as captureBehaviors, D as BASE_LOCALE, E as LogManager, F as spatialGain, H as crossfadeGains, I as spatialPan, L as SFX_PRESETS, M as SfxEngine, N as isAudioContextAvailable, O as Localization, P as ROLLOFF_MODELS, R as SFX_PRESET_NAMES, S as behaviorsWithoutSave, T as createSaveStore, U as fadeGain, V as WebAudioMusicBackend, W as AudioBuses, _ as qualityEnvironment, a as UiSlider, b as suggestQuality, c as UiButton, d as UiBanner, f as UiBar, g as Settings, h as Engine, i as UiSelect, j as translationKey, k as T_PREFIX, l as UiDialogue, m as AudioPlayer, n as UiImage, o as UiToggle, p as UiText, r as UiPanel, s as Timer, t as registerCoreNodes, u as HudLayer, w as restoreBehaviors, x as SaveSlots, y as readDeviceHints, z as synthSfx } from "./register-Dm7nrd-E.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
4
|
import { t as Rng } from "./rng-DP-SR7eg.js";
|
|
5
|
-
import { n as startRecording, r as auditScene, t as replay } from "./replay-
|
|
5
|
+
import { n as startRecording, r as auditScene, t as replay } from "./replay-DH0UOuZ-.js";
|
|
6
6
|
import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-BLk7H2Qa.js";
|
|
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";
|
|
@@ -172,6 +172,6 @@ function newUid() {
|
|
|
172
172
|
//#endregion
|
|
173
173
|
//#region src/index.ts
|
|
174
174
|
/** Engine version. Kept in sync with package.json by the release pipeline. */
|
|
175
|
-
const VERSION = "0.
|
|
175
|
+
const VERSION = "0.38.0";
|
|
176
176
|
//#endregion
|
|
177
177
|
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 };
|
package/dist/net.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tt as Node, b as Engine, d as PropSchema, jt as Signal } from "./behavior-
|
|
1
|
+
import { Tt as Node, b as Engine, d as PropSchema, jt as Signal } from "./behavior-B5PJ32eu.js";
|
|
2
2
|
import { c as JsonValue, i as SceneJson, s as JsonObject } from "./schema-CFeioQRE.js";
|
|
3
3
|
|
|
4
4
|
//#region src/net/types.d.ts
|
package/dist/net.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as loadScene } from "./loader-r49nDwB4.js";
|
|
2
|
-
import { h as Engine } from "./register-
|
|
2
|
+
import { h as Engine } from "./register-Dm7nrd-E.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
4
|
import { t as jsonClone } from "./json-BLk7H2Qa.js";
|
|
5
5
|
import { n as createAgent8Server } from "./agent8-CvsfVskX.js";
|
|
6
|
-
import { i as applySyncPatch, n as NetworkSpawner, r as NetworkManager, t as registerNodesNet } from "./register-
|
|
6
|
+
import { i as applySyncPatch, n as NetworkSpawner, r as NetworkManager, t as registerNodesNet } from "./register-B4RRQbyq.js";
|
|
7
7
|
//#region src/net/loopback.ts
|
|
8
8
|
/**
|
|
9
9
|
* In-memory multiplayer hub implementing the SAME kernel contract as
|
|
@@ -1,7 +1,7 @@
|
|
|
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 { _ as RigidBody2D, b as validateCollider2D, g as PhysicsBody2D, h as CharacterBody2D, m as Area2D, p as Joint2D, y as Node2D } from "./register-
|
|
4
|
+
import { _ as RigidBody2D, b as validateCollider2D, g as PhysicsBody2D, h as CharacterBody2D, m as Area2D, p as Joint2D, y as Node2D } from "./register-DnB9m7Rl.js";
|
|
5
5
|
import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
|
|
6
6
|
//#region src/2d/physics/physics-2d.ts
|
|
7
7
|
var physics_2d_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -3,7 +3,7 @@ import { v as diagnose } from "./loader-r49nDwB4.js";
|
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
4
|
import { F as PhysicsBody3D, I as RigidBody3D, N as Area3D, P as CharacterBody3D, R as Node3D, z as validateCollider3D } from "./gameplay-CsJDUQh_.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-C0Axpfth.js";
|
|
7
7
|
import { Euler, Matrix4, Quaternion, Vector3 } from "three";
|
|
8
8
|
//#region src/3d/physics/collider-lines.ts
|
|
9
9
|
/**
|
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as Scene, b as Engine, n as BehaviorCtor } from "./behavior-
|
|
1
|
+
import { N as Scene, b as Engine, n as BehaviorCtor } from "./behavior-B5PJ32eu.js";
|
|
2
2
|
import { c as JsonValue } from "./schema-CFeioQRE.js";
|
|
3
3
|
import { CSSProperties, ReactNode } from "react";
|
|
4
4
|
|
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-DqY2lMBc.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-C4t5gVhc.js").then((n) => n.n)).createGame2D(o)))(opts);
|
|
160
160
|
if (disposed) {
|
|
161
161
|
next.dispose();
|
|
162
162
|
return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { E as Signal, f as Node, t as buildNodeJson } from "./loader-r49nDwB4.js";
|
|
2
|
-
import { t as registerCoreNodes } from "./register-
|
|
2
|
+
import { t as registerCoreNodes } from "./register-Dm7nrd-E.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
4
|
import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
|
|
5
5
|
import { l as registerNode } from "./registry-IyWCGe4q.js";
|
|
@@ -1403,7 +1403,10 @@ const DEFAULTS = {
|
|
|
1403
1403
|
sensitivity: 1,
|
|
1404
1404
|
invertY: false,
|
|
1405
1405
|
reduceMotion: false,
|
|
1406
|
-
language: "en"
|
|
1406
|
+
language: "en",
|
|
1407
|
+
qualityChosen: false,
|
|
1408
|
+
maxFps: 0,
|
|
1409
|
+
renderScale: 1
|
|
1407
1410
|
};
|
|
1408
1411
|
const TIERS = [
|
|
1409
1412
|
"low",
|
|
@@ -1469,6 +1472,64 @@ var Settings = class {
|
|
|
1469
1472
|
for (const key of Object.keys(DEFAULTS)) this.set(key, DEFAULTS[key]);
|
|
1470
1473
|
}
|
|
1471
1474
|
/**
|
|
1475
|
+
* Choose a starting tier from the device, ONCE.
|
|
1476
|
+
*
|
|
1477
|
+
* Only on a first visit: after someone has picked a tier, re-detecting on
|
|
1478
|
+
* every launch would silently undo their choice — which is the behaviour every
|
|
1479
|
+
* player experiences as "the settings do not save".
|
|
1480
|
+
*/
|
|
1481
|
+
autoQuality(hints = readDeviceHints()) {
|
|
1482
|
+
if (!this.values.qualityChosen) this.values.quality = suggestQuality(hints);
|
|
1483
|
+
return this.values.quality;
|
|
1484
|
+
}
|
|
1485
|
+
/** Record that the tier came from a person, not from the device probe. */
|
|
1486
|
+
chooseQuality(tier) {
|
|
1487
|
+
this.set("quality", tier);
|
|
1488
|
+
this.set("qualityChosen", true);
|
|
1489
|
+
}
|
|
1490
|
+
/**
|
|
1491
|
+
* Apply the saved quality tier to a live scene, and keep applying it.
|
|
1492
|
+
*
|
|
1493
|
+
* The same shape as `bindAudio` and `bindLocale`. Until 0.38 this did not
|
|
1494
|
+
* exist: `settings.quality` was written to disk and read by NOBODY, and
|
|
1495
|
+
* `qualityEnvironment` — the function that turns a tier into something the
|
|
1496
|
+
* renderer understands — emitted patches the environment parser rejects, for
|
|
1497
|
+
* all three tiers. Both were public, documented and never once called.
|
|
1498
|
+
*/
|
|
1499
|
+
bindQuality(apply) {
|
|
1500
|
+
apply(qualityEnvironment(this.values.quality));
|
|
1501
|
+
return this.changed.connect((key) => {
|
|
1502
|
+
if (key === "quality") apply(qualityEnvironment(this.values.quality));
|
|
1503
|
+
});
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Apply the saved frame cap, and again whenever it changes.
|
|
1507
|
+
*
|
|
1508
|
+
* Separate from `bindQuality` because it is not a tier: a player caps the
|
|
1509
|
+
* frame rate to keep a phone cool or a battery alive, on the highest visual
|
|
1510
|
+
* settings the device can hold, and those two choices do not belong on one
|
|
1511
|
+
* slider. 0 means uncapped. Returns the unsubscribe.
|
|
1512
|
+
*/
|
|
1513
|
+
bindFrameCap(apply) {
|
|
1514
|
+
apply(this.values.maxFps);
|
|
1515
|
+
return this.changed.connect((key) => {
|
|
1516
|
+
if (key === "maxFps") apply(this.values.maxFps);
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1519
|
+
/**
|
|
1520
|
+
* Apply the saved resolution multiplier, and again whenever it changes.
|
|
1521
|
+
*
|
|
1522
|
+
* The lever that buys the most frames per unit of ugliness on a weak GPU —
|
|
1523
|
+
* shading 44% of the pixels at 0.66 costs a soft image and nothing else,
|
|
1524
|
+
* while dropping a quality tier costs shadows entirely.
|
|
1525
|
+
*/
|
|
1526
|
+
bindRenderScale(apply) {
|
|
1527
|
+
apply(this.values.renderScale);
|
|
1528
|
+
return this.changed.connect((key) => {
|
|
1529
|
+
if (key === "renderScale") apply(this.values.renderScale);
|
|
1530
|
+
});
|
|
1531
|
+
}
|
|
1532
|
+
/**
|
|
1472
1533
|
* Apply the saved language, and keep it in step both ways.
|
|
1473
1534
|
*
|
|
1474
1535
|
* The same shape as `bindAudio`: a game that writes
|
|
@@ -1502,45 +1563,67 @@ var Settings = class {
|
|
|
1502
1563
|
}
|
|
1503
1564
|
};
|
|
1504
1565
|
/**
|
|
1505
|
-
* What a quality tier MEANS, as
|
|
1566
|
+
* What a quality tier MEANS, as a LIVE environment patch.
|
|
1567
|
+
*
|
|
1568
|
+
* Only the levers that actually cost: shadows, post, bloom and clouds.
|
|
1569
|
+
* Deliberately an `environment` patch, because `setEnvironment3D(engine, patch)`
|
|
1570
|
+
* already applies one live and validated — this is not a second rendering
|
|
1571
|
+
* pipeline, it is three presets for the one that exists.
|
|
1506
1572
|
*
|
|
1507
|
-
*
|
|
1508
|
-
*
|
|
1509
|
-
*
|
|
1510
|
-
*
|
|
1511
|
-
*
|
|
1573
|
+
* The `off` spelling matters and got this wrong for three releases: every tier
|
|
1574
|
+
* emitted `{ enabled: false }`, which the environment parser rejects
|
|
1575
|
+
* (`environment.bloom has unknown key 'enabled'`). Nothing called this function,
|
|
1576
|
+
* so nothing found out. In a live patch `null` DELETES a key — that is how a
|
|
1577
|
+
* stage is turned off — and `shadows` alone takes a real `false`.
|
|
1578
|
+
*
|
|
1579
|
+
* Antialiasing and pixel ratio are NOT here: `antialias` is a WebGL context
|
|
1580
|
+
* attribute and cannot change without rebuilding the renderer. See
|
|
1581
|
+
* `qualityRendering`.
|
|
1512
1582
|
*/
|
|
1513
1583
|
function qualityEnvironment(tier) {
|
|
1514
1584
|
if (tier === "low") return {
|
|
1515
|
-
shadows:
|
|
1516
|
-
bloom:
|
|
1517
|
-
post:
|
|
1518
|
-
clouds:
|
|
1519
|
-
rendering: {
|
|
1520
|
-
antialias: false,
|
|
1521
|
-
pixelRatio: 1
|
|
1522
|
-
}
|
|
1585
|
+
shadows: false,
|
|
1586
|
+
bloom: null,
|
|
1587
|
+
post: null,
|
|
1588
|
+
clouds: null
|
|
1523
1589
|
};
|
|
1524
1590
|
if (tier === "medium") return {
|
|
1525
|
-
shadows: {
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
},
|
|
1529
|
-
bloom: { enabled: true },
|
|
1530
|
-
post: { enabled: false },
|
|
1531
|
-
rendering: {
|
|
1532
|
-
antialias: true,
|
|
1533
|
-
pixelRatio: 1
|
|
1534
|
-
}
|
|
1591
|
+
shadows: { static: true },
|
|
1592
|
+
bloom: {},
|
|
1593
|
+
post: null
|
|
1535
1594
|
};
|
|
1536
1595
|
return {
|
|
1537
|
-
shadows:
|
|
1538
|
-
bloom: {
|
|
1539
|
-
post: {
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1596
|
+
shadows: true,
|
|
1597
|
+
bloom: {},
|
|
1598
|
+
post: {}
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
/**
|
|
1602
|
+
* What a quality tier means for the levers that can only be set at BOOT.
|
|
1603
|
+
*
|
|
1604
|
+
* `antialias` is a context attribute: three fixes it when the WebGL context is
|
|
1605
|
+
* created, so a settings menu that changes it is choosing what the NEXT launch
|
|
1606
|
+
* gets. Every engine has this constraint and every game's options screen says
|
|
1607
|
+
* "requires restart" next to it — `createGame3D` reads the saved tier at boot,
|
|
1608
|
+
* so the restart is all it takes.
|
|
1609
|
+
*
|
|
1610
|
+
* `pixelRatio` CAN change live (adaptive resolution already does it), but it
|
|
1611
|
+
* belongs with antialias as "how many pixels do we draw" rather than "what is in
|
|
1612
|
+
* the scene".
|
|
1613
|
+
*/
|
|
1614
|
+
function qualityRendering(tier) {
|
|
1615
|
+
const device = Math.min(globalThis.devicePixelRatio ?? 1, 2);
|
|
1616
|
+
if (tier === "low") return {
|
|
1617
|
+
antialias: false,
|
|
1618
|
+
pixelRatio: 1
|
|
1619
|
+
};
|
|
1620
|
+
if (tier === "medium") return {
|
|
1621
|
+
antialias: true,
|
|
1622
|
+
pixelRatio: Math.min(device, 1.5)
|
|
1623
|
+
};
|
|
1624
|
+
return {
|
|
1625
|
+
antialias: true,
|
|
1626
|
+
pixelRatio: device
|
|
1544
1627
|
};
|
|
1545
1628
|
}
|
|
1546
1629
|
//#endregion
|
|
@@ -1671,6 +1754,7 @@ var Engine = class {
|
|
|
1671
1754
|
this.maxFixedSteps = opts.maxFixedStepsPerTick ?? 5;
|
|
1672
1755
|
this.scheduler = opts.scheduler ?? rafScheduler;
|
|
1673
1756
|
this.rng = new Rng(opts.seed ?? Math.random() * 4294967295 >>> 0);
|
|
1757
|
+
this.maxFps = opts.maxFps ?? 0;
|
|
1674
1758
|
}
|
|
1675
1759
|
get scene() {
|
|
1676
1760
|
return this._scene;
|
|
@@ -1693,6 +1777,7 @@ var Engine = class {
|
|
|
1693
1777
|
start() {
|
|
1694
1778
|
if (this.disposeScheduler) return;
|
|
1695
1779
|
this.disposeScheduler = this.scheduler((now) => {
|
|
1780
|
+
if (!this.frameIsDue(now)) return;
|
|
1696
1781
|
try {
|
|
1697
1782
|
this.tick(now);
|
|
1698
1783
|
} catch (error) {
|
|
@@ -1701,6 +1786,51 @@ var Engine = class {
|
|
|
1701
1786
|
});
|
|
1702
1787
|
}
|
|
1703
1788
|
/**
|
|
1789
|
+
* The frame cap: fps, or 0 for "as fast as the display goes" (the default).
|
|
1790
|
+
*
|
|
1791
|
+
* Live — a settings menu writes it mid-game. It gates the whole frame, not
|
|
1792
|
+
* just the render: an uncapped loop on a 144 Hz phone burns battery running
|
|
1793
|
+
* game logic nobody sees.
|
|
1794
|
+
*
|
|
1795
|
+
* `tick()` is deliberately NOT gated. A headless harness driving its own
|
|
1796
|
+
* clock asked for that frame; the cap is about the real-time loop.
|
|
1797
|
+
*/
|
|
1798
|
+
maxFps = 0;
|
|
1799
|
+
nextFrameAt = 0;
|
|
1800
|
+
lastOfferedAt = null;
|
|
1801
|
+
displayPeriodMs = 0;
|
|
1802
|
+
/**
|
|
1803
|
+
* Should this display frame run?
|
|
1804
|
+
*
|
|
1805
|
+
* The obvious `if (now - last < interval) return` is wrong in a way that only
|
|
1806
|
+
* shows up between the round numbers: a 45 fps cap on a 60 Hz display misses
|
|
1807
|
+
* every other deadline by a fraction of a millisecond, waits a whole display
|
|
1808
|
+
* frame more, and delivers 30 — asking for 45 makes the game slower than not
|
|
1809
|
+
* capping at all. The fix is to allow a frame that is within half a display
|
|
1810
|
+
* period of its deadline, and to advance the deadline by the interval rather
|
|
1811
|
+
* than from `now`, so the error does not accumulate.
|
|
1812
|
+
*/
|
|
1813
|
+
frameIsDue(now) {
|
|
1814
|
+
const prev = this.lastOfferedAt;
|
|
1815
|
+
this.lastOfferedAt = now;
|
|
1816
|
+
if (prev !== null) {
|
|
1817
|
+
const delta = now - prev;
|
|
1818
|
+
if (delta > 0 && delta < 500) this.displayPeriodMs = this.displayPeriodMs === 0 ? delta : this.displayPeriodMs * .9 + delta * .1;
|
|
1819
|
+
}
|
|
1820
|
+
if (!(this.maxFps > 0)) {
|
|
1821
|
+
this.nextFrameAt = 0;
|
|
1822
|
+
return true;
|
|
1823
|
+
}
|
|
1824
|
+
const interval = 1e3 / this.maxFps;
|
|
1825
|
+
if (this.nextFrameAt === 0) {
|
|
1826
|
+
this.nextFrameAt = now + interval;
|
|
1827
|
+
return true;
|
|
1828
|
+
}
|
|
1829
|
+
if (now < this.nextFrameAt - this.displayPeriodMs * .5) return false;
|
|
1830
|
+
this.nextFrameAt = Math.max(now, this.nextFrameAt + interval);
|
|
1831
|
+
return true;
|
|
1832
|
+
}
|
|
1833
|
+
/**
|
|
1704
1834
|
* A frame threw somewhere outside a single node (a renderer, physics, a
|
|
1705
1835
|
* signal handler). Report the first one and count the rest: a broken frame
|
|
1706
1836
|
* repeats sixty times a second, and sixty identical traces a second is how
|
|
@@ -3241,6 +3371,161 @@ var UiLanguageSelect = class extends UiSelect {
|
|
|
3241
3371
|
return ENDONYMS[value] ?? value;
|
|
3242
3372
|
}
|
|
3243
3373
|
};
|
|
3374
|
+
/**
|
|
3375
|
+
* A select bound to one persisted setting — the shape all three graphics
|
|
3376
|
+
* controls share.
|
|
3377
|
+
*
|
|
3378
|
+
* The engine owns quality tiers, the frame cap and the resolution scale, and
|
|
3379
|
+
* every one of them was reachable only from TypeScript. A vibe-coded game whose
|
|
3380
|
+
* whole world is JSON could not put a graphics menu on screen without a
|
|
3381
|
+
* behavior, a signal connection, and the knowledge that `Settings` persists —
|
|
3382
|
+
* which is how "supports low-end devices" quietly becomes "does not".
|
|
3383
|
+
*
|
|
3384
|
+
* Subclasses say which setting, what the options are, and what they read as.
|
|
3385
|
+
*/
|
|
3386
|
+
var UiSettingSelect = class extends UiSelect {
|
|
3387
|
+
/** Last value we PUSHED into the select, to tell an engine change from a player one. */
|
|
3388
|
+
lastPushed = null;
|
|
3389
|
+
_engine() {
|
|
3390
|
+
return this.tree?.engine ?? null;
|
|
3391
|
+
}
|
|
3392
|
+
/**
|
|
3393
|
+
* The translated option label, or the English one.
|
|
3394
|
+
*
|
|
3395
|
+
* `locale.t` returns the KEY when nothing declares it, and a menu reading
|
|
3396
|
+
* `settings.quality.high` is worse than one reading `High`. English is the
|
|
3397
|
+
* base language and the fallback, always.
|
|
3398
|
+
*/
|
|
3399
|
+
_tOr(key, fallback) {
|
|
3400
|
+
const locale = this._engine()?.locale;
|
|
3401
|
+
return locale?.has(key) ? locale.t(key) : fallback;
|
|
3402
|
+
}
|
|
3403
|
+
_sync() {
|
|
3404
|
+
const engine = this._engine();
|
|
3405
|
+
if (engine) {
|
|
3406
|
+
const stored = this._read(engine);
|
|
3407
|
+
if (stored !== this.lastPushed) {
|
|
3408
|
+
this.lastPushed = stored;
|
|
3409
|
+
this.value = stored;
|
|
3410
|
+
} else if (this.value !== stored) {
|
|
3411
|
+
this._write(engine, this.value);
|
|
3412
|
+
this.lastPushed = this._read(engine);
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
super._sync();
|
|
3416
|
+
}
|
|
3417
|
+
};
|
|
3418
|
+
/**
|
|
3419
|
+
* The graphics quality picker.
|
|
3420
|
+
*
|
|
3421
|
+
* ```json
|
|
3422
|
+
* { "name": "Quality", "type": "UiQualitySelect" }
|
|
3423
|
+
* ```
|
|
3424
|
+
*
|
|
3425
|
+
* Writes through `chooseQuality`, NOT `set('quality')`: a tier a person picked
|
|
3426
|
+
* has to survive the next launch's device detection, and the two are
|
|
3427
|
+
* indistinguishable afterwards unless the choice is recorded as one.
|
|
3428
|
+
*
|
|
3429
|
+
* Shadows, bloom, post and clouds follow immediately. Antialiasing follows on
|
|
3430
|
+
* the next launch — it is a WebGL context attribute and cannot change while a
|
|
3431
|
+
* context exists.
|
|
3432
|
+
*/
|
|
3433
|
+
var UiQualitySelect = class extends UiSettingSelect {
|
|
3434
|
+
static typeName = "UiQualitySelect";
|
|
3435
|
+
static props = {
|
|
3436
|
+
...UiSelect.props,
|
|
3437
|
+
label: { default: "Quality" },
|
|
3438
|
+
options: { default: "low,medium,high" }
|
|
3439
|
+
};
|
|
3440
|
+
label = "Quality";
|
|
3441
|
+
options = "low,medium,high";
|
|
3442
|
+
_key() {
|
|
3443
|
+
return "quality";
|
|
3444
|
+
}
|
|
3445
|
+
_read(engine) {
|
|
3446
|
+
return String(engine.settings.get("quality"));
|
|
3447
|
+
}
|
|
3448
|
+
_write(engine, value) {
|
|
3449
|
+
if (value === "low" || value === "medium" || value === "high") engine.settings.chooseQuality(value);
|
|
3450
|
+
}
|
|
3451
|
+
_optionLabel(value) {
|
|
3452
|
+
const english = value.charAt(0).toUpperCase() + value.slice(1);
|
|
3453
|
+
return this._tOr(`settings.quality.${value}`, english);
|
|
3454
|
+
}
|
|
3455
|
+
};
|
|
3456
|
+
/**
|
|
3457
|
+
* The frame-rate cap: fewer frames, a cooler phone, a longer battery.
|
|
3458
|
+
*
|
|
3459
|
+
* ```json
|
|
3460
|
+
* { "name": "FrameCap", "type": "UiFrameCapSelect" }
|
|
3461
|
+
* ```
|
|
3462
|
+
*
|
|
3463
|
+
* `0` is uncapped and is the default — a cap nobody asked for is a downgrade.
|
|
3464
|
+
* The cap gates the whole frame, so it saves the CPU as well as the GPU.
|
|
3465
|
+
*/
|
|
3466
|
+
var UiFrameCapSelect = class extends UiSettingSelect {
|
|
3467
|
+
static typeName = "UiFrameCapSelect";
|
|
3468
|
+
static props = {
|
|
3469
|
+
...UiSelect.props,
|
|
3470
|
+
label: { default: "Frame rate" },
|
|
3471
|
+
/** `0` means uncapped and reads as a word, not as a number. */
|
|
3472
|
+
options: { default: "30,60,120,0" }
|
|
3473
|
+
};
|
|
3474
|
+
label = "Frame rate";
|
|
3475
|
+
options = "30,60,120,0";
|
|
3476
|
+
_key() {
|
|
3477
|
+
return "maxFps";
|
|
3478
|
+
}
|
|
3479
|
+
_read(engine) {
|
|
3480
|
+
return String(engine.settings.get("maxFps"));
|
|
3481
|
+
}
|
|
3482
|
+
_write(engine, value) {
|
|
3483
|
+
const fps = Number(value);
|
|
3484
|
+
if (!Number.isFinite(fps) || fps < 0) return;
|
|
3485
|
+
engine.settings.set("maxFps", fps);
|
|
3486
|
+
engine.maxFps = fps;
|
|
3487
|
+
}
|
|
3488
|
+
_optionLabel(value) {
|
|
3489
|
+
if (value === "0") return this._tOr("settings.frameCap.unlimited", "Unlimited");
|
|
3490
|
+
return value;
|
|
3491
|
+
}
|
|
3492
|
+
};
|
|
3493
|
+
/**
|
|
3494
|
+
* The resolution scale — the cheapest frames on a weak GPU.
|
|
3495
|
+
*
|
|
3496
|
+
* ```json
|
|
3497
|
+
* { "name": "Resolution", "type": "UiRenderScaleSelect" }
|
|
3498
|
+
* ```
|
|
3499
|
+
*
|
|
3500
|
+
* At 75% the fragment shaders run over 56% of the pixels for a slightly softer
|
|
3501
|
+
* image and nothing else, where dropping a quality tier costs the shadows
|
|
3502
|
+
* outright. Reads as a percentage, because `0.75` means nothing to a player.
|
|
3503
|
+
*/
|
|
3504
|
+
var UiRenderScaleSelect = class extends UiSettingSelect {
|
|
3505
|
+
static typeName = "UiRenderScaleSelect";
|
|
3506
|
+
static props = {
|
|
3507
|
+
...UiSelect.props,
|
|
3508
|
+
label: { default: "Resolution" },
|
|
3509
|
+
options: { default: "0.5,0.75,1" }
|
|
3510
|
+
};
|
|
3511
|
+
label = "Resolution";
|
|
3512
|
+
options = "0.5,0.75,1";
|
|
3513
|
+
_key() {
|
|
3514
|
+
return "renderScale";
|
|
3515
|
+
}
|
|
3516
|
+
_read(engine) {
|
|
3517
|
+
return String(engine.settings.get("renderScale"));
|
|
3518
|
+
}
|
|
3519
|
+
_write(engine, value) {
|
|
3520
|
+
const scale = Number(value);
|
|
3521
|
+
if (!Number.isFinite(scale) || scale <= 0) return;
|
|
3522
|
+
engine.settings.set("renderScale", scale);
|
|
3523
|
+
}
|
|
3524
|
+
_optionLabel(value) {
|
|
3525
|
+
const pct = Math.round(Number(value) * 100);
|
|
3526
|
+
return Number.isFinite(pct) ? `${pct}%` : value;
|
|
3527
|
+
}
|
|
3528
|
+
};
|
|
3244
3529
|
//#endregion
|
|
3245
3530
|
//#region src/core/register.ts
|
|
3246
3531
|
/**
|
|
@@ -3264,6 +3549,9 @@ function registerCoreNodes() {
|
|
|
3264
3549
|
registerNode(UiToggle);
|
|
3265
3550
|
registerNode(UiSelect);
|
|
3266
3551
|
registerNode(UiLanguageSelect);
|
|
3552
|
+
registerNode(UiQualitySelect);
|
|
3553
|
+
registerNode(UiFrameCapSelect);
|
|
3554
|
+
registerNode(UiRenderScaleSelect);
|
|
3267
3555
|
}
|
|
3268
3556
|
//#endregion
|
|
3269
|
-
export {
|
|
3557
|
+
export { suggestLocale as A, MusicManager as B, captureBehaviors as C, BASE_LOCALE as D, LogManager as E, spatialGain as F, crossfadeGains as H, spatialPan as I, SFX_PRESETS as L, SfxEngine as M, isAudioContextAvailable as N, Localization as O, ROLLOFF_MODELS as P, SFX_PRESET_NAMES as R, behaviorsWithoutSave as S, createSaveStore as T, fadeGain as U, WebAudioMusicBackend as V, AudioBuses as W, qualityEnvironment as _, UiSlider as a, suggestQuality as b, UiButton as c, UiBanner as d, UiBar as f, Settings as g, Engine as h, UiSelect as i, translationKey as j, T_PREFIX as k, UiDialogue as l, AudioPlayer as m, UiImage as n, UiToggle as o, UiText as p, UiPanel as r, Timer as s, registerCoreNodes as t, HudLayer as u, qualityRendering as v, restoreBehaviors as w, SaveSlots as x, readDeviceHints as y, synthSfx as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { f as Node, h as effectiveOrder } from "./loader-r49nDwB4.js";
|
|
2
|
-
import { t as registerCoreNodes } from "./register-
|
|
2
|
+
import { t as registerCoreNodes } from "./register-Dm7nrd-E.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
4
|
import { t as Rng } from "./rng-DP-SR7eg.js";
|
|
5
5
|
import { i as getNodeSchema, l as registerNode } from "./registry-IyWCGe4q.js";
|