Boss becomes a real fight + readable-but-fair enemy threat

BossState (server-only) + BossAISystem: sole mover, seek -> telegraphed
radial slam (AttackWindup) -> phase-2 speed + swarmer summon. Excluded from
the EnemyAISystem Charger pass; knockback-immune at all 3 stamp sites;
arena-anchored spawn; scaled Health/HitRadius/AttackRange. Grunt windup now
commits in its last ~30% (whiffs out-of-range); Charger stagger roots; grunt
speed 4.2->5.2; swarmer telegraph synced. SweptMove + zone-enemy spawn-stamp
extracted to shared helpers. Zero new [GhostField].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-05 20:21:18 -07:00
parent c6b7890212
commit 3995af736c
16 changed files with 456 additions and 70 deletions
@@ -67,7 +67,7 @@ namespace ProjectM.Authoring
Debug.LogError($"Enemy '{authoring.name}' has BOTH ChargerAuthoring and SpitterAuthoring; it would match no AI pass and never move. Remove one.", authoring);
if (GetComponent<ChargerAuthoring>() != null) { kind = ZoneEnemyMath.KindCharger; windup = 30; }
else if (spitter != null) { kind = ZoneEnemyMath.KindSpitter; windup = (byte)Mathf.Clamp(spitter.WindupTicks, 1, 255); }
else if (GetComponent<SwarmerAuthoring>() != null) { kind = ZoneEnemyMath.KindSwarmer; windup = 6; }
else if (GetComponent<SwarmerAuthoring>() != null) { kind = ZoneEnemyMath.KindSwarmer; windup = (byte)Tuning.AttackWindupTicks; /* B4: match the server windup (grunt-path swarmers use GruntWindupTicks); baked 6 was a snap-ramp lie */ }
AddComponent(entity, new EnemyTelegraph { WindupTicks = windup, Kind = kind });
}
}