using Unity.Entities; namespace ProjectM.Simulation { /// /// Marks a Husk enemy: a server-simulated, OWNERLESS INTERPOLATED ghost that seeks the nearest player /// and strikes on contact. Damageable like the training dummy (Health/HitRadius/DamageEvent), but unlike /// the dummy it IS a replicated ghost, so every client sees it. Movement is server-authoritative — written /// to LocalTransform in the plain SimulationSystemGroup (interpolated ghosts are NOT predicted) and /// replicated via the stock LocalTransform default variant (no hand-written [GhostField]). Spawned by /// the (round-robin over Husk variants). /// public struct EnemyTag : IComponentData { } /// /// Baked Husk tunables — identical on both worlds, not replicated (only server systems read them). Different /// Husk variants (Grunt / Swarmer / Brute) are just different baked values of this component. /// public struct EnemyStats : IComponentData { /// Planar seek speed toward the target, world units/second. public float MoveSpeed; /// Centre-to-centre distance at which the Husk can strike a player. public float AttackRange; /// Damage dealt per strike. public float AttackDamage; /// Simulation ticks between strikes. public int AttackCooldownTicks; } /// /// Server-only per-Husk attack gate. Raw tick value of the earliest tick it may strike again; 0 = /// ready. Compared by wrapping into a (raw subtraction is unsafe /// across tick wraparound), mirroring . Not replicated. /// public struct EnemyAttackCooldown : IComponentData { public uint NextAttackTick; } }