@datamoc/mw_games 0.9.0-alpha → 0.9.1
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/CHANGELOG.md +71 -0
- package/README.md +4 -0
- package/dist/core/ActionJournal.d.ts +2 -0
- package/dist/core/ActionJournal.d.ts.map +1 -1
- package/dist/core/ActionJournal.js +6 -0
- package/dist/core/ActionJournal.js.map +1 -1
- package/dist/core/Multiplayer.d.ts +21 -4
- package/dist/core/Multiplayer.d.ts.map +1 -1
- package/dist/core/Multiplayer.js +31 -4
- package/dist/core/Multiplayer.js.map +1 -1
- package/dist/core/State.d.ts +38 -0
- package/dist/core/State.d.ts.map +1 -1
- package/dist/core/State.js +76 -0
- package/dist/core/State.js.map +1 -1
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/mw_games.global.js +113 -113
- package/dist/mwl/catalog.d.ts +7 -0
- package/dist/mwl/catalog.d.ts.map +1 -1
- package/dist/mwl/catalog.js +0 -0
- package/dist/mwl/catalog.js.map +1 -1
- package/dist/mwl/compiler.d.ts +3 -0
- package/dist/mwl/compiler.d.ts.map +1 -1
- package/dist/mwl/compiler.js +10 -3
- package/dist/mwl/compiler.js.map +1 -1
- package/dist/mwl/grammar.d.ts +8 -1
- package/dist/mwl/grammar.d.ts.map +1 -1
- package/dist/mwl/grammar.js +207 -39
- package/dist/mwl/grammar.js.map +1 -1
- package/dist/mwl/hooks.d.ts +35 -2
- package/dist/mwl/hooks.d.ts.map +1 -1
- package/dist/mwl/hooks.js +8 -6
- package/dist/mwl/hooks.js.map +1 -1
- package/dist/mwl/index.d.ts +6 -6
- package/dist/mwl/index.d.ts.map +1 -1
- package/dist/mwl/index.js +3 -3
- package/dist/mwl/index.js.map +1 -1
- package/dist/mwl/persistence.d.ts +18 -1
- package/dist/mwl/persistence.d.ts.map +1 -1
- package/dist/mwl/persistence.js +59 -3
- package/dist/mwl/persistence.js.map +1 -1
- package/dist/mwl/readers.d.ts +37 -0
- package/dist/mwl/readers.d.ts.map +1 -1
- package/dist/mwl/readers.js +69 -0
- package/dist/mwl/readers.js.map +1 -1
- package/dist/mwl/runtime.d.ts +45 -1
- package/dist/mwl/runtime.d.ts.map +1 -1
- package/dist/mwl/runtime.js +72 -8
- package/dist/mwl/runtime.js.map +1 -1
- package/dist/mwl/schema.d.ts +31 -0
- package/dist/mwl/schema.d.ts.map +1 -1
- package/dist/mwl/schema.js +57 -2
- package/dist/mwl/schema.js.map +1 -1
- package/dist/simulation/Runtime.d.ts +66 -1
- package/dist/simulation/Runtime.d.ts.map +1 -1
- package/dist/simulation/Runtime.js +131 -3
- package/dist/simulation/Runtime.js.map +1 -1
- package/dist/simulation/index.d.ts +2 -2
- package/dist/simulation/index.d.ts.map +1 -1
- package/dist/simulation/index.js +1 -1
- package/dist/simulation/index.js.map +1 -1
- package/dist/two-d/render/RpgmAutotile.d.ts +65 -0
- package/dist/two-d/render/RpgmAutotile.d.ts.map +1 -0
- package/dist/two-d/render/RpgmAutotile.js +110 -0
- package/dist/two-d/render/RpgmAutotile.js.map +1 -0
- package/dist/two-d/render/index.d.ts +2 -0
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +1 -0
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/tools/mwl.mjs +85 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,77 @@ the public API may still change between minor versions.
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.1] - 2026-09-14
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `rpgmAutotileFrame` and `RpgmAutotileAtlas` - renderer-neutral RPG Maker MV autotile
|
|
15
|
+
atlas geometry, including four-slot decoding, quadrant selection, validation, and cached
|
|
16
|
+
frame descriptions (roadmap item 348).
|
|
17
|
+
|
|
18
|
+
## [0.9.0] - 2026-09-13
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- `core.CanonicalState` - a defensive, JSON-safe root state combined with `StateRegistry`
|
|
23
|
+
extensions, with snapshots, version migrations, transactions, and atomic restore covering
|
|
24
|
+
both pieces together (item 341).
|
|
25
|
+
- `simulation.validateSimulationReplay`, and an optional `history` option on `SimulationRuntime`:
|
|
26
|
+
replay a recorded journal from a checkpoint and compare deterministic event batches, and
|
|
27
|
+
restore complete state/scheduler/RNG/journal undo-redo checkpoints (item 341).
|
|
28
|
+
- `LockstepClient`/`createLockstepServer` carry a session seed and initial state, validate
|
|
29
|
+
game-supplied commands, and exchange per-tick state checksums, with new `onReject`/`onDesync`
|
|
30
|
+
signals reporting rejected input and diverging peers (item 341).
|
|
31
|
+
- MWL JSON5 authoring accepts schema-neutral named-node sugar (`{ unit_type: { id: 'hero' } }`
|
|
32
|
+
and repeated object children) alongside the generic `tag`/`children` envelope, lowered before
|
|
33
|
+
validation runs (item 338).
|
|
34
|
+
- `MwlDomainHook`/`MwlDomainHookRegistry`/`MwlDomainHookDeclaration` - game-declared hook
|
|
35
|
+
namespaces (`item-effect:potion-strength`) get a typed context/input/output boundary that MWG
|
|
36
|
+
validates and emits without knowing the domain's own types or rules (item 342).
|
|
37
|
+
- `HookWorld.random` - every MWL hook, built-in or domain, draws from the runtime's own seeded
|
|
38
|
+
`core.Generator` instead of `Math.random()`, via the new `MwlRuntimeOptions.random`; the draw
|
|
39
|
+
position is carried on `MwlWorld.random` and resumes exactly across save/restore (item 342).
|
|
40
|
+
Any game hand-building its own `HookWorld` (only `MwlRuntime` constructs one today) must now
|
|
41
|
+
provide this field too, the same rule item 319's `variableAt` addition already established.
|
|
42
|
+
- `MwlSaveableHookState`/`MwlHookRegistry.saveable` - a game may explicitly expose JSON-safe hook
|
|
43
|
+
state; `MwlRuntime.save()`/`restore()` round-trip it through the same save envelope (item 341).
|
|
44
|
+
- `MwlRuntime.journal`/`MwlRuntimeAction` - public runtime operations (running a trigger, firing
|
|
45
|
+
an event or a moveto watch, answering a dialogue choice) are recorded in order and persisted
|
|
46
|
+
with the save (item 341).
|
|
47
|
+
- The MWL parser and compiler retain exact JSON5 attribute and value source locations
|
|
48
|
+
(`MwlNode.attributeLocations`/`valueLocations`), used by schema, catalog, and macro
|
|
49
|
+
diagnostics instead of falling back to the owning node's own location (item 342).
|
|
50
|
+
- Unknown MWL macros and hook references are errors by default, with file/line/column
|
|
51
|
+
diagnostics; `MwlPreprocessOptions.macroPolicy: 'ignore'` restores the old silent-passthrough
|
|
52
|
+
behaviour for legacy content (item 342).
|
|
53
|
+
- `schema10`/`MWL_SCHEMA_10` - the published MWL 1.0 vocabulary: required attributes and child
|
|
54
|
+
cardinalities on top of the unchanged 0.1 tag/value contract; `mwl migrate --to 1.0` performs
|
|
55
|
+
a lossless upgrade (item 342).
|
|
56
|
+
- `validateCatalog` reports `MWL_ALIAS_CYCLE` for cycles in resolved `aliasof` chains, and the new
|
|
57
|
+
`MwlValidationOptions.mapBounds` rejects authored coordinates outside declared map dimensions
|
|
58
|
+
(item 342).
|
|
59
|
+
- `readTableMap`/`readTableIndex`/`tableKey` - typed table-row projections with collision-free
|
|
60
|
+
native composite keys, and inverse indexes that retain every matching row (items 339, 346).
|
|
61
|
+
- `mwl diagnostics`/`mwl ci` CLI modes emit stable, machine-readable JSON diagnostics; `mwl
|
|
62
|
+
format`/`mwl migrate --to 1.0` emit a deterministic canonical document (items 342, 346).
|
|
63
|
+
- `tests/random.test.ts` gained a hardcoded-output compatibility test for `core.Generator`'s
|
|
64
|
+
stream, guarding fixed seeds against a future silent algorithm change (item 342).
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- `mwl/grammar.ts`'s macro expansion, gettext rewrite, and tag-site collection now share one
|
|
69
|
+
`skipStringOrComment` scan instead of three near-identical hand-rolled copies of it.
|
|
70
|
+
- `LockstepClient.submitInput` accepts an optional per-tick checksum and an optional client-side
|
|
71
|
+
`validateInput`; rejected input reports through the new `onReject` signal instead of silently
|
|
72
|
+
going nowhere.
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
|
|
76
|
+
- `src/mwl/catalog.ts` carried a literal NUL byte, rather than an escaped `\0`, inside one
|
|
77
|
+
composite map key, which made the file register as binary to `git diff` and `grep`. Replaced
|
|
78
|
+
with the same `\0` escape already used for the identical purpose elsewhere in the file; no
|
|
79
|
+
behaviour change.
|
|
80
|
+
|
|
10
81
|
## [0.9.0-alpha] - 2026-09-13
|
|
11
82
|
|
|
12
83
|
### Changed
|
package/README.md
CHANGED
|
@@ -418,6 +418,10 @@ time with:
|
|
|
418
418
|
|
|
419
419
|
```sh
|
|
420
420
|
npm run mwl -- validate game.mwl
|
|
421
|
+
npm run mwl -- diagnostics game.mwl
|
|
422
|
+
npm run mwl -- ci game.mwl
|
|
423
|
+
npm run mwl -- format game.mwl -o generated/game.mwl
|
|
424
|
+
npm run mwl -- migrate game.mwl --to 1.0 -o generated/game-1.0.mwl
|
|
421
425
|
npm run mwl -- build game.mwl -o generated/
|
|
422
426
|
npm run mwl -- compile game.mwl -o generated/game-data.ts
|
|
423
427
|
npm run mwl -- extract-i18n game.mwl -o generated/i18n.json
|
|
@@ -31,6 +31,8 @@ export declare class ActionJournal<Action, Event> {
|
|
|
31
31
|
/** Drops entries at and after a checkpoint, as an undo operation would. */
|
|
32
32
|
truncate(sequence: number): void;
|
|
33
33
|
toJSON(): ActionJournalEntry<Action, Event>[];
|
|
34
|
+
/** Replaces the log from a validated snapshot, preserving contiguous sequence numbers. */
|
|
35
|
+
replace(entries: readonly ActionJournalEntry<Action, Event>[]): void;
|
|
34
36
|
static fromJSON<Action, Event>(entries: readonly ActionJournalEntry<Action, Event>[]): ActionJournal<Action, Event>;
|
|
35
37
|
}
|
|
36
38
|
//# sourceMappingURL=ActionJournal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionJournal.d.ts","sourceRoot":"","sources":["../../src/core/ActionJournal.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB,CAAC,MAAM,EAAE,KAAK;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAa,CAAC,MAAM,EAAE,KAAK;IACvC,OAAO,CAAC,OAAO,CAA2C;IAC1D,OAAO,CAAC,YAAY,CAAK;IAEzB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,SAAS,KAAK,EAAO,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAIvF;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,GAAG,IAAI,SAAS,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAEtD;IAED,gFAAgF;IAChF,IAAI,IAAI,MAAM,CAEb;IAED,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAE3D;IAED,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAG/B;IAED,MAAM,IAAI,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAE5C;IAED,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAC5B,OAAO,EAAE,SAAS,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,GACnD,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAa9B;CACD"}
|
|
1
|
+
{"version":3,"file":"ActionJournal.d.ts","sourceRoot":"","sources":["../../src/core/ActionJournal.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB,CAAC,MAAM,EAAE,KAAK;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAa,CAAC,MAAM,EAAE,KAAK;IACvC,OAAO,CAAC,OAAO,CAA2C;IAC1D,OAAO,CAAC,YAAY,CAAK;IAEzB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,SAAS,KAAK,EAAO,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAIvF;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,GAAG,IAAI,SAAS,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAEtD;IAED,gFAAgF;IAChF,IAAI,IAAI,MAAM,CAEb;IAED,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAE3D;IAED,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAG/B;IAED,MAAM,IAAI,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAE5C;IAED,0FAA0F;IAC1F,OAAO,CAAC,OAAO,EAAE,SAAS,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,IAAI,CAInE;IAED,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAC5B,OAAO,EAAE,SAAS,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,GACnD,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAa9B;CACD"}
|
|
@@ -44,6 +44,12 @@ export class ActionJournal {
|
|
|
44
44
|
toJSON() {
|
|
45
45
|
return this.all;
|
|
46
46
|
}
|
|
47
|
+
/** Replaces the log from a validated snapshot, preserving contiguous sequence numbers. */
|
|
48
|
+
replace(entries) {
|
|
49
|
+
const restored = ActionJournal.fromJSON(entries);
|
|
50
|
+
this.entries = restored.entries;
|
|
51
|
+
this.nextSequence = restored.nextSequence;
|
|
52
|
+
}
|
|
47
53
|
static fromJSON(entries) {
|
|
48
54
|
const journal = new ActionJournal();
|
|
49
55
|
let expected = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionJournal.js","sourceRoot":"","sources":["../../src/core/ActionJournal.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,aAAa;IAA1B;QACS,YAAO,GAAwC,EAAE,CAAC;QAClD,iBAAY,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ActionJournal.js","sourceRoot":"","sources":["../../src/core/ActionJournal.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,aAAa;IAA1B;QACS,YAAO,GAAwC,EAAE,CAAC;QAClD,iBAAY,GAAG,CAAC,CAAC;IA0D1B,CAAC;IAxDA,MAAM,CAAC,MAAc,EAAE,MAAM,GAAqB,EAAE;QACnD,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC;QAC9F,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,IAAI,GAAG;QACN,OAAO,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,gFAAgF;IAChF,IAAI;QACH,OAAO,IAAI,CAAC,YAAY,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,QAAgB;QACrB,OAAO,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,2EAA2E;IAC3E,QAAQ,CAAC,QAAgB;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC;QACzE,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;IAC9B,CAAC;IAED,MAAM;QACL,OAAO,IAAI,CAAC,GAA0C,CAAC;IACxD,CAAC;IAED,0FAA0F;IAC1F,OAAO,CAAC,OAAqD;QAC5D,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,QAAQ,CACd,OAAqD;QAErD,MAAM,OAAO,GAAG,IAAI,aAAa,EAAiB,CAAC;QACnD,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ;gBACvE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC1E,OAAO,CAAC,OAAO,CAAC,IAAI,CACnB,eAAe,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAC9F,CAAC;YACF,QAAQ,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,CAAC,YAAY,GAAG,QAAQ,CAAC;QAChC,OAAO,OAAO,CAAC;IAChB,CAAC;CACD"}
|
|
@@ -15,11 +15,22 @@ export interface LockstepClientOptions {
|
|
|
15
15
|
url: string;
|
|
16
16
|
/** defaults to the global `WebSocket`; inject a fake in tests, or `ws`'s own client in Node */
|
|
17
17
|
create?: (url: string) => WebSocketLike;
|
|
18
|
+
/** Optional client-side command contract. Returning a string rejects with that reason. */
|
|
19
|
+
validateInput?: (payload: unknown) => boolean | string;
|
|
20
|
+
}
|
|
21
|
+
export interface LockstepWelcome {
|
|
22
|
+
id: string;
|
|
23
|
+
/** The room seed, when the server configured one. */
|
|
24
|
+
seed?: number;
|
|
25
|
+
/** The JSON-safe state from which every peer must start, when configured. */
|
|
26
|
+
initialState?: unknown;
|
|
18
27
|
}
|
|
19
28
|
export interface TickEvent {
|
|
20
29
|
tick: number;
|
|
21
30
|
/** this room's every client id mapped to its input for `tick`, or `null` if it missed the deadline */
|
|
22
31
|
inputs: Record<string, unknown>;
|
|
32
|
+
/** state checksums reported by peers after applying this tick, when supplied */
|
|
33
|
+
checksums?: Record<string, number>;
|
|
23
34
|
}
|
|
24
35
|
/**
|
|
25
36
|
* A client for this project's own reference lockstep server (`tools/multiplayer-server.mjs`):
|
|
@@ -53,14 +64,20 @@ export interface TickEvent {
|
|
|
53
64
|
* ```
|
|
54
65
|
*/
|
|
55
66
|
export declare class LockstepClient {
|
|
56
|
-
readonly onWelcome: Signal<
|
|
57
|
-
id: string;
|
|
58
|
-
}>;
|
|
67
|
+
readonly onWelcome: Signal<LockstepWelcome>;
|
|
59
68
|
readonly onTick: Signal<TickEvent>;
|
|
69
|
+
readonly onReject: Signal<{
|
|
70
|
+
reason: string;
|
|
71
|
+
}>;
|
|
72
|
+
readonly onDesync: Signal<{
|
|
73
|
+
tick: number;
|
|
74
|
+
checksums: Record<string, number>;
|
|
75
|
+
}>;
|
|
60
76
|
readonly onClose: Signal<void>;
|
|
61
77
|
private socket;
|
|
62
78
|
private readonly url;
|
|
63
79
|
private readonly createSocket;
|
|
80
|
+
private readonly validateInput?;
|
|
64
81
|
private _id;
|
|
65
82
|
constructor(options: LockstepClientOptions);
|
|
66
83
|
/** this client's own id, assigned by the server's `welcome` message; `null` before it arrives */
|
|
@@ -68,7 +85,7 @@ export declare class LockstepClient {
|
|
|
68
85
|
get connected(): boolean;
|
|
69
86
|
connect(): void;
|
|
70
87
|
/** submits this client's input for the current tick; a no-op before the connection is open */
|
|
71
|
-
submitInput(payload: unknown): void;
|
|
88
|
+
submitInput(payload: unknown, checksum?: number): void;
|
|
72
89
|
close(): void;
|
|
73
90
|
private handleMessage;
|
|
74
91
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Multiplayer.d.ts","sourceRoot":"","sources":["../../src/core/Multiplayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,yGAAyG;AACzG,MAAM,WAAW,aAAa;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1C,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3C,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CACtD;AAID,MAAM,WAAW,qBAAqB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,+FAA+F;IAC/F,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"Multiplayer.d.ts","sourceRoot":"","sources":["../../src/core/Multiplayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,yGAAyG;AACzG,MAAM,WAAW,aAAa;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1C,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3C,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CACtD;AAID,MAAM,WAAW,qBAAqB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,+FAA+F;IAC/F,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,aAAa,CAAC;IACxC,0FAA0F;IAC1F,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,GAAG,MAAM,CAAC;CACvD;AAED,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,sGAAsG;IACtG,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,cAAc;IAC1B,QAAQ,CAAC,SAAS,0BAAiC;IACnD,QAAQ,CAAC,MAAM,oBAA2B;IAC1C,QAAQ,CAAC,QAAQ;gBAAwB,MAAM;OAAM;IACrD,QAAQ,CAAC,QAAQ;cAAsB,MAAM;mBAAa,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;OAAM;IACtF,QAAQ,CAAC,OAAO,eAAsB;IAEtC,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAyC;IACxE,OAAO,CAAC,GAAG,CAAuB;IAElC,YAAY,OAAO,EAAE,qBAAqB,EAKzC;IAED,iGAAiG;IACjG,IAAI,EAAE,IAAI,MAAM,GAAG,IAAI,CAEtB;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,OAAO,IAAI,IAAI,CAUd;IAED,8FAA8F;IAC9F,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAUrD;IAED,KAAK,IAAI,IAAI,CAEZ;IAED,OAAO,CAAC,aAAa;CAkCrB"}
|
package/dist/core/Multiplayer.js
CHANGED
|
@@ -35,6 +35,8 @@ export class LockstepClient {
|
|
|
35
35
|
constructor(options) {
|
|
36
36
|
this.onWelcome = new Signal();
|
|
37
37
|
this.onTick = new Signal();
|
|
38
|
+
this.onReject = new Signal();
|
|
39
|
+
this.onDesync = new Signal();
|
|
38
40
|
this.onClose = new Signal();
|
|
39
41
|
this.socket = null;
|
|
40
42
|
this._id = null;
|
|
@@ -42,6 +44,7 @@ export class LockstepClient {
|
|
|
42
44
|
throw new Error('lockstep client url is required');
|
|
43
45
|
this.url = options.url;
|
|
44
46
|
this.createSocket = options.create ?? ((url) => new WebSocket(url));
|
|
47
|
+
this.validateInput = options.validateInput;
|
|
45
48
|
}
|
|
46
49
|
/** this client's own id, assigned by the server's `welcome` message; `null` before it arrives */
|
|
47
50
|
get id() {
|
|
@@ -63,10 +66,17 @@ export class LockstepClient {
|
|
|
63
66
|
this.socket = socket;
|
|
64
67
|
}
|
|
65
68
|
/** submits this client's input for the current tick; a no-op before the connection is open */
|
|
66
|
-
submitInput(payload) {
|
|
69
|
+
submitInput(payload, checksum) {
|
|
67
70
|
if (!this.connected)
|
|
68
71
|
return;
|
|
69
|
-
this.
|
|
72
|
+
const validation = this.validateInput?.(payload);
|
|
73
|
+
if (validation === false || typeof validation === 'string') {
|
|
74
|
+
this.onReject.dispatch({
|
|
75
|
+
reason: validation === false ? 'input rejected by client validation' : validation,
|
|
76
|
+
});
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.socket?.send(JSON.stringify({ type: 'input', payload, ...(checksum === undefined ? {} : { checksum }) }));
|
|
70
80
|
}
|
|
71
81
|
close() {
|
|
72
82
|
this.socket?.close();
|
|
@@ -75,10 +85,27 @@ export class LockstepClient {
|
|
|
75
85
|
const message = JSON.parse(raw);
|
|
76
86
|
if (message.type === 'welcome' && message.id !== undefined) {
|
|
77
87
|
this._id = message.id;
|
|
78
|
-
this.onWelcome.dispatch({
|
|
88
|
+
this.onWelcome.dispatch({
|
|
89
|
+
id: message.id,
|
|
90
|
+
...(message.seed === undefined ? {} : { seed: message.seed }),
|
|
91
|
+
...(message.initialState === undefined ? {} : { initialState: message.initialState }),
|
|
92
|
+
});
|
|
79
93
|
}
|
|
80
94
|
else if (message.type === 'tick' && message.tick !== undefined && message.inputs !== undefined) {
|
|
81
|
-
|
|
95
|
+
const event = {
|
|
96
|
+
tick: message.tick,
|
|
97
|
+
inputs: message.inputs,
|
|
98
|
+
...(message.checksums === undefined ? {} : { checksums: message.checksums }),
|
|
99
|
+
};
|
|
100
|
+
this.onTick.dispatch(event);
|
|
101
|
+
if (message.checksums) {
|
|
102
|
+
const checksums = Object.values(message.checksums);
|
|
103
|
+
if (checksums.some((checksum) => checksum !== checksums[0]))
|
|
104
|
+
this.onDesync.dispatch({ tick: message.tick, checksums: message.checksums });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (message.type === 'rejected') {
|
|
108
|
+
this.onReject.dispatch({ reason: message.reason ?? 'input rejected by server' });
|
|
82
109
|
}
|
|
83
110
|
}
|
|
84
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Multiplayer.js","sourceRoot":"","sources":["../../src/core/Multiplayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAarC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,wFAAwF;
|
|
1
|
+
{"version":3,"file":"Multiplayer.js","sourceRoot":"","sources":["../../src/core/Multiplayer.ts"],"names":[],"mappings":"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"}
|
package/dist/core/State.d.ts
CHANGED
|
@@ -28,6 +28,44 @@ export interface StateRestoreDiagnostic {
|
|
|
28
28
|
readonly to: number;
|
|
29
29
|
readonly status: 'migrated' | 'unchanged' | 'reset' | 'removed';
|
|
30
30
|
}
|
|
31
|
+
export interface CanonicalStateSnapshot<State extends StateValue = StateValue> {
|
|
32
|
+
readonly version: number;
|
|
33
|
+
readonly state: State;
|
|
34
|
+
readonly extensions: Readonly<Record<string, StateValue>>;
|
|
35
|
+
readonly extensionVersions?: Readonly<Record<string, number>>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A single JSON-safe source of truth for a game's logical state. The root value belongs to the
|
|
39
|
+
* game, while framework or game subsystems register independent versioned extensions beside it.
|
|
40
|
+
* Reads and writes clone values, so a renderer cannot mutate authoritative state accidentally.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { CanonicalState } from '@datamoc/mw_games/core';
|
|
45
|
+
*
|
|
46
|
+
* const state = new CanonicalState({ turn: 1, gold: 10 });
|
|
47
|
+
* state.update((current) => ({ ...current, gold: current.gold - 3 }));
|
|
48
|
+
* const save = state.snapshot();
|
|
49
|
+
* state.restore(save);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare class CanonicalState<State extends StateValue> {
|
|
53
|
+
private _state;
|
|
54
|
+
private readonly version;
|
|
55
|
+
private readonly migrations;
|
|
56
|
+
readonly extensions: StateRegistry;
|
|
57
|
+
constructor(initial: State, options?: {
|
|
58
|
+
readonly version?: number;
|
|
59
|
+
readonly migrations?: Readonly<Record<number, (state: StateValue) => State>>;
|
|
60
|
+
readonly extensions?: StateRegistry;
|
|
61
|
+
});
|
|
62
|
+
get state(): State;
|
|
63
|
+
set(next: State): void;
|
|
64
|
+
update(transform: (current: State) => State): State;
|
|
65
|
+
snapshot(): CanonicalStateSnapshot<State>;
|
|
66
|
+
restore(snapshot: CanonicalStateSnapshot<State>, options?: Parameters<StateRegistry['restore']>[1]): readonly StateRestoreDiagnostic[];
|
|
67
|
+
transaction<T>(work: (state: CanonicalState<State>) => T): T;
|
|
68
|
+
}
|
|
31
69
|
/**
|
|
32
70
|
* Coordinates game-owned save state without knowing its schema.
|
|
33
71
|
*
|
package/dist/core/State.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"State.d.ts","sourceRoot":"","sources":["../../src/core/State.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,EAAE,GAAG;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAAA;CAAE,CAAC;AAElH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAChE,yCAAyC;IACzC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACrC,iFAAiF;IACjF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC;IACzE,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,uFAAuF;IACvF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;CAChE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,UAAU,CAAqC;IAEvD,QAAQ,CAAC,CAAC,SAAS,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAcvE;IAED,QAAQ,IAAI,aAAa,CAMxB;IAED,OAAO,CACN,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE;QACR,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;QAC/C,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,sBAAsB,KAAK,IAAI,CAAC;KAChE,GACJ,SAAS,sBAAsB,EAAE,CAiCnC;IAED,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAQ/B;CACD"}
|
|
1
|
+
{"version":3,"file":"State.d.ts","sourceRoot":"","sources":["../../src/core/State.ts"],"names":[],"mappings":"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"}
|
package/dist/core/State.js
CHANGED
|
@@ -1,3 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A single JSON-safe source of truth for a game's logical state. The root value belongs to the
|
|
3
|
+
* game, while framework or game subsystems register independent versioned extensions beside it.
|
|
4
|
+
* Reads and writes clone values, so a renderer cannot mutate authoritative state accidentally.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { CanonicalState } from '@datamoc/mw_games/core';
|
|
9
|
+
*
|
|
10
|
+
* const state = new CanonicalState({ turn: 1, gold: 10 });
|
|
11
|
+
* state.update((current) => ({ ...current, gold: current.gold - 3 }));
|
|
12
|
+
* const save = state.snapshot();
|
|
13
|
+
* state.restore(save);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export class CanonicalState {
|
|
17
|
+
constructor(initial, options = {}) {
|
|
18
|
+
this._state = structuredClone(initial);
|
|
19
|
+
this.version = options.version ?? 1;
|
|
20
|
+
this.migrations = options.migrations ?? {};
|
|
21
|
+
this.extensions = options.extensions ?? new StateRegistry();
|
|
22
|
+
}
|
|
23
|
+
get state() {
|
|
24
|
+
return structuredClone(this._state);
|
|
25
|
+
}
|
|
26
|
+
set(next) {
|
|
27
|
+
this._state = structuredClone(next);
|
|
28
|
+
}
|
|
29
|
+
update(transform) {
|
|
30
|
+
const next = transform(this.state);
|
|
31
|
+
this.set(next);
|
|
32
|
+
return this.state;
|
|
33
|
+
}
|
|
34
|
+
snapshot() {
|
|
35
|
+
const extensions = this.extensions.snapshot();
|
|
36
|
+
return {
|
|
37
|
+
version: this.version,
|
|
38
|
+
state: this.state,
|
|
39
|
+
extensions: extensions.extensions,
|
|
40
|
+
extensionVersions: extensions.versions,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
restore(snapshot, options = {}) {
|
|
44
|
+
if (!Number.isSafeInteger(snapshot.version) || snapshot.version < 1)
|
|
45
|
+
throw new Error('canonical state snapshot version must be a positive integer');
|
|
46
|
+
if (snapshot.version > this.version)
|
|
47
|
+
throw new Error(`canonical state snapshot version ${snapshot.version} is newer than ${this.version}`);
|
|
48
|
+
const before = this.snapshot();
|
|
49
|
+
try {
|
|
50
|
+
let state = structuredClone(snapshot.state);
|
|
51
|
+
for (let version = snapshot.version; version < this.version; version++) {
|
|
52
|
+
const migration = this.migrations[version + 1];
|
|
53
|
+
if (!migration)
|
|
54
|
+
throw new Error(`missing canonical state migration to version ${version + 1}`);
|
|
55
|
+
state = migration(state);
|
|
56
|
+
}
|
|
57
|
+
this._state = structuredClone(state);
|
|
58
|
+
return this.extensions.restore({ extensions: snapshot.extensions, versions: snapshot.extensionVersions }, options);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
this._state = structuredClone(before.state);
|
|
62
|
+
this.extensions.restore({ extensions: before.extensions, versions: before.extensionVersions }, { missing: 'keep' });
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
transaction(work) {
|
|
67
|
+
const before = this.snapshot();
|
|
68
|
+
try {
|
|
69
|
+
return work(this);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
this.restore(before);
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
1
77
|
/**
|
|
2
78
|
* Coordinates game-owned save state without knowing its schema.
|
|
3
79
|
*
|
package/dist/core/State.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"State.js","sourceRoot":"","sources":["../../src/core/State.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"State.js","sourceRoot":"","sources":["../../src/core/State.ts"],"names":[],"mappings":"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"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -18,13 +18,13 @@ export { Generator, MersenneTwister, RandomStreams } from './Random.ts';
|
|
|
18
18
|
export type { MersenneTwisterState } from './Random.ts';
|
|
19
19
|
export { SaveSystem } from './Save.ts';
|
|
20
20
|
export type { SaveMeta, SaveData, SaveStorage, SaveSystemOptions } from './Save.ts';
|
|
21
|
-
export { StateRegistry } from './State.ts';
|
|
22
|
-
export type { StateValue, StateExtension, StateSnapshot, StateRestoreDiagnostic } from './State.ts';
|
|
21
|
+
export { CanonicalState, StateRegistry } from './State.ts';
|
|
22
|
+
export type { CanonicalStateSnapshot, StateValue, StateExtension, StateSnapshot, StateRestoreDiagnostic, } from './State.ts';
|
|
23
23
|
export { scramble, unscramble } from './Scramble.ts';
|
|
24
24
|
export { SaveSyncClient } from './SaveSync.ts';
|
|
25
25
|
export type { SaveSyncOptions, SaveSyncResponse } from './SaveSync.ts';
|
|
26
26
|
export { LockstepClient } from './Multiplayer.ts';
|
|
27
|
-
export type { WebSocketLike, LockstepClientOptions, TickEvent } from './Multiplayer.ts';
|
|
27
|
+
export type { WebSocketLike, LockstepClientOptions, LockstepWelcome, TickEvent } from './Multiplayer.ts';
|
|
28
28
|
export { RunHistory } from './RunHistory.ts';
|
|
29
29
|
export type { RunHistoryEntry, RunHistoryOptions } from './RunHistory.ts';
|
|
30
30
|
export { PlayerStats } from './Stats.ts';
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"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"}
|
package/dist/core/index.js
CHANGED
|
@@ -10,7 +10,7 @@ export * as Input from './Input.js';
|
|
|
10
10
|
export { PlayerInput } from './PlayerInput.js';
|
|
11
11
|
export { Generator, MersenneTwister, RandomStreams } from './Random.js';
|
|
12
12
|
export { SaveSystem } from './Save.js';
|
|
13
|
-
export { StateRegistry } from './State.js';
|
|
13
|
+
export { CanonicalState, StateRegistry } from './State.js';
|
|
14
14
|
export { scramble, unscramble } from './Scramble.js';
|
|
15
15
|
export { SaveSyncClient } from './SaveSync.js';
|
|
16
16
|
export { LockstepClient } from './Multiplayer.js';
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAExE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAExE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAQ3D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEzG,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEhG,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAExH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC"}
|