#if UNITY_EDITOR using ProjectM.Simulation; using Unity.Collections; using Unity.Entities; using Unity.NetCode; namespace ProjectM.Server { /// /// MC-0 — EDITOR-ONLY server telemetry sampler/sender. Ensures the singleton, /// samples live-enemy-count + the server tick each tick, and every ships a /// snapshot to every connection (so the dev overlay shows live fun-gate /// counters over a real connection too). Combat systems increment the real counters at the stamp sites (MC-1+). /// Plain server (NOT the predicted loop); non-Burst (managed-simple, /// editor-only). Stripped from builds; the wire TYPE is unconditional. /// [WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)] [UpdateInGroup(typeof(SimulationSystemGroup))] public partial struct DevTelemetrySystem : ISystem { const uint ReportPeriodTicks = 15; EntityQuery m_Husks; public void OnCreate(ref SystemState state) { state.RequireForUpdate(); m_Husks = state.GetEntityQuery(ComponentType.ReadOnly()); if (state.GetEntityQuery(ComponentType.ReadWrite()).IsEmpty) state.EntityManager.CreateEntity(typeof(DevTelemetry)); } public void OnUpdate(ref SystemState state) { var serverTick = SystemAPI.GetSingleton().ServerTick; if (!serverTick.IsValid) return; uint now = serverTick.TickIndexForValidTick; var telem = SystemAPI.GetSingletonRW(); telem.ValueRW.LiveEnemyCount = (uint)m_Husks.CalculateEntityCount(); telem.ValueRW.LastSampleTick = now; if (now == 0 || (now % ReportPeriodTicks) != 0) return; var t = telem.ValueRO; var report = new DebugTelemetryReport { DashIFrameNegatedHits = t.DashIFrameNegatedHits, DashesWasted = t.DashesWasted, ChargerWhiffWindowsOpened = t.ChargerWhiffWindowsOpened, ChargerWhiffPunishesLanded = t.ChargerWhiffPunishesLanded, LiveEnemyCount = t.LiveEnemyCount, LastSampleTick = t.LastSampleTick, }; var ecb = new EntityCommandBuffer(Allocator.Temp); foreach (var (netId, connEnt) in SystemAPI.Query>().WithEntityAccess()) { var req = ecb.CreateEntity(); ecb.AddComponent(req, report); ecb.AddComponent(req, new SendRpcCommandRequest { TargetConnection = connEnt }); } ecb.Playback(state.EntityManager); ecb.Dispose(); } } } #endif