Make the web client game-generic against the platform API

Send creation options as the nested options object the lobby expects,
drive the creation form from each game's options_schema, and render
history/leaderboard from the generic result payload (nullable teams,
float points). The lobby uses the payload's seats_open, and the
scopone-specific table, hand-end and game-over views are gated on its
game_type with an unsupported-game fallback for future games. The
websocket protocol is unchanged.
This commit is contained in:
2026-09-21 13:04:08 +08:00
parent 4b66407fa4
commit 83ecf9bed3
6 changed files with 763 additions and 73 deletions
+5 -2
View File
@@ -35,9 +35,12 @@ pub async fn game_types() -> Result<Vec<GameTypeInfo>, String> {
Ok(page.results)
}
pub async fn create_game(game_type: &str, target_score: i32, napola: bool) -> Result<GameView, String> {
/// Create a lobby game. `options` is the game-specific creation object
/// described by the engine's `options_schema` (see
/// [`crate::model::GameTypeInfo::option_fields`]).
pub async fn create_game(game_type: &str, options: serde_json::Value) -> Result<GameView, String> {
let resp = Request::post("/api/games")
.json(&serde_json::json!({ "game_type": game_type, "target_score": target_score, "napola": napola }))
.json(&serde_json::json!({ "game_type": game_type, "options": options }))
.map_err(|e| e.to_string())?
.send()
.await