@datamoc/mw_games 0.26.1 → 0.30.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +2 -1
  3. package/api-surface.json +564 -0
  4. package/dist/ai/Suggest.d.ts +54 -0
  5. package/dist/ai/Suggest.d.ts.map +1 -0
  6. package/dist/ai/Suggest.js +48 -0
  7. package/dist/ai/Suggest.js.map +1 -0
  8. package/dist/ai/index.d.ts +2 -0
  9. package/dist/ai/index.d.ts.map +1 -1
  10. package/dist/ai/index.js +1 -0
  11. package/dist/ai/index.js.map +1 -1
  12. package/dist/core/Input.d.ts +7 -0
  13. package/dist/core/Input.d.ts.map +1 -1
  14. package/dist/core/Input.js +9 -0
  15. package/dist/core/Input.js.map +1 -1
  16. package/dist/core/Random.d.ts +32 -5
  17. package/dist/core/Random.d.ts.map +1 -1
  18. package/dist/core/Random.js.map +1 -1
  19. package/dist/core/Replay.d.ts +28 -4
  20. package/dist/core/Replay.d.ts.map +1 -1
  21. package/dist/core/Replay.js +38 -9
  22. package/dist/core/Replay.js.map +1 -1
  23. package/dist/core/ReplayFile.d.ts +197 -0
  24. package/dist/core/ReplayFile.d.ts.map +1 -0
  25. package/dist/core/ReplayFile.js +257 -0
  26. package/dist/core/ReplayFile.js.map +1 -0
  27. package/dist/core/index.d.ts +4 -2
  28. package/dist/core/index.d.ts.map +1 -1
  29. package/dist/core/index.js +2 -1
  30. package/dist/core/index.js.map +1 -1
  31. package/dist/mw_games.global.js +113 -113
  32. package/dist/simulation/Training.d.ts +77 -0
  33. package/dist/simulation/Training.d.ts.map +1 -1
  34. package/dist/simulation/Training.js +87 -0
  35. package/dist/simulation/Training.js.map +1 -1
  36. package/dist/simulation/index.d.ts +2 -2
  37. package/dist/simulation/index.d.ts.map +1 -1
  38. package/dist/simulation/index.js +1 -1
  39. package/dist/simulation/index.js.map +1 -1
  40. package/dist/two-d/render/Beam.d.ts +136 -0
  41. package/dist/two-d/render/Beam.d.ts.map +1 -0
  42. package/dist/two-d/render/Beam.js +203 -0
  43. package/dist/two-d/render/Beam.js.map +1 -0
  44. package/dist/two-d/render/Flights.d.ts +90 -0
  45. package/dist/two-d/render/Flights.d.ts.map +1 -0
  46. package/dist/two-d/render/Flights.js +135 -0
  47. package/dist/two-d/render/Flights.js.map +1 -0
  48. package/dist/two-d/render/Particles.d.ts +57 -0
  49. package/dist/two-d/render/Particles.d.ts.map +1 -1
  50. package/dist/two-d/render/Particles.js +68 -1
  51. package/dist/two-d/render/Particles.js.map +1 -1
  52. package/dist/two-d/render/index.d.ts +5 -1
  53. package/dist/two-d/render/index.d.ts.map +1 -1
  54. package/dist/two-d/render/index.js +2 -0
  55. package/dist/two-d/render/index.js.map +1 -1
  56. package/dist/two-d/ui/MessageLog.d.ts +28 -0
  57. package/dist/two-d/ui/MessageLog.d.ts.map +1 -1
  58. package/dist/two-d/ui/MessageLog.js +23 -6
  59. package/dist/two-d/ui/MessageLog.js.map +1 -1
  60. package/dist/two-d/ui/OnScreenKeyboard.d.ts +91 -0
  61. package/dist/two-d/ui/OnScreenKeyboard.d.ts.map +1 -0
  62. package/dist/two-d/ui/OnScreenKeyboard.js +109 -0
  63. package/dist/two-d/ui/OnScreenKeyboard.js.map +1 -0
  64. package/dist/two-d/ui/TextPrompt.d.ts +122 -0
  65. package/dist/two-d/ui/TextPrompt.d.ts.map +1 -0
  66. package/dist/two-d/ui/TextPrompt.js +236 -0
  67. package/dist/two-d/ui/TextPrompt.js.map +1 -0
  68. package/dist/two-d/ui/index.d.ts +6 -2
  69. package/dist/two-d/ui/index.d.ts.map +1 -1
  70. package/dist/two-d/ui/index.js +3 -1
  71. package/dist/two-d/ui/index.js.map +1 -1
  72. package/dist/version.d.ts +1 -1
  73. package/dist/version.js +1 -1
  74. package/package.json +1 -1
  75. package/sbom.cdx.json +6 -6
  76. package/tools/browser-driver.d.mts +30 -0
  77. package/tools/browser-driver.mjs +146 -3
package/CHANGELOG.md CHANGED
@@ -7,6 +7,140 @@ the public API may still change between minor versions.
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.30.0] - 2026-10-07
11
+
12
+ P41, the browser driver's four measured gaps: the viewport option (inner size through the
13
+ protocol, not window flags), the trusted keyboard channel (press through CDP key events and
14
+ BiDi key actions, with the WebDriver key-value table), the Firefox tap that actually reaches
15
+ Pixi 8's EventSystem (the in-page synthetic sequence, measured and documented), and headed
16
+ mode. Live-verified on Chrome and Firefox: exact 800x600 viewport, keys delivered, the
17
+ Firefox tap advancing a real Pixi page.
18
+
19
+ ## [0.29.0] - 2026-10-07
20
+
21
+ P37's touch half: the on-screen keyboard. Rows of keys as data, rendered through the
22
+ theme's own Button, each tap feeding the same core.Input paths a physical key travels -
23
+ dispatchText for a typing key, the new dispatchAction for an action key - so a TextPrompt
24
+ cannot tell the two apart. TextPrompt grows a keyboard option that hosts one beneath the
25
+ field and resizes the window to fit it, UPPERCASE_KEYBOARD is one shipped default, and
26
+ the interface example's Name prompt carries it as the reviewed touch pattern.
27
+
28
+ ## [0.28.0] - 2026-10-07
29
+
30
+ The 0.27.0 consumer wave sharpened asks: the pixel-dungeon port proposal file
31
+ audited what 0.27 shipped against what a real consumer needs, and this release
32
+ closes the four framework-side gaps it found. Flights fades and spins in the
33
+ units games author (fadeIn: progress, spinDegrees), Beam thins as it fades and
34
+ stretches a single art asset along its span with anchor control,
35
+ ParticleEmitter.attach gates visibility (fog-of-war) beside emission, and the
36
+ interface example carries the reviewed TextPrompt hosting pattern a seed or name
37
+ prompt can be copied from.
38
+
39
+ ### Added
40
+
41
+ - `Flights` fade and spin in the units consumers author them in (P40): `fadeIn:
42
+ 'progress'` (or `true`) eases a sprite's alpha 0 to 1 along the flight's own
43
+ progress - the tween's clock, so the fade cannot desynchronise from a duration
44
+ the caller re-computed - while a number keeps its seconds-from-launch meaning,
45
+ and `spinDegrees` is `spin` in degrees per second, converted once, so an
46
+ authored angular speed needs no radian arithmetic at the call site.
47
+
48
+ - `Beam` thins and stretches (P35): `thin: true` narrows the body with its own
49
+ remaining life the way the alpha fades (a plain line's stroke, a strip's height,
50
+ a stretched sprite's `scale.y`), and the `texture` option's object form -
51
+ `{ source, stretch?, anchor? }` - stretches one art asset along the whole span
52
+ instead of tiling it, anchored across the thickness (0.5 by default) for ray
53
+ art that repeats badly. The bare-texture form tiles exactly as it always has.
54
+
55
+ - `ParticleEmitter.attach` takes a `visible` callback beside `enabled` (P36): a
56
+ false return hides the emitter and every particle it has in the air, so a
57
+ fog-of-war gate keeps an aura's spray out of unexplored space without the
58
+ consumer re-placing `visible` every frame. Drawing only - the simulation
59
+ keeps stepping behind the invisibility, emission keeps following `enabled`,
60
+ and `detach()` leaves the emitter visible.
61
+
62
+ - The interface example's new Name button is the reviewed `TextPrompt` hosting
63
+ pattern (P37): push it on a `WindowStack` and it owns typing, caret edits,
64
+ confirm-gated-by-`validate`, cancellation and closing - a seed or name prompt
65
+ with no DOM `<input>` overlay to copy around.
66
+
67
+ ## [0.27.0] - 2026-10-07
68
+
69
+ Two strands in one release. A run is durable and drives the AI (roadmap 396-397): the
70
+ versioned replay envelope refuses another game or framework build by name, `LastRun` keeps
71
+ the newest recording, `runCheckpoint`/`resumeRunPlayer` restore a run mid-run, and the
72
+ `file://` plumbing (download, picker, Blob read) ships with it; `imitationFromReplay` turns
73
+ a recorded run into training samples against its own seeded environment, `runSeededEpisode`
74
+ plays a whole run from a named seed behind any deterministic chooser, and `ai.Suggester`
75
+ is the throttled, non-mutating hint source. The render and UI strand: `Flights` owns live
76
+ projectile flights, `Beam`/`Beams` draw one-shot beams, `TextPrompt` asks for one line with
77
+ IME and screen-reader support, `MessageLog.lastEntries` reads retained entries back, and
78
+ `ParticleEmitter.attach` follows a target; `core.FloatSource` narrows the injectable random
79
+ stream for float-only helpers.
80
+
81
+ ### Added
82
+
83
+ - `core.FloatSource` splits `core.RandomSource`: helpers that draw floats only
84
+ (`float`, `chance`, `weighted`, `weightedKey`) accept the narrower
85
+ `{ float(): number }`, so a float-only stream needs no dead `int`. The
86
+ integer helpers (`int`, `range`, `normalRange`, `element`, `shuffle`) keep
87
+ requiring the full source; `element` stays wide deliberately, because it
88
+ draws through `int()` and re-spelling that draw would change its stream.
89
+
90
+ - `MessageLog.lastEntries(n)` reads the newest retained entries back as plain
91
+ `{ text, level }` records, oldest first, without scraping rendered children:
92
+ entries the wrapped-line budget already dropped are gone, over-count reads
93
+ everything retained, and zero or negative reads nothing. The slice lives in
94
+ the pure `takeLastEntries` beside the existing `linesToDrop` budget, so the
95
+ readback contract is testable without a renderer.
96
+
97
+ - `ParticleEmitter.attach(target)` follows a display object or position thunk on
98
+ every update tick and every `burst()`, with `offsetX`/`offsetY`, an `enabled`
99
+ callback gating tick emission, and auto-detach for destroyed targets;
100
+ `detach()` keeps the last position. The follow math is tested headless through
101
+ textureless emitters.
102
+
103
+ - `Flights` owns a scene's live projectile flights over the existing `Projectile`:
104
+ `add(sprite | texture, from, to, { speed, tint?, spin?, fadeIn?, onArrive? })`
105
+ returns a handle, `update(dt)` drives positions with per-flight spin and fade,
106
+ each arrival dispatches once after leaving the list, and `cancel()`/`clear()`
107
+ forget without dispatching. Caller sprites stay caller-owned; texture-built
108
+ sprites are parented here and destroyed with their flight.
109
+
110
+ - `Beam`/`Beams` draw one-shot beams between two screen points: a fading line by
111
+ default, a fading repeating texture strip with `texture`, additive blend unless
112
+ opted out, `retarget` for tracking endpoints, and `update` reporting expiry
113
+ exactly once so the `Beams` group can remove finished beams itself.
114
+
115
+ - `TextPrompt` asks for one line of text over a `TextModel`: typing through
116
+ `onText` (the newest open prompt wins), caret and edits through
117
+ `left`/`right`/`backspace`/`delete` actions, `confirm` gated by `validate` and
118
+ `cancel` giving up. IME compositions preview until they commit, and the
119
+ message plus validation errors announce through `screenReader` (assertive for
120
+ the errors), with an injectable announcer for tests.
121
+
122
+ - A run is durable now (roadmap 396): `exportReplayFile`/`importReplayFile` wrap a
123
+ recording in a versioned, self-describing envelope that refuses another game or
124
+ framework build by name, `LastRun` keeps the newest recording (one deep, bounded,
125
+ over the same storage a save slot uses), and `runCheckpoint`/`resumeRunPlayer`
126
+ pair the partial recording with the saved state so a restored run resumes mid-run
127
+ instead of restarting - `Recorder` and `Player` both take `fromFrame`, and
128
+ `parseReplayEvents` factors out the half of `deserializeReplay`'s check that
129
+ validates an already-parsed array. The `file://` plumbing rides along:
130
+ `downloadReplayFile` (a Blob download, never `fetch()`), `pickReplayFile`
131
+ (the file picker, null on cancel) and `readReplayFile` (any `Blob`, headless
132
+ Node included).
133
+
134
+ - Replays train and drive the AI (roadmap 397): `imitationFromReplay` walks a
135
+ recorded run against the same seeded `TrainingEnvironment` it was played on and
136
+ returns the `(observation, action)` samples a game's own trainer fits;
137
+ `runSeededEpisode` plays a whole run with any deterministic chooser (a heuristic,
138
+ a `NeuralPolicy`'s argmax, not just a `NeuralModel` like `runRollouts`) from a
139
+ named seed, recording every chosen action so runs compare across builds and
140
+ policies; and `ai.Suggester` is the in-game suggestion mode, the same decision
141
+ call pointed at a hint UI instead of the world, throttled by a frame-count budget
142
+ and never mutating state to compute a hint.
143
+
10
144
  ## [0.26.1] - 2026-10-07
11
145
 
12
146
  The 0.26.0 follow-up: its Chrome end-to-end test failed on every CI run, so the
package/README.md CHANGED
@@ -15,7 +15,7 @@ playable in the browser with no download, plus the generated API reference.
15
15
  planning or porting a demanding game with mwg, with links to the [mwg reference](https://github.com/datamoc/mwg/blob/main/REFERENCE.md)
16
16
  and the [mwg Pixel Dungeon study](https://datamoc.github.io/mwg-pixel-dungeon/).
17
17
 
18
- > **Status: pre-alpha (v0.17.1).** Every module in the shared floor below, plus optional
18
+ > **Status: pre-alpha (v0.29.0).** Every module in the shared floor below, plus optional
19
19
  > 3D, mobile (Capacitor) and desktop (WebView2) packaging, is built and tested - see
20
20
  > [ROADMAP.md](https://github.com/datamoc/mwg/blob/main/ROADMAP.md) for open work, and
21
21
  > [CLOSED.md](https://github.com/datamoc/mwg/blob/main/CLOSED.md) for the full, numbered shipped history.
@@ -205,6 +205,7 @@ only some do.
205
205
  | | screen transitions: fade, flash, tint | `mwg/two-d/render` |
206
206
  | **ui** | windows, lists, tooltips, markdown labels | `mwg/two-d/ui` |
207
207
  | | text and fonts, including non-latin fallback | PixiJS |
208
+ | | modal single-line text entry, with validation and an on-screen keyboard for touch | `mwg/two-d/ui` |
208
209
  | | pointer, keyboard and gamepad input with rebinding | `mwg/core` |
209
210
  | **text** | message tables per language, compiled at build time | `mwg/i18n` |
210
211
  | | plurals, gendered forms, interpolation, and Python f-string-style format specs | `mwg/i18n` |