Add microservices, web UI, and replay tooling
Some checks failed
ci / tests (push) Has been cancelled
Some checks failed
ci / tests (push) Has been cancelled
This commit is contained in:
61
docs/architecture.md
Normal file
61
docs/architecture.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Catan Microservices Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
This repo is a monorepo with separate services (each container) and a shared core engine.
|
||||
|
||||
Services:
|
||||
- **api-gateway**: Auth, lobby, websocket fanout, user masking, orchestrates game/AI services.
|
||||
- **game-service**: Authoritative game state + rule validation, trade offers, AI turn loop triggers.
|
||||
- **ai-service**: Model inference + random policy; returns actions + debug metadata.
|
||||
- **analytics-service**: Stats, replays, debug views, replay reconstruction.
|
||||
- **web**: React UI (served by nginx) for lobby, game, analytics, replays.
|
||||
|
||||
Shared:
|
||||
- **catan** package: game engine & rules.
|
||||
- **services/common**: env settings, shared schemas, JWT helpers, db helpers.
|
||||
|
||||
## Runtime data flow
|
||||
|
||||
1. Client logs in via api-gateway (`/api/auth/*`).
|
||||
2. Client interacts with lobby/game via api-gateway.
|
||||
3. api-gateway forwards game mutations to game-service.
|
||||
4. game-service applies actions to the core engine and persists events to Postgres.
|
||||
5. game-service may call ai-service for AI moves.
|
||||
6. api-gateway broadcasts updated game state to connected clients (websocket).
|
||||
7. analytics-service reads events from Postgres to compute stats + replays.
|
||||
|
||||
## Storage
|
||||
|
||||
Postgres (single instance) with service-owned tables:
|
||||
- api-gateway: users
|
||||
- game-service: games, game_events, trade_offers
|
||||
- analytics-service: materialized stats + replay metadata (optional)
|
||||
|
||||
## Replay format
|
||||
|
||||
Replay format is JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"created_at": "...",
|
||||
"seed": 123,
|
||||
"players": ["A", "B"],
|
||||
"actions": [
|
||||
{"idx": 1, "actor": "A", "type": "roll", "payload": {}},
|
||||
{"idx": 2, "actor": "A", "type": "build_road", "payload": {"edge": 4}}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
analytics-service reconstructs a state at any action index by replaying from seed.
|
||||
|
||||
## Debug mode
|
||||
|
||||
`DEBUG=true` enables:
|
||||
- full action payloads
|
||||
- AI logits/probabilities
|
||||
- full observation snapshots
|
||||
|
||||
These are stored in `game_events.debug_payload` (JSON).
|
||||
32
docs/replay_format.md
Normal file
32
docs/replay_format.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Replay Format
|
||||
|
||||
JSON-формат реплея (v1) хранит сид партии и список применённых действий. Состояние восстанавливается повторным проигрыванием событий.
|
||||
|
||||
Пример:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"id": "d7b4b593-0f2a-4c3f-9d90-6f6a8a3ddf2e",
|
||||
"created_at": "2024-03-01T12:00:00Z",
|
||||
"seed": 123456,
|
||||
"players": ["Alice", "Bob"],
|
||||
"winner": "Alice",
|
||||
"slots": [
|
||||
{"slot_id": 1, "name": "Alice", "user_id": 1, "is_ai": false, "ready": true, "color": "red"},
|
||||
{"slot_id": 2, "name": "Bob", "user_id": null, "is_ai": true, "ai_kind": "random", "ready": true, "color": "blue"}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"idx": 1,
|
||||
"ts": "2024-03-01T12:01:00Z",
|
||||
"actor": "Alice",
|
||||
"action": {"type": "roll", "payload": {}},
|
||||
"applied": true,
|
||||
"meta": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Импорт в аналитический сервис сохраняет реплей в базу и делает его доступным в UI.
|
||||
Reference in New Issue
Block a user