@datamoc/mw_games 0.25.0 → 0.27.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/CHANGELOG.md +192 -0
- package/README.md +15 -0
- package/api-surface.json +14942 -0
- package/dist/actors/StatBlock.d.ts +2 -4
- package/dist/actors/StatBlock.d.ts.map +1 -1
- package/dist/actors/StatBlock.js +2 -4
- package/dist/actors/StatBlock.js.map +1 -1
- package/dist/ai/Heuristics.d.ts +1 -1
- package/dist/ai/Heuristics.js +1 -1
- package/dist/ai/Suggest.d.ts +54 -0
- package/dist/ai/Suggest.d.ts.map +1 -0
- package/dist/ai/Suggest.js +48 -0
- package/dist/ai/Suggest.js.map +1 -0
- package/dist/ai/index.d.ts +2 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +1 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/assets/index.d.ts +1 -0
- package/dist/assets/index.d.ts.map +1 -1
- package/dist/assets/index.js.map +1 -1
- package/dist/core/Blob.d.ts.map +1 -1
- package/dist/core/Blob.js +2 -8
- package/dist/core/Blob.js.map +1 -1
- package/dist/core/Grid.d.ts +115 -0
- package/dist/core/Grid.d.ts.map +1 -1
- package/dist/core/Grid.js +125 -0
- package/dist/core/Grid.js.map +1 -1
- package/dist/core/HttpTransport.d.ts +14 -0
- package/dist/core/HttpTransport.d.ts.map +1 -1
- package/dist/core/HttpTransport.js +14 -0
- package/dist/core/HttpTransport.js.map +1 -1
- package/dist/core/Random.d.ts +63 -13
- package/dist/core/Random.d.ts.map +1 -1
- package/dist/core/Random.js +28 -25
- package/dist/core/Random.js.map +1 -1
- package/dist/core/Replay.d.ts +28 -4
- package/dist/core/Replay.d.ts.map +1 -1
- package/dist/core/Replay.js +38 -9
- package/dist/core/Replay.js.map +1 -1
- package/dist/core/ReplayFile.d.ts +197 -0
- package/dist/core/ReplayFile.d.ts.map +1 -0
- package/dist/core/ReplayFile.js +257 -0
- package/dist/core/ReplayFile.js.map +1 -0
- package/dist/core/index.d.ts +9 -5
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -2
- package/dist/core/index.js.map +1 -1
- package/dist/headless/index.d.ts +87 -0
- package/dist/headless/index.d.ts.map +1 -0
- package/dist/headless/index.js +87 -0
- package/dist/headless/index.js.map +1 -0
- package/dist/mw_games.global.js +113 -113
- package/dist/mwl/index.d.ts +1 -1
- package/dist/mwl/index.d.ts.map +1 -1
- package/dist/mwl/index.js.map +1 -1
- package/dist/roguelike/Level.d.ts +1 -1
- package/dist/roguelike/Level.d.ts.map +1 -1
- package/dist/roguelike/Level.js +3 -21
- package/dist/roguelike/Level.js.map +1 -1
- package/dist/roguelike/Targeting.d.ts.map +1 -1
- package/dist/roguelike/Targeting.js +2 -1
- package/dist/roguelike/Targeting.js.map +1 -1
- package/dist/rpg/index.d.ts +1 -1
- package/dist/rpg/index.d.ts.map +1 -1
- package/dist/simulation/Training.d.ts +77 -0
- package/dist/simulation/Training.d.ts.map +1 -1
- package/dist/simulation/Training.js +87 -0
- package/dist/simulation/Training.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/pixi-interop.d.ts +24 -1
- package/dist/two-d/pixi-interop.d.ts.map +1 -1
- package/dist/two-d/pixi-interop.js +23 -1
- package/dist/two-d/pixi-interop.js.map +1 -1
- package/dist/two-d/render/Beam.d.ts +93 -0
- package/dist/two-d/render/Beam.d.ts.map +1 -0
- package/dist/two-d/render/Beam.js +154 -0
- package/dist/two-d/render/Beam.js.map +1 -0
- package/dist/two-d/render/Flights.d.ts +79 -0
- package/dist/two-d/render/Flights.d.ts.map +1 -0
- package/dist/two-d/render/Flights.js +120 -0
- package/dist/two-d/render/Flights.js.map +1 -0
- package/dist/two-d/render/Particles.d.ts +48 -0
- package/dist/two-d/render/Particles.d.ts.map +1 -1
- package/dist/two-d/render/Particles.js +59 -1
- package/dist/two-d/render/Particles.js.map +1 -1
- package/dist/two-d/render/index.d.ts +6 -2
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +2 -0
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/two-d/ui/MessageLog.d.ts +28 -0
- package/dist/two-d/ui/MessageLog.d.ts.map +1 -1
- package/dist/two-d/ui/MessageLog.js +23 -6
- package/dist/two-d/ui/MessageLog.js.map +1 -1
- package/dist/two-d/ui/TextPrompt.d.ts +115 -0
- package/dist/two-d/ui/TextPrompt.d.ts.map +1 -0
- package/dist/two-d/ui/TextPrompt.js +227 -0
- package/dist/two-d/ui/TextPrompt.js.map +1 -0
- package/dist/two-d/ui/index.d.ts +4 -2
- package/dist/two-d/ui/index.d.ts.map +1 -1
- package/dist/two-d/ui/index.js +2 -1
- package/dist/two-d/ui/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +16 -3
- package/sbom.cdx.json +6 -6
- package/tools/audit-adoptions.d.mts +65 -0
- package/tools/audit-adoptions.mjs +252 -0
- package/tools/browser-driver.d.mts +78 -0
- package/tools/browser-driver.mjs +642 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,198 @@ the public API may still change between minor versions.
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.27.0] - 2026-10-07
|
|
11
|
+
|
|
12
|
+
Two strands in one release. A run is durable and drives the AI (roadmap 396-397): the
|
|
13
|
+
versioned replay envelope refuses another game or framework build by name, `LastRun` keeps
|
|
14
|
+
the newest recording, `runCheckpoint`/`resumeRunPlayer` restore a run mid-run, and the
|
|
15
|
+
`file://` plumbing (download, picker, Blob read) ships with it; `imitationFromReplay` turns
|
|
16
|
+
a recorded run into training samples against its own seeded environment, `runSeededEpisode`
|
|
17
|
+
plays a whole run from a named seed behind any deterministic chooser, and `ai.Suggester`
|
|
18
|
+
is the throttled, non-mutating hint source. The render and UI strand: `Flights` owns live
|
|
19
|
+
projectile flights, `Beam`/`Beams` draw one-shot beams, `TextPrompt` asks for one line with
|
|
20
|
+
IME and screen-reader support, `MessageLog.lastEntries` reads retained entries back, and
|
|
21
|
+
`ParticleEmitter.attach` follows a target; `core.FloatSource` narrows the injectable random
|
|
22
|
+
stream for float-only helpers.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- `core.FloatSource` splits `core.RandomSource`: helpers that draw floats only
|
|
27
|
+
(`float`, `chance`, `weighted`, `weightedKey`) accept the narrower
|
|
28
|
+
`{ float(): number }`, so a float-only stream needs no dead `int`. The
|
|
29
|
+
integer helpers (`int`, `range`, `normalRange`, `element`, `shuffle`) keep
|
|
30
|
+
requiring the full source; `element` stays wide deliberately, because it
|
|
31
|
+
draws through `int()` and re-spelling that draw would change its stream.
|
|
32
|
+
|
|
33
|
+
- `MessageLog.lastEntries(n)` reads the newest retained entries back as plain
|
|
34
|
+
`{ text, level }` records, oldest first, without scraping rendered children:
|
|
35
|
+
entries the wrapped-line budget already dropped are gone, over-count reads
|
|
36
|
+
everything retained, and zero or negative reads nothing. The slice lives in
|
|
37
|
+
the pure `takeLastEntries` beside the existing `linesToDrop` budget, so the
|
|
38
|
+
readback contract is testable without a renderer.
|
|
39
|
+
|
|
40
|
+
- `ParticleEmitter.attach(target)` follows a display object or position thunk on
|
|
41
|
+
every update tick and every `burst()`, with `offsetX`/`offsetY`, an `enabled`
|
|
42
|
+
callback gating tick emission, and auto-detach for destroyed targets;
|
|
43
|
+
`detach()` keeps the last position. The follow math is tested headless through
|
|
44
|
+
textureless emitters.
|
|
45
|
+
|
|
46
|
+
- `Flights` owns a scene's live projectile flights over the existing `Projectile`:
|
|
47
|
+
`add(sprite | texture, from, to, { speed, tint?, spin?, fadeIn?, onArrive? })`
|
|
48
|
+
returns a handle, `update(dt)` drives positions with per-flight spin and fade,
|
|
49
|
+
each arrival dispatches once after leaving the list, and `cancel()`/`clear()`
|
|
50
|
+
forget without dispatching. Caller sprites stay caller-owned; texture-built
|
|
51
|
+
sprites are parented here and destroyed with their flight.
|
|
52
|
+
|
|
53
|
+
- `Beam`/`Beams` draw one-shot beams between two screen points: a fading line by
|
|
54
|
+
default, a fading repeating texture strip with `texture`, additive blend unless
|
|
55
|
+
opted out, `retarget` for tracking endpoints, and `update` reporting expiry
|
|
56
|
+
exactly once so the `Beams` group can remove finished beams itself.
|
|
57
|
+
|
|
58
|
+
- `TextPrompt` asks for one line of text over a `TextModel`: typing through
|
|
59
|
+
`onText` (the newest open prompt wins), caret and edits through
|
|
60
|
+
`left`/`right`/`backspace`/`delete` actions, `confirm` gated by `validate` and
|
|
61
|
+
`cancel` giving up. IME compositions preview until they commit, and the
|
|
62
|
+
message plus validation errors announce through `screenReader` (assertive for
|
|
63
|
+
the errors), with an injectable announcer for tests.
|
|
64
|
+
|
|
65
|
+
- A run is durable now (roadmap 396): `exportReplayFile`/`importReplayFile` wrap a
|
|
66
|
+
recording in a versioned, self-describing envelope that refuses another game or
|
|
67
|
+
framework build by name, `LastRun` keeps the newest recording (one deep, bounded,
|
|
68
|
+
over the same storage a save slot uses), and `runCheckpoint`/`resumeRunPlayer`
|
|
69
|
+
pair the partial recording with the saved state so a restored run resumes mid-run
|
|
70
|
+
instead of restarting - `Recorder` and `Player` both take `fromFrame`, and
|
|
71
|
+
`parseReplayEvents` factors out the half of `deserializeReplay`'s check that
|
|
72
|
+
validates an already-parsed array. The `file://` plumbing rides along:
|
|
73
|
+
`downloadReplayFile` (a Blob download, never `fetch()`), `pickReplayFile`
|
|
74
|
+
(the file picker, null on cancel) and `readReplayFile` (any `Blob`, headless
|
|
75
|
+
Node included).
|
|
76
|
+
|
|
77
|
+
- Replays train and drive the AI (roadmap 397): `imitationFromReplay` walks a
|
|
78
|
+
recorded run against the same seeded `TrainingEnvironment` it was played on and
|
|
79
|
+
returns the `(observation, action)` samples a game's own trainer fits;
|
|
80
|
+
`runSeededEpisode` plays a whole run with any deterministic chooser (a heuristic,
|
|
81
|
+
a `NeuralPolicy`'s argmax, not just a `NeuralModel` like `runRollouts`) from a
|
|
82
|
+
named seed, recording every chosen action so runs compare across builds and
|
|
83
|
+
policies; and `ai.Suggester` is the in-game suggestion mode, the same decision
|
|
84
|
+
call pointed at a hint UI instead of the world, throttled by a frame-count budget
|
|
85
|
+
and never mutating state to compute a hint.
|
|
86
|
+
|
|
87
|
+
## [0.26.1] - 2026-10-07
|
|
88
|
+
|
|
89
|
+
The 0.26.0 follow-up: its Chrome end-to-end test failed on every CI run, so the
|
|
90
|
+
`tools/browser-driver` Chrome engine never actually worked on a CI machine (a cold
|
|
91
|
+
Windows runner never reached the debugging endpoint in the old budget; an Ubuntu
|
|
92
|
+
runner crashed in Chrome's sandbox). Chrome now launches against its own profile,
|
|
93
|
+
the endpoint is watched on both output streams with a cold-start budget and a
|
|
94
|
+
diagnostic that names what the browser printed, `close` releases the profile and
|
|
95
|
+
the stdio pipes only after the child exits, and the CI workflows pass
|
|
96
|
+
`--no-sandbox` on Linux through the driver's own `MWG_DRIVER_CHROME_ARGS` channel.
|
|
97
|
+
0.26.0 was tagged before this was known and its npm publish never ran.
|
|
98
|
+
|
|
99
|
+
### Fixed
|
|
100
|
+
|
|
101
|
+
- `tools/browser-driver`'s Chrome engine launches against its own profile
|
|
102
|
+
(`options.profileDir`, or a temp dir the driver creates and removes on `close`)
|
|
103
|
+
instead of the machine's default one, watches both stdout and stderr for the
|
|
104
|
+
debugging endpoint (which stream a build prints it on is not something to bet
|
|
105
|
+
on), waits up to 30 s instead of 15 (a cold CI machine's first Chrome start can
|
|
106
|
+
outrun the old budget), and names what the browser printed when the endpoint
|
|
107
|
+
never arrives. This is the fix for the Chrome end-to-end test failing on every
|
|
108
|
+
CI run since the driver landed: the default profile on a fresh runner never
|
|
109
|
+
reached the endpoint in time. `close` now also destroys the child's stdio
|
|
110
|
+
pipes (surviving browser helper processes could hold a suite open past the
|
|
111
|
+
browser's own death) and releases the profile only after the child exits.
|
|
112
|
+
The failing configuration is now diagnosed, not just reported: the timeout
|
|
113
|
+
names what the browser printed. CI's Linux jobs pass `--no-sandbox` through
|
|
114
|
+
the driver's `MWG_DRIVER_CHROME_ARGS` channel, since an Ubuntu 23.10+ runner
|
|
115
|
+
that disables unprivileged user namespaces is a property of that machine,
|
|
116
|
+
not of the tool.
|
|
117
|
+
|
|
118
|
+
## [0.26.0] - 2026-10-07
|
|
119
|
+
|
|
120
|
+
The machine-readable surface and the audit tooling around it: `api-surface.json` ships as the
|
|
121
|
+
`./api-manifest` subpath (one `{ name, kind, subpath, declaringModule }` row per export), the
|
|
122
|
+
blessed `mwg/headless` entry imports every renderer-free module in one line, `tools/audit-adoptions`
|
|
123
|
+
checks a consumer's imports and local definitions against that manifest, and the dependency-free
|
|
124
|
+
`tools/browser-driver` harness drives real Chrome and Firefox. `core` gained injectable `RandomSource`
|
|
125
|
+
streams for every derived helper and the shared square-grid rulers (`chebyshev`, `manhattan`,
|
|
126
|
+
`euclidean`, `distance` by `DistanceMetric`), the coverage gate now enforces `two-d/ui` instead of
|
|
127
|
+
excluding the whole tree, and the bundle-size baseline is refreshed for the growth those brought.
|
|
128
|
+
|
|
129
|
+
### Added
|
|
130
|
+
|
|
131
|
+
- Exported the types a public signature already names: `mwl` move/evolution/matchup
|
|
132
|
+
definitions, `core` achievement criteria and hex shape types, particle curve and spawn
|
|
133
|
+
area types, screen effect steps, `rpg` route targets, asset loader options, and the
|
|
134
|
+
`core.HttpTransport` base class its four clients already extend.
|
|
135
|
+
|
|
136
|
+
- `core.NEIGHBOURS4`/`NEIGHBOURS8`/`CIRCLE8` share one frozen square-grid offset table
|
|
137
|
+
instead of each module keeping its own: axial, row-major eight, and the clockwise ring
|
|
138
|
+
(`roguelike`'s `neighbourOffsets` returns these now); `core.euclidean` is the
|
|
139
|
+
straight-line ruler beside `roguelike`'s `chebyshevDistance`.
|
|
140
|
+
|
|
141
|
+
- `core.chebyshev` is the king-move ruler beside `euclidean` (a diagonal costs one
|
|
142
|
+
step) and `core.manhattan` the orthogonal-step count; `core.distance` measures with
|
|
143
|
+
the ruler a `DistanceMetric` names, so a data-authored rule picks its geometry by
|
|
144
|
+
name. `roguelike`'s `chebyshevDistance` delegates to `chebyshev` instead of spelling
|
|
145
|
+
the arithmetic out again.
|
|
146
|
+
|
|
147
|
+
- `api-surface.json` is the machine-readable API surface: one
|
|
148
|
+
`{ name, kind, subpath, declaringModule }` entry per export per subpath,
|
|
149
|
+
generated by the same `tools/api-report.mjs` pass that maintains
|
|
150
|
+
`API_REPORT.md`, shipped in the package behind the `./api-manifest` subpath,
|
|
151
|
+
and pinned by `tests/api-manifest.test.ts` (shape and coverage) plus the
|
|
152
|
+
existing `--check` (agreement with the declarations). `node
|
|
153
|
+
tools/api-report.mjs --diff OLD NEW` diffs two releases' surfaces, and the
|
|
154
|
+
report parser no longer drops `export type { ... }` re-export lists.
|
|
155
|
+
|
|
156
|
+
- `core.RandomSource` lets every derived helper (`chance`, `element`,
|
|
157
|
+
`weighted`, `weightedKey`, `shuffle`, `int`, `range`, `normalRange`) draw
|
|
158
|
+
from an injected stream: pass a rule-local `Generator` (or any
|
|
159
|
+
`float`/`int` pair) as the trailing `source` and the ambient stream is left
|
|
160
|
+
untouched, with identical draws and the same `null` reporting.
|
|
161
|
+
|
|
162
|
+
- `node tools/api-report.mjs --diff OLD NEW` lists added, removed and
|
|
163
|
+
kind-changed exports between two `api-surface.json` manifests, so a version
|
|
164
|
+
bump yields a one-command surface diff.
|
|
165
|
+
|
|
166
|
+
- `mwg/headless` is the blessed renderer-free entry: `core`, `simulation`,
|
|
167
|
+
`mwl`, `i18n`, `actors`, `world`, `battle`, `roguelike`, `board`, `audio`,
|
|
168
|
+
`rpg`, `ai`, `testing` and the two renderer-free asset halves, in one import
|
|
169
|
+
with no DOM or WebGL globals. `tests/headless-smoke.test.ts` imports it in
|
|
170
|
+
plain Node, walks the reachable graph for a renderer leak, and replays a
|
|
171
|
+
seeded scenario through it.
|
|
172
|
+
|
|
173
|
+
- `tools/audit-adoptions` (also `mwg-audit-adoptions`) is the shipped consumer
|
|
174
|
+
adoption auditor: manifest plus reasons file plus config (type-only
|
|
175
|
+
directories, subpath deny-lists, per-pattern import budgets), reporting
|
|
176
|
+
unadopted exports, stale reasons, shadowing collisions and config violations
|
|
177
|
+
with `file:line` and a non-zero exit.
|
|
178
|
+
|
|
179
|
+
- `two-d/pixi-interop` now states the interop-only rationale on each
|
|
180
|
+
re-exported primitive's own declaration: every histogram symbol
|
|
181
|
+
(`Rectangle`, `Texture`, `Container`, `Sprite`, `Graphics`, `FillGradient`,
|
|
182
|
+
`TilingSprite`) already has a facade family, so the note names the
|
|
183
|
+
Pixi-typed seam that keeps the raw export, and `tests/pixi-interop-coverage`
|
|
184
|
+
pins both halves.
|
|
185
|
+
|
|
186
|
+
- `tools/browser-driver` is the dependency-free browser harness: a self-served
|
|
187
|
+
static directory on an OS-chosen free port, Chrome over CDP and Firefox over
|
|
188
|
+
WebDriver BiDi behind one surface (`goto`/`waitReady`/`tap` at canvas
|
|
189
|
+
fractions/`evaluate`/`script`/`screenshot`/`consoleErrors`/`close`), reusing
|
|
190
|
+
the `browser-smoke` readiness contract. Verified live on both engines.
|
|
191
|
+
|
|
192
|
+
### Changed
|
|
193
|
+
|
|
194
|
+
- The coverage gate now enforces `two-d/ui` instead of excluding the whole tree:
|
|
195
|
+
the widget tests the suite already ran carry it (97.3/92.6/94.3 against the
|
|
196
|
+
88/89/82 floors), so the exclusion was stale, and a wildcard also left every
|
|
197
|
+
new UI file silently ungated. `EventDialogue` stays excluded as intended, under
|
|
198
|
+
its real path (`two-d/ui`, where the old flag pointed at a nonexistent
|
|
199
|
+
`two-d/stage` copy), and `SelectionModel` gained a direct contract test that
|
|
200
|
+
covers it fully, where before only its embedding widgets exercised it.
|
|
201
|
+
|
|
10
202
|
## [0.25.0] - 2026-10-05
|
|
11
203
|
|
|
12
204
|
Framework support for the Pixel Dungeon port's simulation and content proposals: numeric
|
package/README.md
CHANGED
|
@@ -336,6 +336,21 @@ edited in a proper editor, without any of those options requiring changes to the
|
|
|
336
336
|
It also keeps the content out of the bundle: `tools/compile-resources` treats a map file
|
|
337
337
|
exactly like a sprite sheet, so adding a hundred maps does not touch the build at all.
|
|
338
338
|
|
|
339
|
+
### Objects for behavior, data for content
|
|
340
|
+
|
|
341
|
+
Content is data (above), but a game's *behavior* belongs in classes. A monster kept as
|
|
342
|
+
loose scene fields works for one tutorial room and collapses for a dungeon: give it a
|
|
343
|
+
class holding its state and the methods that change it, built on the framework's own
|
|
344
|
+
bricks (`core.Scene` scenes, `actors.StatBlock` stats, `battle.Creature` opponents,
|
|
345
|
+
`roguelike.Level` maps, `rpg.GridMover` movement, `core.EntityRegistry` identity).
|
|
346
|
+
Subclass the brick that already owns the concern instead of reimplementing it beside an
|
|
347
|
+
interface; no new base class is needed for ordinary actors.
|
|
348
|
+
|
|
349
|
+
The boundary is where serialization starts. `simulation` commands survive
|
|
350
|
+
`structuredClone`, `core.SaveSystem` stores JSON-serialisable state, and MWL rows are
|
|
351
|
+
records by design, so classes stop where those begin: flatten at the boundary the way
|
|
352
|
+
`rpg.GameState` does, and rebuild objects on load rather than storing them.
|
|
353
|
+
|
|
339
354
|
### On writing direction
|
|
340
355
|
|
|
341
356
|
Supporting more than one language is mostly bookkeeping. Supporting more than one writing
|