Bloodlust & Harmony

What happens when someone rage-quits your ranked match?

Updated Jun 24, 2026

Picture a ranked 1v1. Twelve minutes in, you are grinding out a lead, your opponent's castle is one push from falling, and the screen freezes. Connection lost. Back to the main menu. No win. Did your rank even move? Did theirs?

If the player who left happened to be the host, the honest answer in a naive peer-to-peer game is that the match just evaporated. And a losing player who figures that out has discovered a beautiful exploit: Alt-F4 to un-happen a loss.

I spent a research week walking into this wall on purpose. This post is the long version: what the wall is made of, why the obvious fixes fail, what a real server actually costs, and the reframe that solved my problem without any of the hard stuff.

The thing nobody tells you about "just host it yourself"

There are two broad ways to run a multiplayer game. A dedicated server is a neutral machine in a data center running the authoritative game; every player is just a client connecting in. A listen server means one of the players' machines runs the authoritative game and plays it at the same time. Everyone else connects to that player.

Listen servers are wonderful for an indie: zero hosting cost, zero infrastructure, players bring their own compute. For a game with short matches and a handful of players it is the sensible default, and it is the model this game ships on. But there is a sentence you have to sit with until it fully lands:

In a listen server, the host player's machine IS the server. Not "acts like" the server. Is the server.

The entire game lives in that one player's RAM: every unit's health, every cooldown, the wave timers, the score. The other players are watching a replicated shadow of it. So when the host closes the game, the server process terminates, everything in its memory is gone, and every other player gets a network error because the thing they were connected to no longer exists. It is not "handle the host leaving gracefully." It is "the authority just died and took the universe with it."

"Can't you just migrate the host?"

The dream fix is host migration: the host leaves, the game quietly picks a new host, hands them the game state, and play continues. Old Halo and Gears did versions of this. Here is the first hard fact: Unreal Engine has no built-in host migration. No checkbox, no subsystem, no bMigrateHost. Epic engineers confirm it across years of forum threads. If you want it, you build it yourself.

Unreal does give you one primitive people confuse with migration: reconnection. The engine's AGameMode class can stash a disconnected player's identity and score, and re-attach them if they rejoin. Two catches. First, that is reconnection, not migration: it only helps when the server is still alive, meaning a non-host player dropped. Second, it lives on AGameMode specifically, and this project (like many modern UE5 games) is built on the lighter AGameModeBase, which has none of that machinery. The engine hands you a small tool for the easy half of the problem and nothing for the hard half.

Why this game is the worst possible case

Say you are stubborn and want to build it anyway. You would need to continuously snapshot the full authoritative game state somewhere that survives the host's death, elect a new host, have them rebuild the entire game from the snapshot, reconnect everyone, and do it fast enough to not be miserable. Every step is hard. Step three is where my game goes from hard to please-do-not.

  • 150 units, each a mini-database. Every unit runs on Unreal's Gameplay Ability System, where stats are the live result of stacked active effects with durations, stack counts, and ticking cooldowns. The content library has roughly 75 gameplay effect types and 91 ability types feeding that. Multiply by 150 units.
  • The ability system streams, it does not snapshot. It is designed to compute state on a live server and replicate results outward. There is no natural save-and-restore path for active effect containers. You would hand-build that serialization per effect type.
  • Every unit has a private brain that only exists on the host. Targeting, combat phase, stuck detection. None of it replicates. On a host swap, 150 units cold-start their AI and forget who they were fighting.
  • Whole systems do not exist on clients at all. The match orchestrator, wave spawner, and AI opponents run only on the host. They are not shadows a new host could inherit. They are just gone.
  • Time itself is a trap. Wave timers, cooldowns, the sudden-death clock: all measured against the departing host's clock. A new host has a different clock origin, so every timer would need re-basing or everything desyncs.

There is a commercial host-migration plugin on the Unreal marketplace, and it is real, but it handles the plumbing: electing a host, re-hosting, reconnecting. It cannot serialize your game logic for you. That is the 90 percent that is game-specific, and here it is brutal. The plugin gets you the truck; you still build and load the cargo by hand. Verdict: weeks to months of fragile bespoke engineering that still does not cleanly survive a crash. Highest effort, lowest confidence option on the board.

The four doors

DoorWhat it isDifficultyFixes a host leaving?
AReconnect for non-host dropsMediumNo, only client leavers
BPause on disconnect with a reconnect timerLowNo
CTrue host migrationResearch-grade, fragileIf it works
DDedicated serverHigh upfront, cleanStructurally

Doors A and B are genuinely worth building someday: they make a client rage-quit recoverable, which in a 2v2 covers most of your players. Door C we just buried. Door D is the only thing that structurally kills the problem, because with a dedicated server there is no host. The catch is not the code (the game is already server-authoritative), and it is not the monthly bill. It is that you literally cannot build a dedicated server binary with the stock Unreal from the Epic launcher. You have to compile the engine from source first. That is the real gate.

What a server actually costs

Everyone's first instinct is to Google "game server price" and get a useless number. The useful thing is a method, because your cost is a function of your game's shape. The model: one live match equals one headless server process, and the bill is compute plus outbound bandwidth. There are two billing philosophies. On-demand orchestrators (Edgegap, Hathora, GameLift) charge per running minute, scale to zero, and meter bandwidth. Self-hosted flat boxes (Hetzner, OVH) charge a fixed monthly fee, bundle huge bandwidth allowances, and leave the ops to you.

Four inputs decide everything: average players per match (about 3 for my mix of modes), CPU cores used per match, bandwidth per player, and concurrent players. On-demand compute runs about $50 per core-month. A flat Hetzner box works out to roughly $2.30 per core-month. One connected player at 250 kbps uses about 82 GB a month, which cloud providers bill at 9 to 15 cents per GB and cheap hosts simply include. Two of those inputs must be measured on a real packaged server, because guessing them means guessing the whole budget: this game's headless server still runs the full 150-unit simulation with 150 AI brains, so it is heavier than the typical one-core UE server, and its always-relevant replication puts bandwidth on the high side.

Avg concurrent matchesOn-demandSelf-host
3 (~9 players online)~$220/mo~$37/mo
10 (~30 players online)~$750/mo~$75/mo
100 (~300 players online)~$7,500/mo~$700/mo

The famous "under $1 per player" hosting number floating around is real but assumes one hundred thousand concurrent players on discounted instances with 16 matches packed per machine. It is an economies-of-scale number for a hit game. At indie scale the per-player cost is higher but the absolute dollars are tiny. The punchline: hosting is not the expensive part. A couple of flat boxes cost less than a streaming subscription. The expensive part of going dedicated is the one-time engineering: the engine source build, and replacing "join the host" matchmaking with "allocate a server and hand players its address."

The reframe that actually solved it

I almost went down the wrong road for weeks. I kept asking "how do I keep the match alive when the host leaves," and every answer was either impossible or a big architectural pivot. Then I asked a different question: for a ranked match, what does fair actually require?

Not "the match continues." Just two things. The innocent player is not robbed of the win and rank they earned. And the quitter cannot escape the loss by Alt-F4. That is a ledger problem, bookkeeping about who won and who bailed, not a live-simulation problem. And it is exactly how every competitive game on Earth handles rage-quits. None of them save the abandoned match. League's LeaverBuster hands out losses, reduced gains, and low-priority queues that escalate with repeat offenses. Rocket League makes leaving cost more rank than a normal loss plus a matchmaking ban. Apex and friends add a small daily forgiveness budget so an honest disconnect does not feel like a betrayal. There is even a Microsoft patent (US 10,478,732) describing almost exactly my scenario: peer-to-peer, a designated host, clients report the result, and a player who never reports is ruled the abandoner.

Two things already work in my favor. When a non-host client drops, the still-alive host already resolves the match fairly. And my matchmaker picks the host, so a host-side disconnect is attributable: the surviving player's game knows it was connected to the host and the host vanished.

The fairness menu

  • Client-attributed win plus a persistent abandon flag. When your game loses the host mid-ranked-match, your client awards you the win. And the instant a ranked match begins, a small "I am in ranked match Z" marker is written to disk, cleared only on a clean finish. Still there at next launch? You are flagged: the loss applies, plus a penalty and a cooldown, escalating for repeaters. This is the piece that kills Alt-F4-to-dodge-a-loss. Zero infrastructure.
  • Cross-signed stakes. Rank is a zero-sum bet between two players, so treat it like escrow: at match start each player sends the other a signed note staking the match, and whoever survives a disconnect holds the other player's own signed proof they were in it. Provably fair ranked with no backend. The elegant option.
  • A thin result arbiter. A tiny always-on service holding zero game state, just a results ledger. Both clients register the pairing at match start; a player who never reports is ruled the abandoner. This is categorically different from a dedicated game server: it arbitrates results, not simulation, for about $5 a month. The honest middle option between spoofable peer-to-peer and full dedicated servers.
  • Deterrence and forgiveness, layered on any of the above. A visible escalating penalty deters most quitting before it happens, and one free disconnect a day keeps genuine crashes from generating angry threads.

The plan

Ship the abandon flag and the forgiveness budget first: pure client-side plus a save file, no servers, no engine surgery, and it fixes the exploit that actually hurts players. Measure the two server numbers (CPU per match, bandwidth per player) on a packaged build so every future decision is de-risked. Add non-host reconnect if 2v2 drops turn out to be common. Keep dedicated servers as a deliberate later decision, gated by the engine build and matchmaking work rather than the hosting bill. And never build host migration. For this game it is the worst effort-to-payoff on the board, and the fairness reframe means I never needed it.

The bigger lesson

"Listen server" quietly means one of your players is the single point of failure. Engines do not hand you host migration, and not because they forgot: it is genuinely one of the hardest problems in networked games, and it gets harder the more dynamic your simulation is. Modern gameplay frameworks optimize for live replication, not snapshot and restore, which is a great trade for normal play and a nightmare for migration. Hosting is cheap; the engineering around it is not.

And the big one: separate the problem you think you have from the one you actually have. I thought I needed to keep matches alive through a host drop. What I actually needed was for ranked results to be fair. Those look like the same problem and are wildly different in difficulty. The most satisfying fixes in game dev are often like this: you spend a week convinced you need to move a mountain, then realize you just needed to move the goalposts a few feet to the left.