@lewismoten/gamemaker-sandbox-engine 0.0.0-stage → 3.3.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 (129) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +24 -0
  3. package/NOTICE.md +58 -0
  4. package/README.md +149 -2
  5. package/dist/assets/music.worklet-aD2x7RRM.js +466 -0
  6. package/dist/audio/cmfLoad.js +10 -0
  7. package/dist/audio/cmfPlayer.js +201 -0
  8. package/dist/audio/context.js +75 -0
  9. package/dist/audio/engine.js +173 -0
  10. package/dist/audio/mix.js +40 -0
  11. package/dist/audio/opl.js +245 -0
  12. package/dist/audio/output.js +40 -0
  13. package/dist/core/gameFiles.js +89 -0
  14. package/dist/engine/character.js +187 -0
  15. package/dist/engine/funcKeys.js +164 -0
  16. package/dist/engine/game.js +133 -0
  17. package/dist/engine/keys.js +68 -0
  18. package/dist/engine/machine.js +192 -0
  19. package/dist/engine/menus.js +135 -0
  20. package/dist/engine/monsters.js +259 -0
  21. package/dist/engine/playGain.js +10 -0
  22. package/dist/engine/playerLook.js +48 -0
  23. package/dist/engine/recorder.js +127 -0
  24. package/dist/engine/render.js +45 -0
  25. package/dist/engine/scene.js +324 -0
  26. package/dist/engine/scroll.js +79 -0
  27. package/dist/engine/showGraphic.js +107 -0
  28. package/dist/engine/slowPc.js +98 -0
  29. package/dist/engine/slowPcMusic.js +46 -0
  30. package/dist/engine/touch.js +61 -0
  31. package/dist/engine/world.js +205 -0
  32. package/dist/formats/binary.js +120 -0
  33. package/dist/formats/blocks.js +103 -0
  34. package/dist/formats/character.js +83 -0
  35. package/dist/formats/cmf.js +37 -0
  36. package/dist/formats/cmfEdit.js +154 -0
  37. package/dist/formats/cmfPreview.js +89 -0
  38. package/dist/formats/cmfSong.js +190 -0
  39. package/dist/formats/fli.js +340 -0
  40. package/dist/formats/fliFrames.js +34 -0
  41. package/dist/formats/fliLimits.js +54 -0
  42. package/dist/formats/game.js +198 -0
  43. package/dist/formats/gif.js +125 -0
  44. package/dist/formats/gifProgressive.js +99 -0
  45. package/dist/formats/graphicScripts.js +44 -0
  46. package/dist/formats/highscore.js +30 -0
  47. package/dist/formats/jpeg.js +359 -0
  48. package/dist/formats/map.js +38 -0
  49. package/dist/formats/monster.js +69 -0
  50. package/dist/formats/palette.js +58 -0
  51. package/dist/formats/recording.js +17 -0
  52. package/dist/formats/sound.js +44 -0
  53. package/dist/formats/voc.js +303 -0
  54. package/dist/gfx/colorVision.js +45 -0
  55. package/dist/gfx/cp437Glyphs.js +337 -0
  56. package/dist/gfx/font8x8.js +10 -0
  57. package/dist/gfx/screen.js +151 -0
  58. package/dist/index.js +15 -0
  59. package/dist/input/chords.js +46 -0
  60. package/dist/input/deskMouse.js +24 -0
  61. package/dist/input/keyboard.js +82 -0
  62. package/dist/input/scancodes.js +143 -0
  63. package/dist/player/fileExtensions.js +118 -0
  64. package/dist/player/patchRules.js +129 -0
  65. package/dist/player/patchTable.js +1753 -0
  66. package/dist/text/cp437.js +44 -0
  67. package/dist/types/audio/cmfLoad.d.ts +7 -0
  68. package/dist/types/audio/cmfPlayer.d.ts +69 -0
  69. package/dist/types/audio/context.d.ts +12 -0
  70. package/dist/types/audio/engine.d.ts +60 -0
  71. package/dist/types/audio/mix.d.ts +14 -0
  72. package/dist/types/audio/music.worklet.d.ts +22 -0
  73. package/dist/types/audio/opl.d.ts +37 -0
  74. package/dist/types/audio/output.d.ts +13 -0
  75. package/dist/types/core/gameFiles.d.ts +49 -0
  76. package/dist/types/engine/character.d.ts +30 -0
  77. package/dist/types/engine/funcKeys.d.ts +35 -0
  78. package/dist/types/engine/game.d.ts +57 -0
  79. package/dist/types/engine/keys.d.ts +17 -0
  80. package/dist/types/engine/machine.d.ts +103 -0
  81. package/dist/types/engine/menus.d.ts +46 -0
  82. package/dist/types/engine/monsters.d.ts +19 -0
  83. package/dist/types/engine/playGain.d.ts +11 -0
  84. package/dist/types/engine/playerLook.d.ts +44 -0
  85. package/dist/types/engine/recorder.d.ts +67 -0
  86. package/dist/types/engine/render.d.ts +8 -0
  87. package/dist/types/engine/scene.d.ts +188 -0
  88. package/dist/types/engine/scroll.d.ts +24 -0
  89. package/dist/types/engine/showGraphic.d.ts +39 -0
  90. package/dist/types/engine/slowPc.d.ts +124 -0
  91. package/dist/types/engine/slowPcMusic.d.ts +18 -0
  92. package/dist/types/engine/touch.d.ts +33 -0
  93. package/dist/types/engine/world.d.ts +237 -0
  94. package/dist/types/formats/binary.d.ts +44 -0
  95. package/dist/types/formats/blocks.d.ts +52 -0
  96. package/dist/types/formats/character.d.ts +65 -0
  97. package/dist/types/formats/cmf.d.ts +33 -0
  98. package/dist/types/formats/cmfEdit.d.ts +53 -0
  99. package/dist/types/formats/cmfPreview.d.ts +19 -0
  100. package/dist/types/formats/cmfSong.d.ts +74 -0
  101. package/dist/types/formats/fli.d.ts +56 -0
  102. package/dist/types/formats/fliFrames.d.ts +18 -0
  103. package/dist/types/formats/fliLimits.d.ts +13 -0
  104. package/dist/types/formats/game.d.ts +79 -0
  105. package/dist/types/formats/gif.d.ts +15 -0
  106. package/dist/types/formats/gifProgressive.d.ts +46 -0
  107. package/dist/types/formats/graphicScripts.d.ts +18 -0
  108. package/dist/types/formats/highscore.d.ts +10 -0
  109. package/dist/types/formats/jpeg.d.ts +20 -0
  110. package/dist/types/formats/map.d.ts +24 -0
  111. package/dist/types/formats/monster.d.ts +48 -0
  112. package/dist/types/formats/palette.d.ts +15 -0
  113. package/dist/types/formats/recording.d.ts +7 -0
  114. package/dist/types/formats/sound.d.ts +13 -0
  115. package/dist/types/formats/voc.d.ts +13 -0
  116. package/dist/types/gfx/colorVision.d.ts +26 -0
  117. package/dist/types/gfx/cp437Glyphs.d.ts +2 -0
  118. package/dist/types/gfx/font8x8.d.ts +2 -0
  119. package/dist/types/gfx/screen.d.ts +50 -0
  120. package/dist/types/index.d.ts +4 -0
  121. package/dist/types/input/chords.d.ts +22 -0
  122. package/dist/types/input/deskMouse.d.ts +14 -0
  123. package/dist/types/input/keyboard.d.ts +39 -0
  124. package/dist/types/input/scancodes.d.ts +3 -0
  125. package/dist/types/player/fileExtensions.d.ts +44 -0
  126. package/dist/types/player/patchRules.d.ts +24 -0
  127. package/dist/types/player/patchTable.d.ts +83 -0
  128. package/dist/types/text/cp437.d.ts +6 -0
  129. package/package.json +339 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,42 @@
1
+ # Changelog
2
+
3
+ Changes to `@lewismoten/gamemaker-sandbox-engine`, released as `engine-v*` tags. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [3.3.0] - 2026-11-07
9
+
10
+ Slow-PC presets that play a game at the pace of a 486, 386, 286 or IBM PS/1, experimental gameplay patches, live
11
+ control of the sound mix and sound card, and a hook for life losses. Fixes cover scroll speed, JPEG and FLI decoding,
12
+ short CMF files, and a recorded Enter on key screens.
13
+
14
+ ### Added
15
+
16
+ - Slow-PC presets (`SPEED_PRESETS`: 486, 386, 286 and the IBM PS/1) with voice-read stalls, disk-read costs and music holds. They are estimates, and the default speed charges nothing.
17
+ - Experimental gameplay patches (`player/patchTable` group `play`, `World.tune`). With no patches, play is unchanged.
18
+ - Player life-loss events, so a caller can watch for them without counting recorded playback.
19
+ - Color-vision simulation (`gfx/colorVision`) and sparse FLI palette changes.
20
+
21
+ ### Changed
22
+
23
+ - The sound mix (music, voice, effects: on and volume) is followed live, and sound-card output changes without restarting audio or play.
24
+
25
+ ### Fixed
26
+
27
+ - Scroll speed wraps like DOS's 16-bit integers. Damaged FLI and CMF files give a clear error, and progressive JPEGs decode only complete data.
28
+
29
+ Full list: [changes/release/engine/3.3.0.md](https://github.com/lewismoten/GameMaker-SandboxEdition/blob/engine-v3.3.0/changes/release/engine/3.3.0.md)
30
+
31
+ ## [3.1.0] - 2026-10-29
32
+
33
+ The first release of the browser engine as an npm package: the TypeScript port of PLAYGAME with readers and writers
34
+ for every Game-Maker file format, OPL2 and CMF audio, screen, input and fonts.
35
+
36
+ ### Added
37
+
38
+ - The engine, scoped as `@lewismoten/gamemaker-sandbox-engine` and published to GitHub Packages from version tags.
39
+
40
+ [Unreleased]: https://github.com/lewismoten/GameMaker-SandboxEdition/compare/engine-v3.3.0...HEAD
41
+ [3.3.0]: https://github.com/lewismoten/GameMaker-SandboxEdition/compare/engine-v3.1.0...engine-v3.3.0
42
+ [3.1.0]: https://github.com/lewismoten/GameMaker-SandboxEdition/releases/tag/engine-v3.1.0
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 gandrewstone
4
+ Copyright (c) 2026 Lewis Moten (modifications: the web port, the 1994 desk, the
5
+ Sandbox Software and Bard of Bizarre games, and the Mac, Windows and Linux players;
6
+ see NOTICE.md)
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
package/NOTICE.md ADDED
@@ -0,0 +1,58 @@
1
+ # Notices for @lewismoten/gamemaker-sandbox-engine
2
+
3
+ This package contains the browser game engine and audio worklet from
4
+ [Game-Maker: Sandbox Edition](https://github.com/lewismoten/GameMaker-SandboxEdition).
5
+ It is licensed under the MIT License; see [LICENSE](LICENSE). It contains no games,
6
+ site editor, DOS executables, or native player shells.
7
+
8
+ ## Source and contributors
9
+
10
+ - **RSD Game-Maker** was created by G. Andrew (Andy) Stone, G. Oliver Stone,
11
+ Oliver Stone Jr., and Joan Stone for Recreational Software Designs. Andy Stone
12
+ released its source under the MIT License in 2014. The browser engine follows
13
+ that source and its game file formats, including the behavior of its CMF music
14
+ player. The original project is at
15
+ [gandrewstone/GameMaker](https://github.com/gandrewstone/GameMaker).
16
+ - **Game-Maker: Sandbox Edition** is Lewis Moten's fork. Its TypeScript web port
17
+ was written with Claude Opus 5.5 (Anthropic), directed and reviewed by Lewis.
18
+ This npm package was extracted and documented with OpenAI Codex (GPT-6) in
19
+ Visual Studio Code, directed by Lewis.
20
+
21
+ ## Data, formats, and hardware
22
+
23
+ - **8×8 text font:** `font8x8_basic`, `font8x8_ext_latin`, `font8x8_misc`, and
24
+ `font8x8_greek` by Daniel Hepper are public domain. They supply the ASCII and
25
+ selected code page 437 glyphs in `src/gfx/font8x8.ts` and `src/gfx/cp437Glyphs.ts`.
26
+ The upstream headers also credit Marcel Sondaar and International Business Machines
27
+ (public domain VGA fonts) as their basis. [Source](https://github.com/dhepper/font8x8).
28
+ The remaining CP437 symbols and box-drawing glyphs were drawn for this project with
29
+ Anthropic Claude Opus 5.5 under Lewis Moten's direction and are distributed under the
30
+ project's MIT License; they were not copied from IBM's ROM.
31
+ - **GIF:** Graphics Interchange Format is a format and trademark of CompuServe
32
+ Incorporated. The engine implements GIF decoding from the format description.
33
+ - **FLI:** Autodesk Animator's animation format, implemented from its public
34
+ documentation. Autodesk Animator is a product of Autodesk, Inc.
35
+ - **Sound Blaster formats:** CMF, VOC, and SBI are Creative Technology Ltd.
36
+ formats. The CMF player follows RSD Game-Maker's `SBMUSIC.C` and the behavior
37
+ of Creative's SBFMDRV driver. The VOC decoder's Creative ADPCM tables refer
38
+ to the Sound Blaster DSP behavior documented in
39
+ [DOSBox's `sblaster.cpp`](https://github.com/joncampbell123/dosbox-x/blob/master/src/hardware/sblaster.cpp)
40
+ (GPL-2.0-or-later).
41
+ - **OPL2 / YM3812:** Yamaha Corporation's FM synthesis chip. The engine's
42
+ emulation was written for this project from the chip's published register
43
+ documentation.
44
+
45
+ The package does not bundle DOSBox, Creative software, or Autodesk software.
46
+
47
+ ## Incremental JPEG decoding
48
+
49
+ The JPEG decoder follows ITU-T Recommendation T.81 (1992), by CCITT/ITU and the
50
+ Joint Photographic Experts Group: [specification](https://www.w3.org/Graphics/JPEG/itu-t81.pdf).
51
+ This is a format reference; the recommendation's text and diagrams are not bundled.
52
+ The existing AC-refinement procedure identifies libjpeg's `decode_mcu_AC_refine` as its
53
+ algorithm reference (Independent JPEG Group, Thomas G. Lane and contributors;
54
+ [IJG License](https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/README.ijg)).
55
+ This software is based in part on the work of the Independent JPEG Group.
56
+ No libjpeg C source or binaries are bundled. Incremental block visibility and atomic
57
+ MCU updates were corrected with OpenAI Codex (GPT-6), directed by Lewis Moten, under
58
+ this project's MIT License.
package/README.md CHANGED
@@ -1,3 +1,150 @@
1
- # Temporary Holding Version
1
+ # Game-Maker: Sandbox Edition browser engine
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ `@lewismoten/gamemaker-sandbox-engine` runs RSD Game-Maker games from their original DOS files in a browser. It is the same TypeScript engine used by the Game-Maker: Sandbox Edition web player. The package includes its audio worklet and TypeScript declarations; it does not include games or the site's editor and catalog.
4
+
5
+ Install from your configured npm registry:
6
+
7
+ ```sh
8
+ npm install @lewismoten/gamemaker-sandbox-engine
9
+ ```
10
+
11
+ If your registry requires authentication or a scope mapping, configure npm using that registry's instructions.
12
+
13
+ Pass the files from one game's DOS directory to `GameFiles`. Names are case insensitive and use DOS 8.3 names. `GameFiles.mainGame()` finds a `.GAM` file. Keep the original file names and bytes; the game refers to its other files by name.
14
+
15
+ ```ts
16
+ import { GameFiles, Machine, runGame } from '@lewismoten/gamemaker-sandbox-engine';
17
+
18
+ const input = document.querySelector<HTMLInputElement>('#files')!;
19
+ const canvas = document.querySelector<HTMLCanvasElement>('#screen')!;
20
+ const play = document.querySelector<HTMLButtonElement>('#play')!;
21
+ let files: GameFiles | undefined;
22
+
23
+ input.addEventListener('change', async () => {
24
+ const entries = await Promise.all(
25
+ Array.from(input.files ?? [], async (file): Promise<[string, Uint8Array]> => [
26
+ file.name,
27
+ new Uint8Array(await file.arrayBuffer()),
28
+ ]),
29
+ );
30
+ files = new GameFiles(entries);
31
+ play.disabled = !files.mainGame();
32
+ });
33
+
34
+ play.addEventListener('click', async () => {
35
+ if (!files) return;
36
+ const gam = files.mainGame();
37
+ if (!gam) throw new Error('Choose a game directory containing a .GAM file');
38
+
39
+ const machine = new Machine(canvas, files);
40
+ try {
41
+ await machine.audio.resume(); // the click is a user gesture
42
+ await runGame(machine, gam);
43
+ } finally {
44
+ machine.destroy();
45
+ }
46
+ });
47
+ ```
48
+
49
+ ```html
50
+ <input id="files" type="file" webkitdirectory multiple aria-label="Game directory" />
51
+ <button id="play" disabled>Play</button>
52
+ <canvas id="screen" tabindex="0" aria-label="Game screen"></canvas>
53
+ <style>
54
+ #screen { width: min(100%, 960px); aspect-ratio: 8 / 5; image-rendering: pixelated; }
55
+ </style>
56
+ ```
57
+
58
+ `Machine` owns the screen, keyboard and audio. Call `machine.destroy()` when play finishes or the containing page closes. `runGame` accepts `RunOptions` for callbacks, joystick input, playback and the optional DOS player appearance. The game may write saves or high scores into `GameFiles`; use `files.onChange` to persist those bytes. The package targets modern browsers and ES modules.
59
+
60
+ `machine.screen.dosCropped` is observer metadata for PLAYGAME’s CropScreen state: true during level rendering and its fades, false for function-key screens and after a level. `sceneNumber` identifies the last rendered level. These fields do not change rendering or game timing.
61
+
62
+ ## Read a game file in Node.js
63
+
64
+ The format modules need no browser. This reads a `.GAM` file from the original CD (run it from the repository root) and lists its scene titles:
65
+
66
+ ```ts
67
+ import { readFileSync } from 'node:fs';
68
+ import { parseGame } from '@lewismoten/gamemaker-sandbox-engine/formats/game';
69
+ import { fromCp437 } from '@lewismoten/gamemaker-sandbox-engine/text/cp437';
70
+
71
+ const game = parseGame(readFileSync('cd/gameware/peach/peach.gam'));
72
+ console.log(`${game.scenes.length} scenes: ${game.scenes.slice(2, 4).map((s) => fromCp437(s.desc)).join(' and ')}`);
73
+ // prints: 20 scenes: Grasslands 1 and Grasslands 2
74
+ ```
75
+
76
+ A test (`web/test/readmeExamples.test.ts`) runs this block in Node against the built package and compares what it prints with the `// prints:` line.
77
+
78
+ Parsed descriptions are DOS byte strings, not Unicode. For a game name outside DOS use
79
+ `gameTitle(game)` from `formats/game`: it decodes CP437 and trims decorative menu frames.
80
+ For other DOS labels use `fromCp437`; for DOS text-file bytes use `cp437Text` from `text/cp437`,
81
+ which retains ASCII controls so the caller can handle line endings and DOS EOF. Neither API
82
+ is for already decoded Unicode, JSON, HTML or UTF-8 text. Keep the parsed fields and original
83
+ bytes for DOS rendering and round trips; convert only at the presentation boundary.
84
+
85
+ ## Native player screens
86
+
87
+ The package includes the complete DOS player front end. The example above shows
88
+ its title images or animation and menu before play. The menu offers instructions,
89
+ storyline, credits, top scores and quitting; during play the native function keys
90
+ open help, inventory, load and save screens. Include the files named by the game's
91
+ `.GAM` file, along with any saved games or high scores you want to keep.
92
+
93
+ `runGame` uses these screens by default. For a direct play test, pass
94
+ `{ skipTitle: true }` to start a new game at its initial scene link; its normal
95
+ ending screens and menu still follow when play ends. `RunOptions.player` accepts
96
+ DOS player customizations for words, colors, frames, positions, timing and function
97
+ keys. `gmHelp` optionally supplies Game-Maker's own help text before the game's
98
+ instructions. See the exported `RunOptions` type for these settings and callbacks.
99
+
100
+ Observe actual life loss with `onLifeLost`, including the last life, or the final
101
+ result and score with `onPlayEnd`. Recorded demo playback does not emit either
102
+ callback. Persist `GameFiles.onChange` to retain save files and high scores between
103
+ visits.
104
+
105
+ The source is MIT licensed; see `LICENSE` and `NOTICE.md` for credits.
106
+
107
+ Hosts can call `machine.audio.setSoundCard(enabled)` to change the optional sound-card
108
+ output during play. Removing it pauses FM and cuts digital effects without stopping the
109
+ PC speaker. Restoring it resumes the loaded song, or starts the latest song requested
110
+ while absent. `soundCardEnabled` reports the current card state; returning the card
111
+ preserves a disabled music preference. An explicit song stop remains stopped. Normal DOS-compatible startup
112
+ behavior is unchanged unless the host opts into live card control.
113
+ Set the audio card state before `runGame` and call the same method for later switches;
114
+ effects then use the PC speaker while the card is absent. `RunOptions.noSoundCard` retains
115
+ the original startup-only detection, including its fixed speaker-only choice for that run.
116
+
117
+ ## Incremental picture decoding
118
+
119
+ `formats/jpeg` exports `decodePartialJpeg(bytes)` for baseline and progressive Huffman JPEGs.
120
+ Pass only the bytes received so far. `shown` marks pixels with completed luminance/DC blocks;
121
+ `pixels` holds grayscale or RGB data. A partial first progressive scan reveals only its
122
+ completed blocks; later scans retain the previous coefficients until each MCU is complete.
123
+ Restart markers preserve already decoded MCUs. `scans` counts fully delimited scans and
124
+ `complete` reports an end-of-image marker. The decoder does not invent data for unread blocks.
125
+
126
+ `RunOptions.onLifeLost` observes each player death, including the final life.
127
+ `onPlayEnd(score, how, gained)` reports `won`, `lost`, or `quit` once a play ends.
128
+ Neither callback runs during demo or walkthrough playback. These callbacks do not
129
+ change DOS gameplay or the game files.
130
+
131
+ `Machine.onItem` is an observer hook: `showGraphic` calls it as each picture, cartoon, text page or slide list begins (the walkthrough player's item marks). It never changes timing or behavior.
132
+
133
+ ## Subpath exports
134
+
135
+ Everything is also importable from its own subpath, for example `import { parseBlocks } from '@lewismoten/gamemaker-sandbox-engine/formats/blocks'`, so a Node script or a bundler can take one module without the player:
136
+
137
+ - `formats/*`: readers and writers for the DOS files: `blocks`, `character`, `cmf`, `cmfEdit`, `cmfPreview`, `cmfSong`, `fli`, `fliFrames`, `fliLimits`, `game`, `gif`, `gifProgressive`, `graphicScripts`, `highscore`, `jpeg`, `map`, `monster`, `palette`, `recording`, `sound`, `voc`, and `binary` (byte helpers).
138
+ - `engine/*`: the PLAYGAME port: `machine`, `game`, `world`, `scene`, `scroll`, `render`, `showGraphic`, `menus`, `monsters`, `character`, `keys`, `funcKeys`, `touch`, `recorder`, `playGain`, `playerLook`, `slowPc`.
139
+ - `audio/*`: OPL2 and CMF playback: `opl`, `cmfPlayer`, `cmfLoad`, `engine`, `mix`, `output`, `context`.
140
+ - `gfx/*`: `screen`, `font8x8`, `cp437Glyphs`, `colorVision` (color-vision simulation matrices); `text/cp437`.
141
+ - `input/*`: `keyboard`, `scancodes`, `chords`, `deskMouse`.
142
+ - `core/gameFiles` (`GameFiles`) and `player/*` (`fileExtensions`, `patchRules`, `patchTable`).
143
+
144
+ ## Supported environments
145
+
146
+ Playback needs a browser with canvas, Web Audio and keyboard events (the `Machine` class owns them). The file-format, decoding and simulation modules have no DOM dependency and also run in Node.js 22.12 or later, which is the version the package declares in `engines`. It ships as ES modules with TypeScript declarations.
147
+
148
+ ## Developing
149
+
150
+ This package's source lives in [the project's repository](https://github.com/lewismoten/GameMaker-SandboxEdition), in `web/packages/engine`. The folder holds all its source in `src/`, plus its build configuration, license and notices. It can be copied outside the repository: run `npm install` and `npm run verify` there to build and test a packed consumer. Inside the repository, run `npm ci` at the root, then `npm run build -w @lewismoten/gamemaker-sandbox-engine`. Run `npm pack` in the package folder to inspect a local distribution. Tarballs are build artifacts and should not be committed. The [monorepo guide](https://github.com/lewismoten/GameMaker-SandboxEdition/blob/master/docs/monorepo.md) covers the workspace layout, and the [package release guide](https://github.com/lewismoten/GameMaker-SandboxEdition/blob/master/docs/package-releases.md) covers publishing.