@rydr/game-sdk 3.27.0 → 5.0.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 (75) hide show
  1. package/README.md +26 -21
  2. package/dist/client/HardwareStore.d.ts +10 -0
  3. package/dist/client/HardwareStore.d.ts.map +1 -1
  4. package/dist/client/HardwareStore.js +10 -0
  5. package/dist/client/HardwareStore.js.map +1 -1
  6. package/dist/client/PlatformClient.d.ts +51 -28
  7. package/dist/client/PlatformClient.d.ts.map +1 -1
  8. package/dist/client/PlatformClient.js +33 -9
  9. package/dist/client/PlatformClient.js.map +1 -1
  10. package/dist/host/PlatformHost.d.ts +30 -13
  11. package/dist/host/PlatformHost.d.ts.map +1 -1
  12. package/dist/host/PlatformHost.js +42 -8
  13. package/dist/host/PlatformHost.js.map +1 -1
  14. package/dist/nav/README.md +26 -6
  15. package/dist/nav/scroll-nav.d.ts.map +1 -1
  16. package/dist/nav/scroll-nav.js +8 -4
  17. package/dist/nav/scroll-nav.js.map +1 -1
  18. package/dist/nav/spatial-nav.d.ts +27 -0
  19. package/dist/nav/spatial-nav.d.ts.map +1 -1
  20. package/dist/nav/spatial-nav.js +173 -8
  21. package/dist/nav/spatial-nav.js.map +1 -1
  22. package/dist/protocol/boards.d.ts +0 -8
  23. package/dist/protocol/boards.d.ts.map +1 -1
  24. package/dist/protocol/boards.js.map +1 -1
  25. package/dist/protocol/buttons.d.ts +49 -15
  26. package/dist/protocol/buttons.d.ts.map +1 -1
  27. package/dist/protocol/buttons.js +39 -17
  28. package/dist/protocol/buttons.js.map +1 -1
  29. package/dist/protocol/glyphs.d.ts +47 -0
  30. package/dist/protocol/glyphs.d.ts.map +1 -0
  31. package/dist/protocol/glyphs.js +75 -0
  32. package/dist/protocol/glyphs.js.map +1 -0
  33. package/dist/protocol/index.d.ts +1 -0
  34. package/dist/protocol/index.d.ts.map +1 -1
  35. package/dist/protocol/index.js +1 -0
  36. package/dist/protocol/index.js.map +1 -1
  37. package/dist/protocol/messages.d.ts +25 -19
  38. package/dist/protocol/messages.d.ts.map +1 -1
  39. package/dist/protocol/version.d.ts +2 -2
  40. package/dist/protocol/version.d.ts.map +1 -1
  41. package/dist/protocol/version.js +47 -2
  42. package/dist/protocol/version.js.map +1 -1
  43. package/dist/three/README.md +1 -1
  44. package/dist/ui/README.md +6 -6
  45. package/dist/ui/action-card.d.ts +4 -4
  46. package/dist/ui/action-card.d.ts.map +1 -1
  47. package/dist/ui/action-card.js.map +1 -1
  48. package/dist/ui/action-diamond.d.ts +3 -3
  49. package/dist/ui/action-diamond.d.ts.map +1 -1
  50. package/dist/ui/action-diamond.js +4 -2
  51. package/dist/ui/action-diamond.js.map +1 -1
  52. package/dist/ui/choice-card.d.ts +3 -3
  53. package/dist/ui/choice-card.d.ts.map +1 -1
  54. package/dist/ui/choice-card.js +1 -1
  55. package/dist/ui/choice-card.js.map +1 -1
  56. package/dist/ui/dialogue-card.d.ts +3 -3
  57. package/dist/ui/dialogue-card.d.ts.map +1 -1
  58. package/dist/ui/dialogue-card.js +1 -1
  59. package/dist/ui/dialogue-card.js.map +1 -1
  60. package/dist/ui/keycap.d.ts +19 -5
  61. package/dist/ui/keycap.d.ts.map +1 -1
  62. package/dist/ui/keycap.js +63 -9
  63. package/dist/ui/keycap.js.map +1 -1
  64. package/dist/ui/labeled-diamond.d.ts +4 -4
  65. package/dist/ui/labeled-diamond.d.ts.map +1 -1
  66. package/dist/ui/labeled-diamond.js +7 -4
  67. package/dist/ui/labeled-diamond.js.map +1 -1
  68. package/dist/ui/showcase/index.d.ts.map +1 -1
  69. package/dist/ui/showcase/index.js +53 -27
  70. package/dist/ui/showcase/index.js.map +1 -1
  71. package/dist/ui/solo-labeled-diamond.d.ts +5 -5
  72. package/dist/ui/solo-labeled-diamond.d.ts.map +1 -1
  73. package/dist/ui/solo-labeled-diamond.js +4 -2
  74. package/dist/ui/solo-labeled-diamond.js.map +1 -1
  75. package/package.json +1 -1
package/README.md CHANGED
@@ -131,8 +131,8 @@ exists but defaults to ALL; you don't set it.)
131
131
  - `hardware: HardwareStore` — `current: HardwareSnapshot`, and `subscribe(cb) => () => void` (fires immediately, then on every change).
132
132
  - `ready()` · `reportLoadProgress(0..100)` · `reportError(message)`.
133
133
  - `setSimulation(gradePercent)` · `setTargetPower(watts)` · `setErgMode(enabled)` — trainer control.
134
- - `setRoute(path)` · `createRouter({ onRoute })` · `setPowerBar(visible)` · `setMenu(true | false | "hidden")` · `requestExit()` · `requestHardwareModal()`.
135
- - `setMenu`: `true` = shell chrome shown (menu screens) · `false` = immersive play (overlay collapses, but the hamburger **stays** so the rider can always exit) · `"hidden"` = full takeover, the hamburger + floating pills are **removed entirely** use this in every editor/authoring tool (see [Build an in-game editor](#build-an-in-game-editor)).
134
+ - `setRoute(path)` · `createRouter({ onRoute })` · `setPowerBar(visible)` · `requestExit()` · `requestHardwareModal()`.
135
+ - `setPowerBar`: default visible leave it during gameplay **and** menus so a keyboard rider can always feed power. The one exception is an editor/authoring tool, which has nothing to pedal and calls `setPowerBar(false)` (see [Build an in-game editor](#build-an-in-game-editor)).
136
136
 
137
137
  > **Routing — use `createRouter`, not `setRoute` by hand.** `setRoute(path)` only *mirrors* your current route into the shell's top URL (shareable/refreshable). It does **nothing** for browser Back/Forward — those are driven by the history stack, and an iframe's own `history.pushState` entries join that stack, so a guest gets Back/Forward *for free* the moment it pushes one entry per navigation. `session.createRouter({ onRoute })` owns that wiring: `pushState` on `go()`, a `popstate` listener, dispatching the boot path from the real URL / `initialPath`, and re-mirroring via `setRoute` on every dispatch (including Back/Forward). You keep your own route *table* — parse the path in `onRoute` and mount your screen:
138
138
  >
@@ -191,6 +191,11 @@ const anyHeld = session.buttonsDown().length > 0;
191
191
  const throttle = session.axis("RT"); // 0..1 (0 on a plain, non-hall trigger until pressed)
192
192
  const move = session.stick("LSTICK"); // { x, y, magnitude, angle }, radially deadzoned
193
193
  player.x += move.x * speed; // smooth on hall sticks, clean 8-way on a d-pad
194
+ const aim = session.stick("RSTICK"); // the SECOND stick: aim / camera (RX/RY)
195
+
196
+ // The right stick is also readable digitally, and clicking a stick is a plain button:
197
+ const aimX = (session.isDown("RRIGHT") ? 1 : 0) - (session.isDown("RLEFT") ? 1 : 0);
198
+ session.onButton(({ name, edge }) => { if (name === "RSTICK_PRESS" && edge === "down") recentreCamera(); });
194
199
  ```
195
200
 
196
201
  - **Do NOT** add `window.addEventListener("keydown"/"keyup")`, read `e.key`/`e.code`/`keyCode`,
@@ -201,11 +206,12 @@ player.x += move.x * speed; // smooth on hall sticks, clean
201
206
  delivered per-frame and per-focus. `onButton`/`isDown`/`buttonsDown` are immune to all of that:
202
207
  the SDK normalises **keyboard, phone, and Zwift Play** into one stream and delivers it whether
203
208
  the shell or the game canvas holds focus.
204
- - **Canonical names:** `UP`/`DOWN`/`LEFT`/`RIGHT` + face buttons `A`/`B`/`Y`/`Z` + shoulder
205
- triggers `LT`/`RT`. House convention: `A` = confirm/primary, `Z` = back/cancel; `B`/`Y` and
206
- `LT`/`RT` are contextual (no built-in meaning). Show the actual glyph in prompts; never hard-code a
207
- device. (Phones expose at least the `A`/`Z` pair, and not every controller has `LT`/`RT` don't
208
- require them for a flow that must work everywhere.)
209
+ - **Canonical names:** `UP`/`DOWN`/`LEFT`/`RIGHT` (D-pad **and** left stick) + right-stick directions
210
+ `RUP`/`RDOWN`/`RLEFT`/`RRIGHT` + face diamond `DIAMOND_UP`/`DIAMOND_DOWN`/`DIAMOND_LEFT`/`DIAMOND_RIGHT` + shoulder triggers `LT`/`RT` + joystick
211
+ clicks `LSTICK_PRESS`/`RSTICK_PRESS`. House convention: `DIAMOND_DOWN` = confirm/primary, `DIAMOND_RIGHT` = back/cancel (as on Xbox/PlayStation/Nintendo). Never print a letter resolve it per pad with `session.buttonLabel(name)`; every
212
+ other name is contextual (no built-in meaning). Show the actual glyph in prompts; never hard-code a
213
+ device. (Phones expose at least the `DIAMOND_DOWN`/`DIAMOND_RIGHT` pair, and most controllers have no `LT`/`RT`, no second
214
+ stick and no stick click — don't require them for a flow that must work everywhere.)
209
215
  - **Edges are real holds:** a held button emits exactly one `down` and one `up`. For "is it held
210
216
  right now?" use `isDown`/`buttonsDown` rather than tracking edges yourself.
211
217
  - **Analog is opt-in and additive:** when a controller has **hall-effect** sensors, read the
@@ -217,8 +223,10 @@ player.x += move.x * speed; // smooth on hall sticks, clean
217
223
  game uses either or both. And `axis()`/`stick()` are **always readable**: on a plain, non-hall
218
224
  controller the value is quantized to the endpoints (a trigger snaps `0`/`1`, a d-pad snaps
219
225
  `-1`/`0`/`+1`), so you never branch on "does this controller have hall?" — it rests at `0` until a
220
- sample arrives. The **keyboard emulates axes too** (for local dev): the trigger keys drive `LT`/`RT`
221
- and the arrow keys the left stick, so `axis()`/`stick()` work without a controller.
226
+ sample arrives. The **keyboard emulates axes too** (for local dev): the trigger keys drive `LT`/`RT`, the
227
+ arrow keys the left stick and `i`/`j`/`k`/`l` the right stick, so `axis()` and both `stick("LSTICK")` /
228
+ `stick("RSTICK")` work without a controller. The right stick is also readable digitally
229
+ (`RUP`/`RDOWN`/`RLEFT`/`RRIGHT`) and each stick's click is a plain button (`f`/`o` on the keyboard).
222
230
  - **The only legitimate exception is a non-gameplay authoring tool** — an admin-gated **world /
223
231
  level editor** or a dev-only showcase page that runs outside the rider flow. There, raw keyboard
224
232
  (Ctrl+Z, arrows to nudge, Delete) is the correct desktop UX. *Gameplay* never uses it.
@@ -292,7 +300,7 @@ if (r) spawnGhost(r.body.frames); // r = { body: ReplayBody, meta: ReplayMeta |
292
300
  > 2. **The URL carries only the `runId` — fetch everything else.** Do **not** gate replay entry on a level/track/difficulty/song param: you won't have one. `getReplay(runId)` returns the frames, and whatever the run was (which level, the chart, the player) must come from *inside* that replay (put it in the first frame's `customData`, or store it under the run via `saveRun`/`getRun`). This is why the route is the same for every game.
293
301
  > 3. **Handle "no replay" gracefully.** `getReplay` returns `null` when nothing was stored for that id (e.g. a pre-feature or non-PB run). Fall back to a menu — never hang on a blank screen.
294
302
  > 4. **Play it back read-only.** It's a viewer, not a run: **no** hardware input, **no** `startRun`, **no** `saveReplay`/recording. Drive your scene purely from `r.body.frames`.
295
- > 5. **Stay immersive and keep the URL stable.** Set your in-game chrome (e.g. `setMenu(false)`, `setPowerBar(false)`) and call `setRoute('replay/' + runId)` so a refresh stays on the replay. Derive the exit/back target from the fetched replay (e.g. that level's leaderboard), not from the URL.
303
+ > 5. **Keep the URL stable.** A replay is read-only, so hide the power bar (`setPowerBar(false)`) and call `setRoute('replay/' + runId)` so a refresh stays on the replay. Derive the exit/back target from the fetched replay (e.g. that level's leaderboard), not from the URL.
296
304
  > 6. **Serve the path from your origin.** Like every projected route, a hard refresh of `…/replay/<id>` hits your origin as `/replay/<id>` — add the [SPA rewrite](#platformsession) so it falls back to `index.html` instead of 404ing.
297
305
  >
298
306
  > ```ts
@@ -303,8 +311,7 @@ if (r) spawnGhost(r.body.frames); // r = { body: ReplayBody, meta: ReplayMeta |
303
311
  > const runId = m[1];
304
312
  > const r = await session.getReplay(runId); // null ⇒ nothing stored for this run
305
313
  > if (!r) return goToMenu(); // graceful fallback, no blank screen
306
- > session.setMenu(false); // immersive viewer chrome…
307
- > session.setPowerBar(false); // …no live power bar (this isn't a run)
314
+ > session.setPowerBar(false); // read-only viewer — no live power bar
308
315
  > session.setRoute('replay/' + runId); // keep the URL stable across refresh
309
316
  > playReplayReadOnly(r.body.frames); // no input, no startRun, no recording
310
317
  > return; // skip your normal "start a run" boot path
@@ -347,15 +354,14 @@ Any game can ship an **editor** for its own `shared` content (levels, tracks, ch
347
354
 
348
355
  1. **Gate your editor UI** on `session.identity.isAdmin` — show the "Edit" button / editor route only when it's `true`.
349
356
  2. **Call the normal session methods** — `saveContent` / `deleteContent` / `getUploadUrl`. The shell performs the write as the signed-in admin (Supabase RLS on their admin role; your iframe never authenticates). For a non-admin player these reject; for an admin they succeed.
350
- 3. **Hide the shell chrome** — an editor is a full-screen tool with its own navigation, so on boot call **`session.setMenu("hidden")`** (removes the shell hamburger + floating resistance/FTP pills entirely) and **`session.setPowerBar(false)`**. Use `"hidden"`, **not** `false`: `false` is immersive *gameplay*, which keeps the hamburger so a rider can exit mid-ride — an editor has no rider to strand and its own back-nav, so the shell menu must not overlay it. This is mandatory for **any** editor (chart, level, world, voice-over, …).
357
+ 3. **Hide the power bar** — an editor is a full-screen authoring tool with nothing to pedal, so on boot call **`session.setPowerBar(false)`** to drop the trainerless power slider. (The shell draws no other per-game chrome its platform menu is summoned on demand so there's nothing else to hide.) This is the one place a guest should hide the power bar; gameplay and game menus always leave it visible.
351
358
 
352
359
  ```ts
353
360
  // in-game editor (embedded in the shell — the normal case)
354
361
  if (session.identity.isAdmin) {
355
362
  showEditorButton();
356
363
  }
357
- // …on editor boot, take over the screenno shell chrome over an editor:
358
- session.setMenu("hidden"); // remove the hamburger + pills (NOT false, which keeps them for gameplay)
364
+ // …on editor boot, drop the power slider nothing to pedal in an editor:
359
365
  session.setPowerBar(false);
360
366
  // …when the author saves:
361
367
  const { uploadUrl, url } = await session.getUploadUrl({ collection: "songs", filename: "track.mp3" });
@@ -385,8 +391,7 @@ if (!session.identity.isAdmin) {
385
391
  // Not an admin — show "sign in to the platform as an admin", author nothing.
386
392
  return;
387
393
  }
388
- // Take over the screen — an editor shows no shell chrome (hamburger + pills gone).
389
- session.setMenu("hidden");
394
+ // Drop the power slider — an editor has nothing to pedal.
390
395
  session.setPowerBar(false);
391
396
  // Admin: author through the session. The shell writes as the signed-in admin; this iframe never authenticates.
392
397
  const { uploadUrl, url } = await session.getUploadUrl({ collection: "levels", filename: "bg.png" });
@@ -489,16 +494,16 @@ A self-contained DOM/CSS kit for the **controller-button UI** — showing "which
489
494
  import { createKeycap, mountActionDiamond, mountDialogueCard } from "@rydr/game-sdk/ui";
490
495
 
491
496
  // a single A keycap that reflects real presses — pass the session (it satisfies `ButtonSource`)
492
- host.appendChild(createKeycap("A", { press: session }).el);
497
+ host.appendChild(createKeycap("DIAMOND_DOWN", { press: session }).el);
493
498
 
494
- // the full A/B/Y/Z move diamond, wired to input
499
+ // the full face-diamond move diamond, wired to input
495
500
  const dia = mountActionDiamond(host, { press: session, cards: { A: { label: "Séisme" } } });
496
501
  dia.cards.A.setActive(true);
497
502
  dia.cards.Z.keycap.setCooldown(0.4, 3); // depleting ring + countdown
498
503
  ```
499
504
 
500
- - **`createKeycap(button, opts)`** / **`createDpadKeycap(dir, opts)`** — a keycap of the A/B/Y/Z face buttons or the UP/DOWN/LEFT/RIGHT d-pad. A small state machine: `solo` vs `full` diamond, pulse, pressed, cooldown ring + countdown, colored vs mono, disabled, hidden.
501
- - **`mountCard`** — the dark glass container with a content slot. **`mountActionCard`** — that card + a keycap straddling its bottom edge. **`mountActionDiamond`** — the full A/B/Y/Z move diamond.
505
+ - **`createKeycap(button, opts)`** / **`createDpadKeycap(dir, opts)`** — a keycap of the face-diamond face buttons or the UP/DOWN/LEFT/RIGHT d-pad. A small state machine: `solo` vs `full` diamond, pulse, pressed, cooldown ring + countdown, colored vs mono, disabled, hidden.
506
+ - **`mountCard`** — the dark glass container with a content slot. **`mountActionCard`** — that card + a keycap straddling its bottom edge. **`mountActionDiamond`** — the full face-diamond move diamond.
502
507
  - **`mountDialogueCard`** — an NPC dialogue box (name + typewriter line + continue keycap). **`mountChoiceCard`** — a player menu (prompt + selectable list, ▲▼ + confirm). **`mountLabeledDiamond`** — a pip cluster with a card-seated label radiating from each active button.
503
508
 
504
509
  Wire any keycap to real input by passing the `session` — it structurally satisfies `ButtonSource`, and the keycap then shows its pressed sink while its button is held. The kit speaks the canonical `ButtonName`/`ButtonEdge` vocabulary.
@@ -6,6 +6,7 @@
6
6
  * Buttons are events (see `PlatformSession.onButton`), not state, so they live
7
7
  * on the client rather than here.
8
8
  */
9
+ import { type GlyphSet } from "../protocol/glyphs.js";
9
10
  export interface HardwareSnapshot {
10
11
  /**
11
12
  * Raw trainer power, watts — the exact last reading, updated only when a power message
@@ -45,6 +46,15 @@ export interface HardwareSnapshot {
45
46
  * setup; button events themselves stay source-agnostic. Requires the `buttons` capability.
46
47
  */
47
48
  controllerConnected: boolean;
49
+ /**
50
+ * Which lettering the paired controller carries, for rendering button prompts. Prefer
51
+ * `session.buttonLabel(name)` over reading this directly; it's exposed here so a UI that already
52
+ * subscribes to hardware re-renders its prompts when the rider swaps pads mid-session.
53
+ *
54
+ * A *rendering* hint, never a device identity — several brands share a set, and gameplay must not
55
+ * branch on it. Defaults to {@link DEFAULT_GLYPH_SET} until the shell says otherwise.
56
+ */
57
+ glyphSet: GlyphSet;
48
58
  /** ms timestamp of the most recent update (0 before any data). */
49
59
  updatedAt: number;
50
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"HardwareStore.d.ts","sourceRoot":"","sources":["../../src/client/HardwareStore.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;;OAYG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,yEAAyE;IACzE,YAAY,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,mBAAmB,EAAE,OAAO,CAAC;IAC7B,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;CACnB;AAcD,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAMxC,6EAA6E;AAC7E,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;IAEzD,uFAAuF;IACvF,OAAO,CAAC,IAAI,CAAS;IACrB,kFAAkF;IAClF,OAAO,CAAC,UAAU,CAAK;gBAEX,UAAU,GAAE,MAA4B;IAIpD;iFAC6E;IAC7E,IAAI,OAAO,IAAI,gBAAgB,CAG9B;IAED,oGAAoG;IACpG,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAQjD;;;;OAIG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAI1C;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAO9C;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;CAazB"}
1
+ {"version":3,"file":"HardwareStore.d.ts","sourceRoot":"","sources":["../../src/client/HardwareStore.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAqB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;;OAYG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,yEAAyE;IACzE,YAAY,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,mBAAmB,EAAE,OAAO,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,EAAE,QAAQ,CAAC;IACnB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;CACnB;AAeD,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAMxC,6EAA6E;AAC7E,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;IAEzD,uFAAuF;IACvF,OAAO,CAAC,IAAI,CAAS;IACrB,kFAAkF;IAClF,OAAO,CAAC,UAAU,CAAK;gBAEX,UAAU,GAAE,MAA4B;IAIpD;iFAC6E;IAC7E,IAAI,OAAO,IAAI,gBAAgB,CAG9B;IAED,oGAAoG;IACpG,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAQjD;;;;OAIG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAI1C;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAO9C;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;CAazB"}
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Reactive snapshot of bridged hardware state for a game.
3
+ *
4
+ * A game never owns hardware; it observes this store, which the
5
+ * {@link PlatformClient} keeps current from the platform's `hw.*` messages.
6
+ * Buttons are events (see `PlatformSession.onButton`), not state, so they live
7
+ * on the client rather than here.
8
+ */
9
+ import { DEFAULT_GLYPH_SET } from "../protocol/glyphs.js";
1
10
  const EMPTY = {
2
11
  power: 0,
3
12
  smoothedPower: 0,
@@ -7,6 +16,7 @@ const EMPTY = {
7
16
  trainerConnected: false,
8
17
  ergSupported: false,
9
18
  controllerConnected: false,
19
+ glyphSet: DEFAULT_GLYPH_SET,
10
20
  updatedAt: 0,
11
21
  };
12
22
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"HardwareStore.js","sourceRoot":"","sources":["../../src/client/HardwareStore.ts"],"names":[],"mappings":"AAmDA,MAAM,KAAK,GAAqB;IAC9B,KAAK,EAAE,CAAC;IACR,aAAa,EAAE,CAAC;IAChB,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,KAAK,EAAE,CAAC;IACR,gBAAgB,EAAE,KAAK;IACvB,YAAY,EAAE,KAAK;IACnB,mBAAmB,EAAE,KAAK;IAC1B,SAAS,EAAE,CAAC;CACb,CAAC;AAIF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC;gFACgF;AAChF,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,6EAA6E;AAC7E,MAAM,OAAO,aAAa;IAChB,QAAQ,GAAqB,KAAK,CAAC;IAC1B,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEzD,uFAAuF;IAC/E,IAAI,CAAS;IACrB,kFAAkF;IAC1E,UAAU,GAAG,CAAC,CAAC;IAEvB,YAAY,aAAqB,mBAAmB;QAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC;IAED;iFAC6E;IAC7E,IAAI,OAAO;QACT,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,oGAAoG;IACpG,SAAS,CAAC,QAA0B;QAClC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,UAAkB;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAgC;QACrC,IAAI,CAAC,QAAQ,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC;QAC/C,6FAA6F;QAC7F,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjE,CAAC;IAED;;;;;OAKG;IACK,gBAAgB;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,QAAQ,CAAC,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAClD,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;YACtB,OAAO;QACT,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;QAC1E,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,IAAI,EAAE,IAAI,CAAC;YAAE,OAAO;QACpB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACzF,CAAC;CACF"}
1
+ {"version":3,"file":"HardwareStore.js","sourceRoot":"","sources":["../../src/client/HardwareStore.ts"],"names":[],"mappings":"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"}
@@ -174,13 +174,15 @@ export interface PlatformSession {
174
174
  }): Promise<RankResult>;
175
175
  /**
176
176
  * Begin a new run/attempt. The shell mints a fresh {@link runId} (rotating the id used by the
177
- * run's `saveRun`/`saveReplay`) AND opens a named effort window on its ride recording pass
178
- * `name` (e.g. `Level "Crazy Song"`) for the activity Breakdown. Call at the start of each attempt
179
- * so its score/breakdown/replay are stored under their own id. A restart (calling `startRun`
180
- * again) discards the previous still-open *unsaved* window. Resolves with the new id + a
181
- * platform-clock start time. Throws against an older shell that doesn't support it.
177
+ * run's `saveRun`/`saveReplay`) AND opens a named effort window on its ride recording. Pass the
178
+ * run's `name` (e.g. `"Through the Fire and Flames"`) and optional `tags` (e.g. `["Expert", "No Fail"]`)
179
+ * these label the run in the activity Breakdown AND on the leaderboard board it submits to; the
180
+ * platform stores + shows them verbatim and never parses them. Call at the start of each attempt so
181
+ * its score/breakdown/replay are stored under their own id. A restart (calling `startRun` again)
182
+ * discards the previous still-open *unsaved* window. Resolves with the new id + a platform-clock
183
+ * start time. Throws against an older shell that doesn't support it.
182
184
  */
183
- startRun(name?: string): Promise<{
185
+ startRun(name?: string, tags?: string[]): Promise<{
184
186
  runId: string;
185
187
  startedAt: number;
186
188
  }>;
@@ -409,35 +411,32 @@ export interface PlatformSession {
409
411
  * {@link setRoute}); the router does not change that requirement.
410
412
  */
411
413
  createRouter(options: CreateRouterOptions): GuestRouter;
412
- /** Ask the shell to show/hide the trainerless power bar. Default is visible. Editors hide it
413
- * (`setPowerBar(false)`, paired with `setMenu("hidden")` see {@link setMenu}). */
414
+ /** Ask the shell to show/hide the trainerless power bar. Default is visible leave it alone
415
+ * during gameplay and menus (a keyboard rider must always be able to feed power). Editors are
416
+ * the one exception: a full-screen authoring tool has nothing to pedal, so it hides the bar
417
+ * with `setPowerBar(false)`. */
414
418
  setPowerBar(visible: boolean): void;
415
- /**
416
- * Control the in-game platform menu — the hamburger that opens Exit + hardware/settings/profile.
417
- * Three states:
418
- * - `true` (default) — chrome shown; use on menu/browsing screens.
419
- * - `false` — immersive play; the overlay collapses but the hamburger **stays** so the rider can
420
- * always exit and reach hardware mid-ride. Use during gameplay.
421
- * - `"hidden"` — full takeover; the hamburger and the floating resistance/FTP pills are removed
422
- * **entirely**. Use in any authoring tool / editor (chart, album, world, voice-over): an editor
423
- * is a full-screen tool with its own navigation, so the shell menu must not overlay it. There is
424
- * no rider to strand, so hiding the exit is safe.
425
- *
426
- * Rule of thumb: **every game editor must call `setMenu("hidden")`** (alongside
427
- * `setPowerBar(false)`). `false` is for gameplay, never for editors.
428
- */
429
- setMenu(state: boolean | "hidden"): void;
430
419
  /**
431
420
  * Report whether the rider is in **active gameplay** or navigating a **menu** (picker,
432
421
  * results, leaderboard, pause screen, etc.). The shell uses this to ease trainer resistance
433
- * whenever the rider isn't racing — so you keep spinning comfortably while browsing — and
422
+ * (~35%) whenever the rider isn't racing — so you keep spinning comfortably while browsing — and
434
423
  * restores full resistance the instant you go back to `"playing"`. The game never sets a
435
424
  * resistance value; it only declares state.
436
425
  *
437
- * - `"playing"` (default if never called) active gameplay; full rider resistance.
438
- * - `"menu"` any non-racing screen; the shell eases resistance.
426
+ * - `"menu"` any non-racing screen; the shell eases resistance. **This is the default** — a
427
+ * freshly-launched game is treated as being in its own menus until it says otherwise.
428
+ * - `"playing"` — active gameplay; the shell holds FULL rider resistance.
439
429
  *
440
- * Call it wherever you already switch between menu and play (typically alongside `setMenu`).
430
+ * **The one rule: call `setActivity("playing")` when your gameplay loop is live, and `"menu"`
431
+ * on every other screen — including your title/menu screen at boot.** If you never call it, the
432
+ * rider stays eased (~35% lighter) the whole time — safe, but your race won't feel full. You
433
+ * only ever declare menu↔play; the shell owns all the *cleanup* — opening the platform menu,
434
+ * pausing, exiting, or a crash all reset you to the eased rest state automatically, so you can
435
+ * never leave the trainer stuck at full resistance.
436
+ *
437
+ * A DOM-menu game with a screen router should map every screen → state and call this on each
438
+ * transition (see the guitar-hero `ACTIVITY_STATE` map). A game with a phase enum should call
439
+ * `"playing"` on the play phase and `"menu"` on results/pause/etc.
441
440
  */
442
441
  setActivity(state: "playing" | "menu"): void;
443
442
  /** Ask the shell to exit the game (back to the launcher). */
@@ -457,9 +456,15 @@ export interface PlatformSession {
457
456
  * - **Held button** (hold-to-brake, digital steer) → `isDown(name)` / `buttonsDown()` — poll each frame.
458
457
  * - **Analog trigger** (throttle, brake pressure) → `axis("LT"|"RT")` — `0..1`, poll each frame.
459
458
  * - **Joystick** (2D move/aim) → `stick("LSTICK"|"RSTICK")` — deadzoned `{x, y, magnitude, angle}`.
459
+ * - **Second stick, digitally** (8-way aim) → `RUP`/`RDOWN`/`RLEFT`/`RRIGHT` via `onButton`/`isDown` —
460
+ * the right stick's own edges, so they never collide with the D-pad's `UP`/`DOWN`/`LEFT`/`RIGHT`
461
+ * (which the left stick shares).
462
+ * - **Stick click** (crouch, recentre camera) → `LSTICK_PRESS`/`RSTICK_PRESS` via `onButton`/`isDown` —
463
+ * an ordinary button edge, not an axis. Rare hardware: always leave a second way to do it.
460
464
  *
461
465
  * The digital (`onButton`/`isDown`) and analog (`axis`/`stick`) streams run in parallel — the same
462
- * trigger is readable both ways (`isDown("LT")` and `axis("LT")`), so use whichever fits, or both.
466
+ * trigger is readable both ways (`isDown("LT")` / `axis("LT")`) and so is the same stick
467
+ * (`isDown("RLEFT")` / `stick("RSTICK")`), so use whichever fits, or both.
463
468
  * The SDK normalises keyboard, phone, and Zwift Play into these streams and delivers them whether
464
469
  * the shell or the game canvas holds focus (raw DOM key events silently break across iframe focus).
465
470
  *
@@ -494,8 +499,26 @@ export interface PlatformSession {
494
499
  * the stick's two axes (`"LSTICK"` → `LX`/`LY`, `"RSTICK"` → `RX`/`RY`) into `{ x, y, magnitude,
495
500
  * angle }`. Because axes are always populated, this returns a smooth vector on hall hardware and a
496
501
  * clean 8-way vector on a d-pad — one code path. Default deadzone `0.1`; override via `opts`.
502
+ *
503
+ * Clicking the stick is a separate button edge (`LSTICK_PRESS`/`RSTICK_PRESS`), not part of this vector,
504
+ * and the right stick's deflection also arrives digitally as `RUP`/`RDOWN`/`RLEFT`/`RRIGHT`.
497
505
  */
498
506
  stick(name: StickName, opts?: StickOptions): StickVector;
507
+ /**
508
+ * The label to PRINT for a button on the controller the rider is actually holding —
509
+ * `buttonLabel("DIAMOND_DOWN")` gives `"A"` on an Xbox pad, `"✕"` on a DualSense, `"B"` on a
510
+ * Switch Pro.
511
+ *
512
+ * **Use this everywhere you would otherwise type a button letter.** The wire vocabulary is
513
+ * positional ({@link ButtonName}) precisely because no letter is correct on every pad, so a
514
+ * hardcoded "Press A" is wrong for most riders. For a graphical prompt prefer a keycap from
515
+ * `@rydr/game-sdk/ui`, which calls this for you and draws the diamond.
516
+ *
517
+ * Reactive: the value changes when the rider swaps controllers mid-session. If you cache the
518
+ * string, re-read it in `onHardware` (the glyph set lives on the hardware snapshot) — or just call
519
+ * this at render time, it's a table lookup.
520
+ */
521
+ buttonLabel(name: ButtonName): string;
499
522
  /**
500
523
  * Rumble the connected controller. Pass a named effect (`vibrate("hit")`) or a custom
501
524
  * `{ pattern, intensity }` (`vibrate({ pattern: [100, 50, 100], intensity: 1 })`). The shell
@@ -1 +1 @@
1
- {"version":3,"file":"PlatformClient.d.ts","sourceRoot":"","sources":["../../src/client/PlatformClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PlatformClient.d.ts","sourceRoot":"","sources":["../../src/client/PlatformClient.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@
9
9
  import { RYDR_PROTOCOL_VERSION, RYDR_SDK_VERSION } from "../protocol/version.js";
10
10
  import { ALL_CAPABILITIES } from "../protocol/capabilities.js";
11
11
  import { KEY_TO_BUTTON } from "../protocol/buttons.js";
12
+ import { buttonLabel } from "../protocol/glyphs.js";
12
13
  import { setPlatformMaster } from "../sounds/platform-master.js";
13
14
  import { decodeReplay, encodeReplay } from "./replayCodec.js";
14
15
  import { isPlatformToGameMessage, isRydrMessage } from "../protocol/guards.js";
@@ -27,11 +28,14 @@ function emit(set, value) {
27
28
  * it stays renderer-agnostic — only a boolean flag + a DOM CustomEvent, no Three.js dependency.
28
29
  *
29
30
  * Two palindromes: the face-button code, and an arrows-only alternative for games where the face
30
- * code can't be entered — e.g. `Z` is the house back/cancel button, so it pops menus/exits before
31
- * the code completes; the D-pad only navigates *within* a game, never out of it.
31
+ * code can't be entered — `DIAMOND_RIGHT` is the house back/cancel button, so it pops menus/exits
32
+ * before the code completes; the D-pad only navigates *within* a game, never out of it.
33
+ *
34
+ * The face code is a clockwise sweep of the diamond and back (top → right → bottom → left, reversed),
35
+ * so it is the same physical gesture on every pad regardless of the letters printed on it.
32
36
  */
33
37
  const PERF_CODES = [
34
- ["Y", "A", "B", "Z", "Z", "B", "A", "Y"],
38
+ ["DIAMOND_UP", "DIAMOND_RIGHT", "DIAMOND_DOWN", "DIAMOND_LEFT", "DIAMOND_LEFT", "DIAMOND_DOWN", "DIAMOND_RIGHT", "DIAMOND_UP"],
35
39
  ["UP", "RIGHT", "DOWN", "LEFT", "LEFT", "DOWN", "RIGHT", "UP"],
36
40
  ];
37
41
  const PERF_CODE_MAXLEN = Math.max(...PERF_CODES.map((c) => c.length));
@@ -234,6 +238,10 @@ export function connectToPlatform(options) {
234
238
  // Manifest-configured smoothing wins over any ConnectOptions default.
235
239
  if (welcome.powerSmoothing != null)
236
240
  hardware._setSmoothingTau(welcome.powerSmoothing);
241
+ // Seed the glyph set BEFORE resolving, so the game's first frame already prints the right
242
+ // button labels instead of flashing the default and correcting on the first input.status.
243
+ if (welcome.glyphSet)
244
+ hardware._patch({ glyphSet: welcome.glyphSet });
237
245
  resolve(session);
238
246
  break;
239
247
  }
@@ -286,7 +294,12 @@ export function connectToPlatform(options) {
286
294
  hardware._patch({ trainerConnected: msg.connected, ergSupported: msg.ergSupported });
287
295
  break;
288
296
  case "rydr/input.status":
289
- hardware._patch({ controllerConnected: msg.controllerConnected });
297
+ // `glyphSet` is optional on the wire (an older shell omits it), so keep the current value
298
+ // rather than snapping every on-screen prompt back to the default mid-session.
299
+ hardware._patch({
300
+ controllerConnected: msg.controllerConnected,
301
+ ...(msg.glyphSet ? { glyphSet: msg.glyphSet } : {}),
302
+ });
290
303
  break;
291
304
  case "rydr/lifecycle.pause":
292
305
  emit(pauseListeners, undefined);
@@ -396,14 +409,22 @@ export function connectToPlatform(options) {
396
409
  // Keyboard analog emulation: keep the axis values in sync with keyboard-held buttons so
397
410
  // `session.axis()` / `session.stick()` work on the keyboard for local dev — quantized to the
398
411
  // endpoints (a real hall controller sends continuous values over the wire instead). Triggers map
399
- // to their own axis; the arrow / d-pad keys drive the LEFT stick (opposite keys cancel, so
400
- // LEFT+RIGHT reads 0). Derived from `kbDown` (keyboard-only held state), so a relayed controller's
401
- // own `input.axis` samples are the authority whenever one is actually in use.
412
+ // to their own axis; the arrow / d-pad keys drive the LEFT stick and the i/j/k/l keys
413
+ // (RUP/RLEFT/RDOWN/RRIGHT) the RIGHT one opposite keys cancel, so LEFT+RIGHT (and RLEFT+RRIGHT)
414
+ // reads 0. The stick-click keys (f/o LSTICK_PRESS/RSTICK_PRESS) are buttons only and have no axis.
415
+ // Derived from `kbDown` (keyboard-only held state), so a relayed controller's own `input.axis`
416
+ // samples are the authority whenever one is actually in use.
417
+ //
418
+ // The right-stick keys deliberately do NOT also feed `LX`/`LY`: a twin-stick game would move while
419
+ // aiming, and the keyboard is the reference implementation of the documented contract ("LSTICK" reads
420
+ // LX/LY). A game wanting one merged scheme can OR the two sticks itself; the reverse isn't possible.
402
421
  const syncKeyboardAxes = () => {
403
422
  axisValues.set("LT", kbDown.has("LT") ? 1 : 0);
404
423
  axisValues.set("RT", kbDown.has("RT") ? 1 : 0);
405
424
  axisValues.set("LX", (kbDown.has("RIGHT") ? 1 : 0) - (kbDown.has("LEFT") ? 1 : 0));
406
425
  axisValues.set("LY", (kbDown.has("UP") ? 1 : 0) - (kbDown.has("DOWN") ? 1 : 0));
426
+ axisValues.set("RX", (kbDown.has("RRIGHT") ? 1 : 0) - (kbDown.has("RLEFT") ? 1 : 0));
427
+ axisValues.set("RY", (kbDown.has("RUP") ? 1 : 0) - (kbDown.has("RDOWN") ? 1 : 0));
407
428
  };
408
429
  // A game canvas has no text fields, but admin editors mounted as guests (the song and
409
430
  // voice-over editors) do. When a keystroke is destined for a focused editable element, it
@@ -568,7 +589,7 @@ export function connectToPlatform(options) {
568
589
  knownBoard(boardId);
569
590
  return request((nonce) => post({ rydr: true, type: "rydr/leaderboard.rankQuery", nonce, boardId, key: opts.key, value: opts.value })).then((r) => ({ boardId, rank: r.rank, total: r.total }));
570
591
  },
571
- startRun: (name) => request((nonce) => post({ rydr: true, type: "rydr/run.start", nonce, name })).then((r) => {
592
+ startRun: (name, tags) => request((nonce) => post({ rydr: true, type: "rydr/run.start", nonce, name, tags })).then((r) => {
572
593
  if (r.error)
573
594
  throw new Error(`[rydr-sdk] startRun: ${r.error}`);
574
595
  runId = r.runId; // rotate the closure-captured id so `session.runId` + shell-stamped writes follow
@@ -763,7 +784,6 @@ export function connectToPlatform(options) {
763
784
  return router;
764
785
  },
765
786
  setPowerBar: (visible) => post({ rydr: true, type: "rydr/ui.setPowerBar", visible }),
766
- setMenu: (state) => post({ rydr: true, type: "rydr/ui.setMenu", visible: state === true, hidden: state === "hidden" }),
767
787
  setActivity: (state) => post({ rydr: true, type: "rydr/activity.set", state }),
768
788
  requestExit: () => post({ rydr: true, type: "rydr/exitRequest" }),
769
789
  requestHardwareModal: () => post({ rydr: true, type: "rydr/ui.requestHardwareModal" }),
@@ -790,6 +810,9 @@ export function connectToPlatform(options) {
790
810
  const scale = scaled / rawMag; // maps the raw vector to the rescaled, clamped magnitude
791
811
  return { x: rawX * scale, y: rawY * scale, magnitude: scaled, angle: Math.atan2(rawY, rawX) };
792
812
  },
813
+ // Read through to the live snapshot rather than capturing the set, so a mid-session controller
814
+ // swap changes every prompt on the next render with no game-side subscription.
815
+ buttonLabel: (name) => buttonLabel(hardware.current.glyphSet, name),
793
816
  vibrate: (effect) => post({ rydr: true, type: "rydr/haptics.vibrate", effect }),
794
817
  onPause: (cb) => {
795
818
  pauseListeners.add(cb);
@@ -810,6 +833,7 @@ export function connectToPlatform(options) {
810
833
  teardownKeyboard();
811
834
  buttonListeners.clear();
812
835
  heldButtons.clear();
836
+ axisValues.clear();
813
837
  pauseListeners.clear();
814
838
  resumeListeners.clear();
815
839
  identityListeners.clear();