Hygiene B2: dead-code removal

Delete (unreferenced in any scene, per operator decision):
- TrainingDummy* chain (authoring/spawner/system/components/prefab) + UpgradePickup* chain (authoring/spawner/systems/components/prefab); remove TrainingDummyTag from the 3 live combat queries (AbilityFire/Melee/HealthApplyDamage now key on EnemyTag) and repoint HealthApplyDamageSystemTests to EnemyTag.
- Dead RPC RegionTransitSystem + RegionTransitRequest (no sender, ungated) + its test.
- Heartbeat + HeartbeatSystem (no WorldSystemFilter, ran no-op every tick) + its test.
- BuildSendSystem dead conveyor/pylon dev hooks (s_ConveyorDir, [/] rotation, Place{Pylon,Harvester,Conveyor} statics).
- Deprecated CyclePhase alias consts (Expedition/Defend/Build/*Ticks); repoint WaveSystemTests to Siege/Calm.
- Unread FeelConfig fields (HitFlashDurationMs, RumbleHeavy) + dangling HudUi doc-comments + stale crefs.

451/451 EditMode tests pass. CLAUDE.md HeartbeatSystemTests example ref to be repointed in B7.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-07 23:16:53 -07:00
parent b1041003f0
commit 589e712db3
53 changed files with 28 additions and 1229 deletions
@@ -80,7 +80,7 @@ namespace ProjectM.Simulation
if (isServer)
{
foreach (var (tx, th, te) in
SystemAPI.Query<RefRO<LocalTransform>, RefRO<Health>>().WithAny<TrainingDummyTag, EnemyTag>().WithEntityAccess())
SystemAPI.Query<RefRO<LocalTransform>, RefRO<Health>>().WithAll<EnemyTag>().WithEntityAccess())
{
if (th.ValueRO.Current <= 0f) continue; // B3: corpses are neither aim magnets nor cleave targets
candidatePositions.Add(tx.ValueRO.Position);
@@ -4,7 +4,7 @@ namespace ProjectM.Simulation
{
/// <summary>
/// EB-1 — opt-in marker for an entity that <see cref="ProjectM.Server.HealthApplyDamageSystem"/> DESTROYS when
/// its <see cref="Health"/> hits 0 (alongside <c>TrainingDummyTag</c>/<c>EnemyTag</c>). Baked ONLY on the
/// its <see cref="Health"/> hits 0 (alongside <c>EnemyTag</c>). Baked ONLY on the
/// player-built structure ghosts (Turret/Wall/Pylon) so "machines can die". DELIBERATELY a distinct tag rather
/// than gating on bare <see cref="PlacedStructure"/>: that identity is SHARED by the reserved M7 automation
/// machines (Harvester/Fabricator/Conveyor) whose teardown would silently drop in-flight conveyor cargo — the
@@ -7,7 +7,7 @@ namespace ProjectM.Simulation
/// Hit points for any damageable ghost (players, training dummies). Server-authoritative:
/// only server systems write <see cref="Current"/>; clients receive it via the [GhostField]
/// for display and prediction reconciliation. <see cref="Max"/> is baked identically on both
/// worlds and is not replicated. Added by PlayerBaker / TrainingDummyBaker.
/// worlds and is not replicated. Added by PlayerBaker.
/// </summary>
public struct Health : IComponentData
{
@@ -1,26 +0,0 @@
using Unity.Entities;
using Unity.Mathematics;
namespace ProjectM.Simulation
{
/// <summary>
/// Baked singleton describing the training-dummy field to spawn at world start. Consumed once by
/// the server-only TrainingDummySpawnSystem, which instantiates <see cref="Count"/> dummies from
/// <see cref="Prefab"/> and then destroys this singleton so the spawn runs exactly once. Not
/// replicated — dummies are spawned authoritatively on the server and reach clients as ghosts.
/// </summary>
public struct TrainingDummySpawner : IComponentData
{
/// <summary>Baked entity prefab to instantiate for each dummy.</summary>
public Entity Prefab;
/// <summary>Number of dummies to spawn.</summary>
public int Count;
/// <summary>World-unit gap between consecutive dummies along the spawn line (X axis).</summary>
public float Spacing;
/// <summary>World-space position of the first dummy; subsequent dummies offset by <see cref="Spacing"/>.</summary>
public float3 Origin;
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: a8f27601fb20640718aaed2c48d1d016
@@ -1,11 +0,0 @@
using Unity.Entities;
namespace ProjectM.Simulation
{
/// <summary>
/// Zero-size marker identifying a training-dummy enemy. Server auto-target collects
/// <see cref="TrainingDummyTag"/> entities as candidates, and the damage/death path destroys
/// a dummy when its <c>Health.Current</c> reaches zero. Added by TrainingDummyBaker.
/// </summary>
public struct TrainingDummyTag : IComponentData { }
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: ebe9114e40db748669d89ef861415bac
@@ -1,17 +0,0 @@
using Unity.Entities;
namespace ProjectM.Simulation
{
/// <summary>
/// A world pickup that, on player overlap, grants one StatModifier (server-authoritative) and is then
/// destroyed. Mirrors a single StatModifier payload (Target/Op as bytes). The pickup is an
/// interpolated ghost so clients see and despawn it; the grant is applied by UpgradePickupSystem.
/// </summary>
public struct UpgradePickup : IComponentData
{
public byte Target; // StatTarget
public byte Op; // ModOp
public float Value;
public uint SourceId;
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: a0d34f4d0b12241c7b0f0b1d002142f3
@@ -1,17 +0,0 @@
using Unity.Entities;
using Unity.Mathematics;
namespace ProjectM.Simulation
{
/// <summary>
/// Singleton describing how many upgrade pickups to spawn and where (mirrors TrainingDummySpawner).
/// Consumed once by the server's UpgradePickupSpawnSystem.
/// </summary>
public struct UpgradePickupSpawner : IComponentData
{
public Entity Prefab;
public float3 Origin;
public int Count;
public float Spacing;
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 059368b62be834614ae3a110a51d42da
@@ -1,13 +0,0 @@
using Unity.Entities;
namespace ProjectM.Simulation
{
/// <summary>
/// Trivial unmanaged component used by the setup smoke test to prove the ECS
/// compile + source-gen + tick path works. Safe to delete once real gameplay exists.
/// </summary>
public struct Heartbeat : IComponentData
{
public int Tick;
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: a0347bd6d99db438f85ec1985b7f81e1
@@ -1,23 +0,0 @@
using Unity.Burst;
using Unity.Entities;
namespace ProjectM.Simulation
{
/// <summary>
/// Smoke-test system: increments every <see cref="Heartbeat"/> once per tick.
/// Default (no <c>[WorldSystemFilter]</c>) so it runs in the SimulationSystemGroup of
/// every world. Burst-compiled and unmanaged (<see cref="ISystem"/>) per DOTS convention.
/// </summary>
[BurstCompile]
public partial struct HeartbeatSystem : ISystem
{
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
foreach (var heartbeat in SystemAPI.Query<RefRW<Heartbeat>>())
{
heartbeat.ValueRW.Tick++;
}
}
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 78349f49733934f348acb488689fc9ec
@@ -174,7 +174,7 @@ namespace ProjectM.Simulation
var enemyPositions = new NativeList<float3>(Allocator.Temp);
foreach (var (xform, health, enemyEntity) in
SystemAPI.Query<RefRO<LocalTransform>, RefRO<Health>>()
.WithAny<EnemyTag, TrainingDummyTag>()
.WithAll<EnemyTag>()
.WithEntityAccess())
{
if (health.ValueRO.Current <= 0f)
@@ -12,7 +12,6 @@ namespace ProjectM.Simulation
/// <para>
/// <b>Values that already live in a clear, public, semantically-named home (NOT duplicated here):</b>
/// <list type="bullet">
/// <item><see cref="CyclePhase.ExpeditionTicks"/> / <see cref="CyclePhase.BuildTicks"/> — cycle phase durations.</item>
/// <item><see cref="RegionMath.ExpeditionOffsetX"/> — base→expedition world-space offset.</item>
/// <item>Per-ability/character stats — authored in ScriptableObjects, baked to the AbilityDatabase blob (M3).</item>
/// </list>
@@ -39,22 +39,6 @@ namespace ProjectM.Simulation
/// <summary>The base is under assault by a Husk wave (event-triggered; ends when the wave is cleared).</summary>
public const byte Siege = 1;
// ---- Deprecated aliases (kept so HUD/audio/tests keep compiling through the cut-over; cleaned up later). ----
/// <summary>DEPRECATED alias of <see cref="Calm"/>.</summary>
public const byte Expedition = 0;
/// <summary>DEPRECATED alias of <see cref="Siege"/>.</summary>
public const byte Defend = 1;
/// <summary>DEPRECATED, unreachable — the timed Build phase is retired.</summary>
public const byte Build = 2;
/// <summary>DEPRECATED — the forced Expedition timer is retired (the loop is player-driven). Kept so existing crefs resolve.</summary>
public const uint ExpeditionTicks = 3600;
/// <summary>DEPRECATED — the forced Build timer is retired. Kept so existing crefs resolve.</summary>
public const uint BuildTicks = 1200;
}
/// <summary>
@@ -1,17 +0,0 @@
using Unity.NetCode;
namespace ProjectM.Simulation
{
/// <summary>
/// Client -&gt; server request to move the sender's player between world regions (base &lt;-&gt; expedition).
/// A one-off action, so an RPC (not a per-tick predicted input), mirroring <see cref="StorageOpRequest"/>.
/// TargetRegion is a byte (see <see cref="RegionId"/>) to keep the generated serializer trivial. The
/// server teleports the sender's player to the region origin and flips its <see cref="RegionTag"/>, which
/// re-scopes GhostRelevancy so the client gains the target region's ghosts and drops the old region's.
/// </summary>
public struct RegionTransitRequest : IRpcCommand
{
/// <summary>Destination region id (see <see cref="RegionId"/>).</summary>
public byte TargetRegion;
}
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 32c76b46284ed1845a412ca030de2499