incanto 0.69.0 → 0.70.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/_behaviors-loader.mjs +22 -0
- package/bin/_read-json.mjs +28 -0
- package/bin/incanto-assets.mjs +5 -4
- package/bin/incanto-check.mjs +58 -31
- package/bin/incanto-editor.mjs +128 -5
- package/bin/incanto-env.mjs +3 -2
- package/bin/incanto-feel.mjs +24 -13
- package/bin/incanto-frame.mjs +8 -1
- package/bin/incanto-multiplay.mjs +11 -9
- package/bin/incanto-new.mjs +105 -10
- package/bin/incanto-play.mjs +158 -16
- package/bin/incanto-playtest.mjs +66 -23
- package/bin/incanto-skills.mjs +14 -2
- package/bin/incanto-verify.mjs +125 -44
- package/bin/incanto.mjs +3 -2
- package/dist/2d.d.ts +281 -34
- package/dist/2d.js +4 -4
- package/dist/3d.d.ts +157 -9
- package/dist/3d.js +7 -7
- package/dist/{agent8-CvsfVskX.js → agent8-CmNF01gA.js} +61 -8
- package/dist/{audio-player-C0j2k-yB.d.ts → audio-player-DaMxqfNE.d.ts} +2 -2
- package/dist/{behavior-rm8vVzu_.d.ts → behavior-DZExDn9o.d.ts} +744 -46
- package/dist/{create-game-CwxEDlCm.js → create-game-Bwvh6q8A.js} +142 -59
- package/dist/{create-game-CvJ1wSRP.js → create-game-C7ffQWW7.js} +97 -47
- package/dist/debug.d.ts +1 -1
- package/dist/debug.js +2 -3
- package/dist/diagnostics-Cu85N3tL.d.ts +12 -0
- package/dist/{editor-switch-CnIOiyNJ.d.ts → editor-switch-CFU9mCec.d.ts} +22 -13
- package/dist/editor.js +1065 -863
- package/dist/env.d.ts +1 -1
- package/dist/env.js +5 -3
- package/dist/{environment-presets-BO-7XoFV.js → environment-presets-D6Q5BxeE.js} +298 -45
- package/dist/{gameplay-D1KixWK8.js → gameplay-BfHkuzVb.js} +809 -211
- package/dist/gameplay.d.ts +187 -7
- package/dist/gameplay.js +1 -1
- package/dist/{heightmap-CRK0M4jT.js → heightmap-BYgD5Edk.js} +1 -1
- package/dist/index.d.ts +156 -13
- package/dist/index.js +10 -12
- package/dist/json-CfTjpvW8.js +67 -0
- package/dist/{loader-DadV2QCT.d.ts → loader-Cff09LMm.d.ts} +2 -2
- package/dist/net.d.ts +27 -3
- package/dist/net.js +2 -2
- package/dist/{noise-CGUMx44x.js → noise-D3nPpmFg.js} +1 -1
- package/dist/{physics-2d-CF5yyjbj.js → physics-2d-CE0Qvy3V.js} +136 -11
- package/dist/{physics-3d-DbYaEcZy.js → physics-3d-CpH-2gn5.js} +104 -23
- package/dist/{teardown-CMqFVxO9.js → picking-CQJ_PJKh.js} +103 -12
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/{register-mmfugpaQ.js → register-6DYnKZcy.js} +546 -817
- package/dist/{register-DbVArsns.js → register-Bkk0wSDB.js} +332 -23
- package/dist/{replay-BEHLDcQV.js → replay-DjAkAzMq.js} +224 -14
- package/dist/{replay-BQfkX4x7.d.ts → replay-Dmw-PKQu.d.ts} +20 -3
- package/dist/{schema-B6ugCV1Q.d.ts → rng-Bb-IutXB.d.ts} +38 -21
- package/dist/{rng-DP-SR7eg.js → rng-CDOMybym.js} +22 -0
- package/dist/{loader-DZE7B07H.js → save-slots-BXVg148r.js} +4570 -2322
- package/dist/{split-screen-Cg76MCV5.d.ts → split-screen--k-XpBjr.d.ts} +36 -4
- package/dist/{split-screen-CauMwu6y.js → split-screen-PL78oVXP.js} +159 -26
- package/dist/{sprite-animation-CY-mrr1L.js → sprite-animation-CqR2o3SA.js} +39 -8
- package/dist/{src-CYEu-_S9.js → src-Cxfiv1Hg.js} +2 -17
- package/dist/test-iHYVUcDK.js +4036 -0
- package/dist/test.d.ts +531 -30
- package/dist/test.js +3 -3
- package/dist/touch-BnCyPA0G.js +519 -0
- package/dist/vite.d.ts +20 -37
- package/dist/vite.js +176 -6
- package/dist/{webgl-unavailable-Z5_g8x9H.js → webgl-unavailable-C8aDbGmR.js} +44 -0
- package/editor/assets/agent8-D0MS174y.js +1 -0
- package/editor/assets/{debug-CMULinBW.js → debug-BnXkKuYu.js} +2 -2
- package/editor/assets/index-CIu3uc3l.js +11046 -0
- package/editor/index.html +1 -1
- package/package.json +4 -14
- package/schemas/scene.schema.json +30 -3
- package/skills/incanto-3d-character.md +14 -1
- package/skills/incanto-3d-models.md +12 -0
- package/skills/incanto-assets.md +9 -1
- package/skills/incanto-audio.md +8 -2
- package/skills/incanto-behaviors-and-scripts.md +83 -6
- package/skills/incanto-building-2d-games.md +77 -8
- package/skills/incanto-building-3d-games.md +58 -4
- package/skills/incanto-editor.md +46 -7
- package/skills/incanto-environment.md +19 -1
- package/skills/incanto-game-feel.md +70 -0
- package/skills/incanto-gameplay-behaviors.md +109 -19
- package/skills/incanto-hud.md +128 -7
- package/skills/incanto-localization.md +13 -5
- package/skills/incanto-multiplayer.md +83 -3
- package/skills/incanto-node-reference.md +222 -58
- package/skills/incanto-performance.md +52 -0
- package/skills/incanto-physics-and-input.md +123 -24
- package/skills/incanto-playtesting.md +78 -2
- package/skills/incanto-save-slots.md +161 -6
- package/skills/incanto-scene-json-authoring.md +69 -12
- package/skills/incanto-verifying-your-game.md +196 -10
- package/skills/incanto-web-integration.md +28 -0
- package/skills/incanto-your-first-game.md +3 -1
- package/templates-app/beacon-isle-3d/generate-world.ts +77 -9
- package/templates-app/beacon-isle-3d/package.json +2 -2
- package/templates-app/beacon-isle-3d/src/behaviors.ts +22 -0
- package/templates-app/beacon-isle-3d/src/game.scene.json +103 -378
- package/templates-app/beacon-isle-3d/src/main.ts +11 -1
- package/templates-app/beacon-isle-3d/tsconfig.json +1 -1
- package/templates-app/beacon-isle-3d/verify.ts +3 -1
- package/templates-app/molehill-2d/.incanto/playtest/lost-seed1.json +4277 -0
- package/templates-app/molehill-2d/PROJECT/Context.md +58 -0
- package/templates-app/molehill-2d/PROJECT/Requirements.md +39 -0
- package/templates-app/molehill-2d/PROJECT/Status.md +27 -0
- package/templates-app/molehill-2d/PROJECT/Structure.md +48 -0
- package/templates-app/molehill-2d/docs/project-2d-rules.md +44 -0
- package/templates-app/molehill-2d/index.html +73 -0
- package/templates-app/molehill-2d/package.json +23 -0
- package/templates-app/molehill-2d/src/behaviors.ts +198 -0
- package/templates-app/molehill-2d/src/game.scene.json +1255 -0
- package/templates-app/molehill-2d/src/main.ts +41 -0
- package/templates-app/molehill-2d/tsconfig.json +13 -0
- package/templates-app/molehill-2d/verify.ts +247 -0
- package/templates-app/molehill-2d/vite.config.ts +12 -0
- package/templates-app/platformer-2d/package.json +2 -2
- package/templates-app/platformer-2d/src/game.scene.json +128 -600
- package/templates-app/platformer-2d/src/main.ts +11 -1
- package/templates-app/platformer-2d/tsconfig.json +1 -1
- package/templates-app/star-survivor/package.json +2 -2
- package/templates-app/star-survivor/src/game.scene.json +41 -195
- package/templates-app/star-survivor/src/main.ts +11 -1
- package/templates-app/star-survivor/tsconfig.json +1 -1
- package/templates-app/tps-3d/PROJECT/Context.md +1 -1
- package/templates-app/tps-3d/package.json +2 -2
- package/templates-app/tps-3d/src/behaviors.ts +19 -1
- package/templates-app/tps-3d/src/game.scene.json +78 -217
- package/templates-app/tps-3d/src/main.ts +13 -2
- package/templates-app/tps-3d/tsconfig.json +1 -1
- package/templates-app/village-quest-3d/.incanto/playtest/swapped-seed1.json +1735 -0
- package/templates-app/village-quest-3d/package.json +2 -2
- package/templates-app/village-quest-3d/src/behaviors.ts +21 -0
- package/templates-app/village-quest-3d/src/grove.scene.json +54 -221
- package/templates-app/village-quest-3d/src/main.ts +11 -1
- package/templates-app/village-quest-3d/src/village.scene.json +199 -838
- package/templates-app/village-quest-3d/tsconfig.json +1 -1
- package/templates-app/village-quest-3d/verify.ts +14 -1
- package/dist/duplicate-Dj4L-5AA.js +0 -22
- package/dist/json-CwwhxQgb.js +0 -36
- package/dist/registry-CF70EArN.js +0 -212
- package/dist/rolldown-runtime-D7D4PA-g.js +0 -13
- package/dist/test-D6ISmuFE.js +0 -2383
- package/dist/touch-DEAmqGdf.js +0 -225
- package/editor/assets/agent8-BDvaZMQJ.js +0 -1
- package/editor/assets/index-CZIRr5EL.js +0 -10958
package/dist/index.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-CfTjpvW8.js";
|
|
2
|
+
import { C as isConstRef, D as newUid, E as resolveViewport, H as UiBar, J as describeRefProblem, K as Node, M as effectiveOrder, N as resolveOrderGroups, O as SceneTree, P as InputMap, Q as Behavior, R as HudLayer, S as CONST_REF_KEY, T as computeViewport, U as UiText, V as UiBanner, X as resolveRefInJson, Y as nodeRefWarnings, Z as parseNodePath, _ as SCENE_FORMAT, a as restoreBehaviors, at as registeredBehaviors, et as behaviorSchema, g as serializeNode, h as Scene, i as captureBehaviors, it as registerBehavior, j as ORDER_GROUP_BASE, k as createSaveStore, n as SaveSlots, nt as clearBehaviors, o as savesWithoutUid, ot as Signal, p as loadScene, r as behaviorsWithoutSave, rt as getBehavior, s as duplicateNode, tt as behaviorSignals, w as resolveConstants } from "./save-slots-BXVg148r.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-6DYnKZcy.js";
|
|
3
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
4
|
-
import { t as Rng } from "./rng-
|
|
5
|
-
import { n as
|
|
6
|
-
import {
|
|
7
|
-
import { i as joystickVector, n as attachTouchControls, t as TouchControls } from "./touch-DEAmqGdf.js";
|
|
8
|
-
import { n as startRecording, r as auditScene, t as replay } from "./replay-BEHLDcQV.js";
|
|
5
|
+
import { t as Rng } from "./rng-CDOMybym.js";
|
|
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-DjAkAzMq.js";
|
|
9
8
|
import { t as showBootFailure } from "./boot-failure-CKYrEcGF.js";
|
|
10
|
-
import { a as logText, i as logReport, o as parseDrive, r as resolveRendering, t as isWebGLAvailable } from "./webgl-unavailable-
|
|
11
|
-
import { t as createNoise2D } from "./noise-
|
|
12
|
-
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-
|
|
13
|
-
import { a as
|
|
14
|
-
import { t as duplicateNode } from "./duplicate-Dj4L-5AA.js";
|
|
9
|
+
import { a as logText, i as logReport, o as parseDrive, r as resolveRendering, t as isWebGLAvailable } from "./webgl-unavailable-C8aDbGmR.js";
|
|
10
|
+
import { t as createNoise2D } from "./noise-D3nPpmFg.js";
|
|
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-Cxfiv1Hg.js";
|
|
15
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 };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/core/json.ts
|
|
14
|
+
var json_exports = /* @__PURE__ */ __exportAll({
|
|
15
|
+
jsonClone: () => jsonClone,
|
|
16
|
+
jsonEquals: () => jsonEquals,
|
|
17
|
+
jsonKind: () => jsonKind,
|
|
18
|
+
parseJsonText: () => parseJsonText
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* `JSON.parse`, minus the byte nobody can see.
|
|
22
|
+
*
|
|
23
|
+
* A UTF-8 byte order mark is legal in a UTF-8 file and meaningless in it, and
|
|
24
|
+
* `JSON.parse` refuses it. Windows PowerShell 5.1's `Set-Content` writes one by
|
|
25
|
+
* default and several editors add it on "save as UTF-8", so a scene written by
|
|
26
|
+
* an ordinary tool came back as
|
|
27
|
+
*
|
|
28
|
+
* ```
|
|
29
|
+
* [BAD_JSON] Unexpected token '\uFEFF', "\uFEFF{ "format"... is not valid JSON
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* about a character that is ZERO WIDTH: the author sees valid JSON, an error
|
|
33
|
+
* pointing at nothing, and no way forward. Node's own `require()` of a .json
|
|
34
|
+
* file has stripped it for a decade; `JSON.parse` is the one door that does not.
|
|
35
|
+
*/
|
|
36
|
+
function parseJsonText(text) {
|
|
37
|
+
return JSON.parse(text.charCodeAt(0) === 65279 ? text.slice(1) : text);
|
|
38
|
+
}
|
|
39
|
+
function jsonKind(value) {
|
|
40
|
+
if (value === null) return "null";
|
|
41
|
+
if (Array.isArray(value)) return "array";
|
|
42
|
+
const t = typeof value;
|
|
43
|
+
if (t === "string" || t === "number" || t === "boolean") return t;
|
|
44
|
+
return "object";
|
|
45
|
+
}
|
|
46
|
+
/** Deep structural equality over JSON values (used for delta-only serialization). */
|
|
47
|
+
function jsonEquals(a, b) {
|
|
48
|
+
if (a === b) return true;
|
|
49
|
+
if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((v, i) => jsonEquals(v, b[i]));
|
|
50
|
+
if (a !== null && b !== null && typeof a === "object" && typeof b === "object") {
|
|
51
|
+
if (Array.isArray(a) || Array.isArray(b)) return false;
|
|
52
|
+
const ka = Object.keys(a);
|
|
53
|
+
const kb = Object.keys(b);
|
|
54
|
+
return ka.length === kb.length && ka.every((k) => k in b && jsonEquals(a[k], b[k]));
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Deep clone of JSON-safe data (defaults must never be shared between
|
|
60
|
+
* instances). The value must contain only JSON types.
|
|
61
|
+
*/
|
|
62
|
+
function jsonClone(value) {
|
|
63
|
+
if (value === null || typeof value !== "object") return value;
|
|
64
|
+
return JSON.parse(JSON.stringify(value));
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { parseJsonText as a, json_exports as i, jsonEquals as n, __exportAll as o, jsonKind as r, jsonClone as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as Scene, b as Engine } from "./behavior-
|
|
2
|
-
import {
|
|
1
|
+
import { P as Scene, b as Engine } from "./behavior-DZExDn9o.js";
|
|
2
|
+
import { a as SceneJson } from "./rng-Bb-IutXB.js";
|
|
3
3
|
|
|
4
4
|
//#region src/core/scene/loader.d.ts
|
|
5
5
|
interface LoadSceneOptions {
|
package/dist/net.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { d as PropSchema, jt as Node } from "./behavior-
|
|
2
|
-
import {
|
|
1
|
+
import { d as PropSchema, jt as Node } from "./behavior-DZExDn9o.js";
|
|
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--k-XpBjr.js";
|
|
3
4
|
|
|
4
5
|
//#region src/net/agent8.d.ts
|
|
5
6
|
/**
|
|
@@ -22,7 +23,7 @@ declare function createAgent8Server(config?: {
|
|
|
22
23
|
verse?: string;
|
|
23
24
|
account?: string;
|
|
24
25
|
auth?: string;
|
|
25
|
-
}): Promise<NetworkTransport>;
|
|
26
|
+
}, diagnostics?: DiagnosticSink | null): Promise<NetworkTransport>;
|
|
26
27
|
//#endregion
|
|
27
28
|
//#region src/net/nodes/network-spawner.d.ts
|
|
28
29
|
/**
|
|
@@ -48,6 +49,8 @@ declare class NetworkSpawner extends Node {
|
|
|
48
49
|
private readonly positionTargets;
|
|
49
50
|
private readonly failedKeys;
|
|
50
51
|
private readonly reported;
|
|
52
|
+
/** Seconds spent looking for a NetworkManager — see the report in `update`. */
|
|
53
|
+
private waited;
|
|
51
54
|
override update(dt: number): void;
|
|
52
55
|
private currentEntries;
|
|
53
56
|
/**
|
|
@@ -63,6 +66,27 @@ declare class NetworkSpawner extends Node {
|
|
|
63
66
|
/** Say it ONCE per message — a per-frame repeat would drown the log. */
|
|
64
67
|
private report;
|
|
65
68
|
private setProp;
|
|
69
|
+
/**
|
|
70
|
+
* What the NETWORK last said this node's position is — not where it is drawn.
|
|
71
|
+
*
|
|
72
|
+
* A remote copy renders slightly in the past, chasing its target at
|
|
73
|
+
* ~12.5%/frame. That is the right way to draw one and the wrong way to
|
|
74
|
+
* COMPARE one: `incanto-multiplay`'s `agrees` rung read the rendered
|
|
75
|
+
* position, so a late joiner whose interpolation had not converged was
|
|
76
|
+
* reported as disagreeing with the owner —
|
|
77
|
+
*
|
|
78
|
+
* ✗ late has p1's `position` as [-3.3465…], not [-3.3989…]
|
|
79
|
+
*
|
|
80
|
+
* — on both SHIPPED 2D multiplayer examples, which exit 1 today on the plain
|
|
81
|
+
* documented command. The size of the "disagreement" is the player's speed
|
|
82
|
+
* times the chase lag, so a faster game fails harder while replicating
|
|
83
|
+
* perfectly.
|
|
84
|
+
*
|
|
85
|
+
* `undefined` when this spawner has no target for that node: it is not one of
|
|
86
|
+
* ours, or `interpolate` is off, in which case the drawn value IS the
|
|
87
|
+
* received one.
|
|
88
|
+
*/
|
|
89
|
+
replicatedPosition(node: Node): number[] | undefined;
|
|
66
90
|
private stepInterpolation;
|
|
67
91
|
}
|
|
68
92
|
//#endregion
|
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-CmNF01gA.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-PL78oVXP.js";
|
|
3
3
|
export { LocalGameServer, LocalGameServerTransport, LoopbackHub, LoopbackTransport, NetworkManager, NetworkSpawner, applySyncPatch, createAgent8Server, createLocalGameServer, createSplitScreen, registerNodesNet };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { o as __exportAll } from "./json-CfTjpvW8.js";
|
|
2
|
+
import { q as diagnose } from "./save-slots-BXVg148r.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-Bkk0wSDB.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
|
|
@@ -108,8 +108,10 @@ var Physics2D = class {
|
|
|
108
108
|
}
|
|
109
109
|
const lv = e.body.linvel();
|
|
110
110
|
node.linearVelocity = [lv.x * SCALE, lv.y * SCALE];
|
|
111
|
+
node.angularVelocity = e.body.angvel();
|
|
111
112
|
e.lastVX = node.linearVelocity[0] ?? 0;
|
|
112
113
|
e.lastVY = node.linearVelocity[1] ?? 0;
|
|
114
|
+
e.lastAV = node.angularVelocity;
|
|
113
115
|
}
|
|
114
116
|
const t2 = e.body.translation();
|
|
115
117
|
e.lastX = t2.x * SCALE;
|
|
@@ -130,6 +132,29 @@ var Physics2D = class {
|
|
|
130
132
|
}
|
|
131
133
|
});
|
|
132
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* May `candidate` carry `rider`?
|
|
137
|
+
*
|
|
138
|
+
* The rule used to be "never a CharacterBody2D", which is the whole CLASS —
|
|
139
|
+
* and a `CharacterBody2D` animated by POSITION WRITES is the documented
|
|
140
|
+
* moving-platform path (`Oscillate`, `MoveTo`, `PathFollow`, or a behaviour of
|
|
141
|
+
* your own). `incanto-physics-and-input.md` promises twice that a character
|
|
142
|
+
* standing on ANY moving body is carried; it was not, and the rider reported
|
|
143
|
+
* `isOnFloor() === true` the whole time while sliding off in world space.
|
|
144
|
+
*
|
|
145
|
+
* What the guard was really for is a CYCLE: two characters standing on each
|
|
146
|
+
* other would carry each other forever. So the test is the rider's own
|
|
147
|
+
* carrier chain, not the type — a platform that is not (transitively) riding
|
|
148
|
+
* you can carry you.
|
|
149
|
+
*/
|
|
150
|
+
canCarry(rider, candidate) {
|
|
151
|
+
let at = candidate;
|
|
152
|
+
for (let depth = 0; depth < 8 && at; depth++) {
|
|
153
|
+
if (at === rider) return false;
|
|
154
|
+
at = this.entries.get(at)?.ground ?? null;
|
|
155
|
+
}
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
133
158
|
/** @internal Called by CharacterBody2D.moveAndSlide (during tree fixedUpdate). */
|
|
134
159
|
moveAndSlide(node) {
|
|
135
160
|
const e = this.ensureEntry(node);
|
|
@@ -137,6 +162,8 @@ var Physics2D = class {
|
|
|
137
162
|
if (node.stickToGround && vy >= 0) this.kcc.enableSnapToGround(.05);
|
|
138
163
|
else this.kcc.disableSnapToGround();
|
|
139
164
|
this.kcc.setMaxSlopeClimbAngle(node.slopeLimitDeg * DEG);
|
|
165
|
+
if (node.stepHeight > 0) this.kcc.enableAutostep(node.stepHeight / SCALE, node.stepHeight / SCALE / 2, false);
|
|
166
|
+
else this.kcc.disableAutostep();
|
|
140
167
|
let carryX = 0;
|
|
141
168
|
let carryY = 0;
|
|
142
169
|
if (e.ground && e.ground._physics === this) {
|
|
@@ -144,9 +171,10 @@ var Physics2D = class {
|
|
|
144
171
|
carryX = gx - (e.groundX ?? gx);
|
|
145
172
|
carryY = gy - (e.groundY ?? gy);
|
|
146
173
|
} else e.ground = null;
|
|
174
|
+
const vyTerm = carryY < -.1 && node.isOnFloor?.() === true && vy > 0 ? 0 : vy * this.lastDt;
|
|
147
175
|
const desired = {
|
|
148
176
|
x: ((node.velocity[0] ?? 0) * this.lastDt + carryX) / SCALE * 1,
|
|
149
|
-
y: (
|
|
177
|
+
y: (vyTerm + carryY) / SCALE * 1
|
|
150
178
|
};
|
|
151
179
|
const charBottomPx = e.body.translation().y * SCALE + charHalfHeight(node);
|
|
152
180
|
const predicate = (collider) => {
|
|
@@ -171,7 +199,7 @@ var Physics2D = class {
|
|
|
171
199
|
for (let i = 0; i < hits; i++) {
|
|
172
200
|
const n = this.kcc.computedCollision(i)?.normal1;
|
|
173
201
|
if (!n) continue;
|
|
174
|
-
if (
|
|
202
|
+
if (n.y > .7) {
|
|
175
203
|
if (!node._grounded) node._onCeiling = true;
|
|
176
204
|
} else if (Math.abs(n.x) > .7) node._onWall = n.x > 0 ? -1 : 1;
|
|
177
205
|
}
|
|
@@ -179,7 +207,7 @@ var Physics2D = class {
|
|
|
179
207
|
const footX = (t.x + corrected.x) * SCALE;
|
|
180
208
|
const footY = (t.y + corrected.y) * SCALE + charHalfHeight(node) - 2;
|
|
181
209
|
const hit = this.castRay([footX, footY], [0, 1], 8, node);
|
|
182
|
-
if (hit?.node &&
|
|
210
|
+
if (hit?.node && this.canCarry(node, hit.node)) {
|
|
183
211
|
e.ground = hit.node;
|
|
184
212
|
const [gx, gy] = worldPosition2D(hit.node);
|
|
185
213
|
e.groundX = gx;
|
|
@@ -340,13 +368,48 @@ var Physics2D = class {
|
|
|
340
368
|
return [...set];
|
|
341
369
|
}
|
|
342
370
|
/**
|
|
343
|
-
*
|
|
371
|
+
* Mass the solver actually uses (collider-derived unless overridden).
|
|
372
|
+
*
|
|
373
|
+
* The 3D twin has had this since `CharacterController3D` needed it to size an
|
|
374
|
+
* impulse; 2D had no way to ask, so a 2D game scaling a push by mass had to
|
|
375
|
+
* read the AUTHORED `mass` prop and hope it was the number Rapier settled on.
|
|
376
|
+
*/
|
|
377
|
+
massOf(node) {
|
|
378
|
+
return this.entries.get(node)?.body.mass() ?? 1;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Current solver velocity in px/s (fresher than the node prop mid-step).
|
|
382
|
+
*
|
|
383
|
+
* `linearVelocity` is written back once per step, so a behavior reading it
|
|
384
|
+
* from inside `fixedUpdate` — after a collision, before the write-back — sees
|
|
385
|
+
* the value from BEFORE the impact. That is exactly when a game wants to know
|
|
386
|
+
* how hard it hit something.
|
|
387
|
+
*/
|
|
388
|
+
velocityOf(node) {
|
|
389
|
+
const v = this.entries.get(node)?.body.linvel();
|
|
390
|
+
return v ? [v.x * SCALE, v.y * SCALE] : [0, 0];
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* A world-space impulse in px.kg/s (y-down) — the 2D twin of
|
|
394
|
+
* `Physics3D.applyImpulse`, which the physics skill has documented for both
|
|
395
|
+
* adapters while only one of them had it.
|
|
396
|
+
*/
|
|
397
|
+
applyImpulse(node, impulse) {
|
|
398
|
+
this.entries.get(node)?.body.applyImpulse({
|
|
399
|
+
x: impulse[0] / SCALE,
|
|
400
|
+
y: impulse[1] / SCALE
|
|
401
|
+
}, true);
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* World-space raycast in PIXELS (y-down); `dir` may be any length (it is
|
|
405
|
+
* normalized), so `distance` and `maxLen` are pixels. `exclude` skips that body — a
|
|
344
406
|
* shooter probing from inside its own collider needs it. Sensors (Area2D)
|
|
345
407
|
* never block rays. Returns distance (px), the surface normal, and the hit
|
|
346
408
|
* body — or null.
|
|
347
409
|
*/
|
|
348
410
|
castRay(origin, dir, maxLen, exclude, opts) {
|
|
349
|
-
const len = Math.hypot(dir[0], dir[1])
|
|
411
|
+
const len = Math.hypot(dir[0], dir[1]);
|
|
412
|
+
if (!(len > 0)) return null;
|
|
350
413
|
const ray = new this.R.Ray({
|
|
351
414
|
x: origin[0] / SCALE,
|
|
352
415
|
y: origin[1] / SCALE
|
|
@@ -358,9 +421,44 @@ var Physics2D = class {
|
|
|
358
421
|
const flags = opts?.staticOnly ? this.R.QueryFilterFlags.EXCLUDE_DYNAMIC | this.R.QueryFilterFlags.EXCLUDE_KINEMATIC : void 0;
|
|
359
422
|
const hit = this.world.castRayAndGetNormal(ray, maxLen / SCALE, true, flags, void 0, excludeCollider, void 0, (collider) => !collider.isSensor());
|
|
360
423
|
if (!hit) return null;
|
|
424
|
+
const distance = hit.timeOfImpact * SCALE;
|
|
361
425
|
return {
|
|
362
|
-
distance
|
|
426
|
+
distance,
|
|
363
427
|
normal: [hit.normal.x, hit.normal.y],
|
|
428
|
+
node: this.byColliderHandle.get(hit.collider.handle) ?? null,
|
|
429
|
+
point: [origin[0] + dir[0] / len * distance, origin[1] + dir[1] / len * distance]
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Sweep a CIRCLE of `radius` from `origin` along `dir` — a thick ray, in
|
|
434
|
+
* pixels. The 2D twin of `Physics3D.castSphere`.
|
|
435
|
+
*
|
|
436
|
+
* 3D has had this since the camera spring arm needed it and 2D never got it,
|
|
437
|
+
* so the shared `PhysicsQuery` interface declares it OPTIONAL and every 2D
|
|
438
|
+
* game that wanted a probe with THICKNESS — a shot that must not thread a
|
|
439
|
+
* one-pixel gap between two tiles, a ledge feeler, a camera that should not
|
|
440
|
+
* clip a wall it skims — had to fire several thin rays and hope.
|
|
441
|
+
*
|
|
442
|
+
* Same filters as `castRay`: sensors never hit, `staticOnly` ignores dynamic
|
|
443
|
+
* and kinematic bodies, `dir` may be any length. Returns the travel distance
|
|
444
|
+
* of the circle's CENTRE, or null when the sweep is clear.
|
|
445
|
+
*/
|
|
446
|
+
castSphere(origin, dir, radius, maxLen, exclude, opts) {
|
|
447
|
+
const R = this.R;
|
|
448
|
+
const len = Math.hypot(dir[0], dir[1]);
|
|
449
|
+
if (!(len > 0)) return null;
|
|
450
|
+
const excludeEntry = exclude ? this.entries.get(exclude) : void 0;
|
|
451
|
+
const flags = opts?.staticOnly ? R.QueryFilterFlags.EXCLUDE_DYNAMIC | R.QueryFilterFlags.EXCLUDE_KINEMATIC : void 0;
|
|
452
|
+
const hit = this.world.castShape({
|
|
453
|
+
x: origin[0] / SCALE,
|
|
454
|
+
y: origin[1] / SCALE
|
|
455
|
+
}, 0, {
|
|
456
|
+
x: dir[0] / len,
|
|
457
|
+
y: dir[1] / len
|
|
458
|
+
}, new R.Ball(radius / SCALE), 0, maxLen / SCALE, true, flags, void 0, excludeEntry?.collider, excludeEntry?.body, (collider) => !collider.isSensor());
|
|
459
|
+
if (!hit) return null;
|
|
460
|
+
return {
|
|
461
|
+
distance: hit.time_of_impact * SCALE,
|
|
364
462
|
node: this.byColliderHandle.get(hit.collider.handle) ?? null
|
|
365
463
|
};
|
|
366
464
|
}
|
|
@@ -465,13 +563,15 @@ var Physics2D = class {
|
|
|
465
563
|
const x = wx / SCALE;
|
|
466
564
|
const y = wy / SCALE;
|
|
467
565
|
let desc;
|
|
468
|
-
|
|
566
|
+
const dyn = node instanceof RigidBody2D;
|
|
567
|
+
if (dyn) desc = R.RigidBodyDesc.dynamic();
|
|
469
568
|
else if (node instanceof CharacterBody2D || node instanceof Area2D) desc = R.RigidBodyDesc.kinematicPositionBased();
|
|
470
569
|
else desc = R.RigidBodyDesc.fixed();
|
|
471
570
|
desc.setTranslation(x, y).setRotation(node.rotation * DEG);
|
|
472
571
|
if (node instanceof RigidBody2D) {
|
|
473
572
|
desc.setGravityScale(node.gravityScale);
|
|
474
573
|
desc.setLinvel((node.linearVelocity[0] ?? 0) / SCALE, (node.linearVelocity[1] ?? 0) / SCALE);
|
|
574
|
+
desc.setAngvel(node.fixedRotation ? 0 : node.angularVelocity);
|
|
475
575
|
if (node.fixedRotation) desc.lockRotations();
|
|
476
576
|
}
|
|
477
577
|
const body = this.world.createRigidBody(desc);
|
|
@@ -488,7 +588,12 @@ var Physics2D = class {
|
|
|
488
588
|
lastY: wy,
|
|
489
589
|
lastRot: node.rotation,
|
|
490
590
|
lastVX: 0,
|
|
491
|
-
lastVY: 0
|
|
591
|
+
lastVY: 0,
|
|
592
|
+
lastAV: dyn ? node.angularVelocity : 0,
|
|
593
|
+
lastMass: dyn ? node.mass : 1,
|
|
594
|
+
lastFriction: dyn ? node.friction : .5,
|
|
595
|
+
lastRestitution: dyn ? node.restitution : 0,
|
|
596
|
+
lastGravityScale: dyn ? node.gravityScale : 1
|
|
492
597
|
};
|
|
493
598
|
this.entries.set(node, e);
|
|
494
599
|
this.byColliderHandle.set(collider.handle, node);
|
|
@@ -530,6 +635,26 @@ var Physics2D = class {
|
|
|
530
635
|
e.lastVX = vx;
|
|
531
636
|
e.lastVY = vy;
|
|
532
637
|
}
|
|
638
|
+
if (node.angularVelocity !== e.lastAV) {
|
|
639
|
+
e.body.setAngvel(node.angularVelocity, true);
|
|
640
|
+
e.lastAV = node.angularVelocity;
|
|
641
|
+
}
|
|
642
|
+
if (node.gravityScale !== e.lastGravityScale) {
|
|
643
|
+
e.body.setGravityScale(node.gravityScale, true);
|
|
644
|
+
e.lastGravityScale = node.gravityScale;
|
|
645
|
+
}
|
|
646
|
+
if (node.mass !== e.lastMass) {
|
|
647
|
+
e.collider.setMass(node.mass);
|
|
648
|
+
e.lastMass = node.mass;
|
|
649
|
+
}
|
|
650
|
+
if (node.friction !== e.lastFriction) {
|
|
651
|
+
e.collider.setFriction(node.friction);
|
|
652
|
+
e.lastFriction = node.friction;
|
|
653
|
+
}
|
|
654
|
+
if (node.restitution !== e.lastRestitution) {
|
|
655
|
+
e.collider.setRestitution(node.restitution);
|
|
656
|
+
e.lastRestitution = node.restitution;
|
|
657
|
+
}
|
|
533
658
|
}
|
|
534
659
|
return e;
|
|
535
660
|
}
|