Skip to content

Latest commit

 

History

History
116 lines (85 loc) · 3.42 KB

File metadata and controls

116 lines (85 loc) · 3.42 KB

Analysis API

Post-game analysis powered by Stockfish.

Endpoints (Auth Required)

POST /api/v1/games/:id/analyze

Queue a game for analysis. Must be a player in the game. Game must be completed.

Response (200):

{ "status": "queued", "message": "Analysis queued" }

If already queued/processing: returns current status without re-queuing.

GET /api/v1/games/:id/analysis

Get analysis results.

Response (processing):

{ "status": "processing", "analysis": null }

Response (done):

{
  "status": "done",
  "analysis": {
    "id": "clx...",
    "whiteAccuracy": 87.3,
    "blackAccuracy": 72.1,
    "opening": { "name": "Sicilian Defense", "eco": "B20" },
    "feedback": [
      {
        "ply": 1,
        "san": "e4",
        "uci": "e2e4",
        "fen": "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1",
        "classification": "BEST",
        "bestMove": "e2e4",
        "evalBefore": 0,
        "evalAfter": 25
      }
    ]
  }
}

Analysis Pipeline

  1. API pushes gameId to Redis analysis:queue list
  2. Worker polls queue every 2 seconds
  3. For each position:
    • Stockfish evaluates at depth 18 (MultiPV 1)
    • For brilliant detection: MultiPV 2 on position before the move
  4. Each move classified by centipawn loss
  5. Accuracy computed per player
  6. Results saved to GameAnalysis + MoveFeedback tables

Reliability

The worker includes several reliability mechanisms:

  • Circuit breaker: If 3 consecutive analysis jobs fail, the Stockfish engine is automatically restarted
  • Retry tracking: Failed jobs are re-queued up to 3 times (retry count tracked in Redis with 1h TTL)
  • Dead letter queue: Jobs that fail 3 times are moved to analysis:dlq and marked as error — they won't be retried
  • Graceful recovery: After engine restart, the worker resumes processing from the next job in the queue

Move Classifications

Classification CP Loss Color
Brilliant < 5 + sacrifice + alternatives > 150 worse Cyan
Great 0 - 5 Blue
Best 0 - 10 Green
Excellent 10 - 25 Light green
Good 25 - 50 Gray
Inaccuracy 50 - 100 Yellow
Mistake 100 - 200 Orange
Blunder 200+ Red
Forced Only 1 legal move Gray

Brilliant Detection

A move is brilliant if:

  1. It involves a material sacrifice (attacker value > captured value)
  2. Centipawn loss < 5 (it's a good move)
  3. The next-best alternative loses > 150 centipawns

Accuracy Formula

accuracy = average(2 / (1 + exp(0.004 * cpLoss)) * 100)

Computed separately for white and black moves.

Opening Recognition

~65 common openings indexed by SAN move sequence. Longest prefix match (most specific opening that matches the game's moves).

Job Status

Tracked in Redis as analysis:status:{gameId}:

  • queued — waiting in queue
  • processing — worker is analyzing
  • done — results saved to DB
  • error — analysis failed