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
@@ -2409,16 +2409,13 @@ void
|
||||
<< " zones=" << m->damageZoneCount << "\n" << std::flush;
|
||||
}
|
||||
|
||||
// CROSS-POD DAMAGE PROOF HOOK (BT_MP_FORCE_DMG, task #46/#47): once a
|
||||
// second, dispatch a real unaimed TakeDamage at the first live
|
||||
// REPLICANT candidate through the SAME engine path a beam hit uses
|
||||
// (Entity::Dispatch -> replicant reroute -> SendMessage(ownerID)).
|
||||
// This isolates the cross-pod delivery from the interactive aim/drive
|
||||
// plumbing so a 2-node test can watch the wire without having to line
|
||||
// up a boresight. It does NOT stamp/patch the id -- Entity::Dispatch
|
||||
// reads this->entityID at offset 0x17C, which the [mp-layout] probe
|
||||
// proved is IDENTICAL in the reconstructed and engine TUs (both 380,
|
||||
// sizeof(Entity)=444), so no cross-TU translation is needed or done.
|
||||
// CROSS-POD DAMAGE TEST HOOK (BT_MP_FORCE_DMG, task #47): once a second,
|
||||
// dispatch an unaimed TakeDamage at the first live REPLICANT through the
|
||||
// SAME virtual Entity::Dispatch path a beam hit uses -- Entity::Dispatch
|
||||
// reroutes a replicant's message to the owning master over the wire, the
|
||||
// master's now-valid mech resolves + applies it (cylinder lookup). Lets a
|
||||
// 2-node test exercise cross-pod delivery without lining up a boresight.
|
||||
// Off by default; the interactive beam path needs no such hook.
|
||||
if (getenv("BT_MP_FORCE_DMG"))
|
||||
{
|
||||
static float s_fd = 0.0f; s_fd += dt;
|
||||
@@ -2440,9 +2437,10 @@ void
|
||||
Entity::TakeDamageMessageID,
|
||||
sizeof(Entity::TakeDamageMessage),
|
||||
GetEntityID(), -1, dmg);
|
||||
DEBUG_STREAM << "[mp-force] " << (void*)m
|
||||
<< " Dispatch unaimed TakeDamage id=" << m->GetEntityID()
|
||||
<< " ownerID=" << (int)m->GetOwnerID() << "\n" << std::flush;
|
||||
if (getenv("BT_MP_LOG"))
|
||||
DEBUG_STREAM << "[mp-force] " << (void*)m
|
||||
<< " cross-pod TakeDamage id=" << m->GetEntityID()
|
||||
<< " -> ownerID=" << (int)m->GetOwnerID() << "\n" << std::flush;
|
||||
m->Dispatch(&td);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user