incanto 0.48.0 → 0.50.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-model.mjs +13 -1
- package/bin/incanto-play.mjs +42 -17
- package/bin/incanto-playtest.mjs +7 -0
- package/bin/incanto-verify.mjs +10 -2
- package/dist/2d.d.ts +21 -12
- package/dist/2d.js +57 -3
- package/dist/3d.d.ts +38 -1
- package/dist/3d.js +114 -4
- package/dist/{create-game-CniOiWzN.js → create-game-BLDjy_PW.js} +5 -5
- package/dist/{create-game-akjPkFv5.js → create-game-DqqxEax1.js} +5 -5
- package/dist/{duplicate-CRtihGmC.js → duplicate-CI9WF_bg.js} +1 -1
- package/dist/{environment-presets-D1b0ydTS.js → environment-presets-XFuqu5jv.js} +15 -20
- package/dist/{gameplay-BQOeAid6.js → gameplay-DbaI313d.js} +96 -11
- package/dist/gameplay.d.ts +17 -0
- package/dist/gameplay.js +1 -1
- package/dist/index.d.ts +40 -2
- package/dist/index.js +7 -7
- package/dist/{loader-r49nDwB4.js → loader-DwazzlQb.js} +36 -6
- package/dist/net.js +3 -3
- package/dist/{physics-2d-BmgXBNDB.js → physics-2d-_9VBOHn6.js} +4 -4
- package/dist/{physics-3d-CSoGjM8P.js → physics-3d-DrpF5hcG.js} +9 -9
- package/dist/react.js +1 -1
- package/dist/{register-R2JTnIMw.js → register-BNPZYJmd.js} +23 -22
- package/dist/{register-D651it1J.js → register-CB11yp21.js} +2 -2
- package/dist/{register-BSXV8T9F.js → register-uvaZj1KX.js} +62 -2
- package/dist/{replay-CAphXMyM.d.ts → replay-DYdy1wb0.d.ts} +5 -1
- package/dist/{replay-DilbZgQI.js → replay-j-m6lJ4W.js} +23 -3
- package/dist/sprite-animation-CMr6f1K2.d.ts +44 -0
- package/dist/{particle-sim-Bw7hB93B.js → sprite-animation-D_p28jwU.js} +63 -1
- package/dist/{src-Bl1Kire1.js → src-B3HrKuAi.js} +1 -1
- package/dist/{test-E4-otKqK.js → test-D16igj4C.js} +245 -38
- package/dist/test.d.ts +39 -7
- package/dist/test.js +2 -2
- package/dist/vite.js +2 -2
- package/editor/assets/{agent8-_007gPF8.js → agent8-t3kl5q9K.js} +1 -1
- package/editor/assets/{debug-0DI_MJaq.js → debug-Bu3eeAlO.js} +1 -1
- package/editor/assets/{index-B-6eYZEi.js → index-Df5g8ofT.js} +92 -92
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +10 -3
- package/skills/incanto-3d-character.md +13 -2
- package/skills/incanto-3d-models.md +40 -0
- package/skills/incanto-assets.md +15 -0
- package/skills/incanto-building-2d-games.md +57 -5
- package/skills/incanto-building-3d-games.md +7 -0
- package/skills/incanto-gameplay-behaviors.md +29 -1
- package/skills/incanto-hud.md +39 -0
- package/skills/incanto-node-reference.md +5 -3
- package/skills/incanto-physics-and-input.md +1 -1
- package/skills/incanto-playtesting.md +22 -4
- package/skills/incanto-verifying-your-game.md +14 -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
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { f as Node, h as effectiveOrder, n as loadScene, w as registerBehavior, y as Behavior } from "./loader-
|
|
1
|
+
import { f as Node, h as effectiveOrder, n as loadScene, w as registerBehavior, y as Behavior } from "./loader-DwazzlQb.js";
|
|
2
2
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
3
3
|
import { t as jsonClone } from "./json-BLk7H2Qa.js";
|
|
4
|
-
import { t as duplicateNode } from "./duplicate-
|
|
4
|
+
import { t as duplicateNode } from "./duplicate-CI9WF_bg.js";
|
|
5
5
|
import { Color, CubeCamera, DepthTexture, DoubleSide, Euler, FloatType, Frustum, HalfFloatType, LinearMipmapLinearFilter, MathUtils, Matrix4, Mesh, MeshDepthMaterial, Object3D, PerspectiveCamera, Plane, PlaneGeometry, Quaternion, ShaderMaterial, Sphere, Vector2, Vector3, Vector4, WebGLCubeRenderTarget, WebGLRenderTarget } from "three";
|
|
6
6
|
//#region src/3d/frustum.ts
|
|
7
7
|
const scratchFrustum = new Frustum();
|
|
@@ -2553,7 +2553,7 @@ var CharacterBody3D = class extends PhysicsBody3D {
|
|
|
2553
2553
|
0,
|
|
2554
2554
|
0
|
|
2555
2555
|
] },
|
|
2556
|
-
|
|
2556
|
+
stickToGround: { default: true },
|
|
2557
2557
|
slopeLimitDeg: { default: 45 }
|
|
2558
2558
|
};
|
|
2559
2559
|
/** m/s, y-up (up = +y). */
|
|
@@ -2562,9 +2562,30 @@ var CharacterBody3D = class extends PhysicsBody3D {
|
|
|
2562
2562
|
0,
|
|
2563
2563
|
0
|
|
2564
2564
|
];
|
|
2565
|
-
|
|
2565
|
+
/**
|
|
2566
|
+
* Hold the capsule against the surface while it moves, so walking down a
|
|
2567
|
+
* slope does not become a series of small falls.
|
|
2568
|
+
*
|
|
2569
|
+
* Named apart from `Node3D.snapToGround` (which PLACES a node on the ground
|
|
2570
|
+
* at load) because sharing the name silently broke both: the boolean shadowed
|
|
2571
|
+
* the placement prop, its `true` default made the placement pass teleport
|
|
2572
|
+
* every character body in a terrain scene, and a lift value was rejected
|
|
2573
|
+
* outright — so the only escape from the teleport also turned this off.
|
|
2574
|
+
*/
|
|
2575
|
+
stickToGround = true;
|
|
2566
2576
|
/** Max climbable slope angle. */
|
|
2567
2577
|
slopeLimitDeg = 45;
|
|
2578
|
+
/**
|
|
2579
|
+
* `snapToGround` on a character body is ambiguous, so it is refused.
|
|
2580
|
+
*
|
|
2581
|
+
* A boolean here used to mean the ground-stick, and as placement it means
|
|
2582
|
+
* "leave y alone" — which is already the default. Rather than pick one and
|
|
2583
|
+
* silently do the other thing to an existing scene, say which prop was meant.
|
|
2584
|
+
*/
|
|
2585
|
+
onReady() {
|
|
2586
|
+
if (typeof this.snapToGround === "boolean") throw new IncantoError("PROP_TYPE_MISMATCH", `'${this.getPath()}' sets snapToGround to a boolean. On a character body that is ambiguous: 'stickToGround' holds the capsule against the surface while it moves (default true), while 'snapToGround' PLACES the node on the ground at load and takes a lift in metres (e.g. 0.8) — omit it to leave y exactly as authored.`, { prop: "snapToGround" });
|
|
2587
|
+
super.onReady();
|
|
2588
|
+
}
|
|
2568
2589
|
/** @internal Updated by Physics3D.moveAndSlide. */
|
|
2569
2590
|
_grounded = false;
|
|
2570
2591
|
moveAndSlide() {
|
|
@@ -4231,6 +4252,20 @@ function firstWater(node) {
|
|
|
4231
4252
|
return null;
|
|
4232
4253
|
}
|
|
4233
4254
|
//#endregion
|
|
4255
|
+
//#region src/gameplay/move-body.ts
|
|
4256
|
+
function moveBody(node, to, dt) {
|
|
4257
|
+
const body = node;
|
|
4258
|
+
if (typeof body.moveAndSlide !== "function" || body._physics == null || dt <= 0) {
|
|
4259
|
+
node.position = [...to];
|
|
4260
|
+
return;
|
|
4261
|
+
}
|
|
4262
|
+
const from = body.position;
|
|
4263
|
+
const v = [];
|
|
4264
|
+
for (let i = 0; i < from.length; i++) v.push(((to[i] ?? from[i] ?? 0) - (from[i] ?? 0)) / dt);
|
|
4265
|
+
body.velocity = v;
|
|
4266
|
+
body.moveAndSlide();
|
|
4267
|
+
}
|
|
4268
|
+
//#endregion
|
|
4234
4269
|
//#region src/gameplay/spatial.ts
|
|
4235
4270
|
/** Duck-type test: every spatial node (Node2D/Node3D) exposes `position: number[]`. */
|
|
4236
4271
|
function hasPosition$1(node) {
|
|
@@ -4393,7 +4428,7 @@ var Chase = class extends Behavior {
|
|
|
4393
4428
|
this.inRange = false;
|
|
4394
4429
|
const step = Math.min(this.speed * dt, this.stopRange > 0 ? d - this.stopRange : d);
|
|
4395
4430
|
const { position } = moveToward(mover.position, target.position, Math.max(0, step));
|
|
4396
|
-
mover
|
|
4431
|
+
moveBody(mover, position, dt);
|
|
4397
4432
|
}
|
|
4398
4433
|
};
|
|
4399
4434
|
//#endregion
|
|
@@ -4553,7 +4588,8 @@ var Health = class extends Behavior {
|
|
|
4553
4588
|
static signals = [
|
|
4554
4589
|
"damaged",
|
|
4555
4590
|
"healed",
|
|
4556
|
-
"died"
|
|
4591
|
+
"died",
|
|
4592
|
+
"healthChanged"
|
|
4557
4593
|
];
|
|
4558
4594
|
max = 100;
|
|
4559
4595
|
regenPerSec = 0;
|
|
@@ -4602,13 +4638,29 @@ var Health = class extends Behavior {
|
|
|
4602
4638
|
this.setCurrent(0);
|
|
4603
4639
|
this.die();
|
|
4604
4640
|
}
|
|
4641
|
+
/**
|
|
4642
|
+
* The one funnel every change goes through — and therefore the one place a
|
|
4643
|
+
* HUD can be told about.
|
|
4644
|
+
*
|
|
4645
|
+
* `damaged`/`healed` both lead with the DELTA, which is the number a bar must
|
|
4646
|
+
* not show; wire either to `UiBar.setValue` and the bar paints the damage as
|
|
4647
|
+
* the health and looks like it works. Regeneration is worse: it moves
|
|
4648
|
+
* `current` through here and emits NEITHER, so a regen bar sat still while
|
|
4649
|
+
* the character healed. `healthChanged(current, max)` carries the max too, so
|
|
4650
|
+
* a raised ceiling needs no second wire.
|
|
4651
|
+
*
|
|
4652
|
+
* Silent when nothing moved: a bar that repaints on nothing is noise.
|
|
4653
|
+
*/
|
|
4605
4654
|
setCurrent(value) {
|
|
4606
|
-
|
|
4655
|
+
const next = Math.max(0, Math.min(this.max, value));
|
|
4656
|
+
if (next === this.current) return;
|
|
4657
|
+
this.current = next;
|
|
4658
|
+
this.emit("healthChanged", this.current, this.max);
|
|
4607
4659
|
}
|
|
4608
4660
|
die() {
|
|
4609
4661
|
if (this.dead) return;
|
|
4610
4662
|
this.dead = true;
|
|
4611
|
-
this.
|
|
4663
|
+
this.setCurrent(0);
|
|
4612
4664
|
this.emit("died");
|
|
4613
4665
|
if (this.freeOnDeath) this.node.queueFree();
|
|
4614
4666
|
}
|
|
@@ -5637,7 +5689,7 @@ var Patrol = class extends Behavior {
|
|
|
5637
5689
|
const target = this.pointAt(this.index);
|
|
5638
5690
|
if (!target) return;
|
|
5639
5691
|
const { position, reached } = moveToward(node.position, target, this.speed * dt);
|
|
5640
|
-
node
|
|
5692
|
+
moveBody(node, position, dt);
|
|
5641
5693
|
if (reached) {
|
|
5642
5694
|
this.emit("reachedPoint", this.index);
|
|
5643
5695
|
this.advance();
|
|
@@ -5675,6 +5727,10 @@ var Patrol = class extends Behavior {
|
|
|
5675
5727
|
* On overlap with a node in `collectorGroup`, emits `collected(value, other)`
|
|
5676
5728
|
* then `queueFree()`s itself. Wire `collected → ScoreKeeper.addScore` (the
|
|
5677
5729
|
* value is the first arg) or `collected → Collector.collect`.
|
|
5730
|
+
*
|
|
5731
|
+
* `other` is the ENTITY, not whichever of its parts touched — see
|
|
5732
|
+
* {@link findCollector}. A player is a body with children (a reach sensor, a
|
|
5733
|
+
* hitbox), and the part that enters first is rarely the part carrying the group.
|
|
5678
5734
|
*/
|
|
5679
5735
|
var Pickup = class extends Behavior {
|
|
5680
5736
|
static props = {
|
|
@@ -5695,12 +5751,41 @@ var Pickup = class extends Behavior {
|
|
|
5695
5751
|
}
|
|
5696
5752
|
tryCollect(other) {
|
|
5697
5753
|
if (this.collectedAlready) return;
|
|
5698
|
-
|
|
5754
|
+
const collector = findCollector(other, this.collectorGroup);
|
|
5755
|
+
if (!collector) return;
|
|
5699
5756
|
this.collectedAlready = true;
|
|
5700
|
-
this.emit("collected", this.value,
|
|
5757
|
+
this.emit("collected", this.value, collector);
|
|
5701
5758
|
this.node.queueFree();
|
|
5702
5759
|
}
|
|
5703
5760
|
};
|
|
5761
|
+
/**
|
|
5762
|
+
* The entity in `group` that this contact belongs to, or null.
|
|
5763
|
+
*
|
|
5764
|
+
* The same search `DamageOnContact` has always used for `Health` — the
|
|
5765
|
+
* contacted node, its descendants, then the ancestor CHAIN — and for the same
|
|
5766
|
+
* reason. An entity is a body with children (a reach sensor, a hitbox, a skin),
|
|
5767
|
+
* the group sits on one node of it, and whichever part happens to touch first
|
|
5768
|
+
* is rarely that node.
|
|
5769
|
+
*
|
|
5770
|
+
* Matching the literal entering node was a silent failure in exactly the shape
|
|
5771
|
+
* the gameplay skill recommends: a player with a `Grab` area collected almost
|
|
5772
|
+
* nothing, because the sensor is wider than the body and entered first. Five
|
|
5773
|
+
* pickups fired `triggerEnter`; one fired `collected`.
|
|
5774
|
+
*
|
|
5775
|
+
* The ancestor climb deliberately does NOT descend into siblings: past a shared
|
|
5776
|
+
* parent every other entity hangs off it too, and a coin would be collected by
|
|
5777
|
+
* a crate standing next to the player.
|
|
5778
|
+
*/
|
|
5779
|
+
function findCollector(node, group) {
|
|
5780
|
+
const queue = [node];
|
|
5781
|
+
while (queue.length > 0) {
|
|
5782
|
+
const n = queue.shift();
|
|
5783
|
+
if (n.isInGroup(group)) return n;
|
|
5784
|
+
queue.push(...n.children);
|
|
5785
|
+
}
|
|
5786
|
+
for (let n = node.parent; n; n = n.parent) if (n.isInGroup(group)) return n;
|
|
5787
|
+
return null;
|
|
5788
|
+
}
|
|
5704
5789
|
//#endregion
|
|
5705
5790
|
//#region src/gameplay/projectile.ts
|
|
5706
5791
|
/**
|
package/dist/gameplay.d.ts
CHANGED
|
@@ -97,6 +97,19 @@ declare class Health extends Behavior {
|
|
|
97
97
|
heal(n: number): void;
|
|
98
98
|
/** Drop to 0 and die immediately (ignores i-frames). */
|
|
99
99
|
kill(): void;
|
|
100
|
+
/**
|
|
101
|
+
* The one funnel every change goes through — and therefore the one place a
|
|
102
|
+
* HUD can be told about.
|
|
103
|
+
*
|
|
104
|
+
* `damaged`/`healed` both lead with the DELTA, which is the number a bar must
|
|
105
|
+
* not show; wire either to `UiBar.setValue` and the bar paints the damage as
|
|
106
|
+
* the health and looks like it works. Regeneration is worse: it moves
|
|
107
|
+
* `current` through here and emits NEITHER, so a regen bar sat still while
|
|
108
|
+
* the character healed. `healthChanged(current, max)` carries the max too, so
|
|
109
|
+
* a raised ceiling needs no second wire.
|
|
110
|
+
*
|
|
111
|
+
* Silent when nothing moved: a bar that repaints on nothing is noise.
|
|
112
|
+
*/
|
|
100
113
|
private setCurrent;
|
|
101
114
|
private die;
|
|
102
115
|
/** Current HP and whether death already fired — `max` comes back from JSON. */
|
|
@@ -318,6 +331,10 @@ declare class Patrol extends Behavior {
|
|
|
318
331
|
* On overlap with a node in `collectorGroup`, emits `collected(value, other)`
|
|
319
332
|
* then `queueFree()`s itself. Wire `collected → ScoreKeeper.addScore` (the
|
|
320
333
|
* value is the first arg) or `collected → Collector.collect`.
|
|
334
|
+
*
|
|
335
|
+
* `other` is the ENTITY, not whichever of its parts touched — see
|
|
336
|
+
* {@link findCollector}. A player is a body with children (a reach sensor, a
|
|
337
|
+
* hitbox), and the part that enters first is rarely the part carrying the group.
|
|
321
338
|
*/
|
|
322
339
|
declare class Pickup extends Behavior {
|
|
323
340
|
static readonly props: PropSchema;
|
package/dist/gameplay.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as FollowCamera, D as Health, E as DamageOnContact, O as Collector, S as restartScene, T as phaseOf, _ as hitStop, a as Wander, b as GameFlow, c as Projectile, d as PathFollow, f as Oscillate, g as Cooldown, h as CameraShake, i as WaveSpawner, k as Chase, l as Pickup, m as Lifetime, n as registerGameplayBehaviors, o as Spawner, p as MoveTo, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Patrol, v as screenFlash, w as DayNight, x as goToScene, y as Interactable } from "./gameplay-
|
|
1
|
+
import { C as FollowCamera, D as Health, E as DamageOnContact, O as Collector, S as restartScene, T as phaseOf, _ as hitStop, a as Wander, b as GameFlow, c as Projectile, d as PathFollow, f as Oscillate, g as Cooldown, h as CameraShake, i as WaveSpawner, k as Chase, l as Pickup, m as Lifetime, n as registerGameplayBehaviors, o as Spawner, p as MoveTo, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Patrol, v as screenFlash, w as DayNight, x as goToScene, y as Interactable } from "./gameplay-DbaI313d.js";
|
|
2
2
|
export { CameraShake, Chase, Collector, Cooldown, DamageOnContact, DayNight, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, Projectile, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, phaseOf, registerGameplayBehaviors, restartScene, screenFlash };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { $ as suggestLocale, A as SettingsValues, At as LogLevel, B as captureBehaviors, C as EngineStats, Ct as PlayMusicOptions, Dt as NodeLifecycle, E as DeviceHints, Et as Node, F as BehaviorState, G as OrderGroup, H as SaveStore, I as RestoreReport, J as resolveOrderGroups, K as OrderGroupTable, L as SaveSlot, M as readDeviceHints, Mt as Signal, N as suggestQuality, Nt as SignalListener, O as QualityTier, Ot as SceneTree, P as Scene, Q as T_PREFIX, R as SaveSlots, S as Scheduler, St as MusicTrack, T as RendererStats, Tt as BusName, U as createSaveStore, V as restoreBehaviors, W as ORDER_GROUP_BASE, X as LocaleTables, Y as BASE_LOCALE, Z as Localization, _ as mergeStaticSignals, _t as SfxWave, a as clearBehaviors, at as Voice, b as Engine, bt as MusicBackend, c as registeredBehaviors, ct as ROLLOFF_MODELS, d as PropSchema, dt as Vec3, et as translationKey, f as clearRegistry, ft as spatialGain, g as getNodeType, gt as SfxParams, h as getNodeSignals, ht as SFX_PRESET_NAMES, i as behaviorSignals, it as isAudioContextAvailable, j as qualityEnvironment, jt as LogManager, k as Settings, kt as LogEntry, l as NodeCtor, lt as RolloffModel, m as getNodeSchema, mt as SFX_PRESETS, n as BehaviorCtor, nt as SfxEngine, o as getBehavior, ot as VoicePreset, p as createNode, pt as spatialPan, q as effectiveOrder, r as behaviorSchema, rt as SfxPlayOptions, s as registerBehavior, st as Listener, t as Behavior, tt as InputMap, u as PropDef, ut as SpatialParams, v as registerNode, vt as SynthOptions, w as GameStats, wt as AudioBuses, x as EngineOptions, xt as MusicManager, y as registeredTypes, yt as synthSfx, z as behaviorsWithoutSave } from "./behavior-62q0HWBO.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
3
|
import { n as loadScene, t as LoadSceneOptions } from "./loader-CeyU_bm1.js";
|
|
4
|
+
import { i as resolveFrames, n as AnimationEntry, r as resolveAnimation, t as AnimationDef } from "./sprite-animation-CMr6f1K2.js";
|
|
4
5
|
import { n as ParticleSimConfig, r as ParticleView, t as ParticleSim } from "./particle-sim-BzJ1yxoE.js";
|
|
5
6
|
import { a as AudioElementLike, i as gridFromRows, n as PathGrid, o as AudioPlayer, r as findPath, t as FindPathOptions } from "./pathfinding-C49JSNNq.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-
|
|
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-DYdy1wb0.js";
|
|
7
8
|
|
|
8
9
|
//#region src/core/audio/crossfade.d.ts
|
|
9
10
|
/**
|
|
@@ -319,10 +320,37 @@ declare class UiText extends HudWidgetBase {
|
|
|
319
320
|
static override readonly typeName: string;
|
|
320
321
|
static override readonly props: PropSchema;
|
|
321
322
|
text: string;
|
|
323
|
+
/**
|
|
324
|
+
* A template with a `{}` slot that `setText` fills — `"Gems {} / 8"`.
|
|
325
|
+
*
|
|
326
|
+
* Empty (the default) means `setText` replaces the whole line. Resolved at
|
|
327
|
+
* PAINT like `text`, so `"@t:hud.gems"` works and changing locale re-reads
|
|
328
|
+
* it: the value lives here, the words live in the strings table.
|
|
329
|
+
*/
|
|
330
|
+
format: string;
|
|
322
331
|
size: number;
|
|
323
332
|
color: string;
|
|
324
333
|
shadow: boolean;
|
|
325
334
|
private last;
|
|
335
|
+
/** null until something has actually set a value — see `shown`. */
|
|
336
|
+
private slot;
|
|
337
|
+
/**
|
|
338
|
+
* Put a signal's value on screen — `scoreChanged → setText`.
|
|
339
|
+
*
|
|
340
|
+
* A `connections[]` handler must be a METHOD and `text` is a property, so the
|
|
341
|
+
* one wire every game needs (score to screen) could not be declared: every
|
|
342
|
+
* HUD began with a behavior whose whole job was one assignment.
|
|
343
|
+
*/
|
|
344
|
+
setText(value: unknown): void;
|
|
345
|
+
/**
|
|
346
|
+
* What it actually paints, after the template and the locale.
|
|
347
|
+
*
|
|
348
|
+
* Before the first value arrives, a formatted widget shows `text` — its
|
|
349
|
+
* authored opening line. Filling the slot with nothing instead would put
|
|
350
|
+
* `"Gems / 8"` on screen for every game's first frame, and a score line
|
|
351
|
+
* that starts blank looks broken rather than empty.
|
|
352
|
+
*/
|
|
353
|
+
get shown(): string;
|
|
326
354
|
protected _build(): HTMLElement;
|
|
327
355
|
protected override _sync(): void;
|
|
328
356
|
}
|
|
@@ -345,6 +373,16 @@ declare class UiBar extends HudWidgetBase {
|
|
|
345
373
|
private lastRatio;
|
|
346
374
|
/** Current fill ratio 0..1 (what the bar shows). */
|
|
347
375
|
get ratio(): number;
|
|
376
|
+
/**
|
|
377
|
+
* Drive the bar from a signal — `healthChanged → setValue`.
|
|
378
|
+
*
|
|
379
|
+
* Takes the max as a second argument because that is the shape the signal
|
|
380
|
+
* already has, so a bar whose ceiling moves (a max-HP upgrade) needs no
|
|
381
|
+
* second wire.
|
|
382
|
+
*/
|
|
383
|
+
setValue(value: number, max?: number): void;
|
|
384
|
+
/** Move the ceiling on its own, leaving the fill where it is. */
|
|
385
|
+
setMax(max: number): void;
|
|
348
386
|
protected _build(): HTMLElement;
|
|
349
387
|
protected override _sync(): void;
|
|
350
388
|
}
|
|
@@ -810,4 +848,4 @@ declare function computeViewport(canvasW: number, canvasH: number, viewport: {
|
|
|
810
848
|
/** Engine version. Kept in sync with package.json by the release pipeline. */
|
|
811
849
|
declare const VERSION: string;
|
|
812
850
|
//#endregion
|
|
813
|
-
export { type AssetFailure, AudioBuses, type AudioElementLike, AudioPlayer, BASE_LOCALE, Behavior, type BehaviorCtor, type BehaviorState, type BusName, CONST_REF_KEY, type ComputedViewport, type ConnectionJson, type CrossfadeGains, type DebugLineSource, type DeviceHints, type DriveScript, type DriveStep, Engine, type EngineOptions, type EngineStats, type FindPathOptions, type GameStats, type GroupedLog, type HudAnchor, HudLayer, IncantoError, type IncantoErrorCode, type IncantoErrorDetails, InputMap, type JsonKind, type JsonObject, type JsonValue, type Listener, type LiveInput, type LiveReport, type LoadSceneOptions, type LocaleTables, Localization, type LogEntry, type LogLevel, LogManager, type MusicBackend, MusicManager, type MusicTrack, Node, type NodeCtor, type NodeJson, type NodeLifecycle, ORDER_GROUP_BASE, type OrderGroup, type OrderGroupTable, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, type ParsedNodePath, type ParticlePresetValues, ParticleSim, type ParticleSimConfig, type ParticleView, type PathGrid, type PlayMusicOptions, type PreloadResult, type PropDef, type PropSchema, type QualityTier, ROLLOFF_MODELS, type Recorder, type RendererStats, type ReplayEvent, type ReplayJson, type ResolvedRendering, type ResolvedViewport, type RestoreReport, Rng, type RolloffModel, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, type SaveSlot, SaveSlots, type SaveStore, Scene, type SceneJson, SceneTree, type Scheduler, Settings, type SettingsValues, SfxEngine, type SfxParams, type SfxPlayOptions, type SfxWave, Signal, type SignalListener, type SpatialParams, type SynthOptions, T_PREFIX, Timer, TouchControls, type TouchControlsOptions, UiBanner, UiBar, UiButton, UiDialogue, UiImage, UiPanel, UiSelect, UiSlider, UiText, UiToggle, VERSION, type Vec3, type ViewportFit, type Voice, type VoicePreset, 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, logReport, logText, mergeStaticSignals, newUid, parseDrive, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveConstants, resolveOrderGroups, resolveRendering, resolveViewport, restoreBehaviors, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
|
|
851
|
+
export { type AnimationDef, type AnimationEntry, type AssetFailure, AudioBuses, type AudioElementLike, AudioPlayer, BASE_LOCALE, Behavior, type BehaviorCtor, type BehaviorState, type BusName, CONST_REF_KEY, type ComputedViewport, type ConnectionJson, type CrossfadeGains, type DebugLineSource, type DeviceHints, type DriveScript, type DriveStep, Engine, type EngineOptions, type EngineStats, type FindPathOptions, type GameStats, type GroupedLog, type HudAnchor, HudLayer, IncantoError, type IncantoErrorCode, type IncantoErrorDetails, InputMap, type JsonKind, type JsonObject, type JsonValue, type Listener, type LiveInput, type LiveReport, type LoadSceneOptions, type LocaleTables, Localization, type LogEntry, type LogLevel, LogManager, type MusicBackend, MusicManager, type MusicTrack, Node, type NodeCtor, type NodeJson, type NodeLifecycle, ORDER_GROUP_BASE, type OrderGroup, type OrderGroupTable, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, type ParsedNodePath, type ParticlePresetValues, ParticleSim, type ParticleSimConfig, type ParticleView, type PathGrid, type PlayMusicOptions, type PreloadResult, type PropDef, type PropSchema, type QualityTier, ROLLOFF_MODELS, type Recorder, type RendererStats, type ReplayEvent, type ReplayJson, type ResolvedRendering, type ResolvedViewport, type RestoreReport, Rng, type RolloffModel, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, type SaveSlot, SaveSlots, type SaveStore, Scene, type SceneJson, SceneTree, type Scheduler, Settings, type SettingsValues, SfxEngine, type SfxParams, type SfxPlayOptions, type SfxWave, Signal, type SignalListener, type SpatialParams, type SynthOptions, T_PREFIX, Timer, TouchControls, type TouchControlsOptions, UiBanner, UiBar, UiButton, UiDialogue, UiImage, UiPanel, UiSelect, UiSlider, UiText, UiToggle, VERSION, type Vec3, type ViewportFit, type Voice, type VoicePreset, 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, logReport, logText, mergeStaticSignals, newUid, parseDrive, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveAnimation, resolveConstants, resolveFrames, resolveOrderGroups, resolveRendering, resolveViewport, restoreBehaviors, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
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-
|
|
2
|
-
import { A as T_PREFIX, B as synthSfx, C as behaviorsWithoutSave, D as LogManager, E as createSaveStore, F as ROLLOFF_MODELS, G as AudioBuses, H as WebAudioMusicBackend, I as spatialGain, L as spatialPan, M as translationKey, N as SfxEngine, O as BASE_LOCALE, P as isAudioContextAvailable, R as SFX_PRESETS, S as SaveSlots, T as restoreBehaviors, U as crossfadeGains, V as MusicManager, W as fadeGain, a as UiSlider, b as readDeviceHints, c as UiButton, d as UiBanner, f as UiBar, g as Settings, h as Engine, i as UiSelect, j as suggestLocale, k as Localization, 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, v as qualityEnvironment, w as captureBehaviors, x as suggestQuality, z as SFX_PRESET_NAMES } from "./register-
|
|
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-DwazzlQb.js";
|
|
2
|
+
import { A as T_PREFIX, B as synthSfx, C as behaviorsWithoutSave, D as LogManager, E as createSaveStore, F as ROLLOFF_MODELS, G as AudioBuses, H as WebAudioMusicBackend, I as spatialGain, L as spatialPan, M as translationKey, N as SfxEngine, O as BASE_LOCALE, P as isAudioContextAvailable, R as SFX_PRESETS, S as SaveSlots, T as restoreBehaviors, U as crossfadeGains, V as MusicManager, W as fadeGain, a as UiSlider, b as readDeviceHints, c as UiButton, d as UiBanner, f as UiBar, g as Settings, h as Engine, i as UiSelect, j as suggestLocale, k as Localization, 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, v as qualityEnvironment, w as captureBehaviors, x as suggestQuality, z as SFX_PRESET_NAMES } from "./register-uvaZj1KX.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-j-m6lJ4W.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 { n as logText, r as parseDrive, t as logReport } from "./log-report-lxrQY9cH.js";
|
|
9
9
|
import { t as createNoise2D } from "./noise-CGUMx44x.js";
|
|
10
|
-
import { i as
|
|
11
|
-
import { a as findPath, i as preloadUrls, n as newUid, o as gridFromRows, r as assetUrls, t as VERSION } from "./src-
|
|
10
|
+
import { a as PARTICLE_PRESETS, i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-D_p28jwU.js";
|
|
11
|
+
import { a as findPath, i as preloadUrls, n as newUid, o as gridFromRows, r as assetUrls, t as VERSION } from "./src-B3HrKuAi.js";
|
|
12
12
|
import { i as resolveRendering, n as attachTouchControls, r as joystickVector, t as TouchControls } from "./touch-BoNg_MnF.js";
|
|
13
|
-
import { t as duplicateNode } from "./duplicate-
|
|
14
|
-
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, logReport, logText, mergeStaticSignals, newUid, parseDrive, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveConstants, resolveOrderGroups, resolveRendering, resolveViewport, restoreBehaviors, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
|
|
13
|
+
import { t as duplicateNode } from "./duplicate-CI9WF_bg.js";
|
|
14
|
+
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, logReport, logText, mergeStaticSignals, newUid, parseDrive, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveAnimation, resolveConstants, resolveFrames, resolveOrderGroups, resolveRendering, resolveViewport, restoreBehaviors, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
|
|
@@ -1606,13 +1606,17 @@ function wireConnections(root, connections, declareSignals = false) {
|
|
|
1606
1606
|
const listener = (...args) => {
|
|
1607
1607
|
if (conn.filter && !matchesFilter(args[0], conn.filter)) return;
|
|
1608
1608
|
if (conn.once) fromNode.off(conn.signal, listener);
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1609
|
+
try {
|
|
1610
|
+
const fn = toNode[conn.handler];
|
|
1611
|
+
if (typeof fn === "function") {
|
|
1612
|
+
fn.apply(toNode, args);
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
const bfn = toNode.behavior ? toNode.behavior[conn.handler] : void 0;
|
|
1616
|
+
if (typeof bfn === "function") bfn.apply(toNode.behavior, args);
|
|
1617
|
+
} catch (error) {
|
|
1618
|
+
quarantineWire(fromNode, toNode, conn, listener, error);
|
|
1613
1619
|
}
|
|
1614
|
-
const bfn = toNode.behavior ? toNode.behavior[conn.handler] : void 0;
|
|
1615
|
-
if (typeof bfn === "function") bfn.apply(toNode.behavior, args);
|
|
1616
1620
|
};
|
|
1617
1621
|
try {
|
|
1618
1622
|
fromNode.on(conn.signal, listener);
|
|
@@ -1622,6 +1626,32 @@ function wireConnections(root, connections, declareSignals = false) {
|
|
|
1622
1626
|
}
|
|
1623
1627
|
}
|
|
1624
1628
|
}
|
|
1629
|
+
/**
|
|
1630
|
+
* A handler threw. Turn THAT WIRE off, and leave the game running.
|
|
1631
|
+
*
|
|
1632
|
+
* The engine already draws this line for scripts: "a behavior is your code; the
|
|
1633
|
+
* node is the engine's. A typo in the first must not switch off the second, or
|
|
1634
|
+
* breaking a sword script stops the character from walking." A connection is
|
|
1635
|
+
* the same category — authored wiring, not the emitting node's own logic — and
|
|
1636
|
+
* it behaved the opposite way, because the handler runs inside `Signal.emit`
|
|
1637
|
+
* and its exception surfaces in whoever EMITTED. The node quarantine then blames
|
|
1638
|
+
* and skips that node, so a `movementStateChanged → play` wire naming a clip the
|
|
1639
|
+
* sheet does not have switched off the character controller: no animation, and
|
|
1640
|
+
* no movement either.
|
|
1641
|
+
*
|
|
1642
|
+
* Reported ONCE and disconnected, on the same reasoning as the node quarantine:
|
|
1643
|
+
* a handler that throws throws every frame, and sixty identical traces a second
|
|
1644
|
+
* bury the one line that matters.
|
|
1645
|
+
*/
|
|
1646
|
+
function quarantineWire(fromNode, toNode, conn, listener, error) {
|
|
1647
|
+
fromNode.off(conn.signal, listener);
|
|
1648
|
+
const target = toNode.behavior ? `'${conn.handler}' on behavior '${toNode.script?.name}' (${toNode.getPath()})` : `'${conn.handler}' on ${toNode.getPath()}`;
|
|
1649
|
+
const message = `[incanto] connection '${conn.signal}' from ${fromNode.getPath()} → handler ${target} threw — THIS WIRE is now off; the node that emitted the signal, and the rest of the scene, keep running.`;
|
|
1650
|
+
const engine = toNode.tree?.engine ?? fromNode.tree?.engine;
|
|
1651
|
+
engine?.log.error(message, error);
|
|
1652
|
+
engine?._nodeErrored(toNode);
|
|
1653
|
+
console.error(message, error);
|
|
1654
|
+
}
|
|
1625
1655
|
function resolveEndpoint(root, path, conn, side) {
|
|
1626
1656
|
try {
|
|
1627
1657
|
return root.getNode(path);
|
package/dist/net.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { n as loadScene } from "./loader-
|
|
2
|
-
import { h as Engine } from "./register-
|
|
1
|
+
import { n as loadScene } from "./loader-DwazzlQb.js";
|
|
2
|
+
import { h as Engine } from "./register-uvaZj1KX.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-CB11yp21.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
|
-
import { v as diagnose } from "./loader-
|
|
2
|
+
import { v as diagnose } from "./loader-DwazzlQb.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-BNPZYJmd.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({
|
|
@@ -90,7 +90,7 @@ var Physics2D = class {
|
|
|
90
90
|
this.world.step(this.events);
|
|
91
91
|
for (const [node, e] of this.entries) {
|
|
92
92
|
const t = e.body.translation();
|
|
93
|
-
if (!e.body.isFixed()) {
|
|
93
|
+
if (!e.body.isFixed() && !(node instanceof Area2D)) {
|
|
94
94
|
const [ox, oy] = parentWorldOffset2D(node);
|
|
95
95
|
node.position = [t.x * SCALE - ox, t.y * SCALE - oy];
|
|
96
96
|
}
|
|
@@ -122,7 +122,7 @@ var Physics2D = class {
|
|
|
122
122
|
moveAndSlide(node) {
|
|
123
123
|
const e = this.ensureEntry(node);
|
|
124
124
|
const vy = node.velocity[1] ?? 0;
|
|
125
|
-
if (node.
|
|
125
|
+
if (node.stickToGround && vy >= 0) this.kcc.enableSnapToGround(.05);
|
|
126
126
|
else this.kcc.disableSnapToGround();
|
|
127
127
|
this.kcc.setMaxSlopeClimbAngle(node.slopeLimitDeg * DEG);
|
|
128
128
|
let carryX = 0;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { v as diagnose } from "./loader-
|
|
2
|
+
import { v as diagnose } from "./loader-DwazzlQb.js";
|
|
3
3
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
|
-
import { F as PhysicsBody3D, I as RigidBody3D, N as Area3D, P as CharacterBody3D, R as Node3D, z as validateCollider3D } from "./gameplay-
|
|
4
|
+
import { F as PhysicsBody3D, I as RigidBody3D, N as Area3D, P as CharacterBody3D, R as Node3D, z as validateCollider3D } from "./gameplay-DbaI313d.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-XFuqu5jv.js";
|
|
7
7
|
import { Euler, Matrix4, Quaternion, Vector3 } from "three";
|
|
8
8
|
//#region src/3d/physics/collider-lines.ts
|
|
9
9
|
/**
|
|
@@ -291,7 +291,7 @@ var Physics3D = class {
|
|
|
291
291
|
this.world.step(this.events);
|
|
292
292
|
for (const [node, e] of this.entries) {
|
|
293
293
|
const t = e.body.translation();
|
|
294
|
-
if (!e.body.isFixed()) {
|
|
294
|
+
if (!e.body.isFixed() && !(node instanceof Area3D)) {
|
|
295
295
|
const [ox, oy, oz] = parentWorldOffset3D(node);
|
|
296
296
|
const next = [
|
|
297
297
|
t.x - ox,
|
|
@@ -323,10 +323,10 @@ var Physics3D = class {
|
|
|
323
323
|
e.lastV[1] = lv.y;
|
|
324
324
|
e.lastV[2] = lv.z;
|
|
325
325
|
}
|
|
326
|
-
const
|
|
327
|
-
e.last[0] =
|
|
328
|
-
e.last[1] =
|
|
329
|
-
e.last[2] =
|
|
326
|
+
const t2 = e.body.translation();
|
|
327
|
+
e.last[0] = t2.x;
|
|
328
|
+
e.last[1] = t2.y;
|
|
329
|
+
e.last[2] = t2.z;
|
|
330
330
|
}
|
|
331
331
|
this.events.drainCollisionEvents((h1, h2, started) => {
|
|
332
332
|
const a = this.byColliderHandle.get(h1);
|
|
@@ -373,7 +373,7 @@ var Physics3D = class {
|
|
|
373
373
|
const e = this.ensureEntry(node);
|
|
374
374
|
if (!e) return;
|
|
375
375
|
const vy = node.velocity[1] ?? 0;
|
|
376
|
-
if (node.
|
|
376
|
+
if (node.stickToGround && vy <= 0) this.kcc.enableSnapToGround(.1);
|
|
377
377
|
else this.kcc.disableSnapToGround();
|
|
378
378
|
this.kcc.setMaxSlopeClimbAngle(node.slopeLimitDeg * DEG);
|
|
379
379
|
let carryX = 0;
|
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-DqqxEax1.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-BLDjy_PW.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 { f as Node, h as effectiveOrder } from "./loader-
|
|
2
|
-
import { t as registerCoreNodes } from "./register-
|
|
1
|
+
import { f as Node, h as effectiveOrder } from "./loader-DwazzlQb.js";
|
|
2
|
+
import { t as registerCoreNodes } from "./register-uvaZj1KX.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";
|
|
6
|
-
import { i as
|
|
6
|
+
import { i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, r as validateAnimationAliases, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-D_p28jwU.js";
|
|
7
7
|
import { AdditiveBlending, BufferAttribute, BufferGeometry, CanvasTexture, Color, DynamicDrawUsage, Group, InstancedMesh, MathUtils, Matrix4, Mesh, MeshBasicMaterial, NearestFilter, NormalBlending, Object3D, PlaneGeometry } from "three";
|
|
8
8
|
//#region src/2d/physics/collider-validate.ts
|
|
9
9
|
/**
|
|
@@ -198,13 +198,19 @@ var CharacterBody2D = class extends PhysicsBody2D {
|
|
|
198
198
|
static typeName = "CharacterBody2D";
|
|
199
199
|
static props = {
|
|
200
200
|
velocity: { default: [0, 0] },
|
|
201
|
-
|
|
201
|
+
stickToGround: { default: true },
|
|
202
202
|
slopeLimitDeg: { default: 45 }
|
|
203
203
|
};
|
|
204
|
+
/**
|
|
205
|
+
* Renamed to match the 3D body, where `snapToGround` had to give the name
|
|
206
|
+
* back to `Node3D`'s PLACEMENT prop. 2D has no placement prop, so nothing is
|
|
207
|
+
* ambiguous here and old scenes keep loading unchanged.
|
|
208
|
+
*/
|
|
209
|
+
static propAliases = { snapToGround: "stickToGround" };
|
|
204
210
|
/** px/s, y-down (up = -y). */
|
|
205
211
|
velocity = [0, 0];
|
|
206
212
|
/** Keep contact on slopes/steps while not moving upward. */
|
|
207
|
-
|
|
213
|
+
stickToGround = true;
|
|
208
214
|
/** Max climbable slope angle. */
|
|
209
215
|
slopeLimitDeg = 45;
|
|
210
216
|
/** @internal Updated by Physics2D.moveAndSlide. */
|
|
@@ -402,13 +408,19 @@ var AnimatedSprite2D = class extends Sprite2D {
|
|
|
402
408
|
frameList = [];
|
|
403
409
|
frameIndex = 0;
|
|
404
410
|
frameTime = 0;
|
|
411
|
+
currentDef = null;
|
|
405
412
|
ownTexture = null;
|
|
406
413
|
loadedSheetRef = "";
|
|
414
|
+
/**
|
|
415
|
+
* `currentAnimation` reports the clip that is RUNNING, not the name asked
|
|
416
|
+
* for: an alias is a rename, and a state machine that reads back `fall` while
|
|
417
|
+
* the idle frames play is describing something that is not happening.
|
|
418
|
+
*/
|
|
407
419
|
play(name) {
|
|
408
|
-
const def = this.animations
|
|
409
|
-
|
|
410
|
-
this.
|
|
411
|
-
this.frameList = resolveFrames(def.frames,
|
|
420
|
+
const { name: resolved, def } = resolveAnimation(this.animations, name, this.name);
|
|
421
|
+
this.currentAnimation = resolved;
|
|
422
|
+
this.currentDef = def;
|
|
423
|
+
this.frameList = resolveFrames(def.frames, resolved);
|
|
412
424
|
this.frameIndex = 0;
|
|
413
425
|
this.currentFrame = this.frameList[0] ?? 0;
|
|
414
426
|
this.frameTime = 0;
|
|
@@ -418,11 +430,12 @@ var AnimatedSprite2D = class extends Sprite2D {
|
|
|
418
430
|
this.playing = false;
|
|
419
431
|
}
|
|
420
432
|
onReady() {
|
|
433
|
+
validateAnimationAliases(this.animations, this.name);
|
|
421
434
|
if (this.autoplay) this.play(this.autoplay);
|
|
422
435
|
}
|
|
423
436
|
update(dt) {
|
|
424
437
|
if (!this.playing || this.currentAnimation === "") return;
|
|
425
|
-
const def = this.
|
|
438
|
+
const def = this.currentDef;
|
|
426
439
|
if (!def || !Number.isFinite(def.fps) || def.fps <= 0) return;
|
|
427
440
|
const perFrame = 1 / def.fps;
|
|
428
441
|
this.frameTime += dt;
|
|
@@ -462,18 +475,6 @@ var AnimatedSprite2D = class extends Sprite2D {
|
|
|
462
475
|
};
|
|
463
476
|
}
|
|
464
477
|
};
|
|
465
|
-
function resolveFrames(frames, name) {
|
|
466
|
-
if (!Array.isArray(frames) || frames.length === 0) throw new IncantoError("BAD_FORMAT", `Animation '${name}': "frames" must be a non-empty array.`);
|
|
467
|
-
if (frames.length === 2) {
|
|
468
|
-
const [start, end] = frames;
|
|
469
|
-
if (end >= start) {
|
|
470
|
-
const out = [];
|
|
471
|
-
for (let f = start; f <= end; f++) out.push(f);
|
|
472
|
-
return out;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
return [...frames];
|
|
476
|
-
}
|
|
477
478
|
//#endregion
|
|
478
479
|
//#region src/2d/nodes/camera-2d.ts
|
|
479
480
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { E as Signal, f as Node, t as buildNodeJson } from "./loader-
|
|
2
|
-
import { t as registerCoreNodes } from "./register-
|
|
1
|
+
import { E as Signal, f as Node, t as buildNodeJson } from "./loader-DwazzlQb.js";
|
|
2
|
+
import { t as registerCoreNodes } from "./register-uvaZj1KX.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";
|