From 798cc2e4a5f46d60fcfd6b9f4b6f26a68d74b316 Mon Sep 17 00:00:00 2001 From: Mohcine Chraibi Date: Tue, 11 Aug 2026 16:24:30 +0200 Subject: [PATCH] fix(hdf5): check entity coverage instead of peak concurrent count The incomplete-data warning compared the busiest timestep's agent count against MaxAgents, which false-positives whenever agents enter and leave over the run: the peak concurrent count is legitimately lower than the number of distinct entities. Track which entity IDs appear in any sample and warn only when some declared entities never show up at all. --- .../MassAI/SubSystems/AgentDataSubsystem.cpp | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/UnrealFolder/ProjectMobius/Source/ProjectMobius/Private/MassAI/SubSystems/AgentDataSubsystem.cpp b/UnrealFolder/ProjectMobius/Source/ProjectMobius/Private/MassAI/SubSystems/AgentDataSubsystem.cpp index 7c4922a3..b76f2241 100644 --- a/UnrealFolder/ProjectMobius/Source/ProjectMobius/Private/MassAI/SubSystems/AgentDataSubsystem.cpp +++ b/UnrealFolder/ProjectMobius/Source/ProjectMobius/Private/MassAI/SubSystems/AgentDataSubsystem.cpp @@ -1298,11 +1298,6 @@ void FProcessSimulationDataRunnable::RunHdf5SimDataGatheringLoop(bool bCalculate // --- Incomplete data detection --- int32 ActualTimestepCount = MaxTimestepIndex + 1; - int32 PeakEntityCount = 0; - for (int32 Count : NumOfAgentsPerTimeStep) - { - PeakEntityCount = FMath::Max(PeakEntityCount, Count); - } // Timestep mismatch: metadata says more timesteps than we actually loaded if (Hdf5Data.Meta.Duration > 0 && Hdf5Data.Meta.SamplingRate > 0) @@ -1318,14 +1313,31 @@ void FProcessSimulationDataRunnable::RunHdf5SimDataGatheringLoop(bool bCalculate } } - // Entity count mismatch: fewer entities observed than metadata declares - if (MaxAgents > 0 && PeakEntityCount > 0 && PeakEntityCount < MaxAgents) + // Entity coverage: every entity the metadata declares should appear in at least one + // timestep. This deliberately does not compare against the busiest timestep, because + // agents enter and leave over the course of a simulation, so the peak concurrent count + // is legitimately lower than the total number of distinct entities. + if (MaxAgents > 0) { - ReportAgentDataErrorAnyThread(OwnerSubsystem.Get(), - TEXT("Incomplete entity data"), - FString::Printf(TEXT("HDF5: peak entity count %d < MaxAgents %d. Some entities may be missing."), - PeakEntityCount, MaxAgents), - TEXT("AgentDataSubsystem - RunHdf5SimDataGatheringLoop")); + TBitArray<> ObservedEntities(false, MaxAgents); + int32 ObservedEntityCount = 0; + for (const FHdf5SampleData& Sample : Hdf5Data.Samples) + { + if (ObservedEntities.IsValidIndex(Sample.EntityId) && !ObservedEntities[Sample.EntityId]) + { + ObservedEntities[Sample.EntityId] = true; + ++ObservedEntityCount; + } + } + + if (ObservedEntityCount < MaxAgents) + { + ReportAgentDataErrorAnyThread(OwnerSubsystem.Get(), + TEXT("Incomplete entity data"), + FString::Printf(TEXT("HDF5: %d of %d entities have no samples. Data may be incomplete."), + MaxAgents - ObservedEntityCount, MaxAgents), + TEXT("AgentDataSubsystem - RunHdf5SimDataGatheringLoop")); + } } }