@thegeem/protocol 0.1.33 → 0.1.35

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/dist/index.cjs CHANGED
@@ -90,6 +90,7 @@ var HelpType = import_zod.z.enum([
90
90
  var Pv = import_zod.z.number().int().min(1).max(1e6).optional();
91
91
  var IdToken = import_zod.z.string().max(4096).optional();
92
92
  var Platform = import_zod.z.enum(["web", "ios", "android"]).optional();
93
+ var AppVersion = import_zod.z.string().trim().max(24).regex(/^[0-9]+(\.[0-9]+){0,3}([-+][0-9A-Za-z.-]+)?$/, "bad app version").optional();
93
94
  var Avatar = import_zod.z.object({
94
95
  emoji: import_zod.z.string().min(1).max(16).transform((s) => s.replace(UNSAFE_CHARS, "")).refine((s) => s.length >= 1, "empty emoji"),
95
96
  color: import_zod.z.string().regex(/^#[0-9a-fA-F]{6}$/, "color must be #rrggbb")
@@ -97,7 +98,7 @@ var Avatar = import_zod.z.object({
97
98
  var Character = import_zod.z.enum(CHARACTER_IDS);
98
99
  var ClientMsg = import_zod.z.discriminatedUnion("t", [
99
100
  // room / lobby
100
- import_zod.z.object({ t: import_zod.z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), game: import_zod.z.enum(GAME_IDS).optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
101
+ import_zod.z.object({ t: import_zod.z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), game: import_zod.z.enum(GAME_IDS).optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
101
102
  // Host sets/changes their display name AFTER createRoom (for anonymous one-tap
102
103
  // hosts who started nameless). Host-only; the relay re-broadcasts the lobby.
103
104
  // SUPERSEDED by setProfile (kept working for shipped builds).
@@ -111,8 +112,8 @@ var ClientMsg = import_zod.z.discriminatedUnion("t", [
111
112
  // view carries names+avatars so it updates live; dama/ersimha views are id-keyed (clients
112
113
  // map ids→names from the lobby roster), so a change there lands on the next lobby.
113
114
  import_zod.z.object({ t: import_zod.z.literal("setProfile"), name: DisplayName.optional(), avatar: Avatar.optional(), character: Character.optional() }),
114
- import_zod.z.object({ t: import_zod.z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
115
- import_zod.z.object({ t: import_zod.z.literal("resume"), code: RoomCode, token: import_zod.z.string().max(120), avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
115
+ import_zod.z.object({ t: import_zod.z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
116
+ import_zod.z.object({ t: import_zod.z.literal("resume"), code: RoomCode, token: import_zod.z.string().max(120), avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
116
117
  // `tally` (gs#46) = wins per PLAYER across every game this room has played tonight — «نتيجة الليلة».
117
118
  // Keyed by playerId, NOT by team: team names are recycled each game, so a per-team count means nothing
118
119
  // across a night. Survives playAgain. A One Device game credits nobody (its team slots hold no players).
package/dist/index.d.cts CHANGED
@@ -122,6 +122,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
122
122
  pv: z.ZodOptional<z.ZodNumber>;
123
123
  idToken: z.ZodOptional<z.ZodString>;
124
124
  platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
125
+ appVersion: z.ZodOptional<z.ZodString>;
125
126
  }, "strip", z.ZodTypeAny, {
126
127
  t: "createRoom";
127
128
  name?: string | undefined;
@@ -134,6 +135,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
134
135
  pv?: number | undefined;
135
136
  idToken?: string | undefined;
136
137
  platform?: "web" | "ios" | "android" | undefined;
138
+ appVersion?: string | undefined;
137
139
  }, {
138
140
  t: "createRoom";
139
141
  name?: string | undefined;
@@ -146,6 +148,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
146
148
  pv?: number | undefined;
147
149
  idToken?: string | undefined;
148
150
  platform?: "web" | "ios" | "android" | undefined;
151
+ appVersion?: string | undefined;
149
152
  }>, z.ZodObject<{
150
153
  t: z.ZodLiteral<"renameHost">;
151
154
  name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
@@ -203,6 +206,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
203
206
  pv: z.ZodOptional<z.ZodNumber>;
204
207
  idToken: z.ZodOptional<z.ZodString>;
205
208
  platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
209
+ appVersion: z.ZodOptional<z.ZodString>;
206
210
  }, "strip", z.ZodTypeAny, {
207
211
  code: string;
208
212
  t: "joinRoom";
@@ -215,6 +219,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
215
219
  pv?: number | undefined;
216
220
  idToken?: string | undefined;
217
221
  platform?: "web" | "ios" | "android" | undefined;
222
+ appVersion?: string | undefined;
218
223
  }, {
219
224
  code: string;
220
225
  t: "joinRoom";
@@ -227,6 +232,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
227
232
  pv?: number | undefined;
228
233
  idToken?: string | undefined;
229
234
  platform?: "web" | "ios" | "android" | undefined;
235
+ appVersion?: string | undefined;
230
236
  }>, z.ZodObject<{
231
237
  t: z.ZodLiteral<"resume">;
232
238
  code: z.ZodString;
@@ -245,6 +251,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
245
251
  pv: z.ZodOptional<z.ZodNumber>;
246
252
  idToken: z.ZodOptional<z.ZodString>;
247
253
  platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
254
+ appVersion: z.ZodOptional<z.ZodString>;
248
255
  }, "strip", z.ZodTypeAny, {
249
256
  code: string;
250
257
  t: "resume";
@@ -257,6 +264,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
257
264
  pv?: number | undefined;
258
265
  idToken?: string | undefined;
259
266
  platform?: "web" | "ios" | "android" | undefined;
267
+ appVersion?: string | undefined;
260
268
  }, {
261
269
  code: string;
262
270
  t: "resume";
@@ -269,6 +277,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
269
277
  pv?: number | undefined;
270
278
  idToken?: string | undefined;
271
279
  platform?: "web" | "ios" | "android" | undefined;
280
+ appVersion?: string | undefined;
272
281
  }>, z.ZodObject<{
273
282
  t: z.ZodLiteral<"setPlaying">;
274
283
  playerId: z.ZodOptional<z.ZodString>;
@@ -683,6 +692,34 @@ interface LobbyPlayer {
683
692
  /** Team index once the game has started; null/absent in the lobby. */
684
693
  teamIndex?: number | null;
685
694
  }
695
+ /**
696
+ * Who is in the room, carried ON the game-state push (gs#71).
697
+ *
698
+ * `players[]` in the `lobby` frame is the only other carrier of names, and the lobby does not go out
699
+ * mid-game — deliberately, since a stray `lobby` under a running game bounces clients off their board
700
+ * (the gs#49 class). So a client that refreshed mid-game had NO roster for the rest of the game, and
701
+ * every id→name lookup degraded to whatever that client happened to use as its null-fallback: «؟» on
702
+ * web, the colour name in دامة on Android (readable by luck), and an empty string in ارسمها (a sentence
703
+ * with a hole in it).
704
+ *
705
+ * It rides ON the state message rather than arriving as a separate frame because both consuming teams
706
+ * asked for that independently, for the same reason: a roster in its own message can land either side
707
+ * of the state push, giving one render with names and one without on clients that redraw per state.
708
+ * Bundled, it cannot race.
709
+ *
710
+ * Unlike `LobbyPlayer` this INCLUDES THE HOST (`isHost`), who is filtered out of `lobby.players` by
711
+ * design and therefore has no row — yet needs a face wherever the host can appear, e.g. the `tally`.
712
+ */
713
+ interface RosterEntry {
714
+ id: string;
715
+ name: string;
716
+ /** Privacy-safe avatar (emoji + color); absent if unset. */
717
+ avatar?: AvatarView;
718
+ /** True for the room's host, who has no row in `lobby.players`. */
719
+ isHost?: boolean;
720
+ /** Is this person currently connected? Mirrors `LobbyPlayer.connected`. */
721
+ connected?: boolean;
722
+ }
686
723
  /** Per-recipient context attached to lobby/state pushes. */
687
724
  interface YouContext {
688
725
  id: string;
@@ -945,16 +982,19 @@ type ServerMsg = {
945
982
  view: GameStateView;
946
983
  you: YouContext;
947
984
  teamConnected: boolean[];
985
+ roster?: RosterEntry[];
948
986
  } | {
949
987
  t: 'damaState';
950
988
  gameId: 'dama';
951
989
  view: DamaStateView;
952
990
  you: YouContext;
991
+ roster?: RosterEntry[];
953
992
  } | {
954
993
  t: 'ersimhaState';
955
994
  gameId: 'ersimha';
956
995
  view: ErsimhaStateView;
957
996
  you: YouContext;
997
+ roster?: RosterEntry[];
958
998
  } | {
959
999
  t: 'strokeBatch';
960
1000
  from: string;
@@ -986,4 +1026,4 @@ type ServerMsg = {
986
1026
  message: string;
987
1027
  };
988
1028
 
989
- export { type AvatarView, type BuzzerGameMode, CHARACTER_IDS, type CategoryView, type CharacterId, ClientMsg, type DamaMoveView, type DamaPieceView, type DamaStateView, EMOTE_IDS, type Effect, type EmoteId, type ErsimhaStateView, GAMES, GAME_IDS, type GameId, type GameInfo, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MIN_SUPPORTED_PV, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type ServerMsg, type SoundName, type StrokePointView, type TeamSlotView, type TeamView, type YouContext, gameIdForPv, gamesForPv, modesForGame };
1029
+ export { type AvatarView, type BuzzerGameMode, CHARACTER_IDS, type CategoryView, type CharacterId, ClientMsg, type DamaMoveView, type DamaPieceView, type DamaStateView, EMOTE_IDS, type Effect, type EmoteId, type ErsimhaStateView, GAMES, GAME_IDS, type GameId, type GameInfo, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MIN_SUPPORTED_PV, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type RosterEntry, type ServerMsg, type SoundName, type StrokePointView, type TeamSlotView, type TeamView, type YouContext, gameIdForPv, gamesForPv, modesForGame };
package/dist/index.d.ts CHANGED
@@ -122,6 +122,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
122
122
  pv: z.ZodOptional<z.ZodNumber>;
123
123
  idToken: z.ZodOptional<z.ZodString>;
124
124
  platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
125
+ appVersion: z.ZodOptional<z.ZodString>;
125
126
  }, "strip", z.ZodTypeAny, {
126
127
  t: "createRoom";
127
128
  name?: string | undefined;
@@ -134,6 +135,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
134
135
  pv?: number | undefined;
135
136
  idToken?: string | undefined;
136
137
  platform?: "web" | "ios" | "android" | undefined;
138
+ appVersion?: string | undefined;
137
139
  }, {
138
140
  t: "createRoom";
139
141
  name?: string | undefined;
@@ -146,6 +148,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
146
148
  pv?: number | undefined;
147
149
  idToken?: string | undefined;
148
150
  platform?: "web" | "ios" | "android" | undefined;
151
+ appVersion?: string | undefined;
149
152
  }>, z.ZodObject<{
150
153
  t: z.ZodLiteral<"renameHost">;
151
154
  name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
@@ -203,6 +206,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
203
206
  pv: z.ZodOptional<z.ZodNumber>;
204
207
  idToken: z.ZodOptional<z.ZodString>;
205
208
  platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
209
+ appVersion: z.ZodOptional<z.ZodString>;
206
210
  }, "strip", z.ZodTypeAny, {
207
211
  code: string;
208
212
  t: "joinRoom";
@@ -215,6 +219,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
215
219
  pv?: number | undefined;
216
220
  idToken?: string | undefined;
217
221
  platform?: "web" | "ios" | "android" | undefined;
222
+ appVersion?: string | undefined;
218
223
  }, {
219
224
  code: string;
220
225
  t: "joinRoom";
@@ -227,6 +232,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
227
232
  pv?: number | undefined;
228
233
  idToken?: string | undefined;
229
234
  platform?: "web" | "ios" | "android" | undefined;
235
+ appVersion?: string | undefined;
230
236
  }>, z.ZodObject<{
231
237
  t: z.ZodLiteral<"resume">;
232
238
  code: z.ZodString;
@@ -245,6 +251,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
245
251
  pv: z.ZodOptional<z.ZodNumber>;
246
252
  idToken: z.ZodOptional<z.ZodString>;
247
253
  platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
254
+ appVersion: z.ZodOptional<z.ZodString>;
248
255
  }, "strip", z.ZodTypeAny, {
249
256
  code: string;
250
257
  t: "resume";
@@ -257,6 +264,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
257
264
  pv?: number | undefined;
258
265
  idToken?: string | undefined;
259
266
  platform?: "web" | "ios" | "android" | undefined;
267
+ appVersion?: string | undefined;
260
268
  }, {
261
269
  code: string;
262
270
  t: "resume";
@@ -269,6 +277,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
269
277
  pv?: number | undefined;
270
278
  idToken?: string | undefined;
271
279
  platform?: "web" | "ios" | "android" | undefined;
280
+ appVersion?: string | undefined;
272
281
  }>, z.ZodObject<{
273
282
  t: z.ZodLiteral<"setPlaying">;
274
283
  playerId: z.ZodOptional<z.ZodString>;
@@ -683,6 +692,34 @@ interface LobbyPlayer {
683
692
  /** Team index once the game has started; null/absent in the lobby. */
684
693
  teamIndex?: number | null;
685
694
  }
695
+ /**
696
+ * Who is in the room, carried ON the game-state push (gs#71).
697
+ *
698
+ * `players[]` in the `lobby` frame is the only other carrier of names, and the lobby does not go out
699
+ * mid-game — deliberately, since a stray `lobby` under a running game bounces clients off their board
700
+ * (the gs#49 class). So a client that refreshed mid-game had NO roster for the rest of the game, and
701
+ * every id→name lookup degraded to whatever that client happened to use as its null-fallback: «؟» on
702
+ * web, the colour name in دامة on Android (readable by luck), and an empty string in ارسمها (a sentence
703
+ * with a hole in it).
704
+ *
705
+ * It rides ON the state message rather than arriving as a separate frame because both consuming teams
706
+ * asked for that independently, for the same reason: a roster in its own message can land either side
707
+ * of the state push, giving one render with names and one without on clients that redraw per state.
708
+ * Bundled, it cannot race.
709
+ *
710
+ * Unlike `LobbyPlayer` this INCLUDES THE HOST (`isHost`), who is filtered out of `lobby.players` by
711
+ * design and therefore has no row — yet needs a face wherever the host can appear, e.g. the `tally`.
712
+ */
713
+ interface RosterEntry {
714
+ id: string;
715
+ name: string;
716
+ /** Privacy-safe avatar (emoji + color); absent if unset. */
717
+ avatar?: AvatarView;
718
+ /** True for the room's host, who has no row in `lobby.players`. */
719
+ isHost?: boolean;
720
+ /** Is this person currently connected? Mirrors `LobbyPlayer.connected`. */
721
+ connected?: boolean;
722
+ }
686
723
  /** Per-recipient context attached to lobby/state pushes. */
687
724
  interface YouContext {
688
725
  id: string;
@@ -945,16 +982,19 @@ type ServerMsg = {
945
982
  view: GameStateView;
946
983
  you: YouContext;
947
984
  teamConnected: boolean[];
985
+ roster?: RosterEntry[];
948
986
  } | {
949
987
  t: 'damaState';
950
988
  gameId: 'dama';
951
989
  view: DamaStateView;
952
990
  you: YouContext;
991
+ roster?: RosterEntry[];
953
992
  } | {
954
993
  t: 'ersimhaState';
955
994
  gameId: 'ersimha';
956
995
  view: ErsimhaStateView;
957
996
  you: YouContext;
997
+ roster?: RosterEntry[];
958
998
  } | {
959
999
  t: 'strokeBatch';
960
1000
  from: string;
@@ -986,4 +1026,4 @@ type ServerMsg = {
986
1026
  message: string;
987
1027
  };
988
1028
 
989
- export { type AvatarView, type BuzzerGameMode, CHARACTER_IDS, type CategoryView, type CharacterId, ClientMsg, type DamaMoveView, type DamaPieceView, type DamaStateView, EMOTE_IDS, type Effect, type EmoteId, type ErsimhaStateView, GAMES, GAME_IDS, type GameId, type GameInfo, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MIN_SUPPORTED_PV, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type ServerMsg, type SoundName, type StrokePointView, type TeamSlotView, type TeamView, type YouContext, gameIdForPv, gamesForPv, modesForGame };
1029
+ export { type AvatarView, type BuzzerGameMode, CHARACTER_IDS, type CategoryView, type CharacterId, ClientMsg, type DamaMoveView, type DamaPieceView, type DamaStateView, EMOTE_IDS, type Effect, type EmoteId, type ErsimhaStateView, GAMES, GAME_IDS, type GameId, type GameInfo, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MIN_SUPPORTED_PV, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type RosterEntry, type ServerMsg, type SoundName, type StrokePointView, type TeamSlotView, type TeamView, type YouContext, gameIdForPv, gamesForPv, modesForGame };
package/dist/index.js CHANGED
@@ -53,6 +53,7 @@ var HelpType = z.enum([
53
53
  var Pv = z.number().int().min(1).max(1e6).optional();
54
54
  var IdToken = z.string().max(4096).optional();
55
55
  var Platform = z.enum(["web", "ios", "android"]).optional();
56
+ var AppVersion = z.string().trim().max(24).regex(/^[0-9]+(\.[0-9]+){0,3}([-+][0-9A-Za-z.-]+)?$/, "bad app version").optional();
56
57
  var Avatar = z.object({
57
58
  emoji: z.string().min(1).max(16).transform((s) => s.replace(UNSAFE_CHARS, "")).refine((s) => s.length >= 1, "empty emoji"),
58
59
  color: z.string().regex(/^#[0-9a-fA-F]{6}$/, "color must be #rrggbb")
@@ -60,7 +61,7 @@ var Avatar = z.object({
60
61
  var Character = z.enum(CHARACTER_IDS);
61
62
  var ClientMsg = z.discriminatedUnion("t", [
62
63
  // room / lobby
63
- z.object({ t: z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), game: z.enum(GAME_IDS).optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
64
+ z.object({ t: z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), game: z.enum(GAME_IDS).optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
64
65
  // Host sets/changes their display name AFTER createRoom (for anonymous one-tap
65
66
  // hosts who started nameless). Host-only; the relay re-broadcasts the lobby.
66
67
  // SUPERSEDED by setProfile (kept working for shipped builds).
@@ -74,8 +75,8 @@ var ClientMsg = z.discriminatedUnion("t", [
74
75
  // view carries names+avatars so it updates live; dama/ersimha views are id-keyed (clients
75
76
  // map ids→names from the lobby roster), so a change there lands on the next lobby.
76
77
  z.object({ t: z.literal("setProfile"), name: DisplayName.optional(), avatar: Avatar.optional(), character: Character.optional() }),
77
- z.object({ t: z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
78
- z.object({ t: z.literal("resume"), code: RoomCode, token: z.string().max(120), avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
78
+ z.object({ t: z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
79
+ z.object({ t: z.literal("resume"), code: RoomCode, token: z.string().max(120), avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
79
80
  // `tally` (gs#46) = wins per PLAYER across every game this room has played tonight — «نتيجة الليلة».
80
81
  // Keyed by playerId, NOT by team: team names are recycled each game, so a per-team count means nothing
81
82
  // across a night. Survives playAgain. A One Device game credits nobody (its team slots hold no players).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thegeem/protocol",
3
- "version": "0.1.33",
3
+ "version": "0.1.35",
4
4
  "description": "Geem's wire protocol — shared zod schemas + TypeScript types for talking to the Geem game server over Socket.IO. The source of truth all clients implement against.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://geem.tv",