The autocannon gains its authentic muzzle effect AND becomes visible when an
enemy fires it -- the ballistic-FX gap behind "I only see the AC from my own
view."
MUZZLE FLASH (the genuine shipped effect, not the cut card):
- MUZFLASH.BGF is an orphaned/cut asset (nothing references it) -- so it is NOT
rendered. The shipped projectile-gun muzzle effect is DAFC.PFX, which
BTDPL.INI documents as "the effect used on all projectile guns" (psfx 6
external / 14 internal): an orange fire-smoke blast (btfx:firesmoke1),
maxIssue 25 over ~0.2s so the emitter auto-expires = one burst per shot.
- BTFlashMuzzle (mech4.cpp) spawns it on the gun-port SEGMENT via the existing
BTStartPfxAttached path; the segment frame sprays -Z out the barrel. Hooked
at ProjectileWeapon::FireWeapon (the fire edge). Default ON (BT_MUZZLE=0
disables). AC only -- lasers show their beam, missiles their launch.
ENEMY AC FIRE NOW REPLICATES (the real find):
- ROOT CAUSE: the subsystem-record replication channel EXISTS and works (mech
ticks subsystem->PerformAndWatch(update_stream); Entity::UpdateMessageHandler
routes incoming records to GetSimulation(subsystemID-1)->ReadUpdateRecord).
The emitter (beam) and MissileLauncher (salvo mirror) both call ForceUpdate()
so their fire serializes -> enemy lasers + missiles ARE visible on the peer.
The AUTOCANNON set only `simulationFlags |= 0x1` (the +0x28 instance flag,
NOT the updateModel bit WriteSimulationUpdate walks) and had NO fire record,
so its shot never crossed the wire -- the enemy's cannon was invisible.
- FIX (the AC twin of the missile salvo mirror): ProjectileWeapon::
WriteUpdateRecord/ReadUpdateRecord (fire counter + aim) + ForceUpdate() in
FireWeapon. The replicant edge-detects the counter and mirrors ONE visual
round + DAFC muzzle flash from its own resolved muzzle; a null/untargeted aim
streaks straight out the barrel (launchVelocity) instead of toward origin.
- Verified live 2-node: the watching node logs REPLICANT AC shots + DAFC
flashes at the enemy's gun-port (seg 7), aimed shots fly to the real target;
no crashes.
TRACER: all ACs author TracerInterval=1 (every round is a tracer); the existing
amber streak is acceptable-authentic, so no tracer change was needed.
KB: open-questions.md -- CORRECTED the (wrong) earlier note that claimed no
subsystem-record channel exists; it does, the AC just wasn't using it. Logged
the methodology lesson: the coverage audit finds UNWRITTEN functions, not
"reconstructed but inert" ones (a function present but never called -- the AC
record + the missile mirror both looked done); a LIVENESS audit would catch
that class.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>