MP task #47 SOLVED: cross-pod damage + kill (validate the master mech)
Full cross-pod KILL now works: instance A (host 2) shoots B's mech (host 3) dead over the network; B runs the death transition on its own screen. Verified on a 2-node one-box run (BT_MP_FORCE_DMG on A): B's mech takes ~36 remote hits of 12 and is DESTROYED, with wreck swap + explosion. ROOT CAUSE (one bug): B's own MASTER mech was INVALID. Entity::Receive(Event*) does `if(!IsValid()) event->Defer()` -- so a cross-pod-delivered TakeDamage that arrived, resolved to B's real mech, and Posted, was DEFERRED forever; the handler never ran. The reconstructed Mech::Make force-set ValidFlag only for replicants (the P6 bring-up hack for the partial MakeReady handshake); a locally-created master never got validated. FIX (one line): Mech::Make now sets ValidFlag for the master too -- the reconstructed ctor builds the mech synchronously, so it's safe. Nothing else changed: targeting, the virtual victim->Dispatch, the replicant reroute, the wire, receive, and id resolution were ALL already correct. Two prior root causes were BOTH mis-diagnoses from the WRONG messageID: Entity::TakeDamageMessageID is 18, not 21. Every earlier probe filtered msgID==21, never matched a real TakeDamage, and mis-correlated the stray 21 hits' 3:19 / classID-48 against the real 3:22 hit -- inventing (a) a "cross-TU Entity layout divergence" (disproven: offsetof identical in both TUs, sizeof 444, entityID@0x17C) and (b) a "localID corrupted on the wire". Both FALSE; the id is correct end-to-end (3:22 = B's master). - game/reconstructed/mech.cpp: validate master + replicant at Make. - game/reconstructed/mech4.cpp: BT_MP_FORCE_DMG cleaned to a concise gated 2-node cross-pod reproducer (real virtual Dispatch path). - context/multiplayer.md, reconstruction-gotchas.md: corrected root cause + the validity-defers-cross-pod gotcha. Engine diagnostics reverted to clean. Solo un-regressed (the solo enemy was already force-valid; the change only ADDS ValidFlag). btl4.exe builds; full mission loop clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
04a2049ce2
commit
54b6663b4d
@@ -689,14 +689,17 @@ Mech*
|
||||
return 0;
|
||||
}
|
||||
new (mech) Mech(creation_message, DefaultData); // FUN_004a1674
|
||||
// P6 bring-up (multiplayer): a REPLICANT never gets the master's MakeReady/
|
||||
// CheckLoad validity handshake (the engine's interest layer is a partial
|
||||
// implementation), and an INVALID entity defers every message as an event
|
||||
// (ENTITY.cpp Receive/Dispatch) -- so its network UPDATES never apply AND the
|
||||
// deferred-event churn keeps the peer's CreatingMission queue from ever going
|
||||
// quiet. Validate replicants at creation (same fix the spawned test dummy
|
||||
// needed); the authentic MakeReady flow is future work.
|
||||
if (mech->GetInstance() == Entity::ReplicantInstance)
|
||||
// P6 bring-up (multiplayer): the port's MakeReady/CheckLoad validity handshake
|
||||
// is a partial implementation, so a mech is never authentically validated. An
|
||||
// INVALID entity DEFERS every dispatched message forever (ENTITY.cpp
|
||||
// Entity::Receive -> event->Defer), which silently drops cross-pod TakeDamage
|
||||
// at the owning MASTER (task #47: B receives + resolves the hit to its own mech,
|
||||
// classID 3001, but Entity::Receive sees valid=0 and defers it). It also stalls
|
||||
// a REPLICANT's network UPDATES and churns the peer's CreatingMission queue. The
|
||||
// reconstructed ctor builds the whole mech synchronously, so validating here is
|
||||
// safe for BOTH instances (a master must be valid to take cross-pod damage; a
|
||||
// replicant to apply updates). The authentic MakeReady flow is future work.
|
||||
if (mech != 0)
|
||||
{
|
||||
mech->SetValidFlag();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user