@thegeem/protocol 0.1.32 → 0.1.34
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 +11 -3
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +11 -3
- package/package.json +1 -1
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).
|
|
@@ -176,6 +177,13 @@ var ClientMsg = import_zod.z.discriminatedUnion("t", [
|
|
|
176
177
|
// an explicit seating beats an implicit one.
|
|
177
178
|
// Violations are rejected with `invalid_seat`. Consumed by دامة (the only fixed-seat game today).
|
|
178
179
|
players: import_zod.z.array(PlayerId).min(1).max(LIMITS.MAX_PLAYERS).optional(),
|
|
180
|
+
// SOLO vs the machine (gs#68). Fills the seats a game needs that no human took, so one person can
|
|
181
|
+
// play with nobody else around — دامة's «تمرين». Additive, no pv bump; omit it and nothing changes.
|
|
182
|
+
// The bot is a SEAT the relay drives, never something a client runs: Shape B means the server is
|
|
183
|
+
// still the referee, and a client-side opponent could not be trusted with the board anyway.
|
|
184
|
+
// `difficulty` is one search with different depth+noise, not three implementations.
|
|
185
|
+
// Solo games are deliberately NOT RATED and never touch the دامة ELO ladder — see the driver.
|
|
186
|
+
bot: import_zod.z.object({ difficulty: import_zod.z.enum(["easy", "medium", "hard"]).optional() }).optional(),
|
|
179
187
|
// PREFERRED: pick a mode from the registry (see MODES). The server maps it to the engine
|
|
180
188
|
// rules. Send this and omit buzzerMode/noHost. Falls back to the legacy flags below if omitted.
|
|
181
189
|
modeId: import_zod.z.enum(MODE_IDS).optional(),
|
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>;
|
|
@@ -369,6 +378,13 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
369
378
|
categoryIds: z.ZodArray<z.ZodString, "many">;
|
|
370
379
|
hostPlays: z.ZodOptional<z.ZodBoolean>;
|
|
371
380
|
players: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
381
|
+
bot: z.ZodOptional<z.ZodObject<{
|
|
382
|
+
difficulty: z.ZodOptional<z.ZodEnum<["easy", "medium", "hard"]>>;
|
|
383
|
+
}, "strip", z.ZodTypeAny, {
|
|
384
|
+
difficulty?: "easy" | "medium" | "hard" | undefined;
|
|
385
|
+
}, {
|
|
386
|
+
difficulty?: "easy" | "medium" | "hard" | undefined;
|
|
387
|
+
}>>;
|
|
372
388
|
modeId: z.ZodOptional<z.ZodEnum<["solo", "oneDevice", "snag", "multiplayer"]>>;
|
|
373
389
|
buzzerMode: z.ZodOptional<z.ZodEnum<["off", "solo", "race", "controller"]>>;
|
|
374
390
|
noHost: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -380,6 +396,9 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
380
396
|
modeId?: "snag" | "solo" | "oneDevice" | "multiplayer" | undefined;
|
|
381
397
|
hostPlays?: boolean | undefined;
|
|
382
398
|
players?: string[] | undefined;
|
|
399
|
+
bot?: {
|
|
400
|
+
difficulty?: "easy" | "medium" | "hard" | undefined;
|
|
401
|
+
} | undefined;
|
|
383
402
|
buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
|
|
384
403
|
noHost?: boolean | undefined;
|
|
385
404
|
}, {
|
|
@@ -390,6 +409,9 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
390
409
|
modeId?: "snag" | "solo" | "oneDevice" | "multiplayer" | undefined;
|
|
391
410
|
hostPlays?: boolean | undefined;
|
|
392
411
|
players?: string[] | undefined;
|
|
412
|
+
bot?: {
|
|
413
|
+
difficulty?: "easy" | "medium" | "hard" | undefined;
|
|
414
|
+
} | undefined;
|
|
393
415
|
buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
|
|
394
416
|
noHost?: boolean | undefined;
|
|
395
417
|
}>, z.ZodObject<{
|
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>;
|
|
@@ -369,6 +378,13 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
369
378
|
categoryIds: z.ZodArray<z.ZodString, "many">;
|
|
370
379
|
hostPlays: z.ZodOptional<z.ZodBoolean>;
|
|
371
380
|
players: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
381
|
+
bot: z.ZodOptional<z.ZodObject<{
|
|
382
|
+
difficulty: z.ZodOptional<z.ZodEnum<["easy", "medium", "hard"]>>;
|
|
383
|
+
}, "strip", z.ZodTypeAny, {
|
|
384
|
+
difficulty?: "easy" | "medium" | "hard" | undefined;
|
|
385
|
+
}, {
|
|
386
|
+
difficulty?: "easy" | "medium" | "hard" | undefined;
|
|
387
|
+
}>>;
|
|
372
388
|
modeId: z.ZodOptional<z.ZodEnum<["solo", "oneDevice", "snag", "multiplayer"]>>;
|
|
373
389
|
buzzerMode: z.ZodOptional<z.ZodEnum<["off", "solo", "race", "controller"]>>;
|
|
374
390
|
noHost: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -380,6 +396,9 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
380
396
|
modeId?: "snag" | "solo" | "oneDevice" | "multiplayer" | undefined;
|
|
381
397
|
hostPlays?: boolean | undefined;
|
|
382
398
|
players?: string[] | undefined;
|
|
399
|
+
bot?: {
|
|
400
|
+
difficulty?: "easy" | "medium" | "hard" | undefined;
|
|
401
|
+
} | undefined;
|
|
383
402
|
buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
|
|
384
403
|
noHost?: boolean | undefined;
|
|
385
404
|
}, {
|
|
@@ -390,6 +409,9 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
390
409
|
modeId?: "snag" | "solo" | "oneDevice" | "multiplayer" | undefined;
|
|
391
410
|
hostPlays?: boolean | undefined;
|
|
392
411
|
players?: string[] | undefined;
|
|
412
|
+
bot?: {
|
|
413
|
+
difficulty?: "easy" | "medium" | "hard" | undefined;
|
|
414
|
+
} | undefined;
|
|
393
415
|
buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
|
|
394
416
|
noHost?: boolean | undefined;
|
|
395
417
|
}>, z.ZodObject<{
|
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).
|
|
@@ -139,6 +140,13 @@ var ClientMsg = z.discriminatedUnion("t", [
|
|
|
139
140
|
// an explicit seating beats an implicit one.
|
|
140
141
|
// Violations are rejected with `invalid_seat`. Consumed by دامة (the only fixed-seat game today).
|
|
141
142
|
players: z.array(PlayerId).min(1).max(LIMITS.MAX_PLAYERS).optional(),
|
|
143
|
+
// SOLO vs the machine (gs#68). Fills the seats a game needs that no human took, so one person can
|
|
144
|
+
// play with nobody else around — دامة's «تمرين». Additive, no pv bump; omit it and nothing changes.
|
|
145
|
+
// The bot is a SEAT the relay drives, never something a client runs: Shape B means the server is
|
|
146
|
+
// still the referee, and a client-side opponent could not be trusted with the board anyway.
|
|
147
|
+
// `difficulty` is one search with different depth+noise, not three implementations.
|
|
148
|
+
// Solo games are deliberately NOT RATED and never touch the دامة ELO ladder — see the driver.
|
|
149
|
+
bot: z.object({ difficulty: z.enum(["easy", "medium", "hard"]).optional() }).optional(),
|
|
142
150
|
// PREFERRED: pick a mode from the registry (see MODES). The server maps it to the engine
|
|
143
151
|
// rules. Send this and omit buzzerMode/noHost. Falls back to the legacy flags below if omitted.
|
|
144
152
|
modeId: z.enum(MODE_IDS).optional(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thegeem/protocol",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
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",
|