Here's your hackathon write-up:


Inspiration

Every chess player knows the frustration: you lose a game, run it through an engine, and get told "Stockfish prefers Nf3 with an eval of +1.2." That means nothing to a 1200-rated player. We wanted to build the coach that sits next to you and actually explains why your move was bad — what it gave up, what the better move threatens, and what pattern to remember next time. We also wanted to go beyond single-game analysis: what if you could scout an opponent before a tournament game, or drill the exact openings you're weakest at?

What it does

Chessimus is a three-in-one AI chess coaching platform:

  • Game Analysis — Paste a PGN or Lichess/Chess.com link. Stockfish evaluates every position, then Gemini explains each mistake in plain English. Arrows on the board show what you played vs. what you should have played, with hover tooltips for quick context.

  • Player Scouting — Enter any username to pull their recent games. Chessimus aggregates win rates, opening repertoires, color preferences, nemesis/victim rivalries, and termination patterns. Hit "AI Report" and Gemini writes a full scouting brief — how to beat them, what openings to exploit, where they crumble under pressure.

  • Opening Trainer — Search from 3,600+ openings from the Lichess database. The trainer walks you through each line move-by-move with AI explanations, then quizzes you from memory. A chat panel lets you ask Gemini questions about any position mid-drill.

How we built it

The stack is intentionally lean:

  • Backend: Vanilla Node.js HTTP server (no Express) with Stockfish spawned as a child process and Gemini called via REST API. SSE streaming pushes analysis results to the client move-by-move so the board is interactive immediately.
  • Frontend: Plain HTML/CSS/JS with chessboard.js for the interactive board and chess.js for move validation. No React, no build step. Custom SVG polygon arrows drawn directly on the board.
  • AI Integration: Gemini handles four distinct tasks — game coaching (structured JSON with whyBad/betterMove/tip fields), scout reports (7-section scouting brief), opening explanations (per-move pedagogical context), and freeform Q&A about positions.
  • Data: The Lichess chess-openings database (3,641 entries) is loaded client-side as a JSON file for instant search with zero server round-trips.
  • Deployment: Dockerized with Stockfish installed via apt, deployed on Railway.

Challenges we ran into

  • Gemini response truncation — Early on, coaching explanations would cut off mid-sentence. We had to build a robust JSON repair function that detects unclosed strings, arrays, and objects, then surgically closes them to recover partial responses.

  • SSE payload limits — Scouting 1,000+ games and sending them in a single SSE event would crash the connection. We switched to batched streaming (100 games per event) with client-side aggregation.

  • Making AI coaching actually useful — The first prompt iterations produced generic statements like "this move lost 87 centipawns." We iterated heavily on the system prompt to make Gemini reference specific squares, name tactical themes (pins, forks, outposts), and speak like a real coach — not a computer.

  • Opening trainer speed — The original flow hit the Lichess Explorer API 10-17 times sequentially before calling Gemini, taking ~30 seconds. We rebuilt it to parse openings client-side from the pre-loaded database and created a fast /explain-opening endpoint that skips the Explorer API entirely — load time dropped to under 1 second for the drill, with AI explanations streaming in the background.

  • Arrow positioning math — Drawing polygon-based arrows that look good at any board size and orientation (including flipped) required careful coordinate geometry: $\vec{u} = \frac{\vec{to} - \vec{from}}{|\vec{to} - \vec{from}|}$ for the unit direction vector, with perpendicular $\vec{p} = (-u_y, u_x)$ to compute shaft and arrowhead widths proportional to square size.

Accomplishments that we're proud of

  • The coaching genuinely teaches. It names the chess theme, explains what the better move does strategically, and gives a memorable takeaway — not just engine numbers.
  • Analysis streams in real-time: the board is playable the instant you paste a PGN, with evals and coaching populating progressively.
  • The opening trainer's two-phase flow (watch demo → drill from memory) with on-board tooltips and a chat panel feels like a real lesson, not a flashcard app.
  • The entire app is ~4,200 lines of code across 4 files with zero framework dependencies. It loads fast and runs anywhere.

What we learned

  • Prompt engineering for structured output is an art. Getting Gemini to consistently return valid JSON with the right tone took more iteration than any other part of the project.
  • SSE is underrated for AI applications — it gives you progressive rendering without WebSocket complexity.
  • Client-side data processing (aggregating 1,000+ games in the browser) is surprisingly fast and eliminates server bottleneck concerns.
  • The gap between "AI wrapper" and "AI product" is UX. The arrows, tooltips, streaming, and interactive board are what make the coaching feel real.

What's next for Chessimus

  • Personalized training plans — Use scouting data to automatically generate drills targeting the player's weakest openings and most common mistake patterns.
  • Multiplayer prep mode — Scout a specific opponent and get a pre-game briefing with recommended openings to play against them.
  • Endgame trainer — Extend the trainer to cover critical endgame positions (K+P vs K, rook endgames, etc.) with the same demo-then-drill flow.
  • Game database — Let users save and revisit analyzed games with persistent coaching notes.
  • Mobile optimization — The board and panels work on mobile but deserve a dedicated responsive layout for on-the-go review.

Built With

Share this project:

Updates