using Unity.Entities; using Unity.Mathematics; using Unity.NetCode; namespace ProjectM.Simulation { /// /// Ghost component on the projectile prefab. Drives predicted+server movement and carries the /// classification key used to reconcile a client's predicted-spawned projectile with the server's /// authoritative ghost. is replicated so the server's auto-targeted aim /// reconciles the client's raw-aim prediction; is replicated so it lives in /// snapshot history for the predicted-spawn classifier. Speed/Damage/Range are baked on the prefab /// (identical both worlds → deterministic) and not replicated; DistanceTravelled is integrated /// locally each tick and not replicated. /// public struct Projectile : IComponentData { /// Planar XZ travel direction (world XZ mapped to float2 x,y), normalized. [GhostField(Quantization = 1000)] public float2 Direction; /// /// Classification key: (ownerNetId << 16) | absoluteFireCount. Replicated so it is present /// in snapshot history; the client classifier matches this against its predicted spawn. /// [GhostField] public uint SpawnId; /// Travel speed in units/second. Baked on the prefab; not replicated. public float Speed; /// Damage applied on hit. Baked on the prefab; not replicated. public float Damage; /// Max travel distance before the server expires the projectile. Baked on the prefab; not replicated. public float Range; /// Integrated distance travelled (predicted on client + authoritative on server). Not replicated. public float DistanceTravelled; } }