@wasm-gaming/rsdkv4-wasm 0.1.4 → 0.1.5
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/README.md +188 -35
- package/dist/manifest.json +24 -5
- package/dist/rsdkv4/rsdkv4.manifest.d.ts.map +1 -1
- package/dist/rsdkv4/rsdkv4.manifest.js +14 -2
- package/dist/rsdkv4/rsdkv4.manifest.js.map +1 -1
- package/dist/rsdkv4/rsdkv4.options.d.ts +12 -0
- package/dist/rsdkv4/rsdkv4.options.d.ts.map +1 -1
- package/dist/rsdkv4/rsdkv4.options.js +33 -6
- package/dist/rsdkv4/rsdkv4.options.js.map +1 -1
- package/dist/rsdkv4/rsdkv4.sdk.d.ts +60 -1
- package/dist/rsdkv4/rsdkv4.sdk.d.ts.map +1 -1
- package/dist/rsdkv4/rsdkv4.sdk.js +359 -32
- package/dist/rsdkv4/rsdkv4.sdk.js.map +1 -1
- package/package.json +3 -3
- package/src/rsdkv4.manifest.ts +15 -2
- package/src/rsdkv4.options.ts +41 -6
- package/src/rsdkv4.sdk.ts +466 -32
- package/dist/rsdkv4/rsdkv4.js +0 -9268
- package/dist/rsdkv4/rsdkv4.wasm +0 -0
package/README.md
CHANGED
|
@@ -54,16 +54,77 @@ The launcher decides how Escape behaves and draws its own overlay. It should
|
|
|
54
54
|
intercept Escape in the **capture phase** if it wants to repurpose it (the engine
|
|
55
55
|
ships with `DevMenu=false`, so the native in-canvas menu stays suppressed).
|
|
56
56
|
|
|
57
|
+
> ⚠️ A capture-phase listener on `window` that calls `stopPropagation()` also
|
|
58
|
+
> stops the **bubble**-phase listener SDL registers there — i.e. it takes the
|
|
59
|
+
> keyboard away from the game. Swallow only the keys you actually handle, and
|
|
60
|
+
> only while your overlay is open. (This is exactly how the shared demo
|
|
61
|
+
> template's pause menu used to kill the d-pad; see
|
|
62
|
+
> [src/demo/components/esc-menu.html](src/demo/components/esc-menu.html).)
|
|
63
|
+
|
|
64
|
+
### Start menu — the host can own that too
|
|
65
|
+
`instance.game` exposes RSDKv4's Start Menu as data (the `web_*` embind functions
|
|
66
|
+
in `WebGame.cpp`), so a host can draw its own save / character / options screens
|
|
67
|
+
instead of the engine's in-canvas text menus. The logic mirrors
|
|
68
|
+
`Debug.cpp` move for move — same globals, same `saveRAM`, same
|
|
69
|
+
`InitStartingStage()` — so a game started this way lands in the state the native
|
|
70
|
+
menu would have produced.
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
const engine = await load({ canvas, assets: { data },
|
|
74
|
+
options: { skipStartMenu: true }, // hide the engine's own screens
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
engine.game.type(); // 1 = Sonic 1, 2 = Sonic 2
|
|
78
|
+
engine.game.players(); // ["SONIC", "TAILS", "KNUCKLES", "SONIC AND TAILS"]
|
|
79
|
+
engine.game.saveSlots(); // [{ slot, empty, character, lives, score, emeralds, list, zone }]
|
|
80
|
+
engine.game.start(0, 1); // slot 0 as Tails — a slot with data resumes it
|
|
81
|
+
engine.game.start(null, 0); // no-save mode
|
|
82
|
+
engine.game.deleteSave(2);
|
|
83
|
+
|
|
84
|
+
engine.game.options(); // the engine's GAME OPTIONS screen, as data
|
|
85
|
+
engine.game.setOption('spindash', 1); // written through to the game's save file
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`load()` resolves only once `Engine::Init` has run, so all of the above is safe to
|
|
89
|
+
call the moment it returns. The demo's [start-screens.ts](src/demo/start-screens.ts)
|
|
90
|
+
is a worked example.
|
|
91
|
+
|
|
92
|
+
### Pausing has an owner
|
|
93
|
+
`pause(owner?)` / `resume(owner?)` — the **first** caller to pause owns it, and only
|
|
94
|
+
that owner's `resume()` lifts it. A pause overlay therefore can't resume a game a
|
|
95
|
+
start screen (or the host) had already frozen:
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
engine.pause('menu'); // overlay opens
|
|
99
|
+
engine.resume('menu'); // …closes: only resumes if 'menu' was the one that paused
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Pausing stops the **audio** too: `masterPaused` only freezes the logic loop, so
|
|
103
|
+
without that the music kept playing over the overlay — and `destroy()` kept
|
|
104
|
+
playing it after the host returned to its launcher.
|
|
105
|
+
|
|
57
106
|
### Options
|
|
58
107
|
Engine-specific options are described in [src/rsdkv4.options.ts](src/rsdkv4.options.ts)
|
|
59
108
|
(`Rsdkv4Options` type + `RSDKV4_OPTIONS_SCHEMA`, mirrored into
|
|
60
109
|
[src/rsdkv4.manifest.ts](src/rsdkv4.manifest.ts)'s `options`). When the host doesn't pass an explicit
|
|
61
110
|
`settings` asset, the SDK **generates `settings.ini` from `config.options`**
|
|
62
|
-
(`devMenu`, `engineDebugMode`, `vsync`, `
|
|
111
|
+
(`devMenu`, `engineDebugMode`, `vsync`, `skipStartMenu`,
|
|
112
|
+
`startingCategory/Scene/Player`).
|
|
113
|
+
|
|
114
|
+
> `startingCategory/Scene/Player` default to **255 = unset**, which is what the
|
|
115
|
+
> engine reads as "boot normally". Any other value — *including 0* — makes
|
|
116
|
+
> `Engine::Init` skip the start-menu flow and force that stage.
|
|
63
117
|
|
|
64
118
|
### Other niceties
|
|
65
119
|
- **Canvas id guard** — forces `canvas.id = "canvas"` because Emscripten's SDL2
|
|
66
120
|
port locates the canvas via `querySelector('#canvas')`.
|
|
121
|
+
- **Stale-engine self-heal** — `rsdkv4.js`/`.wasm` are big and most static hosts
|
|
122
|
+
send nothing but `Last-Modified`, so browsers keep a build for hours. Fresh SDK
|
|
123
|
+
against a cached engine is a miserable failure mode: the bridges it calls
|
|
124
|
+
aren't there and every getter quietly answers "empty" — no save slots, no
|
|
125
|
+
characters, an empty pause menu. So `load()` checks the module for the bridges
|
|
126
|
+
it needs and, if any are missing, refetches once with a cache-busting query and
|
|
127
|
+
says so in the console. A healthy build loads the engine exactly once.
|
|
67
128
|
|
|
68
129
|
> Audio autoplay-unlock and the gamepad→keyboard translator are cross-cutting host
|
|
69
130
|
> concerns (the app's shared input script); the SDK only exposes the `input`
|
|
@@ -73,14 +134,19 @@ Engine-specific options are described in [src/rsdkv4.options.ts](src/rsdkv4.opti
|
|
|
73
134
|
|
|
74
135
|
Built with **`-sWASMFS`** — Emscripten's modern filesystem, replacing MEMFS. The
|
|
75
136
|
game working dir `/data` is mounted on **OPFS** (persistent) via the `WebFS.cpp`
|
|
76
|
-
`web_mount_opfs` helper when the page is **cross-origin isolated
|
|
77
|
-
|
|
137
|
+
`web_mount_opfs` helper when the page is **cross-origin isolated** *and* the wasm
|
|
138
|
+
build can create the OPFS backend from the main thread (see the caveat below —
|
|
139
|
+
today's build can't); otherwise it falls back to the WASMFS in-memory backend so
|
|
140
|
+
the engine still boots. `Data.rsdk`
|
|
78
141
|
and the generated `settings.ini` are written there and read via CWD (the engine
|
|
79
142
|
is booted with the `UsingCWD` arg).
|
|
80
143
|
|
|
81
144
|
### Backend selection — `config.persist`
|
|
82
|
-
- `undefined` (default) — **auto**: OPFS when cross-origin isolated
|
|
83
|
-
|
|
145
|
+
- `undefined` (default) — **auto**: OPFS when cross-origin isolated *and* the build
|
|
146
|
+
supports the mount, else in-memory.
|
|
147
|
+
- `'opfs'` — **ask for** OPFS; warn + fall back to in-memory if unavailable. (It
|
|
148
|
+
can't be *forced*: a build that can't mount OPFS would abort the module, so the
|
|
149
|
+
SDK checks first and falls back rather than trying.)
|
|
84
150
|
- `null` — **force the in-memory** WASMFS backend (the MEMFS-equivalent fallback;
|
|
85
151
|
non-persistent).
|
|
86
152
|
|
|
@@ -95,6 +161,32 @@ is booted with the `UsingCWD` arg).
|
|
|
95
161
|
This prevents cross-game reuse collisions and allows purging one game's files
|
|
96
162
|
without touching the others.
|
|
97
163
|
|
|
164
|
+
### `/data` *is* the OPFS root
|
|
165
|
+
`web_mount_opfs` mounts the backend returned by `wasmfs_create_opfs_backend()`,
|
|
166
|
+
whose root is `navigator.storage.getDirectory()`. So the WASM path `/data/<ns>/…`
|
|
167
|
+
and the OPFS path `<ns>/…` a host reaches from JS are **the same file**:
|
|
168
|
+
|
|
169
|
+
| host, from JS (OPFS API) | engine, inside WASMFS |
|
|
170
|
+
| ---------------------------- | ----------------------------- |
|
|
171
|
+
| `rsdkv4/Sonic1/Data.rsdk` | `/data/rsdkv4/Sonic1/Data.rsdk` |
|
|
172
|
+
|
|
173
|
+
A launcher can therefore write a player's `Data.rsdk` straight into the folder the
|
|
174
|
+
engine will use as its working dir and then load with
|
|
175
|
+
`storageNamespace: 'rsdkv4/Sonic1'` and **no `assets.data` at all** — the SDK finds
|
|
176
|
+
the file already persisted and skips the copy. That is what this repo's demo does
|
|
177
|
+
(see [Try it locally](#try-it-locally)); it keeps one copy of a ~40 MB pack instead
|
|
178
|
+
of two, and the game's save data lands next to it in the same folder.
|
|
179
|
+
|
|
180
|
+
### Save data survives even without the mount
|
|
181
|
+
The engine writes its save file (`SData.bin`) into the working dir, which is
|
|
182
|
+
in-memory on every build that can't mount OPFS — so game saves would die with the
|
|
183
|
+
page and every slot would read "NEW GAME" forever. The *host* side of OPFS has no
|
|
184
|
+
such limitation (the plain async API works on any main thread), so the SDK
|
|
185
|
+
mirrors that one file itself: it copies any stored `SData.bin` into the working
|
|
186
|
+
dir before the engine boots, and copies it back out on pause, on `destroy()`, and
|
|
187
|
+
every 10s in between. Saves therefore persist per `storageNamespace` even while
|
|
188
|
+
the working dir does not. `persist: null` turns the mirror off with everything else.
|
|
189
|
+
|
|
98
190
|
### Skip re-fetch when already persisted
|
|
99
191
|
When the working dir is OPFS-backed, the SDK checks whether `/data/Data.rsdk`
|
|
100
192
|
(and `settings.ini`) already exist and **reuses them instead of re-downloading**.
|
|
@@ -126,15 +218,20 @@ const purged = sonic2.purgeStorage();
|
|
|
126
218
|
console.log(purged); // { data: true|false, settings: true|false }
|
|
127
219
|
```
|
|
128
220
|
|
|
129
|
-
> Persistence
|
|
130
|
-
>
|
|
131
|
-
|
|
132
|
-
> ⚠️ **OPFS caveat
|
|
133
|
-
>
|
|
134
|
-
>
|
|
135
|
-
>
|
|
136
|
-
>
|
|
137
|
-
>
|
|
221
|
+
> Persistence doesn't engage with the current build (see the OPFS caveat below),
|
|
222
|
+
> so the skip-fetch benefit isn't real yet — every load fetches.
|
|
223
|
+
|
|
224
|
+
> ⚠️ **OPFS caveat:** OPFS sync-access handles only exist in Workers, so WASMFS's
|
|
225
|
+
> OPFS backend spawns a proxy worker — and it **refuses to do that from the main
|
|
226
|
+
> browser thread** unless the build has **`-sASYNCIFY`** or **`-sJSPI`**. It
|
|
227
|
+
> doesn't fail softly either: `wasmfs_create_opfs_backend()` asserts, and the
|
|
228
|
+
> failed assert `abort()`s the module, so there is nothing left to fall back with.
|
|
229
|
+
> The SDK mounts by calling into the module from the page (main thread) and this
|
|
230
|
+
> build has neither flag, so `web_opfs_supported()` (WebFS.cpp) reports 0 and the
|
|
231
|
+
> SDK never attempts the mount — COOP/COEP alone changes nothing. Making it real
|
|
232
|
+
> means either building with Asyncify/JSPI, or `-pthread` + performing the mount
|
|
233
|
+
> from the engine thread; both interact with SDL2 + `emscripten_set_main_loop` and
|
|
234
|
+
> must be validated with a real build.
|
|
138
235
|
|
|
139
236
|
## Build
|
|
140
237
|
|
|
@@ -149,7 +246,9 @@ make build-wasm # local: runs scripts/build.sh inside emscripten/emsdk (Docker
|
|
|
149
246
|
|
|
150
247
|
- `build-lib` compiles the SDK/options/manifest (`.js` + `.d.ts`) → `dist/rsdkv4/`.
|
|
151
248
|
- `build-manifest` serializes the typed manifest to `dist/manifest.json`.
|
|
152
|
-
- `build-demo` compiles `src/demo/demo.ts` → `dist
|
|
249
|
+
- `build-demo` compiles `src/demo/{demo,library}.ts` → `dist/`, copies the shared
|
|
250
|
+
demo template from `@wasm-gaming/engine-specs` → `dist/demo/`, overwrites its
|
|
251
|
+
launcher with `src/demo/components/launcher.html` (the two-game one), copies
|
|
153
252
|
`src/demo/index.html` → `dist/index.html`, seeds `dist/settings.ini`.
|
|
154
253
|
- **`scripts/build.sh`** does not call Docker — it runs the WASM build steps
|
|
155
254
|
directly and expects an Emscripten SDK on PATH. In CI it runs inside an
|
|
@@ -176,40 +275,94 @@ dist/
|
|
|
176
275
|
│ └── rsdkv4.manifest.js(+ .d.ts)
|
|
177
276
|
├── manifest.json # declarative manifest (artifacts → rsdkv4/rsdkv4.*)
|
|
178
277
|
├── index.html # demo shell (import map → ./rsdkv4/rsdkv4.sdk.js)
|
|
179
|
-
├── demo.js
|
|
278
|
+
├── demo.js # window.SDK + window.rsdkv4Library
|
|
279
|
+
├── library.js # the two-game OPFS library (src/demo/library.ts)
|
|
280
|
+
├── start-screens.js # save-select screen (src/demo/start-screens.ts)
|
|
281
|
+
├── assets/ # demo artwork (game logos), from src/demo/assets/
|
|
282
|
+
├── demo/ # shared template (engine-specs); launcher.html and
|
|
283
|
+
│ # esc-menu.html replaced by our own copies
|
|
180
284
|
├── settings.ini # seeded from src/settings.default.ini if absent
|
|
181
|
-
└── Data.rsdk #
|
|
285
|
+
└── Data.rsdk # unused by the demo; kept for manual experiments
|
|
182
286
|
```
|
|
183
287
|
|
|
184
288
|
## Try it locally
|
|
185
289
|
|
|
186
290
|
```bash
|
|
187
|
-
make build
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
291
|
+
make build # produce dist/ (TypeScript + WASM)
|
|
292
|
+
make preview # serves dist/ on :8024 with COOP/COEP
|
|
293
|
+
# open http://localhost:8024/
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### The launcher is a two-game library
|
|
297
|
+
|
|
298
|
+
One WASM, two games — so the demo launcher is not a ROM picker but a shelf with
|
|
299
|
+
one slot per game. Drop **Sonic 1's** `Data.rsdk` on one slot and **Sonic 2's** on
|
|
300
|
+
the other (drag-and-drop or the file picker), pick a slot, press **Play**. Each
|
|
301
|
+
pack is stored once, in the browser, and never uploaded:
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
OPFS root
|
|
305
|
+
└── rsdkv4/
|
|
306
|
+
├── Sonic1/
|
|
307
|
+
│ ├── Data.rsdk ← what you dropped
|
|
308
|
+
│ ├── settings.ini ← written by the SDK on first launch
|
|
309
|
+
│ └── … ← that game's save data
|
|
310
|
+
└── Sonic2/…
|
|
192
311
|
```
|
|
193
312
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
313
|
+
Because [`/data` is the OPFS root](#data-is-the-opfs-root), that folder *is* the
|
|
314
|
+
engine's working dir: launching loads with `storageNamespace: 'rsdkv4/Sonic1'` and
|
|
315
|
+
no assets, so nothing is copied or re-read. **Replace** swaps the pack; **Remove**
|
|
316
|
+
deletes only `Data.rsdk`, leaving settings and saves for when it comes back.
|
|
317
|
+
|
|
318
|
+
A page that isn't cross-origin isolated can't reach OPFS from WASM (see the caveat
|
|
319
|
+
above), so the SDK falls back to an in-memory working dir and pulls the bytes
|
|
320
|
+
through `dataProvider()` — the library serves them from the same stored copy, so
|
|
321
|
+
the games still launch. Saves still survive, through the
|
|
322
|
+
[save-data mirror](#save-data-survives-even-without-the-mount).
|
|
323
|
+
|
|
324
|
+
### The game's own menus, in HTML
|
|
325
|
+
|
|
326
|
+
Launching goes straight to a **save-select screen** — the demo's, not the engine's
|
|
327
|
+
(it boots with `skipStartMenu: true`). It is laid out like Sonic Mania's: a row of
|
|
328
|
+
portrait cards, status on top, character in the middle, chaos emeralds along the
|
|
329
|
+
bottom, `NO SAVE` first. File and character are the *same* choice: **←/→ picks the
|
|
330
|
+
file, ↑/↓ picks the player** (Sonic, Tails, Knuckles, Sonic & Tails) on any unused
|
|
331
|
+
file, Enter starts. A used file starts as the character it was saved with. Everything but the game logo
|
|
332
|
+
(`src/demo/assets/`) is drawn in CSS, and it drives the engine through
|
|
333
|
+
`instance.game`, so the resulting game is the same one the native text menus
|
|
334
|
+
would have started.
|
|
335
|
+
|
|
336
|
+
**Escape** opens the pause overlay, which pauses the engine *and its music* and
|
|
337
|
+
shows only what RSDKv4 can actually do live:
|
|
338
|
+
|
|
339
|
+
- **Jump to** — buttons for the title screen, the game's stage menu, level select
|
|
340
|
+
and special stages 1-8. Each closes the overlay and warps straight away, so
|
|
341
|
+
there is no "now press resume" step
|
|
342
|
+
- **Game options** — the engine's own GAME OPTIONS (spindash, speed caps, S1
|
|
343
|
+
spikes, item box set, super forms), read and written through the same globals
|
|
344
|
+
and save file the native screen uses
|
|
345
|
+
|
|
346
|
+
The pieces: [src/demo/library.ts](src/demo/library.ts) (storage),
|
|
347
|
+
[src/demo/start-screens.ts](src/demo/start-screens.ts) (save select),
|
|
348
|
+
[src/demo/components/launcher.html](src/demo/components/launcher.html) (the slots),
|
|
349
|
+
[src/demo/components/esc-menu.html](src/demo/components/esc-menu.html) (pause overlay),
|
|
350
|
+
[src/demo/index.html](src/demo/index.html) (wiring to `SDK.load`).
|
|
198
351
|
|
|
199
352
|
## Live demo (GitHub Pages)
|
|
200
353
|
|
|
201
354
|
The `pages` job in [.github/workflows/build.yml](.github/workflows/build.yml)
|
|
202
|
-
publishes `dist/` to GitHub Pages on pushes to `main` (and manual runs).
|
|
203
|
-
|
|
204
|
-
|
|
355
|
+
publishes `dist/` to GitHub Pages on pushes to `main` (and manual runs). No game
|
|
356
|
+
data ships with it, so the live demo opens on two empty slots — drop each game's
|
|
357
|
+
`Data.rsdk` once and they stay in that browser.
|
|
205
358
|
|
|
206
359
|
- **One-time setup:** repo *Settings → Pages → Build and deployment → Source =
|
|
207
360
|
GitHub Actions*. The workflow also calls `actions/configure-pages` with
|
|
208
361
|
`enablement: true`, so first deploy can bootstrap Pages automatically when the
|
|
209
362
|
repo-level Pages site does not exist yet.
|
|
210
|
-
- **OPFS note:**
|
|
211
|
-
|
|
212
|
-
|
|
363
|
+
- **OPFS note:** OPFS stays off and the SDK uses the in-memory WASMFS backend —
|
|
364
|
+
GitHub Pages can't set COOP/COEP headers, and this build couldn't mount OPFS
|
|
365
|
+
even isolated (see the filesystem caveat above).
|
|
213
366
|
|
|
214
367
|
## Status
|
|
215
368
|
|
|
@@ -219,9 +372,9 @@ prompt — drop a `Data.rsdk` to boot.
|
|
|
219
372
|
the `web_devmenu_*` embind bridge, `callMain`/`FS`/`ccall`, no `--preload-file`).
|
|
220
373
|
- ⏳ **End-to-end runtime in a browser** (boot from a real `Data.rsdk`) — not yet
|
|
221
374
|
verified.
|
|
222
|
-
- ⏳ **OPFS persistence** —
|
|
223
|
-
|
|
224
|
-
|
|
375
|
+
- ⏳ **OPFS persistence** — not engaged: WASMFS's OPFS backend can't be created on
|
|
376
|
+
the main browser thread without an Asyncify/JSPI build (see the caveat above),
|
|
377
|
+
so the SDK detects that and falls back to the in-memory WASMFS backend.
|
|
225
378
|
|
|
226
379
|
## License
|
|
227
380
|
|
package/dist/manifest.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "rsdkv4",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"name": "Retro Software Development Kit v4",
|
|
5
|
+
"description": "RSDKv4 compiled to WebAssembly via Emscripten. One game-agnostic WASM binary runs both Sonic 1 and Sonic 2 — the difference is only which Data.rsdk the host supplies at runtime. Ships none of the game: the player provides their own Data.rsdk, and it never leaves their browser.",
|
|
5
6
|
"artifacts": {
|
|
6
7
|
"wasm": "rsdkv4/rsdkv4.wasm",
|
|
7
8
|
"js": "rsdkv4/rsdkv4.js"
|
|
@@ -26,7 +27,17 @@
|
|
|
26
27
|
"description": "Engine settings. Omitted → the SDK generates one from config.options."
|
|
27
28
|
}
|
|
28
29
|
],
|
|
29
|
-
"input":
|
|
30
|
+
"input": {
|
|
31
|
+
"up": "ArrowUp",
|
|
32
|
+
"down": "ArrowDown",
|
|
33
|
+
"left": "ArrowLeft",
|
|
34
|
+
"right": "ArrowRight",
|
|
35
|
+
"a": "KeyZ",
|
|
36
|
+
"b": "KeyX",
|
|
37
|
+
"c": "KeyC",
|
|
38
|
+
"start": "Enter",
|
|
39
|
+
"select": "ShiftLeft"
|
|
40
|
+
},
|
|
30
41
|
"video": {
|
|
31
42
|
"baseWidth": 424,
|
|
32
43
|
"baseHeight": 240,
|
|
@@ -50,20 +61,28 @@
|
|
|
50
61
|
"type": "boolean",
|
|
51
62
|
"default": true
|
|
52
63
|
},
|
|
64
|
+
"skipStartMenu": {
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"default": false,
|
|
67
|
+
"description": "Skip the engine's own save/character/options screens — set it when the host renders them from instance.game."
|
|
68
|
+
},
|
|
53
69
|
"startingCategory": {
|
|
54
70
|
"type": "integer",
|
|
55
71
|
"minimum": 0,
|
|
56
|
-
"default":
|
|
72
|
+
"default": 255,
|
|
73
|
+
"description": "0-based stage-list category; 255 = unset (normal boot flow)."
|
|
57
74
|
},
|
|
58
75
|
"startingScene": {
|
|
59
76
|
"type": "integer",
|
|
60
77
|
"minimum": 0,
|
|
61
|
-
"default":
|
|
78
|
+
"default": 255,
|
|
79
|
+
"description": "0-based scene in the category; 255 = unset (normal boot flow)."
|
|
62
80
|
},
|
|
63
81
|
"startingPlayer": {
|
|
64
82
|
"type": "integer",
|
|
65
83
|
"minimum": 0,
|
|
66
|
-
"default":
|
|
84
|
+
"default": 255,
|
|
85
|
+
"description": "Player/character index; 255 = unset (normal boot flow)."
|
|
67
86
|
}
|
|
68
87
|
}
|
|
69
88
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsdkv4.manifest.d.ts","sourceRoot":"","sources":["../../src/rsdkv4.manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"rsdkv4.manifest.d.ts","sourceRoot":"","sources":["../../src/rsdkv4.manifest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,eAAO,MAAM,QAAQ,EAAE,cA+CtB,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
import { RSDKV4_OPTIONS_SCHEMA } from './rsdkv4.options.js';
|
|
5
5
|
export const manifest = {
|
|
6
6
|
id: 'rsdkv4',
|
|
7
|
-
version: '0.1.
|
|
7
|
+
version: '0.1.5',
|
|
8
8
|
name: 'Retro Software Development Kit v4',
|
|
9
|
+
description: 'RSDKv4 compiled to WebAssembly via Emscripten. One game-agnostic WASM binary runs both Sonic 1 and Sonic 2 — the difference is only which Data.rsdk the host supplies at runtime. Ships none of the game: the player provides their own Data.rsdk, and it never leaves their browser.',
|
|
9
10
|
artifacts: {
|
|
10
11
|
// Relative to the manifest (dist/manifest.json); the engine files live in
|
|
11
12
|
// the dist/rsdkv4/ subfolder.
|
|
@@ -30,7 +31,18 @@ export const manifest = {
|
|
|
30
31
|
description: 'Engine settings. Omitted → the SDK generates one from config.options.',
|
|
31
32
|
},
|
|
32
33
|
],
|
|
33
|
-
|
|
34
|
+
// RSDKv4 keyboard defaults. The key names are KeyboardEvent.code values.
|
|
35
|
+
input: {
|
|
36
|
+
up: 'ArrowUp',
|
|
37
|
+
down: 'ArrowDown',
|
|
38
|
+
left: 'ArrowLeft',
|
|
39
|
+
right: 'ArrowRight',
|
|
40
|
+
a: 'KeyZ',
|
|
41
|
+
b: 'KeyX',
|
|
42
|
+
c: 'KeyC',
|
|
43
|
+
start: 'Enter',
|
|
44
|
+
select: 'ShiftLeft',
|
|
45
|
+
},
|
|
34
46
|
video: { baseWidth: 424, baseHeight: 240, aspect: '16:9' },
|
|
35
47
|
options: RSDKV4_OPTIONS_SCHEMA,
|
|
36
48
|
capabilities: { saveStates: false, sram: false, coreSelectable: false },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsdkv4.manifest.js","sourceRoot":"","sources":["../../src/rsdkv4.manifest.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,8EAA8E;AAC9E,iFAAiF;AAGjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,CAAC,MAAM,QAAQ,GAAmB;IACtC,EAAE,EAAE,QAAQ;IACZ,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE,mCAAmC;IACzC,SAAS,EAAE;QACT,0EAA0E;QAC1E,8BAA8B;QAC9B,IAAI,EAAE,oBAAoB;QAC1B,EAAE,EAAE,kBAAkB;KACvB;IACD,MAAM,EAAE;QACN;YACE,GAAG,EAAE,MAAM;YACX,4EAA4E;YAC5E,0CAA0C;YAC1C,SAAS,EAAE,iBAAiB;YAC5B,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,CAAC,OAAO,CAAC;YACjB,WAAW,EACT,iFAAiF;SACpF;QACD;YACE,GAAG,EAAE,UAAU;YACf,SAAS,EAAE,oBAAoB;YAC/B,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,CAAC,MAAM,CAAC;YAChB,WAAW,EACT,uEAAuE;SAC1E;KACF;IACD,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"rsdkv4.manifest.js","sourceRoot":"","sources":["../../src/rsdkv4.manifest.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,8EAA8E;AAC9E,iFAAiF;AAGjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,CAAC,MAAM,QAAQ,GAAmB;IACtC,EAAE,EAAE,QAAQ;IACZ,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE,mCAAmC;IACzC,WAAW,EACT,uRAAuR;IACzR,SAAS,EAAE;QACT,0EAA0E;QAC1E,8BAA8B;QAC9B,IAAI,EAAE,oBAAoB;QAC1B,EAAE,EAAE,kBAAkB;KACvB;IACD,MAAM,EAAE;QACN;YACE,GAAG,EAAE,MAAM;YACX,4EAA4E;YAC5E,0CAA0C;YAC1C,SAAS,EAAE,iBAAiB;YAC5B,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,CAAC,OAAO,CAAC;YACjB,WAAW,EACT,iFAAiF;SACpF;QACD;YACE,GAAG,EAAE,UAAU;YACf,SAAS,EAAE,oBAAoB;YAC/B,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,CAAC,MAAM,CAAC;YAChB,WAAW,EACT,uEAAuE;SAC1E;KACF;IACD,yEAAyE;IACzE,KAAK,EAAE;QACL,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,YAAY;QACnB,CAAC,EAAE,MAAM;QACT,CAAC,EAAE,MAAM;QACT,CAAC,EAAE,MAAM;QACT,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,WAAW;KACpB;IACD,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE;IAC1D,OAAO,EAAE,qBAAqB;IAC9B,YAAY,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE;CACxE,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -10,6 +10,12 @@ export interface Rsdkv4Options {
|
|
|
10
10
|
engineDebugMode?: boolean;
|
|
11
11
|
/** VSync the engine's SDL window. */
|
|
12
12
|
vsync?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Skip RSDKv4's in-canvas Start Menu (save select / character select / game
|
|
15
|
+
* options). Set this when the host draws those screens itself from
|
|
16
|
+
* `instance.game` — otherwise the engine's own menu runs underneath.
|
|
17
|
+
*/
|
|
18
|
+
skipStartMenu?: boolean;
|
|
13
19
|
/** Boot directly into a stage: 0-based stage-list category. */
|
|
14
20
|
startingCategory?: number;
|
|
15
21
|
/** Boot directly into a stage: 0-based scene within the category. */
|
|
@@ -17,6 +23,12 @@ export interface Rsdkv4Options {
|
|
|
17
23
|
/** Starting player/character index. */
|
|
18
24
|
startingPlayer?: number;
|
|
19
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* RSDKv4 reads 255 as "not set" for the starting stage/player (see Userdata.cpp:
|
|
28
|
+
* anything else — **including 0** — makes Engine::Init skip the start-menu flow
|
|
29
|
+
* and force InitStartingStage). So "boot normally" has to be 255, not 0.
|
|
30
|
+
*/
|
|
31
|
+
export declare const RSDKV4_UNSET = 255;
|
|
20
32
|
export declare const DEFAULT_RSDKV4_OPTIONS: Required<Rsdkv4Options>;
|
|
21
33
|
export declare const RSDKV4_OPTIONS_SCHEMA: JSONSchema;
|
|
22
34
|
//# sourceMappingURL=rsdkv4.options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsdkv4.options.d.ts","sourceRoot":"","sources":["../../src/rsdkv4.options.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qCAAqC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"rsdkv4.options.d.ts","sourceRoot":"","sources":["../../src/rsdkv4.options.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qCAAqC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,MAAM,CAAC;AAEhC,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,aAAa,CAQ1D,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,UAyCnC,CAAC"}
|
|
@@ -10,13 +10,20 @@
|
|
|
10
10
|
// At runtime these options are serialized into RSDKv4's `settings.ini` (see the
|
|
11
11
|
// SDK's settings serializer) when the host does not pass an explicit `settings`
|
|
12
12
|
// asset.
|
|
13
|
+
/**
|
|
14
|
+
* RSDKv4 reads 255 as "not set" for the starting stage/player (see Userdata.cpp:
|
|
15
|
+
* anything else — **including 0** — makes Engine::Init skip the start-menu flow
|
|
16
|
+
* and force InitStartingStage). So "boot normally" has to be 255, not 0.
|
|
17
|
+
*/
|
|
18
|
+
export const RSDKV4_UNSET = 255;
|
|
13
19
|
export const DEFAULT_RSDKV4_OPTIONS = {
|
|
14
20
|
devMenu: false,
|
|
15
21
|
engineDebugMode: true,
|
|
16
22
|
vsync: true,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
skipStartMenu: false,
|
|
24
|
+
startingCategory: RSDKV4_UNSET,
|
|
25
|
+
startingScene: RSDKV4_UNSET,
|
|
26
|
+
startingPlayer: RSDKV4_UNSET,
|
|
20
27
|
};
|
|
21
28
|
export const RSDKV4_OPTIONS_SCHEMA = {
|
|
22
29
|
type: 'object',
|
|
@@ -33,9 +40,29 @@ export const RSDKV4_OPTIONS_SCHEMA = {
|
|
|
33
40
|
description: 'Enables the web devmenu embind bridge (stage list / warp / pause).',
|
|
34
41
|
},
|
|
35
42
|
vsync: { type: 'boolean', default: true },
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
skipStartMenu: {
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
default: false,
|
|
46
|
+
description: "Skip the engine's own save/character/options screens — set it when the host renders them from instance.game.",
|
|
47
|
+
},
|
|
48
|
+
startingCategory: {
|
|
49
|
+
type: 'integer',
|
|
50
|
+
minimum: 0,
|
|
51
|
+
default: RSDKV4_UNSET,
|
|
52
|
+
description: '0-based stage-list category; 255 = unset (normal boot flow).',
|
|
53
|
+
},
|
|
54
|
+
startingScene: {
|
|
55
|
+
type: 'integer',
|
|
56
|
+
minimum: 0,
|
|
57
|
+
default: RSDKV4_UNSET,
|
|
58
|
+
description: '0-based scene in the category; 255 = unset (normal boot flow).',
|
|
59
|
+
},
|
|
60
|
+
startingPlayer: {
|
|
61
|
+
type: 'integer',
|
|
62
|
+
minimum: 0,
|
|
63
|
+
default: RSDKV4_UNSET,
|
|
64
|
+
description: 'Player/character index; 255 = unset (normal boot flow).',
|
|
65
|
+
},
|
|
39
66
|
},
|
|
40
67
|
};
|
|
41
68
|
//# sourceMappingURL=rsdkv4.options.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsdkv4.options.js","sourceRoot":"","sources":["../../src/rsdkv4.options.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,+EAA+E;AAC/E,qCAAqC;AACrC,+EAA+E;AAC/E,8EAA8E;AAC9E,6EAA6E;AAC7E,iEAAiE;AACjE,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,SAAS;
|
|
1
|
+
{"version":3,"file":"rsdkv4.options.js","sourceRoot":"","sources":["../../src/rsdkv4.options.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,+EAA+E;AAC/E,qCAAqC;AACrC,+EAA+E;AAC/E,8EAA8E;AAC9E,6EAA6E;AAC7E,iEAAiE;AACjE,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,SAAS;AA6BT;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAEhC,MAAM,CAAC,MAAM,sBAAsB,GAA4B;IAC7D,OAAO,EAAE,KAAK;IACd,eAAe,EAAE,IAAI;IACrB,KAAK,EAAE,IAAI;IACX,aAAa,EAAE,KAAK;IACpB,gBAAgB,EAAE,YAAY;IAC9B,aAAa,EAAE,YAAY;IAC3B,cAAc,EAAE,YAAY;CAC7B,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAe;IAC/C,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,UAAU,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;YACd,WAAW,EACT,mHAAmH;SACtH;QACD,eAAe,EAAE;YACf,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,oEAAoE;SAClF;QACD,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE;QACzC,aAAa,EAAE;YACb,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;YACd,WAAW,EACT,8GAA8G;SACjH;QACD,gBAAgB,EAAE;YAChB,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,8DAA8D;SAC5E;QACD,aAAa,EAAE;YACb,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,gEAAgE;SAC9E;QACD,cAAc,EAAE;YACd,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,yDAAyD;SACvE;KACF;CACF,CAAC"}
|
|
@@ -12,8 +12,65 @@ export interface RsdkDevMenuBridge {
|
|
|
12
12
|
loadStage(categoryIdx: number, stageIdx: number): void;
|
|
13
13
|
setPaused(paused: boolean): void;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
/** One of RSDKv4's four save slots, as the engine's own save-select screen sees it. */
|
|
16
|
+
export interface RsdkSaveSlot {
|
|
17
|
+
/** 0-3. */
|
|
18
|
+
slot: number;
|
|
19
|
+
/** No game stored here — starting it means picking a character first. */
|
|
20
|
+
empty: boolean;
|
|
21
|
+
/** Character index into `players()`: 0 Sonic, 1 Tails, 2 Knuckles, 3 Sonic & Tails. */
|
|
22
|
+
character: number;
|
|
23
|
+
lives: number;
|
|
24
|
+
score: number;
|
|
25
|
+
emeralds: number;
|
|
26
|
+
/** Stage list the save resumes into (1 regular, 3 special), or -1 when empty. */
|
|
27
|
+
list: number;
|
|
28
|
+
/** 0-based scene within `list` — index it against `devMenu.getStageList()`. */
|
|
29
|
+
zone: number;
|
|
30
|
+
}
|
|
31
|
+
/** A row of the engine's GAME OPTIONS screen (differs between Sonic 1 and 2). */
|
|
32
|
+
export interface RsdkGameOption {
|
|
33
|
+
key: string;
|
|
34
|
+
label: string;
|
|
35
|
+
value: number;
|
|
36
|
+
type: 'boolean' | 'enum';
|
|
37
|
+
/** Choice labels, for `type: 'enum'` (item box sets). */
|
|
38
|
+
values?: string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The engine's Start Menu as data, so a host can render save-slot / character /
|
|
42
|
+
* game-option screens itself. Everything here mirrors what RSDKv4's own in-canvas
|
|
43
|
+
* menu does — see WebGame.cpp.
|
|
44
|
+
*/
|
|
45
|
+
export interface RsdkGameBridge {
|
|
46
|
+
/** 1 = Sonic 1, 2 = Sonic 2, 0 = unrecognised pack. */
|
|
47
|
+
type(): number;
|
|
48
|
+
/** Playable characters from the pack's GameConfig, in engine order. */
|
|
49
|
+
players(): string[];
|
|
50
|
+
saveSlots(): RsdkSaveSlot[];
|
|
51
|
+
/**
|
|
52
|
+
* Start a game the way the native menu would: a slot with data continues it,
|
|
53
|
+
* an empty slot starts a new game as `player`, and `slot: null` plays without
|
|
54
|
+
* saving. Resumes the engine if the SDK had it paused.
|
|
55
|
+
*/
|
|
56
|
+
start(slot: number | null, player?: number): void;
|
|
57
|
+
/** Wipe a slot back to "NEW GAME". */
|
|
58
|
+
deleteSave(slot: number): void;
|
|
59
|
+
options(): RsdkGameOption[];
|
|
60
|
+
/** Set an option; written through to the engine and its save file, as the engine does. */
|
|
61
|
+
setOption(key: string, value: number): void;
|
|
62
|
+
}
|
|
63
|
+
export type Rsdkv4Instance = Omit<EngineInstance, 'pause' | 'resume'> & {
|
|
64
|
+
/**
|
|
65
|
+
* Pause, on behalf of `owner` (default 'host'). The first caller to pause owns
|
|
66
|
+
* it and only that owner's `resume()` lifts it, so a pause overlay can't
|
|
67
|
+
* resume a game a start screen — or the host — had already frozen. Audio stops
|
|
68
|
+
* with the engine.
|
|
69
|
+
*/
|
|
70
|
+
pause(owner?: string): void;
|
|
71
|
+
resume(owner?: string): void;
|
|
16
72
|
devMenu: RsdkDevMenuBridge;
|
|
73
|
+
game: RsdkGameBridge;
|
|
17
74
|
/** True when the working dir is OPFS-backed (persistent) rather than in-memory. */
|
|
18
75
|
persistent: boolean;
|
|
19
76
|
/** Relative storage namespace used under /data (e.g. "sonic1", "sonic2"). */
|
|
@@ -37,6 +94,8 @@ export type Rsdkv4LoadConfig = EngineConfig & {
|
|
|
37
94
|
* Examples: "sonic1", "sonic2", "my-pack/v1".
|
|
38
95
|
*/
|
|
39
96
|
storageNamespace?: string;
|
|
97
|
+
/** Deprecated alias for `canvasEl`, kept for hosts written against 0.0.x. */
|
|
98
|
+
canvas?: HTMLCanvasElement;
|
|
40
99
|
};
|
|
41
100
|
/** Boot the RSDKv4 engine. */
|
|
42
101
|
export declare function load(config: Rsdkv4LoadConfig): Promise<Rsdkv4Instance>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsdkv4.sdk.d.ts","sourceRoot":"","sources":["../../src/rsdkv4.sdk.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rsdkv4.sdk.d.ts","sourceRoot":"","sources":["../../src/rsdkv4.sdk.ts"],"names":[],"mappings":"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"}
|