Building a Multiplayer Game Is Hard. Really Hard. Even With AI.
Building a multiplayer game is hard. Really hard. Even with AI.
Ask an AI for one and it delivers. You open two browser tabs, two squares move around, the state syncs. Then you send the link to a friend in another city, and one of two things happens. Either it keeps working, or their character rubber-bands across the map and the ball rewinds mid-flight like someone scrubbed a video.
Which one you get isn't luck, and it isn't the model having a bad day. It depends on one question about your game, and you can answer it before you write a single prompt.
Every player sees the past
There's a reason online games show your ping and make you pick a server region. A packet from Taipei to New York crosses roughly 12,500 km of fiber, and light in glass travels at about 200,000 km/s, two thirds of its vacuum speed. Round trip, that's a floor of about 125ms before a single router adds its share. No code brings it to zero. Not yours, not Claude's.
Don't wait for a faster internet either. Stuart Cheshire's 1996 essay It's the Latency, Stupid measured 85ms to Boston against a 43ms speed-of-light minimum, already within a factor of two of physics. Bandwidth has improved thousands of times over since then. That 85ms had almost nowhere to go.
So every player sees every other player in the past. Your friend's screen shows where you were 100ms ago, and yours shows where they were 100ms ago. There is no shared "now", and no prompt can create one.
The question
Does your game still work if everyone sees everyone else 100ms in the past?
If yes, AI can one-shot it today. I gave clean-room Claude agents nothing except the antics docs and asked for three games, one shot each. A turn-based trivia game came out working: a question that arrives 200ms late is still the question, which is why Gabriel Gambetta's netcode series says the naive approach "works fine for slow turn based games". So did a 60-second clicker race with a leaderboard, where players never touch each other and only their scores meet at the end. So did a Three.js co-op collector, where your friends render 100ms late and nobody notices because the game is about picking up crystals and nobody ever touches anybody. None were hand-edited. One needed a docs fix and a clean regeneration, and that story is below.
If your game idea lives in that group, stop reading and go build it.
If no, you're on the other side of the split. A ball both players can kick. A shot that has to land on a moving target. A race with collisions. Now two clients disagree about the present tens of times a second, and someone has to decide whose version wins, every time, in a way that fits this particular game. Making that call is most of what netcode is, and it's where raw prompting falls over.
What your players see when it goes wrong
Your playtesters won't file bug reports. They'll text you, and you already know every one of these messages, because you've sent them yourself as a player.
- "I keep getting yanked backward." That's rubber-banding: the server correcting a client's optimistic guess, hard.
- "He's teleporting all over the place." Remote players are drawn straight from the network with no interpolation buffer, so every late packet is a jump cut.
- "The ball jumped backward mid-flight." The game trusted a lagging client about a shared object, so everyone else's ball rewound. The cruel part is that it looks worst for whoever has the best connection.
- "My shots go right through him." Hit events are replayed on other screens without local collision, so the bullet sails through the victim and sparks on the wall behind.
- "It froze when the host tabbed out." One machine ran the world, and the world left with it.
- "Who's the frozen guy at spawn?" Someone still on the menu screen, already rendered to everyone as a ghost at their starting position.
None of these appear in two tabs on your machine. All of them appear the first night your friends play.
Why two tabs can't tell you
Take a shooter. Between "it compiles" and "it feels right" sit three decisions, and a raw prompt makes none of them.
Whose hit counts? If the shooter detects its own hits and the victim applies them as authoritative, shots feel instant. If you wait for the victim to confirm, every hit lags by a full round trip. Neither answer is clean. You're choosing who suffers. Big-budget shooters rewind the server to honor the shooter's past, which is why players still get shot around a corner after reaching cover on their own screen. Netcode never removes the pain of lag. It decides who feels it.
Where is the ball, really? Data on the wire is old by definition. You stamp everything that moves with a shared clock and replay it forward by its age before using it. If you ease toward the raw value instead, you're easing toward the past, and smoothing harder just spreads the lag out.
Who runs the world when the host alt-tabs? Someone's machine runs the NPCs. When that tab backgrounds, authority has to move mid-game without the world freezing.
AI can write all of this. Client-side prediction and entity interpolation are documented techniques, and Valve wrote the paper on latency compensation in 2001. The problem is where the work gets checked: on your machine, where packets travel browser to browser with zero latency. Loopback is the one network your players will never have, and every bug on the list above needs latency to exist.
You can simulate the lag, and that's the only real fix. It takes delay injected into the transport, several clients running against each other at once, and some way to judge the result, because an agent can't feel rubber-banding through a test that passes. None of that is in anyone's default loop, human or model. "Write the game, open two tabs, it works" has no step where 150ms exists, so the netcode ships unrehearsed.
The bugs don't even look like bugs when they arrive. In one playtest a player alt-tabbed mid-keypress, the keyup fired in the other window, and their fighter walked off a ledge in a death loop, haunting the respawn point as a shaking ghost while its owner sat in another window, none the wiser. The fix is one line: clear held keys on window blur. Nobody writes that line until they've watched the ghost.
If your game is on the hard side
Don't prompt harder, and don't plan to add multiplayer later. Sync logic threads through the whole simulation, so bolting multiplayer onto a finished single-player game means rewriting the game. The three decisions above have to be made before the AI writes a line, and the test loop has to contain lag, or the first real test is your launch night.
That is the problem we built antics around. Authority is fixed in advance (the host writes the shared world, each player writes only their own slice, and the relay rejects anything else), room.now() is a clock every device agrees on, interpolation and host migration come as SDK helpers, and verify_game { simulateLatencyMs: 150 } runs the game under lag so an agent can catch the rubber-banding before your players do. The traps live in the docs the AI reads, which is how the localStorage crash from earlier got fixed: one warning in the docs, and the next generation came out clean. Blast-arena, the latency-sensitive demo, had its whole multiplayer layer generated in one shot this way, with a 120ms render delay, fire-and-forget projectiles, victim-authoritative hits and a host-migration-safe round timer. The camera and a hi-DPI canvas bug were hand-tuned afterwards. One prompt got the multiplayer right. Game feel still took hands.
So, the question again: does your game survive showing everyone the past? If yes, you're one prompt away. If no, you're one prompt away on a floor where the physics is already handled. Either way, stop testing in two tabs and make something your friends can break.