All Projects
Video GameJuly 2026

Arcane Chess

A 3D chess sanctuary — play a Stockfish bot solo or duel a friend online with P2P voice, all rendered in a self-playing fairytale garden.

Arcane Chess screenshot

Overview

Most browser chess is a flat 2D grid. Arcane Chess is a proper 3D duel staged inside a fairytale garden — pieces glide and hop across the board, captures shatter into particles, and the whole scene glows with cinematic lighting. There are two ways to play. Solo mode pits you against a chess bot with easy, medium, and hard difficulty, tuned to take a beat before it replies so it never feels robotic. Room mode lets you create a private link and duel a friend online, complete with built-in voice chat so you can talk trash while you play. Even the landing page is alive: the board plays itself, filmed by a camera that drifts and cuts between shots like a movie. And because it installs as an app and works offline, you can keep playing without a connection.

A Baked GLB, Reverse-Engineered

The pieces and board come from a single meshopt-compressed GLB (shrunk from ~8.9MB to 1.2MB) with no semantic node names — every piece is `Circle.001`, `Circle.002`, and so on, each a group of two meshes for the body and its metal accent. Because there are no textures and no labels, pieces are identified by reverse-engineering their world-space position and height in the standard starting layout: file from the X axis, rank from Z, corroborated by measured model-unit heights (king ≈ 8698 down to knight ≈ 4654). The renderer picks one representative node per colour-and-type, clones it, recenters its geometry, and places clones from the live board array. Square size isn't hard-coded either — it self-calibrates at runtime from the distance between two adjacent starting pieces, so swapping in a different model only means rewriting one mapping table.

Authoritative Rooms & P2P Voice

One Cloudflare Worker plus Durable Object instance equals one game. Connection order decides your role — first in is white, second is black, the next fifteen are spectators, capped at seventeen. The Durable Object holds the only real chess.js position: clients send a move, the server validates and applies it, then broadcasts the new state to everyone, so cheating a client does nothing. A new game requires both players to vote yes. Voice is a separate concern — the server relays only WebRTC signaling, and audio travels pure peer-to-peer through a mesh of RTCPeerConnections using the perfect-negotiation pattern so either side can re-offer without glare. Speaking detection runs entirely client-side off a single AudioContext analyser loop, driving live speaking dots and a join/leave activity feed.

Motion, Sound & Cinematics

Moves aren't teleports. Each piece has its own tween — knights hop, everything else glides — and captures animate a sinking, fading clone of the taken piece plus an instanced-mesh particle shatter. New games trigger a staggered materialize where pieces drop and grow in wave by wave across the board. The camera opens on a raised three-quarter framing and, when the board-follow lock is on, spins so your side always faces you. On the landing page a director camera hard-cuts between low glides, close push-ins, a slow orbit, and a pull-back reveal. Most sound effects are synthesized live with the Web Audio API; only the looping background music and the four cycled wooden move-taps are real samples.

Runs Everywhere, Adapts To Everything

Weak hardware is a first-class citizen. A hidden in-Canvas sampler measures real rendered frames per second during a short warmup and picks a High or Low graphics quality automatically the first time you visit — Low drops post-processing and shadows and caps the device pixel ratio — then persists the choice so it never re-measures or flashes on later visits. Player preferences (name, hints, move history, board-follow lock, volume, last colour, graphics quality) live in localStorage behind SSR-safe getters. Every non-trivial pure module — the piece mapping, easing helpers, voice-activity detection, debug FEN scenarios, room role assignment — ships with a runnable Node self-check, and the GLB itself is validated by a script that confirms the mapped nodes still exist and sit at sane heights.

What I Learned

  • 01

    You can build a full 3D game on a model you don't control. The GLB had no usable names, so the entire piece identity had to be derived from geometry — world position and baked height in the starting layout — and the square scale self-calibrated at runtime. It turned an unusable asset into a swappable one.

  • 02

    An authoritative server is the only honest way to do online chess. Letting a Durable Object own the single real position and having clients merely propose moves means there's no client-side state to tamper with, and it made spectators, roles, and rematch voting fall out naturally.

  • 03

    Peer-to-peer voice belongs off the server. Relaying only signaling and letting audio flow browser-to-browser via a perfect-negotiation WebRTC mesh keeps latency low and the server cheap — the hard part is renegotiating cleanly when someone joins voice after connecting.

  • 04

    Auto-detecting graphics quality from measured fps beats asking the user. Sampling real frames during a warmup, persisting the verdict, and only ever measuring once gives weak devices a smooth experience without a settings interrogation or a mid-session quality flash.

  • 05

    Synthesizing sound effects with the Web Audio API instead of shipping audio files keeps the download tiny and makes every cue tweakable in code. Only the things that genuinely need to sound real — the background music and the wooden move-taps — are worth shipping as samples.

  • 06

    A self-playing, cinematically filmed board is a better landing page than any hero copy. Letting the product demo itself the moment someone arrives sells the experience far faster than a screenshot or a paragraph ever could.

Next Project
Thock Mania
Available for projectsReady to make something fun 🎈

Ready to build the next system?Wanna build something awesome together?

Currently accepting high-impact opportunities in frontend engineering and scalable web applications.Got a cool idea rattling around? Let's grab a virtual coffee and turn it into something people love. ☕