Files
RP412/RP_L4
CydandClaude Opus 5 d02117d87c Answer the door before knocking on anyone else's
Players kept failing to get a race started - the host watching pods that
never reported ready. It is not the transport: both wires are already
reliable and ordered, TCP on one path and Steam's reliable channel on the
other, and every failure in the playtest logs is on the game mesh port,
none on the console port. The eggs arrive fine.

It is the order the mesh is built in. Each pod walks the host list from
the egg, connecting out to everyone ahead of it and listening for
everyone after - so in list order the connects all come first, and the
listener was created lazily on the first host of the second kind. That is
to say AFTER every outbound connect had already been made. A connect to a
pod that is not ready blocks for RP412CONNECTWAIT, three times over, so a
pod could spend a minute unable to answer its own door while the very
peers it was waiting on were knocking on it. Their connects to it then
timed out, and the failure went round the ring.

The logs say it plainly: six of eighteen pods never reached "listening on
engine port 1502" at all, and the same pair of players connects in one
round and times out in the next, in both directions. It is not one bad
network - it is a queue.

So the walk now only builds the hosts, and the outbound connects happen
after it. The listener still opens exactly where it did, on the first host
that will be calling us, but nothing has blocked by then so it is up in
the first moments rather than a minute in.

A peer that still does not answer is tried once more, because that is the
other thing the logs show - the slower pod catching up between attempts.
Bounded deliberately: the transport already makes three tries inside each
call, so a round here is expensive and a loop of them would turn a bad
connection into a hung game. RP412MESHRETRY sets it.

And when a peer is genuinely unreachable, say so. Every one of them is
counted in remoteHostCount, so the mesh can never report itself complete
and the pod is never told to load the mission - it just sits there looking
to the host like a player who never got ready. The log now names who
could not be reached and says the mission cannot start.

Not done here: what SHOULD happen then. Dropping that pod out, or racing
with a hole in the mesh, is a decision about the game rather than the
network.

An earlier attempt at this opened the listener unconditionally before the
walk, which was wrong: Connect and Listen both bind localGamePort, so the
pod at the END of the list - which listens for nobody - bound it twice and
its one outgoing connection fought its own listener. Deferring the
connects gets the same ordering with no extra socket.

Verified: two-pod loopback green, both pods scoring 1000, mesh completing,
stale 0, no listener on the last pod any more. Cadence measured against
the previous build over three runs and unchanged - an earlier reading that
looked like a regression was harness variance, the pods being parked and
the numbers heartbeat-dominated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 09:10:15 -05:00
..
2026-08-13 12:59:25 -05:00
2026-08-11 21:34:12 -05:00
2026-08-07 21:21:00 -05:00