eieio.games

by nolen royalty

One Million Chessboards

a million chessboards that anyone can play on

Apr 28, 2025

Hello from the future

This blog has received more traffic than I expected. It’s pretty sparse - sorry about that! I’m working on super-detailed explanation of how One Million Chessboards works. Check back in a few days for a proper writeup and video.

You can follow my mailing list, youtube, twitter, or bsky if you want to catch my update when it goes live.

In the meantime play the game here.

Anyway

I made a website. It’s called One Million Chessboards. It has one million chessboards on it.

Moving a piece moves it for everyone, instantly. There are no turns. You can move between boards.

moving some pieces

What

Well last year I made this game called One Million Checkboxes.

It was a pretty fun time! So I thought I’d do something like this again.

I worked really hard on this one. I hope you like it.

How

This was the most technically challenging thing that I’ve worked on in a long time. I’m going to save a full technical writeup until I see how my decisions pan out, since I think there’s a decent chance I’ll need to make a lot of changes.

But I’ll summarize a few things for you.

  • Unlike One Million Checkboxes, I designed this for scale
  • The game runs on a single server (!)
  • The board is stored fully in-memory; it’s a 2D array of 64 million uint64s
  • The backend is written in go. This is my first go project.
  • I use a single writer thread, tons of reader threads, and coordinate access to the board with a mutex
  • The frontend optimistically applies all moves you make immediately. It then builds up a dependency graph of the moves you’ve made, and backs them out if it receives a conflicting update before the server acks your move.
  • The server ships zstd-compressed protobufs to the clients over websockets for state snapshots (approximately a 100x100 square around the client), move and capture updates, and acks/rejections for moves
  • Clients are grouped into 50x50 “zones” and only receive moves for zones adjacent to their current zone
  • Clients fetch global data (game stats, the minimap, etc) by polling via GET; data is cached in Cloudflare with a low TTL so this is much cheaper than shipping it over every websocket

That last part - optimistic move application with what games people sometimes call “rollback” - is about 1,600 lines of code that took me a ~7 days of fulltime work to write. I don’t remember the last time I wrestled with a problem that hard!

As of 8 PM, 8 hours after launch, players have made about 1.3 million moves and there are about 400 concurrent users most of the time. Load on my server is neglibible!

Can I play

Yes! Play it here.

I really hope you like this one. More updates to come :)

Thanks for reading!

Keep up with me on my socials 👆

Or sub to my newsletter here! 👇