@rydr/game-sdk 9.4.0 → 9.5.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.
@@ -9,5 +9,5 @@
9
9
  export declare const RYDR_PROTOCOL_VERSION: 37;
10
10
  /** Semver of this SDK build. Sent in the handshake for telemetry/debugging.
11
11
  * (Bumped to 2.0.0 by `npm version major` on release — see CHANGELOG [Unreleased].) */
12
- export declare const RYDR_SDK_VERSION = "9.4.0";
12
+ export declare const RYDR_SDK_VERSION = "9.5.0";
13
13
  //# sourceMappingURL=version.d.ts.map
@@ -334,5 +334,5 @@
334
334
  export const RYDR_PROTOCOL_VERSION = 37;
335
335
  /** Semver of this SDK build. Sent in the handshake for telemetry/debugging.
336
336
  * (Bumped to 2.0.0 by `npm version major` on release — see CHANGELOG [Unreleased].) */
337
- export const RYDR_SDK_VERSION = "9.4.0";
337
+ export const RYDR_SDK_VERSION = "9.5.0";
338
338
  //# sourceMappingURL=version.js.map
@@ -185,8 +185,8 @@ See "Compare the watts a rider is OVER their own target" below.
185
185
 
186
186
  ## Who else is riding — and why you must not ask which are real
187
187
 
188
- > **Not shipped yet (PLAT-1667).** The shape below is agreed; the host does not populate it in the
189
- > current release. Design your rendering against it, but check the field exists before you read it.
188
+ > `participants` is optional on the wire — absent on a host older than this — so check it before you
189
+ > read it. `?? []` is the whole guard.
190
190
 
191
191
  A workout is ridden by a **room** — and a room is never empty, because a rider alone is given a
192
192
  **bot pacer** doing the same session. Solo and group are the same path with a different number of
@@ -208,7 +208,7 @@ this was the host's problem, because they were never about rendering —
208
208
  never let one enter a leaderboard.
209
209
 
210
210
  ```ts
211
- const riders = snapshot.workout?.participants ?? [];
211
+ const riders = snapshot.participants ?? [];
212
212
 
213
213
  for (const r of riders) {
214
214
  // Compare the watts they are OVER their own target — not compliance, not raw watts.
@@ -50,6 +50,58 @@ export interface WorkoutPlan {
50
50
  }
51
51
  /** Live authoritative position. Seconds use the platform's single workout clock. */
52
52
  export type WorkoutProgress = Omit<EngineState, "workout" | "timeline">;
53
+ /**
54
+ * Somebody REAL riding this workout alongside you (PLAT-1667).
55
+ *
56
+ * A workout is ridden by a ROOM, and a room is never empty — but the thing that fills an empty seat
57
+ * is **the game's own pacer, not the platform's** (Ben's call, 2026-09-22). This list carries
58
+ * humans; a room of one arrives here as a list of one, and every game is expected to put somebody
59
+ * beside them so solo and group stay a single code path with no "nobody else is here" branch.
60
+ *
61
+ * An earlier draft had the host derive bots into this list so that no game had to. It was dropped
62
+ * because drawing a pacer is not a detail of a bot, it IS the game: a pacer is a rigged cyclist on
63
+ * a road in one, an opponent in a duel in the next, and a company holding a lane in a third. Once
64
+ * the game-specific part is taken out there is no rendering left for anyone else to own, and the
65
+ * part that could still be shared — watts — is the part a game can derive itself from the frozen
66
+ * workout, the shared position and a seed.
67
+ *
68
+ * {@link TrainingParticipant.isBot} therefore arrives `false` from the platform. It stays on the
69
+ * type for the games that merge their own pacer into a list of this shape to render one roster, and
70
+ * it is for WORDING and leaderboards only: **draw bots exactly as you draw people.** A game that
71
+ * branches on it in its geometry shows a solo rider a screen that looks broken, which is the very
72
+ * case a pacer exists to fix.
73
+ */
74
+ export interface TrainingParticipant {
75
+ /** Stable for the session. Synthetic for a bot, and never a real `playerId`. */
76
+ id: string;
77
+ name: string;
78
+ isBot: boolean;
79
+ /**
80
+ * How closely they are holding target, as a fraction — 1 is exactly on it.
81
+ *
82
+ * **Do not rank a room by this.** An earlier draft of this field said it was the only comparable
83
+ * number; PLAT-1668 reversed that, and the README's "Compare the watts a rider is OVER their own
84
+ * target" is the current rule. A fraction flatters whoever is prescribed less: 10 % over a 200 W
85
+ * target is 20 W of extra work and 10 % over 400 W is 40 W, so ranking by the ratio puts the
86
+ * rider doing half the work on top.
87
+ *
88
+ * Still useful for what it actually is — a single-rider readout of "am I on it" that needs no
89
+ * second number to be read. For anything comparing riders, use
90
+ * `power - targetPower` ({@link TrainingParticipant.targetPower}).
91
+ */
92
+ compliance: number;
93
+ /** Their actual watts. Meaningful only against their own target — not comparable raw. */
94
+ power: number;
95
+ /**
96
+ * What they are being asked for, watts. Scaled to THEIR FTP, so it differs across the room.
97
+ *
98
+ * With {@link TrainingParticipant.power}, this is the pair the comparison is built from. It is
99
+ * genuinely per-rider and must never be filled in with the local rider's target: everyone rides
100
+ * the same %FTP against their own FTP, so a room holds as many different prescriptions as it has
101
+ * riders, and substituting one tells a game that everybody is being asked for what YOU are.
102
+ */
103
+ targetPower: number;
104
+ }
53
105
  /** Atomic state: a null workout means no structured training is attached. */
54
106
  export interface TrainingSnapshot {
55
107
  effort: EffortMode;
@@ -70,6 +122,17 @@ export interface TrainingSnapshot {
70
122
  plan: WorkoutPlan;
71
123
  progress: WorkoutProgress;
72
124
  } | null;
125
+ /**
126
+ * Every real rider in this workout, including this one (PLAT-1667).
127
+ *
128
+ * Absent on a host that predates group workouts, and empty when no session is attached. **Bots
129
+ * are not in here** — filling an empty seat is the game's job; see {@link TrainingParticipant}.
130
+ *
131
+ * There is deliberately no position either: the workout's `progress.position` is SHARED, which is
132
+ * what makes it a group workout at all. What differs between riders is only how well each holds
133
+ * their own target.
134
+ */
135
+ participants?: readonly TrainingParticipant[];
73
136
  }
74
137
  /** Transport omits unchanged plans; revision guards reject stale progress. */
75
138
  export interface TrainingUpdate {
@@ -84,6 +147,7 @@ export interface TrainingUpdate {
84
147
  plan?: WorkoutPlan;
85
148
  progress: WorkoutProgress;
86
149
  } | null;
150
+ participants?: readonly TrainingParticipant[];
87
151
  }
88
152
  /** Read-only workout state plus a game's chosen effort preference. */
89
153
  export interface TrainingSession {
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/training/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/training/protocol.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rydr/game-sdk",
3
- "version": "9.4.0",
3
+ "version": "9.5.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/bdefrenne/rydr-game-sdk.git"