// FlatBuffers payloads for the client <-> gateway edge transport (Stage 6). // // Every request and response that rides inside the Connect envelope // (gateway/proto/edge) `payload` field, and every push Event payload, is one of // these tables. They are the binary wire contract shared with the UI, which // generates TypeScript from this same schema (Stage 7). A single namespace keeps // nested tables (GameView inside MoveResult / MatchResult) free of // cross-namespace imports. Keep this schema and the backend JSON DTOs in lockstep // — the gateway transcodes one to the other. // // Generate Go with `make fbs` (flatc, version-pinned). The committed output lives // in fbs/scrabblefb/. namespace scrabblefb; // --- shared building blocks --- // TileRecord is one placed (or to-place) tile: its board coordinate, the concrete // letter ("?" when read from a hand for a blank) and whether it came from a blank. table TileRecord { row:int; col:int; letter:string; blank:bool; } // SeatView is one seat's public standing in a game. display_name is resolved by the // backend from the account store (added trailing — backward-compatible). table SeatView { seat:int; account_id:string; score:int; hints_used:int; is_winner:bool; display_name:string; } // GameView is the shared (non-private) game summary. table GameView { id:string; variant:string; dict_version:string; status:string; players:int; to_move:int; turn_timeout_secs:int; move_count:int; end_reason:string; seats:[SeatView]; } // MoveRecord is one decoded move (a committed play, or a hint preview). table MoveRecord { player:int; action:string; dir:string; main_row:int; main_col:int; tiles:[TileRecord]; words:[string]; count:int; score:int; total:int; } // --- auth (unauthenticated) --- // TelegramLoginRequest carries the platform launch data; the gateway validates // its HMAC before forwarding the extracted identity to the backend. table TelegramLoginRequest { init_data:string; } // GuestLoginRequest bootstraps an ephemeral guest session. locale is an optional // preferred-language hint. table GuestLoginRequest { locale:string; } // EmailRequestRequest asks the backend to send a login confirm-code to email. table EmailRequestRequest { email:string; } // EmailLoginRequest logs in (or provisions) the account owning email, verifying // the confirm-code. table EmailLoginRequest { email:string; code:string; } // Session is the minted credential returned by every auth operation. table Session { token:string; user_id:string; is_guest:bool; display_name:string; } // Ack is a simple success acknowledgement (e.g. an email-code request). table Ack { ok:bool; } // --- profile (authenticated) --- // Profile is the authenticated account's own profile view. table Profile { user_id:string; display_name:string; preferred_language:string; time_zone:string; hint_balance:int; block_chat:bool; block_friend_requests:bool; is_guest:bool; } // --- game (authenticated) --- // SubmitPlayRequest places tiles in a direction on the player's turn. table SubmitPlayRequest { game_id:string; dir:string; tiles:[TileRecord]; } // MoveResult is the outcome of a committed move: the move and the post-move game. table MoveResult { move:MoveRecord; game:GameView; } // StateRequest asks for the requesting player's view of a game. table StateRequest { game_id:string; } // StateView is a player's view of a game: the shared summary plus their private // rack, the bag size and their remaining hint budget. table StateView { game:GameView; seat:int; rack:[string]; bag_len:int; hints_remaining:int; } // GameActionRequest carries just a game id (pass / resign / hint / history). table GameActionRequest { game_id:string; } // ExchangeRequest swaps the listed rack tiles back into the bag. table ExchangeRequest { game_id:string; tiles:[string]; } // EvalRequest previews a tentative play without committing it. table EvalRequest { game_id:string; dir:string; tiles:[TileRecord]; } // EvalResult is an unlimited move preview: legality, score and the words formed. table EvalResult { legal:bool; score:int; words:[string]; } // CheckWordRequest looks a word up in the game's pinned dictionary. table CheckWordRequest { game_id:string; word:string; } // WordCheckResult is the dictionary lookup outcome. table WordCheckResult { word:string; legal:bool; } // ComplaintRequest disputes a word-check result. table ComplaintRequest { game_id:string; word:string; note:string; } // HintResult is the top-ranked move plus the remaining hint budget. table HintResult { move:MoveRecord; hints_remaining:int; } // History is a game's decoded move journal — the source for client board replay. table History { game_id:string; moves:[MoveRecord]; } // GameList is the caller's games (active and finished) for the lobby. table GameList { games:[GameView]; } // --- lobby (authenticated) --- // EnqueueRequest joins the per-variant auto-match pool. table EnqueueRequest { variant:string; } // MatchResult reports whether the caller has been paired into a game yet. table MatchResult { matched:bool; game:GameView; } // --- chat (authenticated) --- // ChatPostRequest posts a per-game chat message. table ChatPostRequest { game_id:string; body:string; } // ChatMessage is one stored chat message or nudge. table ChatMessage { id:string; game_id:string; sender_id:string; kind:string; body:string; created_at_unix:long; } // ChatList is a game's chat history. table ChatList { messages:[ChatMessage]; } // --- push event payloads --- // YourTurnEvent signals that it is now the recipient's turn. table YourTurnEvent { game_id:string; deadline_unix:long; } // OpponentMovedEvent summarises a move another seat just committed; the client // refetches the full state. table OpponentMovedEvent { game_id:string; seat:int; action:string; score:int; total:int; } // NudgeEvent signals that a player nudged the recipient. table NudgeEvent { game_id:string; from_user_id:string; } // MatchFoundEvent signals that an auto-match pairing (or robot substitution) // started a game the recipient is seated in. table MatchFoundEvent { game_id:string; }