I’ve rewritten Galactic Warzone, my 1980s BBS door game, from scratch in Go. It’s multiplayer, it runs in a browser, and you can play it today at https://galwar.smbaker.com/

Some ancient history
I wrote Galactic Warzone sometime back in the 1980s. My memory of that time is a little scattered, but Galwar’s origin came about somewhere around ’88 or’89, while I was in high school. Trade Wars games were already popular inthe BBS space, with Trade Wars 1000 having been published by Alan Davenport and Chris Sherrick. I had graduated up to a Trade Wars clone called MOTU, which if I recall correctly had a few additional features like sector mines. The original TW1000 and MOTU, I’m pretty sure, were written in BASIC.
I was a Turbo Pascal programmer, and I came up with the bright idea of writing a Trade Wars style game in Turbo Pascal. It would be a complete write from scratch. At the time, Turbo Pascal was a very capable language, much more so than the BASIC interpreters and compilers of the day. My game would have 2,000 sectors rather than the usual 1,000, and it would start out with sector mines, cloaking devices, and a few other goodies. I named it Galactic Warzone.
Eventually it grew into a monster with outposts, starbases, planets you could create with a Genesis Device, and a catalog of 53 different devices that couldbe carried on your ship in a 15-slot equipment system. It featured NPC factions such as the Cabal and the Renegades, and an active Cabal-Federation war that ground along in the background whether you participated or not.
Galwar became my first commercially successful program — “commercially successful” here meaning a few thousand dollars in donations, which to a highschool student was a fortune. Eventually Galwar’s time came to pass. I moved on to writing Land of Devastation, and I sold Galactic Warzone.
But now is the time to rewrite it from scratch.
The Great Galactic Warzone Rewrite
I started the rewrite in 2025. These days I’m a Go programmer, so I chose to rewrite Galactic Warzone in Go. Go is a pretty decent language for this sort of thing: interfaces let me separate the game engine from the user interface, goroutines and channels handle the concurrency, and the whole server compiles to a single static binary that I can copy to a cheap cloud host. The original Galwar was strictly one caller at a time — that’s what a door game was — so the headline feature of the rewrite is that Galwar-2025 is multiplayer from the start. There’s no waiting for your friend to log off before you can begin.
Why rewrite it at all? Why not? For any programmer, it’s fun to see how your skills have evolved. Looking back at the original Galwar code, it’s quite primitive — lots of cut-and-paste coding, lots of brute-force logic. The rewrite is about 20,000 lines of Go, and this time the ore, organics, and equipment logic exists once in a table instead of three times via copy-paste.
Some highlights of the remake:
The 1986 rules, preserved. I still have the original Turbo Pascal source, and the Go code treats it as the spec. Combat, planet growth, mine damage, and port pricing are all transcribed from the Pascal, with comments citing the original file and line numbers as the authority. The combat attrition loop is reproduced exactly, including a quirk in a random roll that slightly favors the attacker. There’s a comment on it that says “do not simplify.”
2,000 sectors connected by a warp graph, which you can rewire with a Plasma Device.
Devices: Genesis Devices, Pulsar Bombs, Cloaking Devices, Emergency Warps (which fling you to a random sector to escape a killing blow), Mine Deflectors, Planetary Scanners, Fusion Cells that bank your unused turns overnight, and more. In fairness, the original had a catalog of 53 devices; looking back at it, that was mostly noise around about ten good ideas, and the rewrite keeps the good ideas.
Planets with nightly compounding production. You can land on them, invade them, and steal them.
Battlegroups — launch a strike fleet that fights its way along the shortest warp path through garrisons and minefields, and see what comes back.
NPC factions. The Cabal stays dormant until a player gets rich enough to be worth hunting, then it wakes up and goes after the leaderboard. The Renegades provide ambient piracy. The Federation wars on the Cabal every night to keep it from snowballing, and garrisons the ten sectors of protected FedSpace.
Player-versus-player combat, online or off. Everyone shares one live universe, so if your target is logged in, the attack lands on them right in the middle of their session. And you can still attack a player who isn’t logged in, like the old days — they’ll read about it in the news the next time they call.
The classic death penalty. Get destroyed and you forfeit your entire estate — your sector defenses revolt to the Renegades and your planets fall to the Cabal. The first death is free; after that it starts to hurt.
250 turns per day, reset by a nightly maintenance pass, much like a BBS whose sysop ran maintenance on the first call of the day.
This began as a manual rewrite, and I wrote the game core, universe, ports,terminal interface, etc., all back in 2025. Around 2026 the program hadlagged, so I used Claude Code to polish a few of the rough edges, including adding the web-based console, the google authentication, and other featuresto make it easily playable online.
A web-based application, but also telnet capable
The design decision I’m happiest with is that the game engine does no I/O at all. It doesn’t print, it doesn’t prompt, and it doesn’t know what a screenis. All the rendering lives in a console UI layer that talks to a small Terminal interface — essentially “print a string,” “read a line,” and “read apassword.” Anything that implements those three methods can host the game.
Three things currently do:
1. **A local console**, used for single-player mode and development.
2. **A telnet server.** It’s a real one: it performs telnet option negotiation to put the client into character-at-a-time mode, does its own backspace editing, and masks your password with asterisks. In the door game days, the BBS told the door whether the caller wanted graphics; a bare TCP socket has no BBS to ask, so the telnet server asks you directly: “Do you want ANSI color (Y/n)?”
3. **A web front end.** The browser runs xterm.js, a proper terminal emulator, connected to the server over a WebSocket. The JavaScript is deliberately a dumb terminal: it does local line editing and sends completed lines to the server. The ANSI color you see in the browser is generated by the same code the telnet users get. The color-handling code replicates the set_foreground routine from DoorDriver, the door library I wrote back in the day, and the color constants are named after the Turbo Pascal CRT unit’s color names.
One implementation detail I liked: the web client needs to be told when to stop echoing keystrokes for password entry, and I didn’t want a second protocol channel just for that. Game output never legitimately contains a NUL byte, so control messages to the browser are NUL-prefixed strings riding thesame WebSocket. Stealing an unused byte for signaling felt appropriately1980s.
There’s also some plumbing to make browsers behave: output goes through a buffered channel with a dedicated writer goroutine, so a stalled browser tabgets disconnected rather than ever blocking the game; idle sessions time out after fifteen minutes; and if you log in from a second tab, the newest connection wins and the old one gets a polite “Another session has taken overthis account. Goodbye!”
(The public server currently exposes only the web portal, but if you point atelnet client at a self-hosted instance, it feels exactly like 1986.)
One goroutine owns the universe
Multiplayer meant confronting a problem the original never had: concurrent modification of the universe. My first instinct was mutexes, and the early code was littered with “TODO: lock” comments that I kept not writing, because I could feel the deadlocks waiting for me.
The fix was to stop sharing. The universe is owned by a single goroutine — an actor. Player sessions collect input, build a complete command, and submit it to the actor’s channel, where commands execute one at a time. Every command is atomic with respect to every other command. No locks, no lock ordering, no torn state. A game like this is never going to generate enough traffic to stress one goroutine, and the game logic reads just like the single-player code it was ported from.
Persistence hangs off the same idea. The in-memory universe is authoritative, and a write-behind persister snapshots the whole world to SQLite at most onceper second, in a single transaction. The database on disk is always a consistent snapshot, and a crash costs at most about a second of play. I used modernc.org’s pure-Go SQLite driver — no cgo — which is what lets the servercross-compile to a single static Linux binary. Deployment is a script that builds on my desktop and scp’s one file to the server. No toolchain on theserver, no containers.
Logging in
We don’t really have BBSes, modems, and autodialers these days, and I have no interest in storing anyone’s password if I can avoid it. For the web, I chose”Log in with Google” — a standard OpenID Connect flow. The game keys your account off Google’s stable subject ID rather than your email address, since emails change. Galwar itself only holds a random session token in a cookie.
The telnet side is an interesting contrast, because it exposes what a door game actually was: the BBS knew who you were, and the door simply trusted the BBS. There is no BBS anymore, so telnet users get the one thing the originalnever needed — a password. It’s bcrypt-hashed, and the hash comparison is deliberately done off the game’s actor goroutine so the slow hash can’t stall the universe. Web players can set a telnet password from inside the game withthe PASS command and then use either door.
Testing with robots
A game like this only comes alive when a dozen people play it every day forweeks, and so far the player base is mostly me. So I built a population of bot players — eight personality types, from cautious traders to a “chaos monkey”that answers every prompt with garbage — that play through the exact same terminal interface a human uses. A month of around-the-clock play compresses into a few minutes, and the runs are deterministic, so every simulated month doubles as a regression test. The bots promptly produced an emergent boss fight and a three-way planet war that nobody scripted, but that’s a story for its own post.
Come play
Galactic Warzone is live at https://galwar.smbaker.com/. Log in with Google and go haul some ore. Watch out for mines, and if you get rich enough, the Cabal will come looking for you.
Will anyone actually play it? I have no idea. The original Galwar is still out there, and most people looking for nostalgia would probably just run the original. I suspect most people will get bored rather quickly. But it wasnever really about that.