The choice I parked

Way back in post 17, tracing how a real Fury server put a player into a match, I found there were two paths I could take to rebuild it, and I wrote:

Two routes out of this, and I’m not committing to either until I have a client to test against.

I have a client to test against now. And after last post’s dig through the engine’s guts, I know what it wants. So it’s time to actually pick.

The two doors

Door one: do what the real server did. When a real match started, the matchmaker sent the arena server a little dossier about each player, the server built that player’s character ahead of time, parked a placeholder in it, and loaded the player’s gear and stats from a database. When the player’s client finally connected, it just took over the character that was already standing there. Faithful to the original. It’s the “hotel” flow from post 17.

Rebuilding that means faking a bunch of things the real server talked to and I don’t have: the matchmaker’s dossier, the bulk-data service, twelve database lookups, and, because the server picks the spawn spot on this path, I’d have to crack open the map file and find the coordinates of the player-start markers inside it.

Door two: the side path. There’s a branch in the engine’s code that only fires for the full combat game mode. If my server tells the client it’s running a simpler kind of Fury game, not a combat arena, the code takes a different branch that just spawns the character the plain built-in way when the client connects. No dossier, no database, no digging through the map file.

I said in post 17 that door two “probably isn’t where I end up,” because it’s less faithful to how Fury really worked. I’ve changed my mind, and last post is why.

What the engine dig changed

I spent last post working out the exact byte format the client expects when the server sends it a character: the message header, how objects reference each other, how every type of value gets packed onto the wire, what order to open things in.

Here’s the thing. None of that got any easier on the faithful path. The hard part of milestone 4, the part that’s genuinely weeks of careful work, is getting those bytes exactly right. That work is identical whichever door I go through. The faithful path doesn’t simplify a single field. It just adds the dossier fake, the database fake, the bulk-data fake, and the map-file parsing on top.

And the one thing the faithful path was supposed to buy me, a character spawned at a proper player-start position, turns out to be nothing special. The engine dig showed that the spawn position is just three numbers the server writes into the “here’s your character” message. I can put the character anywhere I like by picking those numbers. For a phase whose entire goal is “I can move,” standing in the exact right spot on the map does not matter even slightly.

So: same hard part, and door two skips four fakes and a file parser. That’s not a close call.

The catch, and why it’s cheap

Door two depends on the client accepting a “this isn’t really a combat game” answer while it’s loading a combat map. It might not. It might insist the game mode and the map agree.

But testing that is now a thirty-second job. I send the WELCOME message with the different game mode, launch the client, and watch: does it load the map and say JOIN like it did in post 20, or does it refuse? If it refuses, I fall back to the combat mode, which post 20 already proved the client is happy with, and I pay for the dossier-and-database fakes after all. Nothing about that fallback got more expensive while I wasn’t looking.

Low downside, decent upside, quick to check. Take door two, keep door one in my back pocket.

Recorded

This is going in the project’s decisions folder as the milestone-4 route call, so future-me doesn’t have to reconstruct the reasoning. The short version: shortcut route, because the wire format is the whole cost and it’s the same either way.

Next

The build. Server opens a channel, names an object, sends a character down it, in the order the last post worked out. Somewhere on the far side of that, the loading bar fills.