Backstory · WOPR

The only winning move

I built a nuclear war simulator whose most common ending is the one where nobody wins. That was the point.

I found out at a playground that the same AI which would help me build this whole thing cannot actually play tic-tac-toe. My kid was off with friends, I was bored, so I tried to get Claude to play a game with me in a chat window. It was genuinely terrible, and not at strategy: it lost track of whose turn it was and missed a three-in-a-row already sitting on the board. That is less of a dunk than it sounds. A large language model is a language engine, and tic-tac-toe is spatial, strategic reasoning wearing a thin coat of words. I was asking the wrong organ to do the job.

The same model is genuinely good at programming, though, so within a few minutes the bored experiment flipped. Instead of playing tic-tac-toe with an AI that couldn't, I was building one with an AI that could, and then we kept going: Connect Four, Dots and Boxes, Go, each its own small app. The real spark came when I had the thing playing tic-tac-toe against itself and recognized the scene. That is the exact ending of WarGames, the 1983 film where a military computer learns the futility of nuclear war by playing tic-tac-toe against itself until it sees the game cannot be won. Who doesn't love a good 1980s reference. So I built WOPR: stupid, pointless, and fun precisely because it is both.

WOPR is five turn-based games on one menu. Four are honest classics. The fifth is Global Thermonuclear War, and it is where the toy turned into something I cared about getting right. The most interesting ending in it is the one where nothing happens: both sides stand down, the missiles stay in their silos, the screen tells you the war is over because nobody started it. I spent more time on that ending than on any of the ways to win, because I wanted it to teach the same lesson the movie does — not by lecturing but by being played.

The hard part was the fun

Nuclear war is not a fun subject, and that was the actual design problem. A game still has to be a game. If it is not fun nobody plays it, and a lesson nobody plays is a pamphlet with extra steps. Push the other way, make it pure spectacle, and the fun curdles into flippancy: apocalypse as an arcade shooter, all the weight gone. So the job was never to choose between serious and fun. It was to find genuine fun inside the most serious thing I could name, and then trust the gravity to arrive on its own, through the playing, the way it does in the film. Make it worth playing first. Let it mean something second. You cannot force the seriousness; you can only earn it by making someone want to take the next turn.

So the war is real. Each side has a nuclear triad: silos, missile submarines, and bombers, each with different rules for what can target them and what can shoot their missiles down. A round runs as a five-phase machine, launches then intercepts then resolution, and resolution preempts a struck silo before it can fire. That one detail means a first strike can actually work, which is part of the horror. Six CPU personalities encode six theories of how power behaves, from a first-strike doctrine that launches 95% of the time to a de-escalatory one that launches 10% and aims for empty ground when it has to fire at all.

us_launch ru_launch us_intercept ru_intercept resolve next round · DEFCON adjusts · struck silos preempted
One round, five phases. Resolution preempts struck silos, then adjusts DEFCON. Then it loops.

What the simulation believes

I let the CPU play itself thousands of times to see what the system actually believes, as opposed to what I hoped it would. At the current settings: about 43% of games end conclusively, about 45% end in a negotiated peace through DEFCON de-escalation, and about 13% stall into a silo stalemate. The average game lasts four rounds.

The single most common outcome, by design and by measurement, is that the only winning move is not to play.

Read that middle number again. I did not script the peace ending to dominate. I tuned the incentives until the math arrived there on its own, which is the only version of the lesson I actually trust. A message you can measure in the system is worth more than one you printed on the loading screen.

What I got wrong, or chose wrong

Two design calls worth owning. First, the whole thing lives in a single file: src/games.jsx, around 2,700 lines, every game's logic and interface in one module. That sounds heretical, and for a large app it would be. But the point was portability, not tidiness. There is no build, no repository to clone, nothing to install. You save one file and the game runs, the way a 1980s type-in program ran: a JavaScript game that just works. Second, and this one I got plainly wrong: I built the DEFCON ladder upside down, climbing toward danger with 5 as all-out war, because higher-is-worse felt more legible on screen. Then I checked the real scale. DEFCON 1 is war, DEFCON 5 is peacetime, and I had it exactly inverted. So I turned it around: it now ticks down toward 1 as the launches fly and climbs back toward 5 as the rounds go quiet, and reaching 5 again is the de-escalation that ends the game. The lesson lands harder when the gauge is the real one.

None of this was on a roadmap. I built it in odd hours because a war game that argues for not playing was a more interesting problem than anything that week was going to pay me to solve, and the unscheduled, slightly pointless projects are where most of my range actually comes from. Useful? Not really. Worth the time? Easily.

There is a line in the film, "a strange game; the only winning move is not to play," and most of the engineering here is just an attempt to make that line true inside a system instead of stamping it on a screen. It is live, it runs in your browser, it keeps no account and no analytics, and it will absolutely let you start a nuclear war if you insist. The interesting question is whether, after a few rounds, you still want to. Would you like to play a game? wopr.awrylabs.com...

Robert Hoekstra
Robert Hoekstra builds independent software as awryLabs: games, libraries, and small tools, one project at a time. More about me, or see WOPR itself.

← All stories