Server: HealthApplyDamageSystem marks EnemyTag Dying{UntilTick} (TickUtil.
NonZero, ~54 ticks) on the lethal 0-crossing instead of instant destroy,
zeroes every live cue (replicated AttackWindup, LungeState + IsLunging bit,
KnockbackState), destroys on expiry; plain-world tests keep instant destroy
(no NetworkTime) so the suite's assertions stay meaningful.
Every consumer now ignores corpses (all confirmed entity-count/unfiltered by
the design review): EnemyAISystem all 4 passes, BossAISystem brain + summon
cap, RoomEnemyDirector room-clear + MaxAlive fit, WaveSystem cap + cleared,
CyclePhaseSystem breach wipe + DefendCleared, ThreatDirector timeout cull,
TurretFire targeting, CoreDamage drain, ProjectileDamage snapshot (corpses
are not shields), AbilityFire auto-aim candidates, debug cull + telemetry.
Wipe passes skip Dying to avoid cross-ECB double-destroys.
Client: EnemyAnimationDriveSystem finally drives the controller's IsDead
param (Health.Current<=0 is the replicated death read; corpse locomotion
zeroed); CombatFeedbackSystem moves the kill CRUNCH to the 0-crossing (the
prune-edge timing would land it ~1 s late) - the prune keeps a small
dissolve puff for corpses and the legacy full read for alive-vanish culls.
456/456 EditMode.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Boss bar reconstructs the true max client-side (Health.Max unreplicated) via
Kind==Charger + expedition-pos filter; boss slam telegraph = a full ground ring
at BossSlamRadius; IsAttacking OR's IsLunging. Player body flash on hurt (distinct
red, jitter-safe threshold). Dash toward movement input when moving else facing.
Warrior cone: muzzle-cue suppressed (cone arc is its cue). Minimal finisher-only
hit-stop (PrototypeCameraRig.Hold, behind FeelConfig flag; never Time.timeScale).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extends the DR-022 player pipeline to Husk enemies. A Husk is an ownerless
interpolated ghost = structurally a remote player, so the new client-only
EnemyAnimationDriveSystem mirrors PlayerAnimationDriveSystem's remote path:
velocity from LocalTransform-delta (prevPos cache, pruned every frame), facing
from LocalTransform.Rotation (AnimParamMath.PlanarForward), maxSpeed from baked
EnemyStats, IsAttacking from the already-replicated AttackWindup telegraph. No
new [GhostField], no server/asmdef/ghost-hash change.
Monster-mash roster: Werewolf (Grunt), Werewolf-Undead (Swarmer), Kaiju (Brute),
built by the reusable, GUID-preserving EnemyRigTools editor tool (materials +
AC_EnemyTopDown + EnemyAttackWindup clip + 3 rigged prefabs). WaveSystem now
preserves the baked variant Scale (was reset to 1 by LocalTransform.FromPosition).
See DR-023. EditMode 208/208; validated in Play (rigs skin, scales replicate,
locomotion + attack telegraph drive correctly).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>