wreck smoke dies WITH the wreck; the audio/effect clock is calibrated to the byte-proven 28

USER REPORT: "when you destroy a mech, it continues to smoke for a very long
time after the mech disappears... up to 30secs to a minute."

MEASURED (new [pfx] timed census with per-def particle attribution): the
death plume (psfx 1 DDTHSMK) was re-armed on a 10s cadence as a WORLD effect
(ownerTag=0) -- so neither the burial transition nor the respawn cleanup
(StopAllEntityEffects) could touch it.  The last-armed window kept emitting
over the empty spot for up to 10s after the hulk vanished, plus 6+-2s authored
particle lives, and back-to-back windows stretched the visible tail to the
reported range.  The re-arm itself is a marked PORT ADDITION [T3]; the binary
fired DDTHSMK once -- its 10s window + particle lives ended right around the
~17s hulk sink.  The authored design: the smoke dies WITH the burial.

FIX: the plume is spawned ATTACHED (BTStartPfxAttached, tagged to the dying
entity -- it also rides the sinking hulk now), and the burial transition calls
BTStopEntityPfx alongside the respawn cleanup that already did.  Verified over
a 175s run containing FOUR wreck events (the enemy kill + three player bay-
fire deaths): every plume's emission ends at its wreck's burial or respawn,
particles fade within ~8-11s, no orphan emitters remain.

THE COUPLING (user relay of Oracle: "prolonged smoke and explosion INCLUDING
SOUND... same lever?") -- CONFIRMED as a family: the binary's audio layer
times in FRAME COUNTS converted by the engine frame-rate global:
    AudioTime::Seconds_To_Frames == fmul [0x52140c]=28.0; fadd 0.5; round
    (@0x42c611, @0x42dd86 -- the 0x42xxxx cluster of the ~90 global consumers)
Our engine's DefaultRendererRate said 30: every audio duration, sequence
delay and compression window ran ~7% fast.  Calibrated to 28 [T1].  NOT yet
explained by this: a truly SUSTAINED/looping explosion sound (7% is not
"prolonged") -- the effect stop-path trace stays open on #114/#51.

Tooling: BTPfxParticle carries defIndex; [pfx] census (BT_PFX_LOG, 2s) prints
emitters + particles PER EFFECT SLOT with a timestamp; wrecksmoke.sh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-08-02 11:25:49 -05:00
co-authored by Claude Opus 5
parent 2df1369168
commit 6dbeb3d266
5 changed files with 88 additions and 4 deletions
+18 -3
View File
@@ -2204,6 +2204,18 @@ void
// the empty spot).
if (!wreck_visible && collisionVolumeCount != 0)
{
// #114-family (user report: smoke continues 30-60s after the mech
// disappears): the re-armed plume was a WORLD effect (ownerTag=0),
// so the respawn/burial cleanups could not kill it -- the last 10s
// emission window played out over an empty spot, plus 6+-2s
// particle lives. The plume is entity-tagged now (below), so end
// the emitters WITH the burial; spawned particles fade in <=8s,
// which is the authored envelope (DDTHSMK once: window 10s,
// life 6+-2 -- the binary's smoke died WITH the sink).
{
extern void BTStopEntityPfx(void *owner);
BTStopEntityPfx((void *)this);
}
// Zeroing the count stops MoveCollisionVolume from re-placing the
// box -- but the mech-vs-mech gather (Mover::GetCurrentCollisions)
// tests mover->collisionVolume DIRECTLY, never the count, so the
@@ -2225,11 +2237,14 @@ void
if (wreck_visible && wreckSmokeTimer <= 0.0f)
{
wreckSmokeTimer = 10.0f; // DDTHSMK's release window
extern void BTStartPfx(int effect_number, float x, float y, float z);
BTStartPfx(1,
// ATTACHED (not world): tagged to this entity so the burial /
// respawn cleanups can end it, and it rides the sinking hulk.
extern void BTStartPfxAttached(int effect_number, void *owner,
int seg_index, float x, float y, float z, const float *rows9);
BTStartPfxAttached(1, (void *)this, 0,
(float)localOrigin.linearPosition.x,
(float)(localOrigin.linearPosition.y + kMuzzleHeight),
(float)localOrigin.linearPosition.z);
(float)localOrigin.linearPosition.z, 0);
if (getenv("BT_DEATH_LOG"))
DEBUG_STREAM << "[death] wreck smoke plume re-armed (psfx 1)\n" << std::flush;
}