Taps can be unreliable inside this app's built-in browser. For the full experience, use its menu to open this page in your browser.
Skip to content

Redrawing A Chessboard 60 Times A Second

A devlog by Neeraj Kotwani, who builds every game on Elipar.

I gave Chess 3D a proper visual pass: real tone mapping, lacquered wooden pieces, coordinates baked into the frame, a knight that actually reads as a horse. Then I measured it and it was the slowest 3D game on the site. Twelve frames a second, against about sixty for Marble Maze on the same machine.

Chess, though. A chessboard spends almost all of its life absolutely motionless.

Draw when something changes

Every 3D game I'd written before this one has a render loop, because every one of them had something moving in it. I'd copied the pattern across without asking whether it applied.

It doesn't. Chess is idle by default. So it now draws a frame when something actually happens: a piece moves, highlights change, the window resizes, or an animation is in progress. Sit and stare at the board and it issues no draw calls at all. I checked: zero over a second and a half.

That is obviously the right shape for a board game and I still find it slightly funny that I built it the other way first.

Testing this is not about counting frames

My first test counted draw calls and asserted the number went up after a move. It failed intermittently, because the opponent has its own thinking delay and my test was racing it. I spent a while assuming I'd broken something.

Counting is the wrong question anyway. Nobody cares how many frames were drawn. What matters is that the picture on screen is never stale, and there's a direct way to ask that: take a hash of the canvas, force exactly one render, hash it again. If those differ, then something had changed the board and failed to ask for a redraw, and you were looking at a lie.

That check now runs after selecting a piece, after moving, after the opponent replies, after undo, after promotion, after checkmate and after a resize. It is a much better test than the one I started with and it's shorter.

The line I would never have guessed

Drawing on demand fixes idling. It doesn't make an individual frame any cheaper, and mine were expensive.

I had suspicions. The shadow map was large. The pieces used a clearcoat material, which is the shiny lacquered look and sounds costly. So rather than guess I toggled things one at a time on the live scene and measured each.

Baseline was about 300 milliseconds a frame in my very slow test environment. Halving the shadow map: 313. No change, arguably worse, well inside the noise. Turning off clearcoat: 305. Also nothing.

Removing the scene's environment map: 161.

One line. Almost half the frame. The environment map is what gives the pieces their soft reflections, and setting it on the scene applies it to every material in it. Including the board, the frame around the board, and the table the whole thing sits on, which between them are by far the largest areas of the screen and which reflect essentially nothing you would ever notice.

So the environment map is attached to the pieces only, which got it from 300 to 222, and trimming the curve resolution on the turned pieces took it to 205. The pieces still look lacquered. The table was never going to shine.

Both of the things I'd suspected were noise and the thing I hadn't considered was all of it. If a Three.js scene is unexpectedly slow, try nulling the scene environment before touching anything else.

Two leaks, found while in there

The function that syncs the pieces to the board state runs after every move, and it was building fresh geometry every time for all the small decorative bits: the crenellations on the rooks, the points on the crowns, the cross on the king. None of it disposed. The highlight overlay was worse, creating both a geometry and a material for every highlighted square on every redraw.

Both are built once now. Neither was the cause of anything I'd noticed, but a game you can leave open for an hour shouldn't leak, and going looking for allocations in a hot path is how you find that sort of thing.

Where it ended up

A single frame costs about 28 per cent more than the old ugly version. I'm completely happy with that, because the old version paid it sixty times a second while nothing moved and the new one pays it when you make a move.

One caveat on those numbers, since I keep having to remind myself: my test machine has no GPU and draws everything on the processor, so the absolute figures are meaningless. Only the comparison against another game on the same machine, or against the previous build, tells you anything at all.

Chess 3D is free in a browser with three difficulty levels, and it no longer works hard to show you a board that isn't doing anything.

We use cookies to keep games running and, once ads are live, to show relevant content. See our Privacy Policy for details.