#81 follow-ups: peer warp must not stomp the POV vortex; panel draw probe; mech3 ghost symbols

Two field observations from watching the 4-node stress, both run down:

1. "A respawn happened without the blue vortex" -- REAL.  The translocation
   effect is ONE global slot shared by the POV lifecycle and the world-anchored
   peer sphere (a port extension).  A peer's un-wreck arriving while the local
   pilot's own collapse/wait/expand was in flight overwrote gWarpPhase/gWarpPOV
   and killed the POV vortex.  Invisible before the respawn fix only because
   overlapping respawns barely existed; now they are routine.  Fix: the POV
   lifecycle owns the slot -- BTStartWarpEffect self-skips while it is active
   ([tloc] peer warp SKIPPED).  2-node bench: 20/20 POV collapse+expand pairs,
   9 peer spheres played, 11 correctly skipped; solo: 8/8 pairs unchanged.

2. "Comms panel counted no deaths" -- panel machinery CORRECT; the 4-node
   zeros were the bench's own CPU crush (4 core-pinned instances starved the
   PilotList to <0.6 Hz, so rows redrew minutes-stale).  Added the arbiter:
   [score] panel DRAW slot/pilot/kills/deaths edge log (BT_SCORE_LOG) -- the
   2-node rerun drew 0->9 / 0->11 live on both nodes, local AND replicated
   (SBMIRROR rows confirm owner->replicant tally flow on all 4 stress nodes).

Also: the mech3 offline-authoring stubs declared every <Subsystem>::DefaultData
as Entity__SharedData while the real statics are Simulation__SharedData (this
engine derives Entity FROM Simulation) -- ~20 ghost symbols /FORCE silently
resolved to garbage.  DefaultData half fixed (SubsystemDefaultData now returns
the true common base Simulation::SharedData); the CreateStreamedSubsystem stub
signatures remain wrong (nested SubsystemResource* + ResourceFile*), are
cold (no callers), and are tracked in open-questions + gotchas §6 stub-typedef
corollary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-07-30 10:10:29 -05:00
co-authored by Claude Fable 5
parent 830a976192
commit bfa1b04990
8 changed files with 106 additions and 15 deletions
+28 -11
View File
@@ -93,19 +93,36 @@
// Reconstruction stand-ins LOCAL to this translation unit.
// The offline "Subsystems" authoring path dispatches each streamed component
// to its subsystem class's static CreateStreamedSubsystem / DefaultData.
// Those ~21 classes live in sibling modules not visible here (and PPC /
// GaussRifle / SubsystemMessageManager have no reconstructed class at all),
// so the uniform factory surface is declared here as minimal stubs. The
// bodies/data are resolved at link against the real subsystem modules; these
// declarations only let the dispatch compile. Kept LOCAL so they never
// collide with the real sibling classes.
// Those ~21 classes live in sibling modules not visible here, so the uniform
// factory surface is declared here as minimal stubs. The bodies/data are
// resolved at link against the real subsystem modules; these declarations
// only let the dispatch compile. Kept LOCAL so they never collide with the
// real sibling classes.
// ⚠ The DefaultData member TYPE must be Simulation__SharedData -- the type
// the real Subsystem-family definitions have (every sibling declares it via
// the inherited SharedData typedef, dumpbin: ?DefaultData@X@@2VSimulation__
// SharedData@@A). Declaring it as Mech::SharedData (== Entity__SharedData)
// mangles to a DIFFERENT symbol, and /FORCE turned all ~20 of the resulting
// unresolved externals into silent garbage pointers instead of link errors
// (reconstruction-gotchas #3). Cold in-game (this is the tool path), but a
// landmine for the authoring tools. FIXED for the DefaultData statics.
// ⚠ STILL UNRESOLVED (known, cold): the CreateStreamedSubsystem stubs below
// do NOT match the real modules' signatures -- the real ones take the
// class's NESTED <X>::SubsystemResource * (arg 4) and a trailing
// ResourceFile * (e.g. mechtech.cpp:407), where these stubs guessed
// void* / int. All 20 factory references therefore stay unresolved under
// /FORCE. Harmless while the offline authoring dispatch has no callers,
// but before wiring a tool through CreateSubsystemStream these must become
// per-module BRIDGE functions in complete-type TUs (the project's bridge
// convention) -- the nested resource types make direct stubs impossible.
// Tracked in context/open-questions.md.
//===========================================================================//
typedef Mech::SharedData SharedData; // namespace-scope alias (== Entity__SharedData)
// 7-arg (non-weapon) streamed-subsystem factory shape.
#define STREAMED_SUBSYS(NAME) \
struct NAME { \
static SharedData DefaultData; \
static Simulation__SharedData DefaultData; \
static int CreateStreamedSubsystem(NotationFile *, const char *, \
const char *, void *, NotationFile *, \
const ResourceDirectories *, int); \
@@ -113,7 +130,7 @@ typedef Mech::SharedData SharedData; // namespace-scope alias (== Entity__Shared
// 8-arg (weapon) streamed-subsystem factory shape (leading pass counter).
#define STREAMED_WEAPON(NAME) \
struct NAME { \
static SharedData DefaultData; \
static Simulation__SharedData DefaultData; \
static int CreateStreamedSubsystem(int, NotationFile *, \
const char *, const char *, void *, NotationFile *, \
const ResourceDirectories *, int); \
@@ -141,13 +158,13 @@ STREAMED_WEAPON(AmmoBin);
// MechTech is forward-declared in mech.hpp; complete it (non-weapon shape).
struct MechTech
{
static SharedData DefaultData;
static Simulation__SharedData DefaultData;
static int CreateStreamedSubsystem(NotationFile *, const char *,
const char *, void *, NotationFile *,
const ResourceDirectories *, int);
};
// MechControlsMapper is forward-declared in mech.hpp; only its DefaultData is used.
struct MechControlsMapper { static SharedData DefaultData; };
struct MechControlsMapper { static Simulation__SharedData DefaultData; };
// SubsystemMessageManager: leading pass, no trailing index, no DefaultData.
struct SubsystemMessageManager
{
@@ -905,7 +922,7 @@ fail:
// CLASSMAP / the per-module reconstructions). Returns 0 for an unknown name.
//###########################################################################
//###########################################################################
/*static*/ SharedData *
/*static*/ Simulation::SharedData *
Mech::SubsystemDefaultData(const char *type_name)
{
if (Streq(type_name, "")) return &Mech::DefaultData; // 0050bde4 (DAT_0050dc1f == "")