incanto 0.70.0 → 0.71.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-verify.mjs +36 -98
- package/dist/2d.d.ts +18 -3
- package/dist/2d.js +3 -3
- package/dist/3d.d.ts +3 -3
- package/dist/3d.js +6 -6
- package/dist/{agent8-CmNF01gA.js → agent8-Cfmd3ar_.js} +1 -1
- package/dist/{audio-player-DaMxqfNE.d.ts → audio-player-L8yccdMP.d.ts} +1 -1
- package/dist/{behavior-DZExDn9o.d.ts → behavior-Dcz0fr1S.d.ts} +11 -0
- package/dist/{create-game-Bwvh6q8A.js → create-game-CH4kt78v.js} +7 -7
- package/dist/{create-game-C7ffQWW7.js → create-game-LCHBLfA4.js} +7 -7
- package/dist/debug.d.ts +1 -1
- package/dist/editor.js +29 -25
- package/dist/{environment-presets-D6Q5BxeE.js → environment-presets-99BzP_L-.js} +3 -3
- package/dist/{frame-report-Dlq13Gyj.js → frame-report-D-_7YF2G.js} +1 -1
- package/dist/{gameplay-BfHkuzVb.js → gameplay-CNULJvwh.js} +108 -6
- package/dist/gameplay.d.ts +68 -4
- package/dist/gameplay.js +2 -2
- package/dist/index.d.ts +27 -4
- package/dist/index.js +4 -4
- package/dist/{loader-Cff09LMm.d.ts → loader-8-IHvbKD.d.ts} +1 -1
- package/dist/net.d.ts +2 -2
- package/dist/net.js +2 -2
- package/dist/{physics-2d-CE0Qvy3V.js → physics-2d-FhrXUc6B.js} +2 -2
- package/dist/{physics-3d-CpH-2gn5.js → physics-3d-CFEGxBXZ.js} +3 -3
- package/dist/{picking-CQJ_PJKh.js → picking-DVo7fI13.js} +3 -3
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-Bkk0wSDB.js → register-BYQCBySi.js} +100 -8
- package/dist/{register-6DYnKZcy.js → register-DuVdzxbq.js} +49 -15
- package/dist/{replay-DjAkAzMq.js → replay-DEvp3kyV.js} +2 -2
- package/dist/{replay-Dmw-PKQu.d.ts → replay-F7IZHdFR.d.ts} +1 -1
- package/dist/{save-slots-BXVg148r.js → save-slots-Bvuh2p_r.js} +56 -3
- package/dist/{split-screen--k-XpBjr.d.ts → split-screen-CIYf1zSf.d.ts} +2 -2
- package/dist/{split-screen-PL78oVXP.js → split-screen-eULetcg-.js} +3 -3
- package/dist/{src-Cxfiv1Hg.js → src-_jk0qLsS.js} +1 -1
- package/dist/{test-iHYVUcDK.js → test-CmN54kWv.js} +252 -24
- package/dist/test.d.ts +113 -5
- package/dist/test.js +3 -3
- package/dist/vite.js +3 -3
- package/editor/assets/{agent8-D0MS174y.js → agent8-yLIEYHbd.js} +1 -1
- package/editor/assets/{debug-BnXkKuYu.js → debug-u31w_yhq.js} +1 -1
- package/editor/assets/{index-CIu3uc3l.js → index-DK9xMGpW.js} +94 -94
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +4 -0
- package/skills/incanto-behaviors-and-scripts.md +30 -9
- package/skills/incanto-building-2d-games.md +20 -2
- package/skills/incanto-gameplay-behaviors.md +63 -1
- package/skills/incanto-hud.md +14 -0
- package/skills/incanto-node-reference.md +18 -2
- package/skills/incanto-playtesting.md +34 -0
- package/skills/incanto-save-slots.md +56 -1
- package/skills/incanto-verifying-your-game.md +11 -0
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/beacon-isle-3d/src/game.scene.json +44 -226
- package/templates-app/molehill-2d/package.json +1 -1
- package/templates-app/molehill-2d/src/game.scene.json +10 -60
- package/templates-app/platformer-2d/package.json +1 -1
- package/templates-app/platformer-2d/src/game.scene.json +80 -416
- package/templates-app/star-survivor/package.json +1 -1
- package/templates-app/star-survivor/src/game.scene.json +5 -24
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/tps-3d/src/game.scene.json +13 -71
- package/templates-app/village-quest-3d/package.json +1 -1
- package/templates-app/village-quest-3d/src/behaviors.ts +21 -4
- package/templates-app/village-quest-3d/src/grove.scene.json +16 -87
- package/templates-app/village-quest-3d/src/village.scene.json +5 -27
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as jsonClone } from "./json-CfTjpvW8.js";
|
|
2
|
-
import {
|
|
2
|
+
import { B as HudLayer, J as Node, K as requireNumber, P as effectiveOrder, Y as diagnose, d as rebuildOptions, et as Behavior, f as rememberAuthoredPath, h as loadScene, n as SaveSlots, ot as registerBehavior, s as duplicateNode } from "./save-slots-Bvuh2p_r.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
4
|
import { t as Rng } from "./rng-CDOMybym.js";
|
|
5
5
|
import { h as didYouMean } from "./touch-BnCyPA0G.js";
|
|
@@ -6984,6 +6984,103 @@ function findCollector(node, group) {
|
|
|
6984
6984
|
return null;
|
|
6985
6985
|
}
|
|
6986
6986
|
//#endregion
|
|
6987
|
+
//#region src/gameplay/prefab-shelf.ts
|
|
6988
|
+
/**
|
|
6989
|
+
* A shelf of templates the GAME clones itself — towers, bolts, damage numbers.
|
|
6990
|
+
*
|
|
6991
|
+
* `Spawner` detaches its one prefab at enter, so a spawned enemy's whole
|
|
6992
|
+
* subtree is live and nobody has to think about it. A game that clones on its
|
|
6993
|
+
* own terms — a tower the player places, a bolt that tower fires — has no
|
|
6994
|
+
* spawner, so its templates sat in the tree as LIVE nodes: their behaviours
|
|
6995
|
+
* ticked, their turrets shot, and `visible: false` hid a node without switching
|
|
6996
|
+
* it off. The documented answer was to author every template `"enabled": false`
|
|
6997
|
+
* and wake the clone with `clone.behavior?.enable()`.
|
|
6998
|
+
*
|
|
6999
|
+
* That wakes ONE node, and the same docs teach that a node carries one
|
|
7000
|
+
* behaviour — so a prefab's parts live on children, and every one of those
|
|
7001
|
+
* stays asleep, silently and for good, because `enabled` is a pause switch that
|
|
7002
|
+
* never complains. Measured on a shipped tower defense: the bolt's
|
|
7003
|
+
* `Projectile` was woken and its sibling `Lifetime` was not, so every bolt that
|
|
7004
|
+
* MISSED flew forever — five still in the tree at 69 seconds, in a game that
|
|
7005
|
+
* passed its harness, its audit and every rung of the ladder.
|
|
7006
|
+
*
|
|
7007
|
+
* ```json
|
|
7008
|
+
* { "name": "Prefabs", "type": "Node2D", "script": { "name": "PrefabShelf" },
|
|
7009
|
+
* "children": [ { "name": "Tower", "type": "Node2D", "children": [] } ] }
|
|
7010
|
+
* ```
|
|
7011
|
+
* ```ts
|
|
7012
|
+
* const shelf = this.node.getNode('/Game/Prefabs').behavior as PrefabShelf;
|
|
7013
|
+
* const tower = shelf.make('Tower'); // detached, like `duplicateNode`
|
|
7014
|
+
* tower.position = at; // set it up BEFORE it readies
|
|
7015
|
+
* this.node.getNode('/Game/Towers').addChild(tower);
|
|
7016
|
+
* ```
|
|
7017
|
+
*
|
|
7018
|
+
* The children never ENTER the tree, so nothing has to be asleep, nothing has
|
|
7019
|
+
* to be hidden, and `make()` hands back a clone that is awake all the way down.
|
|
7020
|
+
*/
|
|
7021
|
+
var PrefabShelf = class extends Behavior {
|
|
7022
|
+
static props = {
|
|
7023
|
+
/**
|
|
7024
|
+
* Which children to take, comma-separated. Empty (the default) takes them
|
|
7025
|
+
* ALL, which is what a shelf is; name them when the node doubles as
|
|
7026
|
+
* something else and only some of its children are templates.
|
|
7027
|
+
*/
|
|
7028
|
+
prefabs: { default: "" } };
|
|
7029
|
+
static signals = [];
|
|
7030
|
+
prefabs = "";
|
|
7031
|
+
/** Templates, in the order they were authored. */
|
|
7032
|
+
held = /* @__PURE__ */ new Map();
|
|
7033
|
+
onEnterTree() {
|
|
7034
|
+
this.claim();
|
|
7035
|
+
}
|
|
7036
|
+
/** A shelf attached at runtime never saw `onEnterTree`; idempotent. */
|
|
7037
|
+
onReady() {
|
|
7038
|
+
this.claim();
|
|
7039
|
+
}
|
|
7040
|
+
claim() {
|
|
7041
|
+
const wanted = this.prefabs.split(",").map((name) => name.trim()).filter((name) => name !== "");
|
|
7042
|
+
const from = wanted.length > 0 ? wanted : [...this.node.children].map((child) => child.name);
|
|
7043
|
+
for (const name of from) {
|
|
7044
|
+
if (this.held.has(name)) continue;
|
|
7045
|
+
const template = this.node.children.find((child) => child.name === name);
|
|
7046
|
+
if (!template) throw new IncantoError("NODE_NOT_FOUND", `PrefabShelf on '${this.node.getPath()}': "prefabs" names '${name}', which is not a child of this node. It holds: ${this.childNames() || "(nothing)"}.`, {
|
|
7047
|
+
prop: "prefabs",
|
|
7048
|
+
path: this.node.getPath()
|
|
7049
|
+
});
|
|
7050
|
+
rememberAuthoredPath(template);
|
|
7051
|
+
this.node.removeChild(template);
|
|
7052
|
+
this.held.set(name, template);
|
|
7053
|
+
}
|
|
7054
|
+
}
|
|
7055
|
+
/** What this shelf holds, in authored order. */
|
|
7056
|
+
names() {
|
|
7057
|
+
return [...this.held.keys()];
|
|
7058
|
+
}
|
|
7059
|
+
/**
|
|
7060
|
+
* A live clone of one template, DETACHED — `addChild` it yourself.
|
|
7061
|
+
*
|
|
7062
|
+
* Detached for the same reason `duplicateNode` is, and it is not a
|
|
7063
|
+
* formality: `onReady` fires on attach, and a behaviour that reads its node
|
|
7064
|
+
* there (`FloatAway` banks its starting position) would bank the wrong one.
|
|
7065
|
+
* Set the clone up, then attach it.
|
|
7066
|
+
*
|
|
7067
|
+
* The clone is VISIBLE even if the template was authored hidden (a scene
|
|
7068
|
+
* migrating off the old `visible: false` shelf keeps working), and every
|
|
7069
|
+
* behaviour in it is however it was authored: awake unless the template
|
|
7070
|
+
* itself asks to sleep, which is now only ever a state machine's own doing.
|
|
7071
|
+
*/
|
|
7072
|
+
make(name) {
|
|
7073
|
+
const template = this.held.get(name);
|
|
7074
|
+
if (!template) throw new IncantoError("NODE_NOT_FOUND", `PrefabShelf on '${this.node.getPath()}': no template named '${name}'. This shelf holds: ${this.childNames() || "(nothing)"}.`, { path: this.node.getPath() });
|
|
7075
|
+
const clone = duplicateNode(template, rebuildOptions(this.node));
|
|
7076
|
+
if (typeof clone.visible === "boolean") clone.visible = true;
|
|
7077
|
+
return clone;
|
|
7078
|
+
}
|
|
7079
|
+
childNames() {
|
|
7080
|
+
return this.names().join(", ");
|
|
7081
|
+
}
|
|
7082
|
+
};
|
|
7083
|
+
//#endregion
|
|
6987
7084
|
//#region src/gameplay/projectile.ts
|
|
6988
7085
|
/**
|
|
6989
7086
|
* Constant-velocity motion in a straight line — bullets, arrows, thrown rocks.
|
|
@@ -7282,7 +7379,7 @@ var SavePoint = class extends Behavior {
|
|
|
7282
7379
|
return;
|
|
7283
7380
|
}
|
|
7284
7381
|
const report = this.engine.restoreState(slot.state);
|
|
7285
|
-
const here = this.engine?.scene?.name;
|
|
7382
|
+
const here = this.scene || this.engine?.scene?.source.name;
|
|
7286
7383
|
if (here && slot.scene && slot.scene !== here) diagnose(this.engine, "error", `[incanto] SavePoint '${this.slot}': this slot was saved in scene '${slot.scene}' and you are in '${here}'. Load that scene first — a save is restored INTO the scene it came from (incanto-save-slots.md).`);
|
|
7287
7384
|
else if (report.expected > 0 && report.restored === 0) diagnose(this.engine, "error", `[incanto] SavePoint '${this.slot}': restored 0 of ${report.expected} saveable behaviour(s)` + (report.missing.length > 0 ? ` — ${report.missing.length} uid(s) in the save are not in this scene, starting with '${report.missing[0]}'. That save is from an older build, or from another scene.` : ". Nothing in the save matched a node here."));
|
|
7288
7385
|
this.emit("restored", report.restored);
|
|
@@ -7437,6 +7534,7 @@ var SpawnSource = class {
|
|
|
7437
7534
|
});
|
|
7438
7535
|
}
|
|
7439
7536
|
if (claim) node.tree?._templates.set(claim, template);
|
|
7537
|
+
rememberAuthoredPath(template);
|
|
7440
7538
|
if (template.parent) template.parent.removeChild(template);
|
|
7441
7539
|
this.detached.set(prefab, template);
|
|
7442
7540
|
return template;
|
|
@@ -7669,8 +7767,9 @@ var Wander = class extends Behavior {
|
|
|
7669
7767
|
* every `interval` seconds, then waits until they're ALL cleared (freed) before
|
|
7670
7768
|
* starting the next wave.
|
|
7671
7769
|
*
|
|
7672
|
-
* Signals: `
|
|
7673
|
-
* its last instance frees, `allCleared` after
|
|
7770
|
+
* Signals: `spawned(node)` per clone, `waveStarted(i)` when a wave begins
|
|
7771
|
+
* spawning, `waveCleared(i)` when its last instance frees, `allCleared` after
|
|
7772
|
+
* the final wave clears.
|
|
7674
7773
|
*/
|
|
7675
7774
|
var WaveSpawner = class extends Behavior {
|
|
7676
7775
|
static props = {
|
|
@@ -7683,6 +7782,7 @@ var WaveSpawner = class extends Behavior {
|
|
|
7683
7782
|
autoStart: { default: true }
|
|
7684
7783
|
};
|
|
7685
7784
|
static signals = [
|
|
7785
|
+
"spawned",
|
|
7686
7786
|
"waveStarted",
|
|
7687
7787
|
"waveCleared",
|
|
7688
7788
|
"allCleared"
|
|
@@ -7768,6 +7868,7 @@ var WaveSpawner = class extends Behavior {
|
|
|
7768
7868
|
const clone = this.source.spawn(this.source.resolveTemplate(wave.prefab));
|
|
7769
7869
|
this.live.add(clone);
|
|
7770
7870
|
this.spawnedThisWave += 1;
|
|
7871
|
+
this.emit("spawned", clone);
|
|
7771
7872
|
this.timer += wave.interval;
|
|
7772
7873
|
}
|
|
7773
7874
|
if (this.spawnedThisWave >= wave.count) this.phase = "clearing";
|
|
@@ -8024,7 +8125,8 @@ const GAMEPLAY_BEHAVIORS = {
|
|
|
8024
8125
|
WaveSpawner,
|
|
8025
8126
|
Projectile,
|
|
8026
8127
|
Buoyancy,
|
|
8027
|
-
FloatAway
|
|
8128
|
+
FloatAway,
|
|
8129
|
+
PrefabShelf
|
|
8028
8130
|
};
|
|
8029
8131
|
/**
|
|
8030
8132
|
* Register all built-in gameplay behaviors. Idempotent and hot-reload tolerant
|
|
@@ -8036,4 +8138,4 @@ function registerGameplayBehaviors(opts) {
|
|
|
8036
8138
|
for (const [name, ctor] of Object.entries(GAMEPLAY_BEHAVIORS)) registerBehavior(name, ctor, { replace });
|
|
8037
8139
|
}
|
|
8038
8140
|
//#endregion
|
|
8039
|
-
export {
|
|
8141
|
+
export { DayNight as A, rejectScale as B, goToScene as C, effectRng as D, FollowCamera as E, Collector as F, StaticBody3D as G, CharacterBody3D as H, Chase as I, createCausticsQuad as J, Node3D as K, Water3D as L, DamageOnContact as M, Health as N, FloatAway as O, Currency as P, worldPosition as Q, WATER_CUTOUT_MAX as R, GameFlow as S, tolerateUnknownAction as T, PhysicsBody3D as U, Area3D as V, RigidBody3D as W, colliderFootDrop as X, WATER_MAX_RIPPLES as Y, localFromWorld as Z, CameraShake as _, Wander as a, screenFlash as b, SavePoint as c, Pickup as d, Patrol as f, Lifetime as g, MoveTo as h, WaveSpawner as i, phaseOf as j, FaceTarget as k, Projectile as l, Oscillate as m, registerGameplayBehaviors as n, Spawner as o, PathFollow as p, validateCollider3D as q, ZombieAI as r, ScoreKeeper as s, GAMEPLAY_BEHAVIORS as t, PrefabShelf as u, Cooldown as v, restartScene as w, Interactable as x, hitStop as y, WaterCutout3D as z };
|
package/dist/gameplay.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, t as Behavior } from "./behavior-
|
|
1
|
+
import { b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, t as Behavior } from "./behavior-Dcz0fr1S.js";
|
|
2
2
|
import { c as JsonValue, s as JsonObject } from "./rng-Bb-IutXB.js";
|
|
3
3
|
|
|
4
4
|
//#region src/gameplay/chase.d.ts
|
|
@@ -826,8 +826,9 @@ declare class Wander extends Behavior {
|
|
|
826
826
|
* every `interval` seconds, then waits until they're ALL cleared (freed) before
|
|
827
827
|
* starting the next wave.
|
|
828
828
|
*
|
|
829
|
-
* Signals: `
|
|
830
|
-
* its last instance frees, `allCleared` after
|
|
829
|
+
* Signals: `spawned(node)` per clone, `waveStarted(i)` when a wave begins
|
|
830
|
+
* spawning, `waveCleared(i)` when its last instance frees, `allCleared` after
|
|
831
|
+
* the final wave clears.
|
|
831
832
|
*/
|
|
832
833
|
declare class WaveSpawner extends Behavior {
|
|
833
834
|
static readonly props: PropSchema;
|
|
@@ -1265,6 +1266,69 @@ declare class PathFollow extends Behavior {
|
|
|
1265
1266
|
override update(dt: number): void;
|
|
1266
1267
|
}
|
|
1267
1268
|
//#endregion
|
|
1269
|
+
//#region src/gameplay/prefab-shelf.d.ts
|
|
1270
|
+
/**
|
|
1271
|
+
* A shelf of templates the GAME clones itself — towers, bolts, damage numbers.
|
|
1272
|
+
*
|
|
1273
|
+
* `Spawner` detaches its one prefab at enter, so a spawned enemy's whole
|
|
1274
|
+
* subtree is live and nobody has to think about it. A game that clones on its
|
|
1275
|
+
* own terms — a tower the player places, a bolt that tower fires — has no
|
|
1276
|
+
* spawner, so its templates sat in the tree as LIVE nodes: their behaviours
|
|
1277
|
+
* ticked, their turrets shot, and `visible: false` hid a node without switching
|
|
1278
|
+
* it off. The documented answer was to author every template `"enabled": false`
|
|
1279
|
+
* and wake the clone with `clone.behavior?.enable()`.
|
|
1280
|
+
*
|
|
1281
|
+
* That wakes ONE node, and the same docs teach that a node carries one
|
|
1282
|
+
* behaviour — so a prefab's parts live on children, and every one of those
|
|
1283
|
+
* stays asleep, silently and for good, because `enabled` is a pause switch that
|
|
1284
|
+
* never complains. Measured on a shipped tower defense: the bolt's
|
|
1285
|
+
* `Projectile` was woken and its sibling `Lifetime` was not, so every bolt that
|
|
1286
|
+
* MISSED flew forever — five still in the tree at 69 seconds, in a game that
|
|
1287
|
+
* passed its harness, its audit and every rung of the ladder.
|
|
1288
|
+
*
|
|
1289
|
+
* ```json
|
|
1290
|
+
* { "name": "Prefabs", "type": "Node2D", "script": { "name": "PrefabShelf" },
|
|
1291
|
+
* "children": [ { "name": "Tower", "type": "Node2D", "children": [] } ] }
|
|
1292
|
+
* ```
|
|
1293
|
+
* ```ts
|
|
1294
|
+
* const shelf = this.node.getNode('/Game/Prefabs').behavior as PrefabShelf;
|
|
1295
|
+
* const tower = shelf.make('Tower'); // detached, like `duplicateNode`
|
|
1296
|
+
* tower.position = at; // set it up BEFORE it readies
|
|
1297
|
+
* this.node.getNode('/Game/Towers').addChild(tower);
|
|
1298
|
+
* ```
|
|
1299
|
+
*
|
|
1300
|
+
* The children never ENTER the tree, so nothing has to be asleep, nothing has
|
|
1301
|
+
* to be hidden, and `make()` hands back a clone that is awake all the way down.
|
|
1302
|
+
*/
|
|
1303
|
+
declare class PrefabShelf extends Behavior {
|
|
1304
|
+
static readonly props: PropSchema;
|
|
1305
|
+
static readonly signals: readonly string[];
|
|
1306
|
+
prefabs: string;
|
|
1307
|
+
/** Templates, in the order they were authored. */
|
|
1308
|
+
private readonly held;
|
|
1309
|
+
override onEnterTree(): void;
|
|
1310
|
+
/** A shelf attached at runtime never saw `onEnterTree`; idempotent. */
|
|
1311
|
+
override onReady(): void;
|
|
1312
|
+
private claim;
|
|
1313
|
+
/** What this shelf holds, in authored order. */
|
|
1314
|
+
names(): string[];
|
|
1315
|
+
/**
|
|
1316
|
+
* A live clone of one template, DETACHED — `addChild` it yourself.
|
|
1317
|
+
*
|
|
1318
|
+
* Detached for the same reason `duplicateNode` is, and it is not a
|
|
1319
|
+
* formality: `onReady` fires on attach, and a behaviour that reads its node
|
|
1320
|
+
* there (`FloatAway` banks its starting position) would bank the wrong one.
|
|
1321
|
+
* Set the clone up, then attach it.
|
|
1322
|
+
*
|
|
1323
|
+
* The clone is VISIBLE even if the template was authored hidden (a scene
|
|
1324
|
+
* migrating off the old `visible: false` shelf keeps working), and every
|
|
1325
|
+
* behaviour in it is however it was authored: awake unless the template
|
|
1326
|
+
* itself asks to sleep, which is now only ever a state machine's own doing.
|
|
1327
|
+
*/
|
|
1328
|
+
make(name: string): Node;
|
|
1329
|
+
private childNames;
|
|
1330
|
+
}
|
|
1331
|
+
//#endregion
|
|
1268
1332
|
//#region src/gameplay/spatial.d.ts
|
|
1269
1333
|
/**
|
|
1270
1334
|
* A node's position with every spatial ancestor's added in.
|
|
@@ -1311,4 +1375,4 @@ declare function registerGameplayBehaviors(opts?: {
|
|
|
1311
1375
|
replace?: boolean;
|
|
1312
1376
|
}): void;
|
|
1313
1377
|
//#endregion
|
|
1314
|
-
export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, type DayPhase, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, type GameFlowState, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
|
|
1378
|
+
export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, type DayPhase, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, type GameFlowState, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, PrefabShelf, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
|
package/dist/gameplay.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
|
|
1
|
+
import { A as DayNight, C as goToScene, E as FollowCamera, F as Collector, I as Chase, M as DamageOnContact, N as Health, O as FloatAway, P as Currency, Q as worldPosition, S as GameFlow, Z as localFromWorld, _ as CameraShake, a as Wander, b as screenFlash, c as SavePoint, d as Pickup, f as Patrol, g as Lifetime, h as MoveTo, i as WaveSpawner, j as phaseOf, k as FaceTarget, l as Projectile, m as Oscillate, n as registerGameplayBehaviors, o as Spawner, p as PathFollow, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as PrefabShelf, v as Cooldown, w as restartScene, x as Interactable, y as hitStop } from "./gameplay-CNULJvwh.js";
|
|
2
|
+
export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, PrefabShelf, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as ParticleSimConfig, c as showBootFailure, i as ParticleSim, n as AudioPlayer, o as ParticleView, s as isWebGLAvailable, t as AudioElementLike } from "./audio-player-
|
|
2
|
-
import { $ as T_PREFIX, A as SettingsValues, At as BusName, B as captureBehaviors, C as EngineStats, Ct as sfxDuration, Dt as MusicTrack, E as DeviceHints, Et as MusicManager, F as BehaviorState, Ft as LogLevel, G as ORDER_GROUP_BASE, H as savesWithoutUid, I as RestoreReport, It as LogManager, J as effectiveOrder, K as OrderGroup, L as SaveSlot, Lt as Signal, M as readDeviceHints, Mt as NodeLifecycle, N as suggestQuality, Nt as SceneTree, O as QualityTier, Ot as PlayMusicOptions, P as Scene, Pt as LogEntry, Q as Localization, R as SaveSlots, Rt as SignalListener, S as Scheduler, St as SynthOptions, T as RendererStats, Tt as MusicBackend, U as SaveStore, V as restoreBehaviors, W as createSaveStore, X as BASE_LOCALE, Y as resolveOrderGroups, Z as LocaleTables, _ as mergeStaticSignals, _t as spatialPan, a as clearBehaviors, at as EffectLog, b as Engine, bt as SfxParams, c as registeredBehaviors, ct as isAudioContextAvailable, d as PropSchema, dt as Listener, et as suggestLocale, f as clearRegistry, ft as ROLLOFF_MODELS, g as getNodeType, gt as spatialGain, h as getNodeSignals, ht as Vec3, i as behaviorSignals, it as EffectKind, j as qualityEnvironment, jt as Node, k as Settings, kt as AudioBuses, l as NodeCtor, lt as Voice, m as getNodeSchema, mt as SpatialParams, n as BehaviorCtor, nt as InputMap, o as getBehavior, ot as SfxEngine, p as createNode, pt as RolloffModel, q as OrderGroupTable, r as behaviorSchema, rt as EffectEvent, s as registerBehavior, st as SfxPlayOptions, t as Behavior, tt as translationKey, u as PropDef, ut as VoicePreset, v as registerNode, vt as SFX_PRESETS, w as GameStats, wt as synthSfx, x as EngineOptions, xt as SfxWave, y as registeredTypes, yt as SFX_PRESET_NAMES, z as behaviorsWithoutSave } from "./behavior-
|
|
1
|
+
import { a as ParticleSimConfig, c as showBootFailure, i as ParticleSim, n as AudioPlayer, o as ParticleView, s as isWebGLAvailable, t as AudioElementLike } from "./audio-player-L8yccdMP.js";
|
|
2
|
+
import { $ as T_PREFIX, A as SettingsValues, At as BusName, B as captureBehaviors, C as EngineStats, Ct as sfxDuration, Dt as MusicTrack, E as DeviceHints, Et as MusicManager, F as BehaviorState, Ft as LogLevel, G as ORDER_GROUP_BASE, H as savesWithoutUid, I as RestoreReport, It as LogManager, J as effectiveOrder, K as OrderGroup, L as SaveSlot, Lt as Signal, M as readDeviceHints, Mt as NodeLifecycle, N as suggestQuality, Nt as SceneTree, O as QualityTier, Ot as PlayMusicOptions, P as Scene, Pt as LogEntry, Q as Localization, R as SaveSlots, Rt as SignalListener, S as Scheduler, St as SynthOptions, T as RendererStats, Tt as MusicBackend, U as SaveStore, V as restoreBehaviors, W as createSaveStore, X as BASE_LOCALE, Y as resolveOrderGroups, Z as LocaleTables, _ as mergeStaticSignals, _t as spatialPan, a as clearBehaviors, at as EffectLog, b as Engine, bt as SfxParams, c as registeredBehaviors, ct as isAudioContextAvailable, d as PropSchema, dt as Listener, et as suggestLocale, f as clearRegistry, ft as ROLLOFF_MODELS, g as getNodeType, gt as spatialGain, h as getNodeSignals, ht as Vec3, i as behaviorSignals, it as EffectKind, j as qualityEnvironment, jt as Node, k as Settings, kt as AudioBuses, l as NodeCtor, lt as Voice, m as getNodeSchema, mt as SpatialParams, n as BehaviorCtor, nt as InputMap, o as getBehavior, ot as SfxEngine, p as createNode, pt as RolloffModel, q as OrderGroupTable, r as behaviorSchema, rt as EffectEvent, s as registerBehavior, st as SfxPlayOptions, t as Behavior, tt as translationKey, u as PropDef, ut as VoicePreset, v as registerNode, vt as SFX_PRESETS, w as GameStats, wt as synthSfx, x as EngineOptions, xt as SfxWave, y as registeredTypes, yt as SFX_PRESET_NAMES, z as behaviorsWithoutSave } from "./behavior-Dcz0fr1S.js";
|
|
3
3
|
import { a as SceneJson, c as JsonValue, d as jsonKind, i as SCENE_FORMAT, l as jsonClone, n as ConnectionJson, o as JsonKind, r as NodeJson, s as JsonObject, t as Rng, u as jsonEquals } from "./rng-Bb-IutXB.js";
|
|
4
|
-
import { n as loadScene, t as LoadSceneOptions } from "./loader-
|
|
4
|
+
import { n as loadScene, t as LoadSceneOptions } from "./loader-8-IHvbKD.js";
|
|
5
5
|
import { i as resolveFrames, n as AnimationEntry, r as resolveAnimation, t as AnimationDef } from "./sprite-animation-CMr6f1K2.js";
|
|
6
6
|
import { i as gridFromRows, n as PathGrid, r as findPath, t as FindPathOptions } from "./pathfinding-_fGrCFmH.js";
|
|
7
|
-
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-
|
|
7
|
+
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-F7IZHdFR.js";
|
|
8
8
|
|
|
9
9
|
//#region src/core/audio/crossfade.d.ts
|
|
10
10
|
/**
|
|
@@ -973,6 +973,17 @@ declare class UiSlider extends HudWidgetBase {
|
|
|
973
973
|
override focusable: boolean;
|
|
974
974
|
/** Left/right nudge by one step — the only sane thing a d-pad can mean here. */
|
|
975
975
|
override _activate(dir: number): void;
|
|
976
|
+
/**
|
|
977
|
+
* Move it as a PERSON would: set the value and say so.
|
|
978
|
+
*
|
|
979
|
+
* `UiButton` has `press()` and the value widgets had nothing, because
|
|
980
|
+
* assigning `.value` deliberately does not emit (restoring a saved setting
|
|
981
|
+
* must not fire the handler that saved it). So a harness — or a game driving
|
|
982
|
+
* its own menu: a preset button, "reset to defaults", a tutorial that moves a
|
|
983
|
+
* slider for you — had one route to "the player changed this", and it was
|
|
984
|
+
* `_activate`, which is internal and takes a direction rather than a value.
|
|
985
|
+
*/
|
|
986
|
+
choose(value: number): void;
|
|
976
987
|
private input;
|
|
977
988
|
private text;
|
|
978
989
|
private last;
|
|
@@ -989,6 +1000,8 @@ declare class UiToggle extends HudWidgetBase {
|
|
|
989
1000
|
override focusable: boolean;
|
|
990
1001
|
/** Confirm flips it; left/right set it explicitly, which reads better on a pad. */
|
|
991
1002
|
override _activate(dir: number): void;
|
|
1003
|
+
/** Flip it as a PERSON would: set the value and say so. See `UiSlider.choose`. */
|
|
1004
|
+
choose(value: boolean): void;
|
|
992
1005
|
private input;
|
|
993
1006
|
private last;
|
|
994
1007
|
protected _build(): HTMLElement;
|
|
@@ -1023,6 +1036,16 @@ declare class UiSelect extends HudWidgetBase {
|
|
|
1023
1036
|
static validateJson(node: Node): void;
|
|
1024
1037
|
/** Left/right (and confirm) walk the list — a select has no other gesture. */
|
|
1025
1038
|
override _activate(dir: number): void;
|
|
1039
|
+
/**
|
|
1040
|
+
* Pick an option as a PERSON would: set the value and say so. See
|
|
1041
|
+
* `UiSlider.choose`.
|
|
1042
|
+
*
|
|
1043
|
+
* An option the list does not offer is refused, for the reason
|
|
1044
|
+
* `validateJson` refuses it in the file: the browser would show the first one
|
|
1045
|
+
* while the node kept answering with what it was given, and nothing would
|
|
1046
|
+
* ever reconcile them.
|
|
1047
|
+
*/
|
|
1048
|
+
choose(value: string): void;
|
|
1026
1049
|
private select;
|
|
1027
1050
|
private labelEl;
|
|
1028
1051
|
private lastLabel;
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-CfTjpvW8.js";
|
|
2
|
-
import {
|
|
3
|
-
import { A as T_PREFIX, B as SFX_PRESET_NAMES, D as EffectLog, E as LogManager, F as isAudioContextAvailable, G as crossfadeGains, H as synthSfx, I as ROLLOFF_MODELS, K as fadeGain, L as spatialGain, N as translationKey, O as BASE_LOCALE, P as SfxEngine, R as spatialPan, S as qualityEnvironment, T as suggestQuality, U as MusicManager, V as sfxDuration, W as WebAudioMusicBackend, _ as AudioPlayer, a as UiMuteToggle, b as Settings, c as UiRenderScaleSelect, d as UiToggle, f as UiVolumeSlider, g as UiDialogue, h as UiButton, i as UiLanguageSelect, j as suggestLocale, k as Localization, l as UiSelect, m as Respawn, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as AudioBuses, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Engine, w as readDeviceHints, z as SFX_PRESETS } from "./register-
|
|
2
|
+
import { $ as parseNodePath, A as SceneTree, B as HudLayer, D as computeViewport, E as resolveConstants, F as resolveOrderGroups, G as UiText, I as InputMap, J as Node, N as ORDER_GROUP_BASE, O as resolveViewport, P as effectiveOrder, Q as resolveRefInJson, T as isConstRef, U as UiBanner, W as UiBar, X as describeRefProblem, Z as nodeRefWarnings, _ as Scene, a as restoreBehaviors, at as getBehavior, ct as Signal, et as Behavior, h as loadScene, i as captureBehaviors, it as clearBehaviors, j as createSaveStore, k as newUid, n as SaveSlots, nt as behaviorSchema, o as savesWithoutUid, ot as registerBehavior, r as behaviorsWithoutSave, rt as behaviorSignals, s as duplicateNode, st as registeredBehaviors, v as serializeNode, w as CONST_REF_KEY, y as SCENE_FORMAT } from "./save-slots-Bvuh2p_r.js";
|
|
3
|
+
import { A as T_PREFIX, B as SFX_PRESET_NAMES, D as EffectLog, E as LogManager, F as isAudioContextAvailable, G as crossfadeGains, H as synthSfx, I as ROLLOFF_MODELS, K as fadeGain, L as spatialGain, N as translationKey, O as BASE_LOCALE, P as SfxEngine, R as spatialPan, S as qualityEnvironment, T as suggestQuality, U as MusicManager, V as sfxDuration, W as WebAudioMusicBackend, _ as AudioPlayer, a as UiMuteToggle, b as Settings, c as UiRenderScaleSelect, d as UiToggle, f as UiVolumeSlider, g as UiDialogue, h as UiButton, i as UiLanguageSelect, j as suggestLocale, k as Localization, l as UiSelect, m as Respawn, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as AudioBuses, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Engine, w as readDeviceHints, z as SFX_PRESETS } from "./register-DuVdzxbq.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
5
|
import { t as Rng } from "./rng-CDOMybym.js";
|
|
6
6
|
import { c as getNodeSchema, f as mergeStaticSignals, i as joystickVector, l as getNodeSignals, m as registeredTypes, n as attachTouchControls, o as clearRegistry, p as registerNode, s as createNode, t as TouchControls, u as getNodeType } from "./touch-BnCyPA0G.js";
|
|
7
|
-
import { n as startRecording, r as auditScene, t as replay } from "./replay-
|
|
7
|
+
import { n as startRecording, r as auditScene, t as replay } from "./replay-DEvp3kyV.js";
|
|
8
8
|
import { t as showBootFailure } from "./boot-failure-CKYrEcGF.js";
|
|
9
9
|
import { a as logText, i as logReport, o as parseDrive, r as resolveRendering, t as isWebGLAvailable } from "./webgl-unavailable-C8aDbGmR.js";
|
|
10
10
|
import { t as createNoise2D } from "./noise-D3nPpmFg.js";
|
|
11
11
|
import { a as PARTICLE_PRESETS, i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-CqR2o3SA.js";
|
|
12
|
-
import { a as findPath, i as preloadUrls, n as assetUrls, o as gridFromRows, r as preloadSceneAssets, t as VERSION } from "./src-
|
|
12
|
+
import { a as findPath, i as preloadUrls, n as assetUrls, o as gridFromRows, r as preloadSceneAssets, t as VERSION } from "./src-_jk0qLsS.js";
|
|
13
13
|
export { AudioBuses, AudioPlayer, BASE_LOCALE, Behavior, CONST_REF_KEY, EffectLog, Engine, HudLayer, IncantoError, InputMap, Localization, LogManager, MusicManager, Node, ORDER_GROUP_BASE, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Respawn, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, SaveSlots, Scene, SceneTree, Settings, SfxEngine, Signal, T_PREFIX, Timer, TouchControls, UiBanner, UiBar, UiButton, UiDialogue, UiFrameCapSelect, UiImage, UiLanguageSelect, UiMuteToggle, UiPanel, UiQualitySelect, UiRenderScaleSelect, UiSelect, UiSlider, UiText, UiToggle, UiVolumeSlider, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, describeRefProblem, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, isWebGLAvailable, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, logReport, logText, mergeStaticSignals, newUid, nodeRefWarnings, parseDrive, parseNodePath, preloadSceneAssets, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveAnimation, resolveConstants, resolveFrames, resolveOrderGroups, resolveRefInJson, resolveRendering, resolveViewport, restoreBehaviors, savesWithoutUid, serializeNode, sfxDuration, showBootFailure, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
|
package/dist/net.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { d as PropSchema, jt as Node } from "./behavior-
|
|
1
|
+
import { d as PropSchema, jt as Node } from "./behavior-Dcz0fr1S.js";
|
|
2
2
|
import { t as DiagnosticSink } from "./diagnostics-Cu85N3tL.js";
|
|
3
|
-
import { a as NetworkManagerOptions, c as LocalGameServer, d as ServerClass, f as createLocalGameServer, g as Unsubscribe, h as NetworkTransport, i as NetworkManager, l as LocalGameServerOptions, m as LoopbackTransport, n as SplitScreenPlayer, o as applySyncPatch, p as LoopbackHub, r as createSplitScreen, s as CollectionOptions, t as SplitScreenOptions, u as LocalGameServerTransport } from "./split-screen
|
|
3
|
+
import { a as NetworkManagerOptions, c as LocalGameServer, d as ServerClass, f as createLocalGameServer, g as Unsubscribe, h as NetworkTransport, i as NetworkManager, l as LocalGameServerOptions, m as LoopbackTransport, n as SplitScreenPlayer, o as applySyncPatch, p as LoopbackHub, r as createSplitScreen, s as CollectionOptions, t as SplitScreenOptions, u as LocalGameServerTransport } from "./split-screen-CIYf1zSf.js";
|
|
4
4
|
|
|
5
5
|
//#region src/net/agent8.d.ts
|
|
6
6
|
/**
|
package/dist/net.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as createAgent8Server } from "./agent8-
|
|
2
|
-
import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-
|
|
1
|
+
import { n as createAgent8Server } from "./agent8-Cfmd3ar_.js";
|
|
2
|
+
import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-eULetcg-.js";
|
|
3
3
|
export { LocalGameServer, LocalGameServerTransport, LoopbackHub, LoopbackTransport, NetworkManager, NetworkSpawner, applySyncPatch, createAgent8Server, createLocalGameServer, createSplitScreen, registerNodesNet };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { o as __exportAll } from "./json-CfTjpvW8.js";
|
|
2
|
-
import {
|
|
2
|
+
import { Y as diagnose } from "./save-slots-Bvuh2p_r.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-BYQCBySi.js";
|
|
5
5
|
import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
|
|
6
6
|
import { n as jointContacts, t as withoutRapierInitNoise } from "./quiet-rapier-C6fW4zcW.js";
|
|
7
7
|
//#region src/2d/physics/physics-2d.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { o as __exportAll } from "./json-CfTjpvW8.js";
|
|
2
|
-
import {
|
|
2
|
+
import { Y as diagnose } from "./save-slots-Bvuh2p_r.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
|
-
import {
|
|
4
|
+
import { H as CharacterBody3D, K as Node3D, U as PhysicsBody3D, V as Area3D, W as RigidBody3D, q as validateCollider3D } from "./gameplay-CNULJvwh.js";
|
|
5
5
|
import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
|
|
6
6
|
import { n as jointContacts, t as withoutRapierInitNoise } from "./quiet-rapier-C6fW4zcW.js";
|
|
7
|
-
import { A as Terrain3D, F as InstancedMesh3D, L as buildMeshGeometry, P as Joint3D } from "./environment-presets-
|
|
7
|
+
import { A as Terrain3D, F as InstancedMesh3D, L as buildMeshGeometry, P as Joint3D } from "./environment-presets-99BzP_L-.js";
|
|
8
8
|
import { Euler, Matrix4, Quaternion, Vector3 } from "three";
|
|
9
9
|
//#region src/3d/physics/collider-lines.ts
|
|
10
10
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { _ as AudioPlayer } from "./register-
|
|
1
|
+
import { _ as AudioPlayer } from "./register-DuVdzxbq.js";
|
|
2
2
|
import { i as logReport, o as parseDrive } from "./webgl-unavailable-C8aDbGmR.js";
|
|
3
|
-
import { a as frameSignature, i as frameImage, o as frameStats } from "./frame-report-
|
|
4
|
-
import {
|
|
3
|
+
import { a as frameSignature, i as frameImage, o as frameStats } from "./frame-report-D-_7YF2G.js";
|
|
4
|
+
import { Q as worldPosition } from "./gameplay-CNULJvwh.js";
|
|
5
5
|
//#region src/core/audio-errors.ts
|
|
6
6
|
/** Every AudioPlayer under `root` whose source could not be played. */
|
|
7
7
|
function audioErrors(root) {
|
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as Scene, b as Engine, n as BehaviorCtor } from "./behavior-
|
|
1
|
+
import { P as Scene, b as Engine, n as BehaviorCtor } from "./behavior-Dcz0fr1S.js";
|
|
2
2
|
import { c as JsonValue } from "./rng-Bb-IutXB.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-LCHBLfA4.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-CH4kt78v.js").then((n) => n.n)).createGame2D(o)))(opts);
|
|
160
160
|
if (disposed) {
|
|
161
161
|
next.dispose();
|
|
162
162
|
return;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { M as translateOn, t as registerCoreNodes } from "./register-
|
|
1
|
+
import { J as Node, P as effectiveOrder, Y as diagnose } from "./save-slots-Bvuh2p_r.js";
|
|
2
|
+
import { M as translateOn, t as registerCoreNodes } from "./register-DuVdzxbq.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
4
|
import { c as getNodeSchema, h as didYouMean, p as registerNode } from "./touch-BnCyPA0G.js";
|
|
5
5
|
import { i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, r as validateAnimations, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-CqR2o3SA.js";
|
|
6
|
-
import {
|
|
6
|
+
import { D as effectRng, Q as worldPosition, T as tolerateUnknownAction, Z as localFromWorld } from "./gameplay-CNULJvwh.js";
|
|
7
7
|
import { t as checkSheetGrid } from "./sheet-grid-Cea343VO.js";
|
|
8
8
|
import { AdditiveBlending, BufferAttribute, BufferGeometry, CanvasTexture, Color, DynamicDrawUsage, Group, InstancedMesh, MathUtils, Matrix4, Mesh, MeshBasicMaterial, NearestFilter, NormalBlending, Object3D, PlaneGeometry, SRGBColorSpace } from "three";
|
|
9
9
|
//#region src/2d/physics/collider-validate.ts
|
|
@@ -1617,6 +1617,15 @@ function mergeSolidRects(grid, solid) {
|
|
|
1617
1617
|
//#endregion
|
|
1618
1618
|
//#region src/2d/nodes/tile-map-2d.ts
|
|
1619
1619
|
/**
|
|
1620
|
+
* Where colour cells live in the index space, above any atlas anyone will draw.
|
|
1621
|
+
*
|
|
1622
|
+
* A million tiles is 1000×1000 atlas cells; a texture that size does not exist,
|
|
1623
|
+
* and the loader refuses `colors` and `texture` together anyway.
|
|
1624
|
+
*/
|
|
1625
|
+
const COLOR_BASE = 1e6;
|
|
1626
|
+
/** `#rgb` or `#rrggbb`, which is what every other colour prop in the engine takes. */
|
|
1627
|
+
const HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
|
|
1628
|
+
/**
|
|
1620
1629
|
* A whole tile level as ONE node — grid render in a single draw call plus
|
|
1621
1630
|
* greedy-merged static colliders. Author the level as rows of characters:
|
|
1622
1631
|
*
|
|
@@ -1653,6 +1662,23 @@ var TileMap2D = class extends Node2D {
|
|
|
1653
1662
|
cells: { default: [] },
|
|
1654
1663
|
/** char → atlas tile index for non-digit chars. */
|
|
1655
1664
|
legend: { default: {} },
|
|
1665
|
+
/**
|
|
1666
|
+
* Char → COLOUR, for a level you author before you have any art.
|
|
1667
|
+
*
|
|
1668
|
+
* `incanto-assets.md` is titled "No art yet? Ship gameplay anyway", and it
|
|
1669
|
+
* was true of everything except the node a grid game is made of: this one
|
|
1670
|
+
* draws from an atlas, so with no texture it rendered nothing at all. A
|
|
1671
|
+
* sokoban built from the published package came out as 24 hand-placed
|
|
1672
|
+
* `ColorRect2D` walls and a `wallAt()` comparing positions — because the
|
|
1673
|
+
* one node that already answers `cellAt`/`tileAt`/`setTile`/`worldAt`, and
|
|
1674
|
+
* merges the colliders, could not be seen.
|
|
1675
|
+
*
|
|
1676
|
+
* A cell painted with one of these chars is a flat quad of that colour, in
|
|
1677
|
+
* the same single draw call. Exclusive with `texture`: one material, one
|
|
1678
|
+
* draw call, and "the art arrived" is a two-line edit rather than a
|
|
1679
|
+
* silently half-textured level.
|
|
1680
|
+
*/
|
|
1681
|
+
colors: { default: {} },
|
|
1656
1682
|
/** Tile indices that get merged static colliders. */
|
|
1657
1683
|
solid: { default: [] },
|
|
1658
1684
|
opacity: {
|
|
@@ -1693,6 +1719,42 @@ var TileMap2D = class extends Node2D {
|
|
|
1693
1719
|
this.geometryDirty = true;
|
|
1694
1720
|
this.collidersDirty = true;
|
|
1695
1721
|
}
|
|
1722
|
+
_colors = {};
|
|
1723
|
+
get colors() {
|
|
1724
|
+
return this._colors;
|
|
1725
|
+
}
|
|
1726
|
+
set colors(value) {
|
|
1727
|
+
this._colors = value;
|
|
1728
|
+
this.geometryDirty = true;
|
|
1729
|
+
this.collidersDirty = true;
|
|
1730
|
+
}
|
|
1731
|
+
/**
|
|
1732
|
+
* The colours, in declaration order — a cell's tile index is `COLOR_BASE + i`.
|
|
1733
|
+
*
|
|
1734
|
+
* A synthetic index rather than a second grid: everything downstream (the
|
|
1735
|
+
* collider merge, `tileAt`, `setTile`, the editor's paint tool) already
|
|
1736
|
+
* speaks in indices, and one number per cell keeps it that way.
|
|
1737
|
+
*/
|
|
1738
|
+
palette() {
|
|
1739
|
+
return Object.values(this._colors);
|
|
1740
|
+
}
|
|
1741
|
+
/** `legend` plus the colour chars, which is what every cell lookup wants. */
|
|
1742
|
+
allChars() {
|
|
1743
|
+
const merged = { ...this._legend };
|
|
1744
|
+
Object.keys(this._colors).forEach((ch, i) => {
|
|
1745
|
+
merged[ch] = COLOR_BASE + i;
|
|
1746
|
+
});
|
|
1747
|
+
return merged;
|
|
1748
|
+
}
|
|
1749
|
+
/** `solid` as INDICES: an entry may name the char that painted the cell. */
|
|
1750
|
+
solidIndices() {
|
|
1751
|
+
const chars = this.allChars();
|
|
1752
|
+
const out = [];
|
|
1753
|
+
for (const entry of this._solid) if (typeof entry === "number") out.push(entry);
|
|
1754
|
+
else if (chars[entry] !== void 0) out.push(chars[entry]);
|
|
1755
|
+
else if (entry.length === 1 && entry >= "0" && entry <= "9") out.push(entry.charCodeAt(0) - 48);
|
|
1756
|
+
return out;
|
|
1757
|
+
}
|
|
1696
1758
|
get solid() {
|
|
1697
1759
|
return this._solid;
|
|
1698
1760
|
}
|
|
@@ -1707,11 +1769,16 @@ var TileMap2D = class extends Node2D {
|
|
|
1707
1769
|
/** Loader hook: bad cells fail at LOAD (unknown chars), not at render. */
|
|
1708
1770
|
static validateJson(node) {
|
|
1709
1771
|
const map = node;
|
|
1710
|
-
|
|
1772
|
+
for (const [ch, value] of Object.entries(map._colors)) {
|
|
1773
|
+
if (typeof value === "string" && HEX.test(value)) continue;
|
|
1774
|
+
throw new IncantoError("PROP_TYPE_MISMATCH", `TileMap2D '${node.name}': "colors" ['${ch}'] is ${JSON.stringify(value)} — a colour here is \`#rgb\` or \`#rrggbb\`, the same as every other colour prop.`, { prop: "colors" });
|
|
1775
|
+
}
|
|
1776
|
+
if (map.texture !== "" && Object.keys(map._colors).length > 0) throw new IncantoError("PROP_TYPE_MISMATCH", `TileMap2D '${node.name}': "colors" and "texture" are exclusive — colours are for a level authored before the art arrives. Drop one of them.`, { prop: "colors" });
|
|
1777
|
+
parseCells(map._cells, map.allChars());
|
|
1711
1778
|
}
|
|
1712
1779
|
/** The parsed index grid (test/tooling hook). */
|
|
1713
1780
|
grid() {
|
|
1714
|
-
return parseCells(this._cells, this.
|
|
1781
|
+
return parseCells(this._cells, this.allChars());
|
|
1715
1782
|
}
|
|
1716
1783
|
/**
|
|
1717
1784
|
* Which CELL is under this world point — `null` outside the grid.
|
|
@@ -1809,7 +1876,7 @@ var TileMap2D = class extends Node2D {
|
|
|
1809
1876
|
if (this._solid.length === 0) return;
|
|
1810
1877
|
const ts = this.tileSize;
|
|
1811
1878
|
const [sx, sy] = this.builtScale;
|
|
1812
|
-
mergeSolidRects(this.grid(), new Set(this.
|
|
1879
|
+
mergeSolidRects(this.grid(), new Set(this.solidIndices())).forEach((r, i) => {
|
|
1813
1880
|
const body = new StaticBody2D(`__tileSolid${i}`);
|
|
1814
1881
|
body.position = [(r.x + r.w / 2) * ts * sx, (r.y + r.h / 2) * ts * sy];
|
|
1815
1882
|
body.collider = {
|
|
@@ -1839,6 +1906,23 @@ var TileMap2D = class extends Node2D {
|
|
|
1839
1906
|
super._syncObject2D(assets);
|
|
1840
1907
|
const mesh = this._mesh();
|
|
1841
1908
|
const mat = mesh.material;
|
|
1909
|
+
if (Object.keys(this._colors).length > 0) {
|
|
1910
|
+
mesh.visible = this.opacity > 0;
|
|
1911
|
+
mesh.renderOrder = this.effectiveRenderOrder;
|
|
1912
|
+
mat.opacity = this.opacity;
|
|
1913
|
+
if (mat.map !== null || !mat.vertexColors) {
|
|
1914
|
+
mat.map = null;
|
|
1915
|
+
mat.vertexColors = true;
|
|
1916
|
+
mat.needsUpdate = true;
|
|
1917
|
+
this.geometryDirty = true;
|
|
1918
|
+
}
|
|
1919
|
+
if (!this.geometryDirty) return;
|
|
1920
|
+
this.geometryDirty = false;
|
|
1921
|
+
this.builtColumns = 1;
|
|
1922
|
+
this.builtRows = 1;
|
|
1923
|
+
this.buildGeometry(mesh.geometry, 1, 1);
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1842
1926
|
if (!this.texture || !assets) {
|
|
1843
1927
|
mesh.visible = false;
|
|
1844
1928
|
return;
|
|
@@ -1882,6 +1966,8 @@ var TileMap2D = class extends Node2D {
|
|
|
1882
1966
|
const positions = [];
|
|
1883
1967
|
const uvs = [];
|
|
1884
1968
|
const indices = [];
|
|
1969
|
+
const palette = this.palette().map((hex) => new Color(hex));
|
|
1970
|
+
const colors = [];
|
|
1885
1971
|
for (let y = 0; y < grid.length; y++) {
|
|
1886
1972
|
const row = grid[y];
|
|
1887
1973
|
for (let x = 0; x < row.length; x++) {
|
|
@@ -1893,18 +1979,24 @@ var TileMap2D = class extends Node2D {
|
|
|
1893
1979
|
const y1 = -((y + 1) * ts);
|
|
1894
1980
|
const base = positions.length / 3;
|
|
1895
1981
|
positions.push(x0, y0, 0, x1, y0, 0, x1, y1, 0, x0, y1, 0);
|
|
1896
|
-
const col = tile % columns;
|
|
1897
|
-
const rowIdx = Math.floor(tile / columns);
|
|
1982
|
+
const col = tile >= COLOR_BASE ? 0 : tile % columns;
|
|
1983
|
+
const rowIdx = tile >= COLOR_BASE ? 0 : Math.floor(tile / columns);
|
|
1898
1984
|
const u0 = col / columns;
|
|
1899
1985
|
const u1 = (col + 1) / columns;
|
|
1900
1986
|
const v0 = 1 - rowIdx / atlasRows;
|
|
1901
1987
|
const v1 = 1 - (rowIdx + 1) / atlasRows;
|
|
1902
1988
|
uvs.push(u0, v0, u1, v0, u1, v1, u0, v1);
|
|
1989
|
+
const paint = tile >= COLOR_BASE ? palette[tile - COLOR_BASE] : void 0;
|
|
1990
|
+
const r = paint?.r ?? 1;
|
|
1991
|
+
const g = paint?.g ?? 1;
|
|
1992
|
+
const b = paint?.b ?? 1;
|
|
1993
|
+
for (let v = 0; v < 4; v++) colors.push(r, g, b);
|
|
1903
1994
|
indices.push(base, base + 2, base + 1, base, base + 3, base + 2);
|
|
1904
1995
|
}
|
|
1905
1996
|
}
|
|
1906
1997
|
geometry.setAttribute("position", new BufferAttribute(new Float32Array(positions), 3));
|
|
1907
1998
|
geometry.setAttribute("uv", new BufferAttribute(new Float32Array(uvs), 2));
|
|
1999
|
+
geometry.setAttribute("color", new BufferAttribute(new Float32Array(colors), 3));
|
|
1908
2000
|
geometry.setIndex(indices);
|
|
1909
2001
|
geometry.computeBoundingSphere();
|
|
1910
2002
|
}
|