@magicworks/client-party-game 0.1.0-rc.4 → 0.1.0-rc.6

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 (52) hide show
  1. package/README.md +18 -3
  2. package/dist/client.d.ts +37 -39
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +160 -183
  5. package/dist/client.js.map +1 -1
  6. package/dist/connection.d.ts +158 -0
  7. package/dist/connection.d.ts.map +1 -0
  8. package/dist/connection.js +375 -0
  9. package/dist/connection.js.map +1 -0
  10. package/dist/protocol/codes.d.ts +29 -0
  11. package/dist/protocol/codes.d.ts.map +1 -0
  12. package/dist/protocol/codes.js +56 -0
  13. package/dist/protocol/codes.js.map +1 -0
  14. package/dist/protocol/events.d.ts +129 -0
  15. package/dist/protocol/events.d.ts.map +1 -0
  16. package/dist/protocol/events.js +131 -0
  17. package/dist/protocol/events.js.map +1 -0
  18. package/dist/protocol/index.d.ts +25 -0
  19. package/dist/protocol/index.d.ts.map +1 -0
  20. package/dist/protocol/index.js +41 -0
  21. package/dist/protocol/index.js.map +1 -0
  22. package/dist/protocol/limits.d.ts +40 -0
  23. package/dist/protocol/limits.d.ts.map +1 -0
  24. package/dist/protocol/limits.js +43 -0
  25. package/dist/protocol/limits.js.map +1 -0
  26. package/dist/protocol/messages.d.ts +294 -0
  27. package/dist/protocol/messages.d.ts.map +1 -0
  28. package/dist/protocol/messages.js +3 -0
  29. package/dist/protocol/messages.js.map +1 -0
  30. package/dist/protocol/placement.d.ts +63 -0
  31. package/dist/protocol/placement.d.ts.map +1 -0
  32. package/dist/protocol/placement.js +82 -0
  33. package/dist/protocol/placement.js.map +1 -0
  34. package/dist/protocol/routing.d.ts +26 -0
  35. package/dist/protocol/routing.d.ts.map +1 -0
  36. package/dist/protocol/routing.js +19 -0
  37. package/dist/protocol/routing.js.map +1 -0
  38. package/dist/protocol/scoring.d.ts +7 -0
  39. package/dist/protocol/scoring.d.ts.map +1 -0
  40. package/dist/protocol/scoring.js +13 -0
  41. package/dist/protocol/scoring.js.map +1 -0
  42. package/dist/protocol/speedtest.d.ts +9 -0
  43. package/dist/protocol/speedtest.d.ts.map +1 -0
  44. package/dist/protocol/speedtest.js +22 -0
  45. package/dist/protocol/speedtest.js.map +1 -0
  46. package/dist/socket.d.ts +4 -2
  47. package/dist/socket.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/dist/protocol.d.ts +0 -509
  50. package/dist/protocol.d.ts.map +0 -1
  51. package/dist/protocol.js +0 -262
  52. package/dist/protocol.js.map +0 -1
@@ -1,509 +0,0 @@
1
- /**
2
- * The party game wire protocol, shared by the server
3
- * (`@magicworks/service-party-game`), the host TV (through `PartyGameClient`)
4
- * and, by hand, the phone page the server hosts (`public/app.js`).
5
- *
6
- * Roles
7
- * -----
8
- * host - the ROXi TV app. Owns the video playback and therefore owns round
9
- * timing. It tells the server when a round starts and ends.
10
- * player - a phone browser. Only ever sends a join request, a ready and an
11
- * answer.
12
- *
13
- * The correct answer index is sent by the host at round start and never
14
- * leaves the server: players receive options only, and the server is the sole
15
- * authority on who scored what.
16
- */
17
- export declare const MAX_PLAYERS = 20;
18
- /**
19
- * How long a finished party stays worth coming back to. Opening a lobby with
20
- * the code of a room touched inside this window reopens that room - same code,
21
- * same players, scores back to zero - so a second game needs a tap on each
22
- * phone rather than a fresh scan and everybody's name typed again. Past it the
23
- * room is left where it is and a new one is opened.
24
- */
25
- export declare const REOPEN_WINDOW_MS: number;
26
- export declare const TOTAL_ROUNDS = 15;
27
- /**
28
- * How many rounds the server lets a game have; a TV asking for anything else
29
- * gets TOTAL_ROUNDS (or the room's count). The lobby offers 5 to 30.
30
- */
31
- export declare const MIN_ROUNDS = 1;
32
- export declare const MAX_ROUNDS = 30;
33
- export declare const MAX_NAME_LENGTH = 16;
34
- /** The most options a round may put to the phones, and the longest an option's label or detail may be. */
35
- export declare const MAX_OPTIONS = 8;
36
- export declare const MAX_OPTION_LENGTH = 200;
37
- /** The longest a round may run, in milliseconds. */
38
- export declare const MAX_ROUND_DURATION_MS: number;
39
- /**
40
- * A round starts on the TV and the phones at once: when the host has the
41
- * round's video preloaded the server picks a start time ROUND_LEAD_MS ahead -
42
- * long enough for the message to reach the TV - or the host's planned start,
43
- * if later. The TV plays the video at that moment by its own clock, corrected
44
- * against the server's with `time:ping`, and the phones get the options then.
45
- */
46
- export declare const ROUND_LEAD_MS = 700;
47
- /**
48
- * The countdown before round 1 runs on the TV and every phone at once, and only
49
- * once everybody is there for it: starting a game asks the TV and every phone
50
- * in the room whether it is ready (`game:prepare`), and the countdown goes out
51
- * to all of them (`game:countdown`) once they have all said so (`game:ready`)
52
- * - or this long after the start, so that one device that never answers cannot
53
- * keep the rest waiting.
54
- */
55
- export declare const GAME_READY_TIMEOUT_MS = 10000;
56
- /** No I, O, 0 or 1 - codes are read off a TV screen and typed on a phone. */
57
- export declare const CODE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
58
- export declare const CODE_LENGTH = 6;
59
- /**
60
- * A room's code starts with the prefix of the server that holds it, and the
61
- * load balancer routes on it: every connection that knows its room carries
62
- * the code in the `c` query parameter (ROUTING_QUERY_KEY), so it reaches that
63
- * server whichever server it would otherwise have been handed to.
64
- */
65
- export declare const CODE_PREFIX_LENGTH = 2;
66
- export declare const ROUTING_QUERY_KEY = "c";
67
- /**
68
- * The speed test a TV times in the lobby, to pick a video rendition it can
69
- * load quickly all game: files of random bytes on the CDN that serves the
70
- * phone page, closer to where the videos come from than the party servers
71
- * are. One file per size, at `speedtestPath(size)`.
72
- */
73
- export declare const SPEEDTEST_SIZES: readonly [number, number, number, number, number, number];
74
- export declare function speedtestPath(size: number): string;
75
- /** What the phone page is told about the party servers: see phonePageConfigScript. */
76
- export interface PhonePageConfig {
77
- /** The servers' global name: for a code from no region it knows. */
78
- socketUrl: string;
79
- /** Each region's own name, for the codes that region hands out (see PARTY_REGIONS). */
80
- regionSocketUrls?: Record<string, string>;
81
- }
82
- /**
83
- * The phone page's `config.js`: where its sockets go. Written when the page
84
- * is deployed, since the party servers' names depend on where; everything
85
- * else the page needs from the protocol is bundled into it.
86
- */
87
- export declare function phonePageConfigScript(config: PhonePageConfig): string;
88
- /** The socket URL for a code, by its region. */
89
- export declare function socketUrlForCode(code: string, config: PhonePageConfig): string;
90
- /**
91
- * Which region's servers hand out the codes starting with which characters.
92
- * A room lives on one server in one region, and the party servers' global
93
- * name is latency-routed, so a TV and a phone in the same room can be sent
94
- * to different regions: a code says which region it belongs to, and a
95
- * client connects for it to that region's own name. Between them the
96
- * regions cover every first character, so any code belongs somewhere.
97
- */
98
- export declare const PARTY_REGIONS: Readonly<Record<string, string>>;
99
- /** The region a code belongs to. */
100
- export declare function regionOfCode(code: string): string | null;
101
- /** `code` tidied up the way a phone types it, or null if it cannot be a code. */
102
- export declare function normaliseCode(code: unknown): string | null;
103
- /** The server prefix a code routes by. */
104
- export declare function codePrefixOf(code: string): string;
105
- /**
106
- * Speed based scoring, mirroring the single player formula in GameCore:
107
- * points scale with the time left on the clock, with a bonus for answering
108
- * in the first half of the round.
109
- */
110
- export declare function scoreForAnswer(secondsLeft: number, totalRoundTime: number, modifier: number): number;
111
- /** The TV or a phone -> server: here, set up, and ready for the countdown. */
112
- export declare const GameEvent: {
113
- readonly Ready: 'game:ready';
114
- };
115
- /** Server -> the TV and the phones */
116
- export declare const GameMessage: {
117
- /** Say when you are ready for the countdown (phones: straight away). */
118
- readonly Prepare: 'game:prepare';
119
- /** Everybody is: start the countdown now. */
120
- readonly Countdown: 'game:countdown';
121
- };
122
- /** TV -> server: the server's clock, for working out the offset to it. */
123
- export declare const TimeEvent: {
124
- readonly Ping: 'time:ping';
125
- };
126
- /** Host -> server */
127
- export declare const HostEvent: {
128
- readonly Create: 'host:create';
129
- readonly Start: 'host:start';
130
- /** The round's options and answer, sent once the host's video is preloaded. */
131
- readonly RoundStart: 'host:round-start';
132
- readonly RoundEnd: 'host:round-end';
133
- /**
134
- * An ad is playing on the TV, between rounds: the phones say so until the
135
- * next round starts.
136
- */
137
- readonly AdBreak: 'host:ad-break';
138
- readonly GameEnd: 'host:game-end';
139
- readonly Restart: 'host:restart';
140
- /** Open, here, a room handed over by a server on its way out: see HostMessage.Move. */
141
- readonly Adopt: 'host:adopt';
142
- /** To the server it is leaving: the room is open again under this code. */
143
- readonly Moved: 'host:moved';
144
- /**
145
- * The players of a room that was lost mid-game - its server went - put
146
- * into this one, the lobby the TV opened instead, for each phone to claim
147
- * back by name: see HostRestoreRequest.
148
- */
149
- readonly Restore: 'host:restore';
150
- };
151
- /** Player -> server */
152
- export declare const PlayerEvent: {
153
- readonly Join: 'player:join';
154
- readonly Ready: 'player:ready';
155
- readonly Answer: 'player:answer';
156
- };
157
- /** Server -> host */
158
- export declare const HostMessage: {
159
- readonly Players: 'players';
160
- readonly AllAnswered: 'round:all-answered';
161
- readonly GameOver: 'game:over';
162
- /** Play the round at `startAt` (server time). */
163
- readonly RoundGo: 'round:go';
164
- /**
165
- * This server is on its way out and the game is over: take the room to
166
- * another one (`host:adopt` with the token, over a connection with no room
167
- * in its query), then say where it went (`host:moved`).
168
- */
169
- readonly Move: 'room:move';
170
- };
171
- /** Server -> player */
172
- export declare const PlayerMessage: {
173
- readonly State: 'state';
174
- readonly Dropped: 'dropped';
175
- readonly RoundStart: 'round:start';
176
- readonly RoundResult: 'round:result';
177
- /** An ad is playing on the TV (a PlayerAdBreak): the next round:start ends it. */
178
- readonly AdBreak: 'ad:break';
179
- readonly GameOver: 'game:over';
180
- /** The party is open under another code: connect for it and rejoin as before. */
181
- readonly Moved: 'room:moved';
182
- /** The party is waiting for its TV, which is gone for now: try again in a while. */
183
- readonly Parked: 'room:parked';
184
- };
185
- export declare const GameStatus: {
186
- readonly Lobby: 'lobby';
187
- readonly Playing: 'playing';
188
- readonly Over: 'over';
189
- };
190
- /**
191
- * Why a host call was refused, in its ack's `reason`.
192
- */
193
- export declare const HostRefusal: {
194
- /**
195
- * A server on its way out: it keeps the rooms it has, but opens no new ones
196
- * (and past its drain deadline, starts no more games), so the host connects
197
- * again without a room in its query - which the load balancer hands to a
198
- * server still taking parties - and asks again.
199
- */
200
- readonly Draining: 'draining';
201
- /** The room is open under another code, `movedTo`: ask again there. */
202
- readonly Moved: 'moved';
203
- /** The room is on its way to another server: ask again once it is there. */
204
- readonly Moving: 'moving';
205
- };
206
- /** Why a phone's call was refused, in its ack's `reason`. */
207
- export declare const PlayerRefusal: {
208
- /** The room is on its way to another server: ask again in a moment, or follow room:moved. */
209
- readonly Moving: 'moving';
210
- /** No party has this code. */
211
- readonly NotFound: 'not-found';
212
- /** A game is being played: new players can join once the TV sets up the next one. */
213
- readonly Started: 'started';
214
- /** The room's TV has left: only the phones already in it can come back. */
215
- readonly TvGone: 'tv-gone';
216
- };
217
- /**
218
- * What a host or a phone can do beyond the first version of the protocol,
219
- * sent with `host:create` and `player:join`. A server only moves a room when
220
- * its host and every phone in it can follow.
221
- */
222
- export declare const Feature: {
223
- readonly Move: 'move';
224
- };
225
- export type PartyFeature = (typeof Feature)[keyof typeof Feature];
226
- /** Enough of a room to open it again on another server. */
227
- export interface RoomSnapshot {
228
- code: string;
229
- gameType: PartyGameType;
230
- genre: string | null;
231
- genreName: string | null;
232
- totalRounds: number;
233
- status: 'lobby' | 'over';
234
- hostId: string | null;
235
- touchedAt: number;
236
- players: {
237
- id: string;
238
- name: string;
239
- score: number;
240
- lastGain: number;
241
- joinedAt: number;
242
- ready: boolean;
243
- canMove: boolean;
244
- pending?: boolean;
245
- }[];
246
- }
247
- export type PartyGameType = 'nametheartist' | 'namethesong' | 'namethesongandartist';
248
- export type PartyStatus = (typeof GameStatus)[keyof typeof GameStatus];
249
- export interface PartyPlayer {
250
- id: string;
251
- name: string;
252
- score: number;
253
- rank: number;
254
- connected: boolean;
255
- /** Has said they are here for this game. New joiners are ready already. */
256
- ready: boolean;
257
- answered: boolean;
258
- /** null until the round is scored, then true/false for this player. */
259
- correct: boolean | null;
260
- /** points gained in the round that was just scored */
261
- gained: number;
262
- /** Brought back from a room that was lost, and not claimed by a phone yet: see HostEvent.Restore. */
263
- pending?: boolean;
264
- }
265
- export interface PartyRoundOption {
266
- id: string;
267
- label: string;
268
- /** A second line, under the label: the artist, in Name the Song and Artist. */
269
- detail?: string;
270
- }
271
- /** Every ack carries `ok`; a refusal says why in `error`. */
272
- export interface Ack {
273
- ok: boolean;
274
- error?: string;
275
- }
276
- export interface HostCreateRequest {
277
- /** A room this TV knows: re-attach to it, or with `reopen`, reopen it. */
278
- code?: string;
279
- /** Opening a lobby rather than re-attaching: a recent room comes back cleared. */
280
- reopen?: boolean;
281
- /** Which TV this is: see `PartyGameClient`'s hostId. */
282
- hostId?: string;
283
- gameType?: PartyGameType;
284
- genre?: string;
285
- /** How the TV names the genre, for the phones: `genre` is only its id. */
286
- genreName?: string | null;
287
- totalRounds?: number;
288
- features?: PartyFeature[];
289
- }
290
- export interface PartyHostSession {
291
- code: string;
292
- joinUrl: string;
293
- /** True when this lobby picked up the previous game's room and players. */
294
- reused: boolean;
295
- maxPlayers: number;
296
- totalRounds: number;
297
- status: PartyStatus;
298
- players: PartyPlayer[];
299
- }
300
- export type HostCreateAck = (Ack & {
301
- ok: true;
302
- } & PartyHostSession) | (Ack & {
303
- ok: false;
304
- reason?: (typeof HostRefusal)[keyof typeof HostRefusal];
305
- movedTo?: string;
306
- });
307
- export interface HostAdoptRequest {
308
- token: string;
309
- hostId?: string;
310
- features?: PartyFeature[];
311
- }
312
- export interface HostMovedRequest {
313
- code: string;
314
- }
315
- export interface RoomMoveMessage {
316
- token: string;
317
- }
318
- export interface RoomMovedMessage {
319
- code: string;
320
- }
321
- export interface HostStartRequest {
322
- totalRounds?: number;
323
- }
324
- export interface HostStartAck extends Ack {
325
- players?: PartyPlayer[];
326
- totalRounds?: number;
327
- }
328
- export interface PartyRoundConfig {
329
- round: number;
330
- options: PartyRoundOption[];
331
- correctIndex: number;
332
- durationMs: number;
333
- modifier: number;
334
- /** Server time the round should not start before: when the TV will be there for it. */
335
- notBefore?: number;
336
- }
337
- /** What one player answered in a round, for the TV's analytics. */
338
- export interface PartyRoundAnswer {
339
- playerId: string;
340
- /** null: no answer */
341
- answerIndex: number | null;
342
- /** Server receipt minus the round's start, on the server's clock; null: no answer. */
343
- answerMs: number | null;
344
- }
345
- export interface PartyRoundResults {
346
- round: number;
347
- correctIndex: number;
348
- players: PartyPlayer[];
349
- /**
350
- * Host only - phones never see each other's answers. Missing from a server
351
- * from before it was added.
352
- */
353
- answers?: PartyRoundAnswer[];
354
- }
355
- export type HostRoundEndAck = Ack & Partial<PartyRoundResults>;
356
- export interface HostGameEndAck extends Ack {
357
- standings?: PartyPlayer[];
358
- }
359
- export interface HostRestartAck extends Ack {
360
- players?: PartyPlayer[];
361
- }
362
- /**
363
- * The players of the room that was lost, with their scores. Each waits in the
364
- * room, pending, until a phone joins under the same name (case aside) and
365
- * carries on as that player, score and all; one that never does stays in the
366
- * standings. Only into a lobby, and never over a name already in it.
367
- */
368
- export interface HostRestoreRequest {
369
- players: {
370
- name: string;
371
- score: number;
372
- }[];
373
- }
374
- export interface HostRestoreAck extends Ack {
375
- players?: PartyPlayer[];
376
- }
377
- export interface TimePingAck {
378
- now: number;
379
- }
380
- /** Server -> host: the roster, scores and who has answered. */
381
- export interface PlayersMessage {
382
- code: string;
383
- status: PartyStatus;
384
- players: PartyPlayer[];
385
- }
386
- /** When a round starts, on the server's clock. */
387
- export interface PartyRoundGo {
388
- round: number;
389
- startAt: number;
390
- /** How far past its planned start the round is starting. */
391
- lateByMs?: number | null;
392
- }
393
- export interface AllAnsweredMessage {
394
- round: number;
395
- }
396
- /** Server -> host: `game:countdown`. A phone's is empty. */
397
- export interface CountdownMessage {
398
- /**
399
- * Phones that said they were ready before the countdown went out - all of
400
- * them, or those ready by GAME_READY_TIMEOUT_MS. Missing from a server from
401
- * before it was added.
402
- */
403
- ready?: number;
404
- }
405
- /** A round as a phone sees it: never the answer. */
406
- export interface PlayerRound {
407
- number: number;
408
- totalRounds: number;
409
- options: PartyRoundOption[];
410
- durationMs: number;
411
- endsAt: number;
412
- serverTime?: number;
413
- }
414
- /** An ad break on the TV, as a phone sees it: `ad:break`, and in its state. */
415
- export interface PlayerAdBreak {
416
- /** The round that starts once the break is over. */
417
- nextRound: number;
418
- totalRounds: number;
419
- }
420
- export interface PlayerLastResult {
421
- correct: boolean;
422
- points: number;
423
- answerIndex: number | null;
424
- }
425
- /** Everything a phone needs to render itself from scratch after a reconnect. */
426
- export interface PlayerState {
427
- code: string;
428
- status: PartyStatus;
429
- gameType: PartyGameType;
430
- /** The genre's id, which picks the game logo the phone shows. */
431
- genre: string | null;
432
- genreName: string | null;
433
- totalRounds: number;
434
- playerId: string;
435
- name: string;
436
- ready: boolean;
437
- score: number;
438
- rank: number | null;
439
- playerCount: number;
440
- answered: number | null;
441
- round: PlayerRound | null;
442
- lastResult: PlayerLastResult | null;
443
- /** An ad is playing on the TV, between rounds: null when not. */
444
- adBreak: PlayerAdBreak | null;
445
- standings: PartyPlayer[] | null;
446
- /**
447
- * Whether the TV is there now. A room outlives its TV for a while, to be
448
- * reopened by its next lobby: a phone coming back meanwhile is told.
449
- */
450
- hostConnected: boolean;
451
- }
452
- export interface PlayerJoinRequest {
453
- code: string;
454
- name?: string;
455
- /** Kept by the phone, so a rejoin keeps its score. */
456
- playerId?: string | null;
457
- /**
458
- * Made up by the phone for a join from scratch, and sent again with a
459
- * retry of it: a join the server took but whose answer never reached the
460
- * phone left a seat under the name, which this retry gets back rather than
461
- * be refused as a name taken. Nothing else matches it.
462
- */
463
- joinId?: string;
464
- features?: PartyFeature[];
465
- }
466
- export interface PlayerJoinAck extends Ack {
467
- state?: PlayerState;
468
- /** The party is open under this code now: join there. */
469
- movedTo?: string;
470
- /** The party is waiting for its TV: try again in a while. */
471
- parked?: boolean;
472
- reason?: (typeof PlayerRefusal)[keyof typeof PlayerRefusal];
473
- }
474
- export interface PlayerAnswerRequest {
475
- index: number;
476
- /**
477
- * The round the answer is for. One that reaches the server once another
478
- * round is on - held up on a stalled connection, say - is refused as
479
- * `no-round` rather than counted for a round the player never saw. Pages
480
- * before this field leave it out, and are scored against the round on.
481
- */
482
- round?: number;
483
- }
484
- export interface PlayerAnswerAck extends Ack {
485
- reason?: string;
486
- answered: number | null;
487
- }
488
- export interface PlayerRoundResult {
489
- round: number;
490
- correctIndex: number;
491
- correct: boolean;
492
- answerIndex: number | null;
493
- gained: number;
494
- score: number;
495
- rank: number;
496
- playerCount: number;
497
- }
498
- export interface PlayerGameOver {
499
- standings: PartyPlayer[];
500
- gameType: PartyGameType;
501
- genre: string | null;
502
- genreName: string | null;
503
- rank: number;
504
- score: number;
505
- }
506
- export interface DroppedMessage {
507
- reason: string;
508
- }
509
- //# sourceMappingURL=protocol.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}