UMassBattleSubsystem
Source/MassBattle/Public/Subsystems/MassBattleSubsystem.h
概述 Overview
MassBattle 的核心总控子系统。四个职责:① 帧控制——时间步进(固定/可变步长)、帧分散(ESubFrame 四子帧)、网络调步与锁步指令出队、游戏暂停总闸;② 处理器派发——13 个处理器实例不再向 Mass 框架自动注册,由本子系统持有并按 6 阶段链(SimStages)手动派发,阶段间调用 ResolvePendingSpawns() 使生成链同帧闭环;③ 全局 UID 空间——所有实体类型共用单调递增的 UID 计数器与双向映射;④ 帧末队列消费——BP 事件、销毁、调试绘制、资产注册等全部 gatherer 队列在此串行排空,并驱动其余 8 个子系统的 ExecuteTick。
The central control subsystem of MassBattle. Four responsibilities: ① frame control — time stepping (fixed/variable step), frame spreading (four ESubFrame sub-ticks), network pacing with lockstep command dequeue, and the master game-pause gate; ② processor dispatch — the 13 processor instances are no longer auto-registered with the Mass framework; this subsystem owns them and dispatches them manually in a 6-stage chain (SimStages), calling ResolvePendingSpawns() between stages so spawn chains resolve within one frame; ③ global UID space — a single monotonic UID counter and bidirectional maps shared by all entity types; ④ end-of-frame queue drain — BP events, destruction, debug drawing and asset registration gatherers are drained serially here, and it drives ExecuteTick of the other eight subsystems.
继承 Inheritance
ESubFrame enum class
帧分散模式的子帧分组(非 UENUM)。bFrameSpreading 为 true 时,一个逻辑帧总是严格分成 ESubFrame::COUNT(4)个引擎帧执行——永不合并、永不追帧。处理器按 IsSubFrameScheduled 自门控,仅在自己所属子帧被调度的引擎帧执行。
Sub-frame groups for frame spreading (not a UENUM). When bFrameSpreading is true, one logic frame is always split across exactly ESubFrame::COUNT (4) engine ticks — never merged, never caught up. Processors self-gate on IsSubFrameScheduled and only execute on engine ticks where their sub-frame is scheduled.
| 值 Value | 说明 Description |
|---|---|
Subtick0 = 0 | 帧起始网格全量重建 + tick 推进 + 锁步指令出队 + 索敌(Trace)。Start-of-frame grid rebuild + tick progression + lockstep dequeue + targeting (Trace). |
Subtick1 = 1 | 行为(开头)+ 弹丸 + 减益 + 反应 + 移动分区 1(UID % Divisor < Threshold)。Behavior (head) + Projectile + Debuff + Reaction + move partition 1 (UID % Divisor < Threshold). |
Subtick2 = 2 | 移动分区 2(其余)+ 宿主(完整移动阶段之后)。Move partition 2 (the rest) + Host (AFTER the full move phase). |
Subtick3 = 3 | 战利品 + 特效 + 渲染 + 网络 + 子系统 tick + 队列消费 + 渲染处理器。Loot + Fx + Render + Network + subsystem ticks + queue drain + render processors. |
COUNT = 4 | 子帧总数,用于掩码与数组尺寸。Total sub-frame count; used for masks and array sizes. |
结构体 Structs
指挥中心共享目标的快照。由 ReinforceProcessor(支援处理器)串行填充,BehaviorProcessor 并行段只读——支援行为据此查找最近共享目标,无需在并行处理期间逐实体查询 fragment。非 USTRUCT,仅头文件内使用。
Snapshot of a command center's shared targets, populated serially by the ReinforceProcessor and read-only in BehaviorProcessor parallel sections — reinforce behavior finds the nearest shared target without per-entity fragment queries during parallel processing. Not a USTRUCT; header-internal only.
成员变量 Members
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
CommandCenterEntity | FEntityHandle | — | 指挥中心实体句柄。Command center entity handle. |
TargetHandles | TArray<FEntityHandle> | 空 | 共享目标实体句柄列表。Shared target entity handles. |
TargetLocations | TArray<FVector> | 空 | 共享目标位置列表(与 TargetHandles 并行)。Shared target locations (parallel to TargetHandles). |
每帧支援上报——追击中的 Agent 将当前目标推送给指挥中心。并行收集(ReinforceReportGatherer),串行聚合为 CommanderSnapshots。
Per-frame reinforce report — chasing agents push their current target to the command center. Collected in parallel (ReinforceReportGatherer), aggregated into CommanderSnapshots in a serial post-pass.
成员变量 Members
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
CommandCenter | FEntityHandle | — | 指挥中心实体句柄。Command center entity handle. |
Target | FEntityHandle | — | 追击中的当前目标实体。Current target entity being chased. |
TargetLocation | FVector | — | 目标位置。Target location. |
公开方法 Public Methods
生命周期 Lifecycle
子系统初始化入口。四件事:① 调用 FFix64::InitializeLUT() 初始化定点三角查找表(跨平台确定性数学);② 注册 FCoreDelegates::OnEndFrame / OnBeginFrame 回调——帧控制必须在 Mass 处理图之外运行(同步 EntityManager API 在 IsProcessing() 期间被禁止);③ 禁用 UE 的 per-actor 调试文本上限(默认 128,高实体数下行为标签会静默丢弃);④ 创建并持有全部 13 个处理器实例(SimStages 9 个 + GridUpdateProcessor + NetworkProcessor + 渲染组 2 个),各处理器 CallInitialize 后存入 OwnedProcessors(UPROPERTY GC 根,仅靠 Outer 不够——UE GC 标记父对象时不会自动标记子对象)。
Subsystem initialization. Four jobs: ① FFix64::InitializeLUT() for the fixed-point trig lookup tables (cross-platform deterministic math); ② registers FCoreDelegates::OnEndFrame / OnBeginFrame callbacks — frame control must run outside the Mass processing graph (synchronous EntityManager APIs are forbidden while IsProcessing()); ③ disables UE's per-actor debug-text cap (default 128 — behavior labels get silently dropped at high entity counts); ④ creates and owns all 13 processor instances (9 in SimStages + GridUpdateProcessor + NetworkProcessor + 2 render processors), each CallInitialized and stored in OwnedProcessors (a UPROPERTY GC root — Outer alone is insufficient since UE GC does not auto-mark children).
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Collection | FSubsystemCollectionBase& | 子系统集合;通过 InitializeDependency<UMassEntitySubsystem> 解析实体管理器。Subsystem collection; resolves UMassEntitySubsystem via InitializeDependency. |
Output
无返回值。副作用:注册两个全局帧回调、创建 13 个处理器实例并初始化、设置调试文本 CVar。
No return value. Side effects: registers two global frame callbacks, creates and initializes 13 processor instances, and sets the debug-text CVar.
子系统销毁入口:注销两个帧回调,清空全部子系统缓存指针、事件 gatherer、调试队列、资产注册队列与注册表、渲染器映射,最后 OwnedProcessors.Reset() 释放 13 个处理器实例。
Subsystem teardown: removes both frame callbacks, clears all subsystem cache pointers, event gatherers, debug queues, asset registration queues/maps, renderer maps, and finally OwnedProcessors.Reset() releases the 13 processor instances.
Input
无参数。
No parameters.
Output
无返回值。副作用:释放全部队列缓冲与处理器实例。
No return value. Side effect: releases all queue buffers and processor instances.
每引擎帧主入口(TG_PostUpdateWork,所有模拟阶段之后)。流程:① 前置子系统有效性校验(9 个子系统任一为空则整帧跳过);② 若 bShouldTickProcessors 且 SimStages 非空——预冲刷命令缓冲、重置 Host 池统计,然后按 6 阶段链逐阶段 RunProcessorsView 派发(每阶段独立 FProcessingContext,作用域退出应用延迟命令),阶段间 ResolvePendingSpawns(),并 EMA 记录整子帧 SimStages 墙钟供 move 分区均衡器;③ Subtick3 维护段(见下);④ 渲染处理器(FxRender/AgentRender)最后运行并打墙钟戳 LastLogicTickWallTime;⑤ HostSub->UpdateHostRenderInterp 与 HostMonoProcessor->TickCpuInterp 每引擎帧运行;⑥ 追帧完成检测——到达 FastForwardTargetTick 时校验 hash、广播 FastForwardCompleted 事件、解除暂停。
Per-engine-frame main entry (runs at TG_PostUpdateWork, after all sim phases). Flow: ① upfront validation — if any of the 9 subsystems is null the whole tick is skipped; ② when bShouldTickProcessors and SimStages is non-empty — pre-flush command buffer, reset Host pool tick stats, then dispatch the 6-stage chain via RunProcessorsView per stage (each stage owns an FProcessingContext whose destructor applies deferred commands), calling ResolvePendingSpawns() between stages, and EMA-record the whole-subtick SimStages wall time for the move partition rebalancer; ③ Subtick3 maintenance block (below); ④ render processors (FxRender/AgentRender) run last and stamp LastLogicTickWallTime; ⑤ HostSub->UpdateHostRenderInterp and HostMonoProcessor->TickCpuInterp run every engine frame; ⑥ fast-forward completion check — at FastForwardTargetTick verifies the hash, broadcasts FastForwardCompleted and releases the pause.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
DeltaTime | float | 本引擎帧墙钟时间(秒),用于 CPU 插值与渲染。Engine frame delta time in seconds; used for CPU interp and rendering. |
Output
无返回值。Subtick3 段的副作用(每逻辑帧一次):ProcessHostOpsQueues 消费宿主操作队列 → 6 个子系统 ExecuteTick(Projectile/HashGrid/Host/Loot/Debuff/Fx)→ ProcessEventQueues 派发 BP 事件 → 弹丸/战利品回收队列与销毁队列 → 调试绘制队列 → NetworkProcessor 采集 hash+snapshot(帧末真态)→ 应用延迟快照、维护哈希历史、触发 OnTickCompleted 网络桥接、按 NetworkFlushIntervalTicks 门控 CacheLatestSnapshot。
No return value. Subtick3 side effects (once per logic frame): ProcessHostOpsQueues drains host op queues → six subsystem ExecuteTick calls (Projectile/HashGrid/Host/Loot/Debuff/Fx) → ProcessEventQueues dispatches BP events → projectile/loot recycle and destruction queues → debug draw queues → NetworkProcessor captures hash+snapshot at the true end-of-frame state → applies deferred snapshots, maintains the hash history, fires the OnTickCompleted network bridge and gates CacheLatestSnapshot on NetworkFlushIntervalTicks.
UTickableWorldSubsystem 要求的 profiling 入口,返回本子系统的快速声明 cycle stat。
Profiling entry required by UTickableWorldSubsystem; returns the quick-declared cycle stat for this subsystem.
Input
无参数。
No parameters.
Output
返回 TStatId。无副作用。
Returns a TStatId. No side effects.
静态访问器 Static Accessors
静态访问器:从任意世界上下文对象解析 UWorld 并取其子系统。空指针提前退出(匹配 UMassAPISubsystem::GetPtr)——避免 PIE 关闭时 BP 异步任务持空 WorldContext 触发无谓的日志噪音。
Static accessor: resolves the UWorld from any world-context object and returns its subsystem. Early-outs on null to match UMassAPISubsystem::GetPtr — avoids noisy log spam at PIE shutdown when BP async tasks hold a null WorldContext.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
WorldContext | const UObject* | 任意 UObject 世界上下文;为 null 时直接返回 nullptr。Any UObject world context; null returns nullptr immediately. |
Output
返回子系统指针;世界上下文无效时为 nullptr。
Returns the subsystem pointer, or nullptr when the world context is invalid.
静态访问器引用版本:取不到即 checkf 断言——用于「子系统必须存在」的不变式场景。
Reference version of the static accessor: checkf assertion when unavailable — for invariant paths where the subsystem must exist.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
WorldContext | const UObject* | 任意 UObject 世界上下文。Any UObject world context. |
Output
返回子系统引用;不可用时触发 checkf 断言("Failed to get UMassBattleSubsystem from world context.")。
Returns the subsystem reference; triggers a checkf assertion ("Failed to get UMassBattleSubsystem from world context.") when unavailable.
子系统 Getters Subsystem Getters
9 个惰性访问器(同名私有缓存成员)。首次调用时从 GetWorld() 取子系统并写入 CurrentWorld 与对应缓存成员;后续直接命中缓存。Loot 版本例外:仅在取到非空子系统时才写缓存——world 拆除/重连期间子系统集合切换产生的瞬态 null 不得永久毒化缓存,否则后续模板恢复路径永远跳过 loot 分支,客户端卡死 PauseForServerSnapshot。
Nine lazy accessors (each with a private cache member). On first call they fetch the subsystem from GetWorld() and fill CurrentWorld plus the matching cache member; later calls hit the cache. Loot is the exception: the cache is only written when the fetched subsystem is non-null — a transient null (world teardown / subsystem collection mid-swap during rejoin) must not poison the cache permanently, or the template-recovery fallback skips the loot branch and the client sticks at PauseForServerSnapshot.
Input
无参数。
No parameters.
Output
返回对应子系统指针(世界不存在时可能为 nullptr)。副作用:填充 CurrentWorld 与对应缓存成员。
Returns the subsystem pointer (may be nullptr without a world). Side effect: fills CurrentWorld and the cache member.
全局 UID 空间 Global UID Space
分配下一个通用实体 UID:EntityUIDAllocator.Allocate() 的薄封装(保留历史 API 名,~30 个调用点零改动)。槽位分配器:2^24 槽占用位图、最小空闲槽、循环利用——上界是同时存在实体数而非累计生成数。仅限游戏线程串行 drain(无锁契约;历史计数器的并行原子递增已随计数器退役)。所有通用实体类型(Agent/Projectile/Loot/Debuff/Host/Fx)共用;障碍物 UID 走 UMassBattleObstSubsystem 的独立槽位空间。
Allocates the next general-entity UID — a thin wrapper over EntityUIDAllocator.Allocate() (the historical API name is kept so ~30 call sites stay untouched). The slot allocator: a 2^24-slot occupancy bitmap, first-free-slot, with recycling — bounded by concurrent entities, never by cumulative spawns. Game-thread serial drain only (lockless contract; the old counter's parallel atomic increment retired with the counter). All general entity types (Agent/Projectile/Loot/Debuff/Host/Fx) share it; obstacle UIDs use UMassBattleObstSubsystem's separate slot space.
Input
无参数。
No parameters.
Output
返回新分配的 UID(起始 -1,首次调用返回 0)。副作用:原子递增共享计数器。
Returns the newly allocated UID (starts at -1; the first call returns 0). Side effect: atomically increments the shared counter.
UID → 句柄的 O(1) 查找(全局唯一,无需类型参数)。UID < 0 或未注册时返回无效句柄。
O(1) UID → handle lookup (UIDs are globally unique, no type parameter needed). Returns an invalid handle for UID < 0 or unregistered UIDs.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
UID | int32 | 实体 UID;-1 = 无效。Entity UID; -1 = invalid. |
Output
返回实体句柄;未命中返回默认(无效)句柄。
Returns the entity handle, or a default (invalid) handle on miss.
句柄 → UID 的 O(1) 查找。先经 IsValid 前置校验(经 Mass API 子系统),句柄无效或未注册返回 -1。
O(1) handle → UID lookup. Validates the handle first via IsValid (through the Mass API subsystem); returns -1 for invalid or unregistered handles.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Handle | FEntityHandle | 实体句柄。Entity handle. |
Output
返回 UID;-1 = 无效/未注册。
Returns the UID; -1 = invalid or unregistered.
hash 折叠路径快速版:跳过 IsValid 前置检查。TMap 键是 (Index, Serial),失效句柄天然 miss;锁步双端句柄有效性一致,折叠保持确定性。
Fast variant for the hash-fold path: skips the IsValid pre-check. Since the TMap key is (Index, Serial), stale handles miss naturally, and lockstep peers agree on handle validity, so the fold stays deterministic.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Handle | FEntityHandle | 实体句柄。Entity handle. |
Output
返回 UID;-1 = 未注册。
Returns the UID; -1 = unregistered.
建立 UID ↔ 句柄双向注册(两个 TMap 各写一条)。UID < 0 时直接返回。由各生成点与快照恢复路径调用(如 MassBattleNetworkProcessor 每 tick 从查询注册、MassBattleAgentSubsystem 生成后注册)。
Registers a UID ↔ handle pair in both directions (one entry in each TMap). Returns immediately when UID < 0. Called from every spawn point and the snapshot-restore path (e.g. MassBattleNetworkProcessor registering from its query each tick, MassBattleAgentSubsystem after spawning).
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
UID | int32 | 实体 UID。Entity UID. |
Handle | FEntityHandle | 实体句柄。Entity handle. |
Output
无返回值。副作用:写两个全局映射(同键覆盖)。
No return value. Side effect: writes both global maps (same key overwrites).
撤销 UID ↔ 句柄注册。仅在双向值均匹配时才移除(防止旧句柄误删新注册),两条映射分别校验。
Removes a UID ↔ handle registration. Only removes when both directions match (prevents a stale handle from deleting a newer registration); each map is checked separately.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
UID | int32 | 实体 UID。Entity UID. |
Handle | FEntityHandle | 实体句柄。Entity handle. |
Output
无返回值。副作用:从两个全局映射移除匹配条目。
No return value. Side effect: removes matching entries from both global maps.
一次性重建全局 UID 映射。映射实际为增量维护(每次生成与快照恢复都写入),此处仅清空两个 TMap。
One-shot rebuild of the global UID maps. The maps are maintained incrementally (written at every spawn and snapshot restore), so this only empties both TMaps.
Input
无参数。
No parameters.
Output
无返回值。副作用:清空两个全局映射。
No return value. Side effect: empties both global maps.
将 UniqueID 与 ResyncGeneration 混合(UniqueID ^ (Gen << 24)),使每次 resync 后 GPU 身份令牌变化,强制跳变而非从旧占有者数据插值。网络子系统不可用时 Gen 取 0。
Mixes UniqueID with ResyncGeneration (UniqueID ^ (Gen << 24)) so the GPU identity token changes after every resync, forcing a snap instead of interpolating from stale previous-occupant data. Gen is 0 when the network subsystem is unavailable.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
UniqueID | int32 | 实体 UID。Entity UID. |
Output
返回混合后的渲染身份令牌。无副作用。
Returns the mixed render identity token. No side effects.
BP 异步任务注册表 BP Async Task Registry
BP 异步任务(AgentsMoveTo / AgentsChaseAttack)的注册/注销。注册前先移除同实例与失效弱引用(幂等);以弱引用存储,访问时惰性清理。任务在工厂注册,在 Cleanup/FinishTask/BeginDestroy 注销。
Registration/unregistration for BP async tasks (AgentsMoveTo / AgentsChaseAttack). Register first removes any stale weak refs and duplicates (idempotent); tasks are held as weak references, pruned lazily on access. Tasks register in their factory and unregister in Cleanup/FinishTask/BeginDestroy.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Task | UMassBattleBPTaskAgentsMoveTo* / UMassBattleBPTaskAgentsChaseAttack* | 任务实例;null 直接返回。Task instance; null returns immediately. |
Output
无返回值。副作用:修改对应弱引用数组。
No return value. Side effect: mutates the matching weak-reference array.
采集全部注册任务为快照记录:Task->CaptureSnapshot 逐任务写入 FAgentTaskSnapshotRecord。仅采集有效(非 pending-kill)任务——幻影记录会使 resync 复活已销毁对象。采集后按 (TaskType → MyTaskID) 确定性排序,双端排序结果一致。由 UMassBattleNetworkSubsystem::CacheLatestSnapshot 调用。
Captures every registered task into snapshot records via Task->CaptureSnapshot. Only valid (non-pending-kill) tasks are captured — a phantom record would make resync resurrect a dead object. Records are then sorted deterministically by (TaskType → MyTaskID) so both peers produce identical ordering. Called from UMassBattleNetworkSubsystem::CacheLatestSnapshot.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
OutRecords | TArray<FAgentTaskSnapshotRecord>& | 输出数组,调用前先 Reset()。Output array, reset before filling. |
Output
无返回值。副作用:填充 OutRecords(确定性排序)。
No return value. Side effect: fills OutRecords (deterministically sorted).
resync 恢复窗口内重建全部注册任务(追帧之前)。流程:① 本地数组拷贝有效指针(终止过程会中途改注册表,range-for 会漏);② 按类独立判定成员——(TaskType, MyTaskID) 命中快照记录的任务静默终止(下方重生,OnTaskEnd 是假结束),未命中的残留任务带 OnTaskEnd 终止(服务器在快照点前已结束);③ 逐记录重建:模板(按 Record.TemplateKey 解析)→ Create*TaskFromSnapshot(保留 ID)→ Bind*Task(delegate 重绑)→ Activate;模板解析失败/为空降级为无绑定创建;④ 每个服务于重建任务的模板收到 OnResyncRecovered 通知,未实现钩子的模板打一次性警告;⑤ 全程 bTaskRebuildInProgress = true,期间拒绝 BP 侧任务创建。由 UMassBattleNetworkSubsystem::ProcessDeferredSnapshot 调用。
Rebuilds every registered task from snapshot records (inside the resync restore window, before fast-forward). Flow: ① copies valid pointers to local arrays (termination mutates the registry mid-iteration; a range-for would skip entries); ② per-class membership check — tasks whose (TaskType, MyTaskID) appears in the records are terminated SILENTLY (they respawn below — OnTaskEnd would be a false end); unmatched residuals are terminated WITH OnTaskEnd (the server ended them before the snapshot); ③ rebuilds each record: template (by Record.TemplateKey) → Create*TaskFromSnapshot (ID preserved) → Bind*Task (delegate rebind) → Activate; unresolvable/empty templates degrade to unbound creation; ④ every template that served a rebuilt task gets OnResyncRecovered; templates without the hook get a one-shot warning; ⑤ bTaskRebuildInProgress stays true throughout, rejecting BP-side task creation. Called from UMassBattleNetworkSubsystem::ProcessDeferredSnapshot.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Records | const TArray<FAgentTaskSnapshotRecord>& | 快照恢复的任务记录数组。Snapshot-restored task records. |
Output
无返回值。副作用:终止现有任务、创建并激活重建任务、调用模板恢复钩子、翻转重建标志。
No return value. Side effects: terminates existing tasks, creates and activates rebuilt tasks, calls template recovery hooks, toggles the rebuild flag.
把任务模板 BP 类路径(Key)解析为缓存实例:LoadClass + NewObject(outer = 本子系统,使模板处理器内 GetWorld() 可用)+ 缓存。首次解析后把 Key 插入 SortedTemplateKeys(LexicalLess 插入排序,模板终身注册不删除,缓存序终生有效)。Key 为空或类加载失败返回 nullptr 并打警告。
Resolves a task template BP class path (Key) to a cached instance: LoadClass + NewObject (outer = this subsystem, so GetWorld() works inside template handlers) + cache. On first resolution the Key is insert-sorted into SortedTemplateKeys (templates are registered once and never removed, so the cached order stays valid for the subsystem lifetime). Returns nullptr with a warning for empty keys or failed class loads.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
WorldContext | UObject* | 世界上下文。World context. |
Key | FName | 模板 BP 类路径;NAME_None 返回 nullptr。Template BP class path; NAME_None returns nullptr. |
Output
返回缓存模板实例;加载失败返回 nullptr。副作用:写 TaskTemplateCache 与 SortedTemplateKeys。
Returns the cached template instance, or nullptr on load failure. Side effects: writes TaskTemplateCache and SortedTemplateKeys.
把所有缓存的 LockstepVarStore 实例折叠进哈希 H。迭代 SortedTemplateKeys(注册时插入排序,双端确定性序——TMap 迭代序不确定),无同步变量的模板跳过,每个实例先以模板键字符串作盐(MixBytesInto)再 FoldInto(H)。由 MassBattleNetworkProcessor 与 NetworkSubsystem 在实体折叠同点调用;采集(CaptureVarStoreBlobs)必须同 tick 执行,保证 ServerHashAtCapture 与 payload 一致。
Folds every cached LockstepVarStore instance into the hash H. Iterates SortedTemplateKeys (insert-sorted at registration — a deterministic order across peers; TMap iteration order is not); templates without synced fields contribute zero. Each instance is first salted with its template key string (MixBytesInto), then FoldInto(H). Called by MassBattleNetworkProcessor and NetworkSubsystem at the same point as the per-entity fold; CaptureVarStoreBlobs must run on the same tick so ServerHashAtCapture matches the payload values.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
H | uint64& | 累加哈希(进出参)。Accumulated hash (in/out). |
Output
无返回值。副作用:修改 H。
No return value. Side effect: mutates H.
把所有缓存的 LockstepVarStore 实例采集为逐实例快照条目(与折叠相同的确定性键序,采集与折叠在采集 tick 必须逐位一致)。无同步变量的模板跳过。由网络处理器在采集 tick 调用。
Captures every cached LockstepVarStore instance into per-instance snapshot entries (same deterministic key order as the fold — capture and fold must agree bit-for-bit on the captured tick). Templates without synced fields are skipped. Called by the network processor on capture ticks.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Out | TArray<FVarStoreSnapshotEntry>& | 输出数组,调用前先 Reset()。Output array, reset before filling. |
Output
无返回值。副作用:填充 Out。
No return value. Side effect: fills Out.
IsTaskRebuildInProgress 返回重建标志(重建窗口内 BP 侧任务创建被拒绝,防止仅本端存在的分叉任务);HasAnyRegisteredTasks 返回两个弱引用数组是否有非零条目。
IsTaskRebuildInProgress returns the rebuild flag (BP-side task creation is rejected during the rebuild window to prevent peer-only divergent tasks); HasAnyRegisteredTasks returns whether either weak-reference array is non-empty.
Input
无参数。
No parameters.
Output
返回布尔标志。无副作用。
Returns the boolean flag. No side effects.
帧控制 Frame Control
FCoreDelegates::OnBeginFrame 入口(Initialize 注册),在任何 tick 组 / Mass 阶段管理器之前触发——必须在 Mass 处理图之外运行,因为内部调用同步 EntityManager API(AgentSub->ExecuteTick 的 BatchCreateEntities / 锁步生成),这些在 IsProcessing() 期间被禁止。读取 FApp::GetDeltaTime(),按 MassBattle.EnableTimeDilation CVar 决定是否乘世界膨胀,然后调 PreProcessorFrameSetup。
FCoreDelegates::OnBeginFrame entry (registered in Initialize), firing before any tick group / Mass phase manager — it must run outside the Mass processing graph because it calls synchronous EntityManager APIs (BatchCreateEntities via AgentSub->ExecuteTick / lockstep spawns), which are forbidden while IsProcessing(). Reads FApp::GetDeltaTime(), applies world dilation only when the MassBattle.EnableTimeDilation CVar allows, then calls PreProcessorFrameSetup.
Input
无参数(从 FApp::GetDeltaTime() 取本帧增量)。
No parameters (delta comes from FApp::GetDeltaTime()).
Output
无返回值。副作用:驱动 PreProcessorFrameSetup(时间步进/网络调步/锁步出队)。
No return value. Side effect: drives PreProcessorFrameSetup (time stepping / network pacing / lockstep dequeue).
每引擎帧先于所有模拟处理器的帧控制入口(原 Tick 顶部逻辑迁移至此)。顺序:① 子系统有效性校验(MA/Net/AgentSub);② 暂停帧刷新 GPU 外推时钟(RefreshPausedRenderClock);③ 网络模式下 Net->TickSnapshotTcpTransport() 接收 TCP 数据;④ 暂停分支——失步恢复(应用延迟快照、冷却到期转硬失步、按冷却窗口 ServerRequestResync、超时升级),硬停帧直接返回;⑤ 主动锁步上限——UpdateNetworkClientPacing,客户端严重超前时挂起等待服务器(补放冻结期间到达的命令、广播 PauseForServerToCatchUp/ResumeAfterServerCatchUp 事件);⑥ 缓存 DeltaTime 与调试相机位置(Simulate 模式编辑器视口优先,回退 PlayerController);⑦ bFrameSpreading 运行时切换检测与状态重置;⑧ 时间步进决策(首帧同步调用,追帧强制逻辑帧);⑨ 子帧激活与 LastSubFrameIndex 记录;⑩ Subtick0 设置——TickCount++、网络锁步下 SimulationTime = TickCount × StepTime 确定性重算、GridUpdateProcessor->RebuildAllGrids 网格重建、广播 MassBattleTick 与 AFlowField::OnSimulationTick、AgentSub->ExecuteTick 同步生成、锁步指令出队(DequeueNetCommandsForTick → ExecuteNetCommand,迟到指令即失步进入恢复);⑪ 置 bIsSimulationTick。
Per-engine-frame frame-control entry that runs before all sim processors (moved from the top of the old Tick). Order: ① subsystem validation (MA/Net/AgentSub); ② paused frames refresh the GPU extrapolation clock (RefreshPausedRenderClock); ③ in networked mode Net->TickSnapshotTcpTransport() receives TCP data; ④ pause branch — desync recovery (apply deferred snapshots, escalate to hard desync after cooldown, ServerRequestResync on the request cooldown, timeout escalation), hard-stopped frames return early; ⑤ proactive lockstep ceiling — UpdateNetworkClientPacing; when the client runs far ahead it suspends waiting for the server (replays commands that arrived while frozen, broadcasts PauseForServerToCatchUp/ResumeAfterServerCatchUp); ⑥ caches DeltaTime and the debug camera location (Simulate-mode editor viewport first, PlayerController fallback); ⑦ runtime-toggle detection and reset for bFrameSpreading; ⑧ time-stepping decision (first frame runs synchronously; fast-forward forces a logic frame every engine frame); ⑨ sub-frame activation and LastSubFrameIndex recording; ⑩ Subtick0 setup — TickCount++, deterministic SimulationTime = TickCount × StepTime rebase under network lockstep, GridUpdateProcessor->RebuildAllGrids grid rebuild, MassBattleTick and AFlowField::OnSimulationTick broadcasts, AgentSub->ExecuteTick synchronous spawns, and lockstep command dequeue (DequeueNetCommandsForTick → ExecuteNetCommand; any late command is a desync entering recovery); ⑪ sets bIsSimulationTick.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
DeltaTime | float | 本帧增量(已按 CVar 决定是否乘世界膨胀)。Frame delta (world dilation applied per CVar). |
Output
无返回值。副作用:推进 TickCount/SimulationTime、激活子帧掩码、执行锁步指令、驱动网格重建与同步生成、广播帧事件。
No return value. Side effects: advances TickCount/SimulationTime, activates sub-frame masks, executes lockstep commands, drives grid rebuild and synchronous spawns, and broadcasts frame events.
非帧分散模式的时间步进决策。暂停时置 bShouldTickProcessors=false 返回。固定步长(或网络锁步客户端):AccumulatedTime += DeltaTime × PacingRatio,达到 EffectiveStepTime 时消费一步并置模拟标志;累计超 StepTime × 2 × 膨胀 的失效保护清零(防止大卡顿后的追帧死循环)。可变步长:每帧都是逻辑帧,CalculatedStepTime = min(DeltaTime, SafeStepTime × 膨胀);网络锁步下强制用 SafeStepTime 作固定步长(不应用膨胀——锁步端必须使用相同步长)。
Time-stepping decision for non-frame-spread mode. Paused sets bShouldTickProcessors=false and returns. Fixed step (or networked lockstep client): AccumulatedTime += DeltaTime × PacingRatio; consuming one step when it reaches EffectiveStepTime; a failsafe resets accumulation above StepTime × 2 × dilation (prevents a catch-up death spiral after huge hitches). Variable step: every frame is a logic frame with CalculatedStepTime = min(DeltaTime, SafeStepTime × dilation); under network lockstep the fixed SafeStepTime is forced regardless of local dilation — lockstep peers must use identical step times.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
DeltaTime | float | 本帧增量(秒)。Frame delta in seconds. |
Output
返回 bShouldTickProcessors。副作用:改写 AccumulatedTime / CalculatedStepTime / 模拟标志。
Returns bShouldTickProcessors. Side effects: mutates AccumulatedTime / CalculatedStepTime / the sim flag.
帧分散模式的时间推进。累计 FrameSpreadAccumulatedTime;逻辑帧进行中则 CurrentSubFrame++,达 COUNT 时结束(置 bHasCompletedLogicFrame)。固定步长下累计达 StepTime 启动新逻辑帧,可变步长下前一逻辑帧完成即启动。不变量:一个逻辑帧严格等于 COUNT 个引擎帧——新帧请求停留在累计器中,当前帧推进完才生效。每引擎帧 ActiveSubFrameMask 只含当前子帧一位;空闲引擎帧掩码为 0(仅渲染插值)。
Time advancement for frame-spread mode. Accumulates FrameSpreadAccumulatedTime; an in-flight logic frame advances CurrentSubFrame++ and ends at COUNT (setting bHasCompletedLogicFrame). Fixed step starts a new logic frame when the accumulator reaches StepTime; variable step starts as soon as the previous frame completes. Invariant: a logic frame is ALWAYS exactly COUNT engine ticks — a due new frame stays parked in the accumulator until the in-flight one finishes. Each engine tick ActiveSubFrameMask holds exactly the current sub-frame bit; idle engine ticks get mask 0 (render interpolation only).
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
DeltaTime | float | 本帧增量(秒)。Frame delta in seconds. |
Output
无返回值。副作用:改写 CurrentSubFrame / ActiveSubFrameMask / FrameSpreadAccumulatedTime / CalculatedStepTime / bShouldTickProcessors。
No return value. Side effects: mutates CurrentSubFrame / ActiveSubFrameMask / FrameSpreadAccumulatedTime / CalculatedStepTime / bShouldTickProcessors.
FCoreDelegates::OnEndFrame 回调:为下一帧推进步长,使所有处理器在整帧内看到一致的 bShouldTickProcessors。首帧跳过(防同 DeltaTime 双推进);追帧期间跳过。帧分散:EMA 记录刚执行的子帧墙钟(α=0.25)、每逻辑帧执行 move 分区动态均衡(比较整子帧 SimStages 耗时,Subtick1 含 Behavior/Projectile/Reaction 固定基线,阈值 ±1 且 EMA+边界抑制振荡)、仅渲染帧按平均逻辑子帧时长 FPlatformProcess::Sleep 调步。非帧分散:固定步长下记录逻辑帧墙钟、EMA 估计每逻辑帧渲染数,渲染帧按每渲染预算睡眠使帧时间均匀。
FCoreDelegates::OnEndFrame callback: advances time stepping for the NEXT frame so all processors see the same bShouldTickProcessors throughout the frame. Skipped on the first frame (prevents double-advancing with the same DeltaTime) and during fast-forward. Frame-spread: EMA-records the wall duration of the sub-frame that just ran (α=0.25), runs the dynamic move-partition rebalancer once per logic frame (compares WHOLE-subtick SimStages durations — Subtick1 carries the fixed Behavior/Projectile/Reaction baseline; threshold shifts ±1 with EMA + hysteresis bounds to prevent oscillation), and render-only frames sleep to the average logic sub-frame duration for pacing. Non-frame-spread: fixed step records logic-frame wall time, EMA-estimates renders per logic frame, and render frames sleep to a per-render budget so frame times stay evenly spaced.
Input
无参数(用本帧缓存的 CachedDeltaTime 与 FrameStartWallTime)。
No parameters (uses the frame-cached CachedDeltaTime and FrameStartWallTime).
Output
无返回值。副作用:推进下一帧步长状态、调整 move 分区阈值、可能睡眠(帧调步)。
No return value. Side effects: advances next-frame stepping state, adjusts the move partition threshold, may sleep (frame pacing).
暂停帧渲染时钟刷新:暂停期间模拟不推送渲染数组,User.LogicTickTime 冻结而 Niagara SystemAge 持续增长,GPU 帧外推会失控使 VAT 动画继续播放。本函数遍历所有 AgentRenderer 的 spawn 批次,把 Niagara 的 User.LogicTickTime 设为当前世界时间,使外推保持 ≈0,冻结的 CPU 帧值停留在画面上。
Paused-frame render clock refresh: paused frames push no render arrays, so User.LogicTickTime would freeze while the Niagara SystemAge keeps advancing — the GPU frame extrapolation runs away and VAT animations keep playing. This walks every AgentRenderer spawn batch and sets the Niagara User.LogicTickTime to the current world time, keeping the extrapolation ≈0 so the frozen CPU frame values hold on screen.
Input
无参数。
No parameters.
Output
无返回值。副作用:写各 Niagara 组件的 User.LogicTickTime 变量。
No return value. Side effect: writes the User.LogicTickTime variable of each Niagara component.
模拟阶段之间的生成冲刷:先 ProcessAssetRegistrationQueues() 加载新生成配置引用的软资源,再 MA->FlushCommandBuffer() 应用上一阶段入队的延迟 Mass 命令(含 ProcessHostOpsQueues 与非处理器代码的 Defer)。可每帧多次安全调用(各 op 队列段后自重置,Merge 只取增量)。注:宿主 op 队列的实际消费已移至 Subtick3 引擎帧(每逻辑帧一次,所有模拟阶段之后)。
Spawn resolution between sim stages: first ProcessAssetRegistrationQueues() loads soft assets referenced by new spawn configs, then MA->FlushCommandBuffer() applies deferred Mass commands queued during the previous stage (including those from ProcessHostOpsQueues and non-processor code). Safe to call multiple times per frame (each op queue resets after its section; Merge takes only the delta). Note: the actual host-op drain moved to the Subtick3 engine tick (once per logic frame, after every sim stage).
Input
无参数。
No parameters.
Output
无返回值。副作用:加载资源、应用延迟命令,使本阶段生成对下一阶段同帧可见。
No return value. Side effects: loads assets and applies deferred commands, making this stage's spawns visible to the next stage same-frame.
子帧门控:请求开始一个子帧消费。仅当该子帧已调度、等于当前派发子帧、且 (TickCount, Frame, ConsumerName) 键在本 tick 未被消费过时返回 true(每个消费者每 tick 每子帧至多通过一次)。SubFrameGateTick 变化时重置消费集合。
Sub-frame gate: requests to start consuming a sub-frame. Returns true only when the sub-frame is scheduled, matches the currently-dispatching sub-frame, and the (TickCount, Frame, ConsumerName) key has not been consumed this tick (each consumer passes at most once per sub-frame per tick). The consumed set resets whenever SubFrameGateTick changes.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Frame | ESubFrame | 请求的子帧。Requested sub-frame. |
ConsumerName | FName | 消费者标识,参与门控键。Consumer identity, part of the gate key. |
Output
返回是否通过门控。副作用:通过时写入 ConsumedSubFrameGates。
Returns whether the gate passed. Side effect: records the key in ConsumedSubFrameGates on pass.
暂停控制 Pause Control
游戏暂停总控(用户暂停):幂等切换 bGamePaused,在边沿广播网络事件——暂停/恢复角色按 NetMode 判定(NM_Client → PauseLocalSim/ResumeLocalSim,其余 → PauseServerSim/ResumeServerSim)。蓝图经 MassBattleFuncLib 调用。
Master game-pause controls (user pause): idempotently toggle bGamePaused and broadcast a network event on the edge — the role is picked by NetMode (NM_Client → PauseLocalSim/ResumeLocalSim, otherwise → PauseServerSim/ResumeServerSim). Blueprint entry via MassBattleFuncLib.
Input
无参数。
No parameters.
Output
无返回值。副作用:切换暂停标志,经 OnNetworkEvent 广播暂停/恢复事件(携带当前 TickCount)。
No return value. Side effects: toggles the pause flag and broadcasts a pause/resume event (with the current TickCount) via OnNetworkEvent.
三级暂停查询(内联)。IsUserPaused:仅 bGamePaused。用于网络恢复暂停必须豁免的检查(失步 ack——网络暂停的客户端在恢复中而非卡死)。IsGamePaused:综合暂停——用户暂停、或网络失步暂停(排除追帧,追帧期间模拟实际在推进)、或等待服务器追帧(bPauseWaitServerActive)。IsSimulationPaused:总闸——用户暂停或网络 bSimulationPaused,为真时模拟处理器全部不执行;刻意不含 bPauseWaitServerActive(它经调速追赶路径冻结 tick 推进,不得进入恢复分支)。
Three-level pause query (inline). IsUserPaused: bGamePaused only — for checks that network recovery pauses must be exempt from (desync acking: a network-paused client is recovering, not stuck). IsGamePaused: composite — user pause, or network desync pause (fast-forward excluded — FF actively advances the sim), or the server-catch-up wait (bPauseWaitServerActive). IsSimulationPaused: master gate — user pause or network bSimulationPaused; when true no sim processors execute. Deliberately excludes bPauseWaitServerActive (it freezes tick advancement via the pacing catch-up path and must not enter the recovery branch).
Input
无参数。
No parameters.
Output
返回布尔判定。无副作用。
Returns the boolean verdict. No side effects.
配置与查询 Configuration & Queries
一次性配置模拟参数:固定/可变步长、帧分散、确定性、定点数学。蓝图经 MassBattleFuncLib::SetSimConfig 转发。
Configures simulation parameters in one call: fixed/variable step, frame spreading, determinism, and fixed-point math. Forwarded from MassBattleFuncLib::SetSimConfig for Blueprint.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
InStepTime | float | 固定时间步长(秒);0 = 可变步长(每帧一个逻辑帧)。Fixed time step in seconds; 0 = variable step (every frame is a logic frame). |
InSafeStepTime | float | 可变步长下的最大帧时间上限;固定步长时忽略。Max delta-time cap in variable step mode; ignored with a fixed step. |
bInFrameSpreading | bool | 将一个逻辑帧分散到多个引擎帧(降单帧 CPU 峰值,增逻辑延迟)。Spread one logic frame across engine ticks (lower per-frame CPU spikes at the cost of logic latency). |
bInDeterministic | bool | 按 UID 排序聚合事件并使用按实体确定性 RNG,使模拟可复现。Sort gathered events by UID and use per-entity deterministic RNG for replayability. |
bInFixPointMath | bool | 用定点算术(MoveProcessorFP)替代浮点(MoveProcessor);跨平台确定性必需。Use fixed-point arithmetic (MoveProcessorFP) instead of float (MoveProcessor); required for cross-platform determinism. |
Output
无返回值。副作用:改写 5 个配置成员。
No return value. Side effect: overwrites the five config members.
已弃用(UE_DEPRECATED(5.8, "Use SetSimConfig instead")):旧版四参配置接口,仅改写步长/帧分散/确定性,不含定点数学开关。
Deprecated (UE_DEPRECATED(5.8, "Use SetSimConfig instead")): the old four-parameter config entry; sets step/safe-step/frame-spreading/determinism only, without the fixed-point toggle.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
InStepTime | float | 固定时间步长(秒)。Fixed time step in seconds. |
InSafeStepTime | float | 可变步长上限(秒)。Variable step cap in seconds. |
bInFrameSpreading | bool | 帧分散开关。Frame spreading toggle. |
bInDeterministic | bool | 确定性开关。Determinism toggle. |
Output
无返回值。副作用:改写 4 个配置成员。
No return value. Side effect: overwrites the four config members.
一组只读内联访问器。GetRenderInterpElapsed:自 LastLogicTickWallTime(渲染处理器上次写入 GPU 插值输入的墙钟)以来的秒数,钳制 [0, MaxClamp],驱动 Niagara 预测外推;仅视觉/非确定性,不进模拟哈希。ShouldTickProcessors/GetCalculatedStepTime/GetSimulationTime/GetTickCount:处理器使用的本帧步长与模拟时钟(用 SimulationTime 而非 GetWorld()->GetTimeSeconds() 保证确定性计时)。IsSimulationTick:本引擎帧游戏 tick 是否推进(bIsSimulationTick)——MassEntity 处理器每引擎帧都运行,此标志防止跳过的帧上重复处理同一游戏 tick。IsSubFrameScheduled:查询指定子帧本引擎帧是否调度;非帧分散时等于 bShouldTickProcessors,帧分散时查 ActiveSubFrameMask 位。IsSubFrameActive:兼容查询,与 Scheduled 相同。ShouldDeterministicSort:返回 bDeterministic。GetAgentPhysicsIterations:WIP,恒返回 1。GetGridUpdateProcessor:网络子系统 post-resync 重建用。GetWorldTimeDilation:WorldSettings 有效膨胀,钳制 ≥ 0,用于模拟时长转墙钟(调试绘制等)。
A set of read-only inline accessors. GetRenderInterpElapsed: seconds since LastLogicTickWallTime (when the render processors last wrote GPU interp inputs), clamped to [0, MaxClamp], drives Niagara prediction extrapolation; visual-only/non-deterministic — never enters the sim hash. ShouldTickProcessors/GetCalculatedStepTime/GetSimulationTime/GetTickCount: the per-frame step and sim clock for processors (use SimulationTime instead of GetWorld()->GetTimeSeconds() for deterministic timing). IsSimulationTick: whether the game tick advances this engine frame (bIsSimulationTick) — MassEntity processors run every engine frame; the flag guards against double-processing the same game tick on skipped frames. IsSubFrameScheduled: whether the given sub-frame is scheduled this engine tick; equals bShouldTickProcessors without frame spreading, otherwise checks the ActiveSubFrameMask bit. IsSubFrameActive: compatibility query, same as Scheduled. ShouldDeterministicSort: returns bDeterministic. GetAgentPhysicsIterations: WIP, always returns 1. GetGridUpdateProcessor: used by the network subsystem for post-resync rebuild. GetWorldTimeDilation: effective WorldSettings dilation clamped ≥ 0, for converting dilated sim durations back to wall-clock seconds (debug drawing etc.).
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
MaxClamp(仅 GetRenderInterpElapsed) | float | 外推时间上限(秒),默认 0.3。Extrapolation clamp in seconds, default 0.3. |
Output
返回对应只读值。无副作用。
Returns the corresponding read-only value. No side effects.
确定性验证:SetDeterminismVerifyTicks 配置要验证的 tick 集与要记录的维度(位置/旋转/索敌结果);ExecuteDeterminismVerification(私有,由 ProcessAssetRegistrationQueues 在处理器全部完成后调用)在目标 tick 上查询全部 FAgentTag 实体、按 UID 排序,分别折叠位置/旋转/索敌哈希(索敌含目标 UID 与 FTracing::TimeLeft 冷却)并 Verbose 级输出,供跨端比对。
Determinism verification: SetDeterminismVerifyTicks configures the target ticks and the dimensions to log (location/rotation/trace result); ExecuteDeterminismVerification (private; called from ProcessAssetRegistrationQueues after all processors complete) queries all FAgentTag entities at target ticks, sorts by UID, folds location/rotation/trace hashes (trace includes the target UID and the FTracing::TimeLeft cooldown), and logs them at Verbose level for cross-peer comparison.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
TargetTicks | const TArray<int32>& | 要验证的 tick 列表;空则禁用。Ticks to verify; empty disables. |
bLogLocation / bLogRotation / bLogTraceResult | bool | 各自维度的哈希记录开关。Per-dimension hash logging toggles. |
Output
无返回值。副作用:改写 4 个验证配置成员;目标 tick 上输出哈希日志。
No return value. Side effects: writes the four verification config members; logs hashes on target ticks.
资产注册 Asset Registration
把注册队列中的软引用加载为硬引用并写入注册表(由 ResolvePendingSpawns 在阶段间调用)。弹丸数据资产特殊处理:先排空弹丸队列,再对新加载的每个资产遍历其 OnBirth/OnHit/OnRemoval 级联链(子弹丸/actor 类/Niagara/Cascade/音效),把引用的软引用重新入队;迭代排空直到队列稳定(级联孙辈全覆盖),最后通用排空其余 6 个队列。末尾执行确定性验证。
Loads soft refs from the registration queues into hard refs in the registry (called from ResolvePendingSpawns between stages). Projectile data assets get special handling: the projectile queue is drained first, then each newly-loaded asset's cascade chain (OnBirth/OnHit/OnRemoval: child projectile assets, actor classes, Niagara, Cascade, sounds) is walked and re-enqueued; the loop drains iteratively until the queue settles (grandchildren covered), then the generic drain covers the remaining six queues. Determinism verification runs at the end.
Input
无参数(队列为成员)。
No parameters (queues are members).
Output
无返回值。副作用:加载软资源,填充 7 个已注册映射,可能触发确定性验证日志。
No return value. Side effects: loads soft assets, fills the seven registered maps, may trigger determinism verification logs.
清空全部已注册资源指针(允许 GC)并排空待注册队列(不加载)。另停用并销毁 Host 子系统所有音频组件池(2D/3D)的组件,防止悬挂组件残留在世界中。战斗状态重置或换关时调用。
Clears all registered asset pointers (allowing GC) and drains the pending registration queues without loading. Also stops and destroys every audio component in the Host subsystem's 2D/3D pools so no dangling components stay attached to the world. Call when resetting the battle state or changing levels.
Input
无参数。
No parameters.
Output
无返回值。副作用:清空 7 个注册表与运行时对象注册表、排空 7 个队列、销毁全部音频池组件。
No return value. Side effects: empties the seven registries and the runtime object registry, drains the seven queues, destroys all audio pool components.
5 个资产预注册模板:确保软引用到达注册表一次并成为热循环可用的硬指针(免 LoadSynchronous)。每个 helper:① 在对应 Registered 映射中查找软指针,命中则拷入本地硬指针字段;② 未命中则 LoadSynchronous 并把软指针入队,下一帧 ProcessAssetRegistrationQueues 写入映射。局部 Config(template fragment,非 DataAsset)被修改,数据资产本身永不被触碰。
Five asset pre-registration templates: ensure soft refs reach the registry once and become hard pointers the hot loop can use without LoadSynchronous. Each helper: ① looks the soft ptr up in the matching Registered map and copies it into the local hard-ptr field if found; ② otherwise LoadSynchronouss and enqueues the soft ptr so ProcessAssetRegistrationQueues adds it next frame. The local Config (a template fragment, not the data asset) is mutated; the data asset itself is never touched.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Cfg | TConfig& | 携带 SoftXxx 软引用与 Xxx 硬指针字段的配置结构(如 FFxConfig)。A config struct carrying SoftXxx soft-ref and Xxx hard-ptr fields (e.g. FFxConfig). |
Output
无返回值。副作用:修改 Cfg 的硬指针字段,可能向注册队列入队。
No return value. Side effects: mutates the hard-ptr fields of Cfg; may enqueue into a registration queue.
遍历通用 Spawn 内容结构(FAppear/FHit/FDeath/FProjectileSpawnContent/FLootSpawnContent 等含 SpawnActor + SpawnFx + PlaySound 数组的结构):逐项调用对应 Register* 模板。带 Projectile 的重载额外遍历 SpawnProjectile 数组。模板化使所有变体配置(FFxConfig vs FFxConfig_Attack 等)免重载。
Walks a generic Spawn-content struct (anything with SpawnActor + SpawnFx + PlaySound TArray fields, e.g. FAppear/FHit/FDeath/FProjectileSpawnContent/FLootSpawnContent), calling the matching Register* template per item. The WithProjectile overload additionally walks the SpawnProjectile array. Templated so all variant configs (FFxConfig vs FFxConfig_Attack, etc.) work without overloads.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Content | TContent& | 含 SpawnActor/SpawnFx/PlaySound(及可选 SpawnProjectile)数组的内容结构。Content struct with SpawnActor/SpawnFx/PlaySound (and optionally SpawnProjectile) arrays. |
Output
无返回值。副作用:逐项解析并注册资源(见单个 Register* 模板)。
No return value. Side effects: resolves and registers assets per item (see the individual Register* templates).
把 TSoftObjectPtr 解析为 TObjectPtr 并注册防 GC。软引用为 null 返回 nullptr;注册表命中且类型正确直接返回;条目过期或类型错误则移除重解析;解析成功后写入 RegisteredRuntimeObjectPtrs(键 = FSoftObjectPath,跨类型 TSoftObjectPtr 通用)。解析失败返回 nullptr。
Resolves a TSoftObjectPtr to a TObjectPtr and registers it to prevent GC. Null soft ptrs return nullptr; a registry hit with the correct type returns the cached value; stale or wrong-typed entries are removed and re-resolved; successful resolutions are stored in RegisteredRuntimeObjectPtrs (keyed by FSoftObjectPath, generic across TSoftObjectPtr specializations). Failed loads return nullptr.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
SoftPtr | const TSoftObjectPtr<T>& | 要解析的软引用。Soft reference to resolve. |
Output
返回解析后的硬指针;null/失败返回 nullptr。副作用:写注册表。
Returns the resolved hard pointer; nullptr on null/failure. Side effect: writes the registry.
快照恢复路径:注册已解析的 UObject 防 GC。幂等(TMap::Add 同键覆盖)。不做 LoadSynchronous——调用方须已通过 FSoftObjectPath::ResolveObject() 解析路径。参数任一无效即返回。
Snapshot-restore path: registers an already-resolved UObject to prevent GC. Idempotent (TMap::Add overwrites the same key). Does NOT LoadSynchronous — the caller must have resolved the path via FSoftObjectPath::ResolveObject(). Returns when either parameter is invalid.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Path | const FSoftObjectPath& | 对象路径(注册键)。Object path (registry key). |
Resolved | UObject* | 已解析对象。Resolved object. |
Output
无返回值。副作用:写运行时对象注册表。
No return value. Side effect: writes the runtime object registry.
为单个实体解析运行时对象指针(快照恢复后 raw 指针为 null 的补救)。覆盖五对:① FNavigation → FNavigating(FlowField 软→硬,解析失败时保持 _Previous 过期,让 MoveProcessor 每帧懒加载重试);② FAgentEvent → FAgentEventRT(事件接收者;软引用为 null 时保留组件赋值的默认接收者——置空会冲掉 InitializeWithEntity 的赋值,客户端事件永不派发);③ FLootEvent → FLootEventRT;④ FProjectileEvent → FProjectileEventRT;⑤ FLootParamsRT/FLootConfig_Final 的 FlowField 软→硬。由 AgentComponent、AgentSubsystem、NetworkSubsystem 在恢复路径调用。
Resolves runtime object pointers for a single entity (remedy after snapshot restore leaves raw ptrs null). Covers five pairs: ① FNavigation → FNavigating (FlowField soft→hard; on failed resolve _Previous stays stale so the MoveProcessor's per-frame lazy load retries until the asset is ready); ② FAgentEvent → FAgentEventRT (event receiver; a null soft ref keeps the component-assigned default receiver — nulling it would clobber InitializeWithEntity's assignment and events would never dispatch on the client); ③ FLootEvent → FLootEventRT; ④ FProjectileEvent → FProjectileEventRT; ⑤ the FlowField soft→hard of FLootParamsRT/FLootConfig_Final. Called from AgentComponent, AgentSubsystem and NetworkSubsystem on the restore path.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Entity | FMassEntityHandle | 目标实体。Target entity. |
Output
无返回值。副作用:解析并写实体 runtime fragment 的 raw 指针,注册防 GC。
No return value. Side effects: resolves and writes the entity's runtime fragment raw pointers, registering against GC.
从 template 自带 soft ptr 初始化 template runtime 指针缓存(FNavigation → FNavigating、FAgentEvent → FAgentEventRT 两对)。template 为空直接返回。
Initializes template runtime pointer caches from template-owned soft ptrs (the FNavigation → FNavigating and FAgentEvent → FAgentEventRT pairs). Returns immediately for empty templates.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
TemplateData | FMassEntityTemplateData& | 要初始化的实体模板。Entity template to initialize. |
Output
无返回值。副作用:修改模板 runtime fragment 指针并注册防 GC。
No return value. Side effects: mutates the template's runtime fragment pointers and registers against GC.
帧末队列消费 End-of-Frame Queue Drain
销毁队列排空:EntitiesToDestroyQueue.Merge() 后,bDeterministic 时按 UID 排序(本地实体 UID=-1 用 MIN_INT 排前;禁止 Entity.Index fallback——resync 重建后双端句柄序不同,排序必须只用 UID,否则销毁序分叉),然后逐条 MA.Defer().DestroyEntity,最后 Reset。由 Tick 的 Subtick3 段每逻辑帧调用。
Destruction queue drain: after EntitiesToDestroyQueue.Merge(), sorts by UID when bDeterministic (local-only entities with UID=-1 sort first via MIN_INT; NO Entity.Index fallback — handle order diverges between peers after resync rebuild, so the sort must use UIDs only, or the destroy order diverges), then MA.Defer().DestroyEntity per entry and Reset. Called once per logic frame from the Tick Subtick3 block.
Input
无参数(请求来自成员 gatherer)。
No parameters (requests come from the member gatherer).
Output
无返回值。副作用:向命令缓冲写入全部销毁命令并清空队列。
No return value. Side effects: writes destroy commands into the command buffer and resets the queue.
BP 事件队列排空(每逻辑帧一次,确定性批处理)。流程:① Merge 全部 18 个事件 gatherer;② bDeterministic 时各队列按 UniqueID 排序;③ 逐事件经实体的事件 fragment 对(FAgentEvent/FAgentEventRT 等)解析接收者 Actor(软引用变更时经 ResolveAndRegisterRuntimeObjectPtr 重解析),接收者实现对应接口(UMassBattleAgentInterface / UMassBattleProjectileInterface / UMassBattleLootInterface)才派发 Execute_OnXxx。实体无效或接收者无效则跳过;最后逐队列 Reset。
BP event queue drain (once per logic frame for deterministic batching). Flow: ① merges all 18 event gatherers; ② sorts each queue by UniqueID when bDeterministic; ③ per event, resolves the receiver actor through the entity's event fragment pair (FAgentEvent/FAgentEventRT etc.; a changed soft ref triggers re-resolution via ResolveAndRegisterRuntimeObjectPtr) and dispatches Execute_OnXxx only when the receiver implements the matching interface (UMassBattleAgentInterface / UMassBattleProjectileInterface / UMassBattleLootInterface). Invalid entities or receivers are skipped; each queue is reset afterwards.
Input
无参数(事件来自成员 gatherer)。
No parameters (events come from the member gatherers).
Output
无返回值。副作用:向接口接收者派发 BP 事件,清空全部事件队列。
No return value. Side effects: dispatches BP events to interface receivers, clears all event queues.
调试绘制队列排空(每逻辑帧一次)。Merge 后:① 时长按世界膨胀逆系数换算(DrawDebug* 需要真实秒数,处理器入队的是模拟时长);② 每队列先按实体 FDeterminism.UniqueID 无条件排序(保证 MaxCount 裁剪的稳定确定性,世界空间项 MAX_int32 排最后);③ MaxCount 过滤——按 UID 排名,入选实体绘制完整调试集,排名超出整组剔除(入选实体不闪烁);④ 逐项调用对应 DrawDebug* API(编辑器门控 ENABLE_DRAW_DEBUG)。LineBatcher 镜像队列(Duration > 0 走 WorldPersistent 批处理器,否则走每帧批处理器)不经过滤/排序,Shipping 可见,用于编队可视化等常驻绘制。
Debug draw queue drain (once per logic frame). After merging: ① durations are converted by the inverse world dilation (DrawDebug* wants real seconds; processors enqueue sim-time durations); ② each queue is sorted unconditionally by entity FDeterminism.UniqueID (stable, deterministic MaxCount culling; world-space items get MAX_int32 and sort last); ③ MaxCount culling — entities ranked by UID draw their FULL debug set, entities beyond their MaxCount are culled entirely (selected entities never flicker mid-set); ④ items are drawn via the matching DrawDebug* API (gated by ENABLE_DRAW_DEBUG in the editor). The LineBatcher mirror queues (Duration > 0 routes to the WorldPersistent batcher, otherwise the per-frame batcher) bypass filtering/sorting — Shipping-visible, used for formation visualization and other always-on rendering.
Input
无参数(绘制项来自成员 gatherer)。
No parameters (draw items come from the member gatherers).
Output
无返回值。副作用:在世界中绘制调试图元,清空全部调试队列。
No return value. Side effects: draws debug primitives into the world, clears all debug queues.
绘制三维扇形(顶面/底面弧 + 半径线 + 侧棱)。参数非法(World 空 / 角度 ≤ 0 / 半径 ≤ 0 / 高度 ≤ 0)直接返回;角度钳制 [1°, 360°];方向近零时回退前向。360° 时跳过半径与侧棱(完整圆柱扇形)。
Draws a 3D sector (top/bottom arcs + radius lines + side edges). Returns immediately on invalid parameters (null World / angle ≤ 0 / radius ≤ 0 / height ≤ 0); angle clamps to [1°, 360°]; a near-zero direction falls back to the forward vector. At 360° the radius lines and side edges are skipped (full cylinder sector).
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
World | UWorld* | 绘制目标世界。World to draw into. |
Center / Direction / Radius / AngleDegrees / Height | FVector / FVector / float / float / float | 扇形中心、朝向、半径、张角(度)、高度。Sector center, facing direction, radius, angle (degrees), height. |
Color / bPersistentLines / LifeTime / DepthPriority / Thickness | FColor / bool / float / uint8 / float | 绘制参数:颜色、常驻线、存活时长、深度优先级、线宽。Draw params: color, persistent lines, lifetime, depth priority, thickness. |
Output
无返回值。副作用:向世界绘制多条调试线段。
No return value. Side effect: draws multiple debug line segments into the world.
伤害与 Debuff Damage & Debuff
点伤害 + debuff 应用。流程:① 用 TSet 去重目标并跳过 IgnoreEntities 与无效实体;② 逐个经 MA.MatchQuery(Overlapper, Damage.Query) 查询匹配过滤;③ bDeterministic 时按 UID 预提取键排序(SortByPreExtractedKeys,本地实体 MIN_INT 排前,无 Entity.Index fallback);④ 逐目标计算击退方向(目标位置 − HitFromLocation 的 2D 归一化),调用共享逻辑 ProcessSingleEntityDamageAndDebuff——内部处理抗性乘数(按 FDefence)、暴击(确定性种子 = TargetUID ^ CauserUID<<8 ^ InstigatorID<<16,每目标自掷骰子)、钳制伤害到剩余生命、致命判定,并向 DmgGatherer/LaunchGatherer/debuff gatherer 收集结果。默认重载经 MA.Defer() 取共享命令缓冲;Context 重载经 Context.Defer()。
Point damage + debuff application. Flow: ① dedupes targets via a TSet and skips IgnoreEntities and invalid entities; ② filters each through MA.MatchQuery(Overlapper, Damage.Query); ③ when bDeterministic, sorts by pre-extracted UID keys (SortByPreExtractedKeys; local entities first via MIN_INT; no Entity.Index fallback); ④ per target computes the knockback direction (2D-normalized target − HitFromLocation) and calls the shared ProcessSingleEntityDamageAndDebuff — which applies resistance multipliers (from FDefence), crit (deterministic seed = TargetUID ^ CauserUID<<8 ^ InstigatorID<<16; each target rolls its own dice), clamps damage to remaining health, detects kills, and gathers into DmgGatherer/LaunchGatherer/debuff gatherers. The default overload uses the shared command buffer via MA.Defer(); the Context overload uses Context.Defer().
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
CommandBuffer(仅重载 2) | FMassCommandBuffer& | 延迟命令缓冲。Deferred command buffer. |
Context(仅重载 3) | FMassExecutionContext& | 执行上下文,经 Context.Defer() 取命令缓冲。Execution context; command buffer via Context.Defer(). |
Entities | const FEntityArray& | 候选目标实体数组。Candidate target entities. |
IgnoreEntities | const FEntityArray& | 豁免实体(转换 TSet 用于 O(1) 判定)。Exempt entities (converted to a TSet for O(1) checks). |
DmgInstigator | const FEntityHandle | 施害者(伤害归属)。Instigator (damage attribution). |
DmgCauser | const FEntityHandle | 造成伤害的实体(causer)。Entity that caused the damage. |
HitFromLocation | const FVector& | 打击来源位置,决定击退方向。Hit origin location; decides the knockback direction. |
Damage | const FDamage_Point& | 伤害配置(含 DmgType/Query 过滤/暴击参数)。Damage config (DmgType/Query filter/crit params). |
Debuff | const FDebuff_Point& | debuff 配置(持续伤害/击退/减速)。Debuff config (temporal damage/launch/slow). |
DamageResults | TArray<FDmgResult>& | 输出伤害结果数组(追加)。Output damage results (appended). |
Output
无返回值。副作用:向 DmgGatherer 收集伤害结果、向 LaunchGatherer 收集击退、向 DebuffSubsystem 两个 gatherer 收集 debuff 生成请求、改写目标 FBeingHit/flag(发光/挤压/受击动画)、填充 DamageResults。
No return value. Side effects: gathers damage results into DmgGatherer, knockbacks into LaunchGatherer, debuff spawn requests into the DebuffSubsystem gatherers, mutates target FBeingHit/flags (glow/jiggle/hit anim), and fills DamageResults.
径向(球形)伤害 + debuff。经 HashGridSub->SphereTraceForAgents 在网格中查找半径 Damage.DmgRadius 内的目标(KeepCount 限制返回数,-1 = 不限制),命中空则返回。确定性排序后逐目标计算衰减——距离测到碰撞体表面(中心距 − 碰撞半径 × 缩放),在 [0, DmgRadius] 上 1→0 钳制映射,Damage.bUseFalloff/Debuff.bUseFalloff 分别启用伤害/击退衰减;其余共享逻辑同点伤害。
Radial (sphere) damage + debuff. Queries targets within Damage.DmgRadius via HashGridSub->SphereTraceForAgents (KeepCount limits the results; -1 = unlimited), returning when nothing is hit. After the deterministic sort, per-target falloff is computed — distance measured to the collider surface (center distance − collider radius × scale), clamped-mapped 1→0 over [0, DmgRadius]; Damage.bUseFalloff/Debuff.bUseFalloff enable damage/knockback falloff independently. The remaining shared logic matches point damage.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
KeepCount | int32 | 保留的命中目标数;-1 = 不限制。Max hit targets kept; -1 = unlimited. |
Origin | const FVector& | 爆炸中心(也是衰减距离基准)。Explosion origin (also the falloff distance base). |
HitFromLocation | const FVector& | 击退方向来源(通常与 Origin 相同)。Knockback direction origin (usually the same as Origin). |
| 其余参数 | 同点伤害 | 与 ApplyPointDamageAndDebuff 相同(Entities 换为网格查询结果,IgnoreEntities/Query 透传给网格 trace)。Same as ApplyPointDamageAndDebuff (Entities replaced by grid-query results; IgnoreEntities/Query forwarded to the grid trace). |
Output
无返回值。副作用:同点伤害(收集 gatherer、改写受击状态、填充 DamageResults)。
No return value. Side effects: same as point damage (gatherer collects, hit-state mutation, DamageResults fill).
光束(扫掠)伤害 + debuff。经 HashGridSub->SphereSweepForAgents 在 StartLocation → EndLocation 间以 Damage.DmgRadius 半径扫掠查目标(KeepCount 限制)。衰减距离用点到直线距离(FMath::PointDistToLine,目标到光束轴的距离)减去碰撞体表面,再钳制映射 1→0。
Beam (sweep) damage + debuff. Queries targets via HashGridSub->SphereSweepForAgents sweeping radius Damage.DmgRadius along StartLocation → EndLocation (KeepCount limits results). The falloff distance uses the point-to-line distance (FMath::PointDistToLine, target to the beam axis) minus the collider surface, then clamp-mapped 1→0.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
KeepCount | int32 | 保留的命中目标数;-1 = 不限制。Max hit targets kept; -1 = unlimited. |
StartLocation / EndLocation | const FVector& | 光束扫掠的起点/终点。Beam sweep start/end. |
| 其余参数 | 同点伤害 | 与点伤害相同。Same as point damage. |
Output
无返回值。副作用:同点伤害。
No return value. Side effects: same as point damage.
暴击判定:Stream.FRand() < Probability 则伤害乘 damageMult 并标记暴击,否则原值返回。随机流由调用方按确定性种子构造。
Crit roll: when Stream.FRand() < Probability the damage is multiplied by damageMult and flagged as critical, otherwise returned unchanged. The stream is seeded deterministically by the caller.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
BaseDamage | float | 基础伤害(已含抗性与衰减)。Base damage (after resistance and falloff). |
damageMult | float | 暴击伤害倍率。Crit damage multiplier. |
Probability | float | 暴击概率 [0,1]。Crit probability [0,1]. |
Stream | FRandomStream& | 随机流。Random stream. |
Output
返回 (是否暴击, 实际伤害)。无副作用。
Returns (is critical, actual damage). No side effects.
把飘字配置写入所有者实体的 FTextPop fragment(加锁追加)。所有者缩放乘到 Scale 中。实体无 FTextPop 时静默跳过。由 MassBattleAgentReactionProcessor 在受击处理时调用。
Appends a text-pop config to the owner entity's FTextPop fragment (locked append). The owner's scale multiplies into Scale. Silently skipped when the entity lacks FTextPop. Called by MassBattleAgentReactionProcessor during hit handling.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Config | FTextPopConfig | 飘字配置(所有者/位置/数值/样式/缩放/半径)。Text-pop config (owner/location/value/style/scale/radius). |
Output
无返回值。副作用:追加 FTextPop 数组。
No return value. Side effect: appends to the FTextPop arrays.
杂项 Misc
滑动窗口平均 FPS:把本帧增量追加进缓冲,累积超窗口时长时从头移除旧帧(至少保留 1 帧),返回 帧数 / 总时长。缓冲由调用方持有。
Sliding-window average FPS: appends the frame delta to the buffer, removes oldest frames from the head while the total exceeds the window (keeping at least one), and returns frames / total time. The buffer is owned by the caller.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
DeltaTimeBuffer | TArray<float>& (ref) | 逐帧增量缓冲(会被修改)。Per-frame delta buffer (will be modified). |
DeltaTime | float | 本帧增量(秒)。Current frame delta in seconds. |
Duration | float | 平均窗口(秒),如 1.0 表示最近 1 秒。Average window in seconds (e.g. 1.0 for the last second). |
Output
返回窗口内平均 FPS;总时长非正返回 0。副作用:修改 DeltaTimeBuffer。
Returns the average FPS over the window; 0 when the total time is non-positive. Side effect: mutates DeltaTimeBuffer.
本地偏移变换转世界:世界旋转旋转本地位置得世界偏移,叠加世界位置;世界旋转乘本地旋转得最终旋转;缩放沿用本地。
Converts a local offset transform to world: the world rotation rotates the local location into a world offset added to the world location; the final rotation is world × local; scale is carried from the local transform.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
WorldRotation | FQuat | 世界朝向。World orientation. |
WorldLocation | FVector | 世界位置。World location. |
LocalTransform | FTransform | 本地偏移变换。Local offset transform. |
Output
返回合成后的世界变换。无副作用。
Returns the composed world transform. No side effects.
编辑器专用诊断(整函数 WITH_EDITOR 门控):输出宿主/实体/音频组件池的当前大小与本 tick 分配明细(总生成数、其中来自池、其中全新构建),9 个 bool 各控制一个池。计数器在 UMassBattleHostSubsystem::ExecuteTick 重置——从 BP 在 tick 之后调用即可看到本 tick 活动。全部经 HostSub->GetPoolCount/GetTotal*PoolSize 与 HostPoolTickStats 等统计成员读取。
Editor-only diagnostic (the whole body is WITH_EDITOR-gated): logs current size and this-tick allocation breakdown for the host/entity/audio component pools (total spawns, of which from pool, of which freshly built); nine bools each toggle one pool. Counters reset every UMassBattleHostSubsystem::ExecuteTick — call from BP after the tick to see this tick's activity. Reads via HostSub->GetPoolCount/GetTotal*PoolSize and the HostPoolTickStats stat members.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
bActorHostPool ... bAudioComponentPool | bool × 9 | 9 个池开关(Actor/Fx/Sound/Projectile/Agent/Loot 宿主池、弹丸/战利品实体池、音频组件池),默认全 true。Nine pool toggles (Actor/Fx/Sound/Projectile/Agent/Loot host pools, projectile/loot entity pools, audio component pool), all true by default. |
Output
无返回值。副作用:向 LogTemp 输出池统计块(Verbose 级)。
No return value. Side effect: logs a pool-stats block to LogTemp (Verbose level).
成员变量 Members
全局 UID 空间 Global UID Space
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
EntityUIDAllocator | FEntityUIDAllocator | 空位图 | 通用实体 UID 槽位分配器(2^24 槽位图 + 循环利用);占用计数折叠进每 tick 哈希,恢复端经 ReconcileUIDAllocator 收敛。取代退役的 NextGlobalUID 计数器。General-entity UID slot allocator (2^24-slot bitmap with recycling); the occupied count is folded into the per-tick hash and the restore side converges it via ReconcileUIDAllocator. Replaces the retired NextGlobalUID counter. |
GlobalUIDToHandle | TMap<int32, FEntityHandle> | 空 | UID → 句柄映射(全局,替代各子系统独立 TMap)。UID → handle map (global, replacing per-subsystem TMaps). |
GlobalHandleToUID | TMap<FEntityHandle, int32> | 空 | 句柄 → UID 映射。Handle → UID map. |
模拟时间与步长 Sim Time & Stepping
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
StepTime | float | 0 | 固定时间步长(秒);> 0 时启用固定步长,0 = 可变步长。Fixed time step in seconds; > 0 enables fixed stepping, 0 = variable step. |
SafeStepTime | float | 0.3333f | 可变步长下的帧时间上限(秒)。Frame-time cap for variable stepping (seconds). |
AccumulatedTime | double | 0.0 | 固定步长时间累积器(Transient)。Fixed-step time accumulator (Transient). |
CalculatedStepTime | float | 0.0f | 本帧处理器应使用的步长(可变步长 = min(DeltaTime, SafeStepTime × 膨胀) 或固定 StepTime)。The delta processors should use this frame (variable = min(DeltaTime, SafeStepTime × dilation), or the fixed StepTime). |
SimulationTime | double | 0.0 | 确定性模拟时钟(每 tick 加 CalculatedStepTime;网络锁步下每 tick 重算为 TickCount × StepTime)。替代 GetWorld()->GetTimeSeconds()。Deterministic sim clock (adds CalculatedStepTime each tick; rebased to TickCount × StepTime per tick under network lockstep). Replaces GetWorld()->GetTimeSeconds(). |
TickCount | int32 | 0 | 模拟 tick 计数(每逻辑帧 +1,Subtick0 先于任何模拟处理器)。Simulation tick counter (+1 per logic frame, at Subtick0 before any sim processor). |
bShouldTickProcessors | bool | false | 本帧处理器是否应执行(时间步进决策产物;帧分散下 = ActiveSubFrameMask 非零)。Whether processors should execute this frame (from the stepping decision; with frame spreading = ActiveSubFrameMask non-zero). |
bTimeSteppingInitialized | bool | false | 时间步进是否已初始化(处理首帧)。Whether time stepping is initialized (first-frame handling). |
bDeterministic | bool | false | 确定性开关:聚合事件按 UID 排序(或确定性随机化)后处理,使模拟可复现。Determinism toggle: gathered events are sorted by UID (or deterministically randomized) before processing for replayability. |
bUseFixPointMath | bool | false | 定点数学开关:true 用 MoveProcessorFP,false 用浮点 MoveProcessor。与 bDeterministic 正交(前者控制排序/RNG,后者控制运算精度)。Fixed-point toggle: true runs MoveProcessorFP, false runs the float MoveProcessor. Orthogonal to bDeterministic (sort/RNG vs arithmetic precision). |
bLogDeterminismDebug | bool | false | 调试:每帧记录确定性相关哈希(需 bDeterministic)。Debug: log determinism-related hashes each frame (requires bDeterministic). |
bIsSimulationTick | bool | false | 本引擎帧游戏 tick 是否推进;渲染处理器据此区分模拟帧(吸附)与仅渲染帧(插值)。Whether the game tick advances this engine frame; render processors use it to distinguish sim frames (snap) from render-only frames (interpolate). |
帧分散与调步 Frame Spreading & Pacing
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
bFrameSpreading | bool | false | 帧分散开关:true 时一个逻辑帧固定分 COUNT 个引擎帧执行,高负载不追帧不合并;渲染插值每帧执行保平滑。Frame-spreading toggle: one logic frame always spans COUNT engine ticks — no catch-up, no merge under load; render interpolation runs every tick. |
bFrameSpreadingSaved | bool | false | 追帧前保存的 bFrameSpreading,追帧后恢复。bFrameSpreading saved before fast-forward and restored after. |
bFrameSpreadPacing | bool | true | 帧调步开关:仅渲染帧睡眠匹配逻辑帧时长,稳定帧率。Pacing toggle: render-only frames sleep to match the logic-frame duration for a stable framerate. |
MovePartitionDivisor | int32 | 10 | move 动态分区模数(UID % Divisor 分桶)。Move partition modulus (UID % Divisor buckets). |
MovePartitionThreshold | int32 | 3 | 分区阈值:UID % Divisor < Threshold → Subtick1,否则 Subtick2;边界 [1, Divisor-1],均衡器每逻辑帧 ±1 调整。Partition threshold: UID % Divisor < Threshold → Subtick1, else Subtick2; bounds [1, Divisor-1]; the rebalancer shifts it ±1 per logic frame. |
bDynamicMoveBalance | bool | true | move 分区均衡器开关。Move partition rebalancer toggle. |
MoveBalanceThreshold | float | 0.001f | 触发阈值移动的最小子帧开销差(秒),抑制帧间噪声振荡。Minimum subtick cost gap (seconds) to shift the threshold; anti-oscillation guard. |
SubFrameSimDurations | float[4] | {} | 整子帧 SimStages 墙钟 EMA(按子帧)。Whole-subtick SimStages wall-clock EMA (per sub-frame). |
CurrentSubFrame | int32 | -1 | 当前子帧(-1 = 无逻辑帧进行,0-3 = 当前子帧)。Current sub-frame (-1 = no logic frame active, 0-3 = current). |
ActiveSubFrameMask | uint8 | 0 | 位掩码:本引擎帧执行哪些子帧。Bitmask of sub-frames executing THIS engine tick. |
FrameSpreadAccumulatedTime | double | 0.0 | 帧分散时间累积器。Frame-spread time accumulator. |
bFrameSpreadingPrev | bool | false | bFrameSpreading 前值,用于运行时切换检测。Previous bFrameSpreading value for runtime toggle detection. |
FrameStartWallTime | double | 0.0 | Tick 起始墙钟(FPlatformTime::Seconds()),供调步计时。Wall clock at Tick start, for pacing timing. |
SubFrameWallDurations | float[4] | {} | 各子帧引擎帧墙钟时长。Wall duration of each sub-frame engine tick. |
LastSubFrameIndex | int32 | -1 | 本引擎帧执行的子帧(-1 = 仅渲染帧)。Which sub-frame THIS tick executed (-1 = render-only). |
bHasCompletedLogicFrame | bool | false | 首个完整逻辑帧完成后置 true。True after the first full logic frame completes. |
LastLogicFrameDuration / RendersSinceLogicFrame / ExpectedRendersPerLogic | float / int32 / float | 0 / 0 / 0 | 非帧分散固定步长调步状态:上个逻辑帧墙钟、累计渲染帧数、EMA 渲染/逻辑帧比。Non-frame-spread fixed-step pacing state: last logic-frame wall time, render frames observed, EMA renders-per-logic estimate. |
bSkipNextEndFrameUpdate | bool | false | 首帧保护:Tick 已同步跑过 UpdateTimeStepping,防帧末双推进。First-frame guard: Tick already ran UpdateTimeStepping; prevents double-advance at frame end. |
LastLogicTickWallTime | double | 0.0 | 渲染处理器上次写入 GPU 插值输入的墙钟;渲染器经 GetRenderInterpElapsed 驱动 Niagara 外推。仅视觉,不入哈希。Wall clock when the render processors last wrote GPU interp inputs; renderers drive Niagara extrapolation via GetRenderInterpElapsed. Visual-only, never in the hash. |
SubFrameGateTick / ConsumedSubFrameGates | int32 / TSet<uint64> | INDEX_NONE / 空 | 子帧门控状态(见 TryBeginSubFrame)。Sub-frame gate state (see TryBeginSubFrame). |
DeterminismVerifyTargetTicks / bDeterminismVerifyLocation / bDeterminismVerifyRotation / bDeterminismVerifyTrace | TArray<int32> / bool × 3 | 空 / false × 3 | 确定性验证配置(目标 tick 集 + 各维度开关)。Determinism verification config (target ticks + per-dimension toggles). |
暂停与网络 Pause & Network
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
bGamePaused | bool (private) | false | 游戏暂停总闸,仅经 PauseGame()/ResumeGame() 修改。Master pause gate; mutated only via PauseGame()/ResumeGame(). |
bNetworkedMode | bool | false | 网络桥接开关,由 GameMode 设置。Network bridge toggle, set by the GameMode. |
MassBattleTick | FMassBattleTick (BlueprintAssignable) | — | 每逻辑帧 TickCount 推进时广播的委托(float DeltaTime, int32 TickCount),Subtick0 网格重建后触发。Delegate broadcast on TickCount progression each logic frame (float DeltaTime, int32 TickCount), fired after the Subtick0 grid rebuild. |
实体计数(BlueprintReadOnly) Entity Counters
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
AgentCount / AppearingAgentCount / SleepingAgentCount / PatrollingAgentCount / AttackingAgentCount / HitAgentCount / DyingAgentCount / ProjectileCount | int32 × 8 | 0 | 各类实体的统计计数(由处理器/子系统更新),蓝图只读。Per-category entity counts (updated by processors/subsystems), Blueprint-read-only. |
渲染器注册表 Renderer Registry
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
AgentRenderers | TMap<int32, TObjectPtr<AMassBattleAgentRenderer>> | 空 | 已注册的 Agent 渲染器(键 = SubType 索引)。Registered agent renderers (key = SubType index). |
FxRenderers | TMap<int32, TObjectPtr<AMassBattleFxRenderer>> | 空 | 已注册的 Fx 渲染器。Registered FX renderers. |
并行收集器与事件队列(公开) Parallel Gatherers & Event Queues
| 名称 Name | 类型 Type | 说明 Description |
|---|---|---|
EntitiesToDestroyQueue | FParallelGatherer<FDestructionData> | 待销毁实体队列,ProcessDestoyQueues 排空。Entities pending destruction; drained by ProcessDestoyQueues. |
OnAppearQueue / OnTraceQueue / OnMoveQueue / OnAttackQueue / OnHitQueue / OnDeathQueue / OnPoolQueue / OnStatisticsChangeQueue / OnAnimStateChangeQueue / OnSleepQueue / OnPatrolQueue / OnChaseQueue / OnReinforceQueue | FParallelGatherer<对应事件数据> | 13 个 Agent 状态事件队列(处理器并行段收集,ProcessEventQueues 串行派发到接口接收者)。13 agent state-event queues (gathered in parallel by processors; ProcessEventQueues dispatches serially to interface receivers). |
ReinforceReportGatherer | FParallelGatherer<FReinforceReport> | 支援上报收集器(追击 agent → 指挥中心)。Reinforce report gatherer (chasing agents → command center). |
OnProjectileSpawnQueue / OnProjectileHitQueue / OnProjectileDeathQueue | FParallelGatherer<对应事件数据> | 弹丸事件队列(命中事件经 CauserEntity 取实体)。Projectile event queues (hit uses CauserEntity). |
OnLootSpawnQueue / OnLootCollectQueue / OnLootDestroyQueue | FParallelGatherer<对应事件数据> | 战利品事件队列(收集事件经 LootEntity 取实体)。Loot event queues (collect uses LootEntity). |
DmgGatherer | FParallelGatherer<FDmgResult> | 伤害结果收集器(Reaction 处理器消费:受击/死亡特效等)。Damage result gatherer (consumed by the Reaction processor: hit/death FX etc.). |
LaunchGatherer | FParallelGatherer<FLaunchResult> | 击退收集器(Move 处理器消费,同逻辑 tick 内施加)。Knockback gatherer (consumed by the Move processor within the same logic tick). |
StatsGatherer | FParallelGatherer<FStatsResult> | 统计结果收集器。Statistics result gatherer. |
LootClaimGatherer | FParallelGatherer<FLootClaimRequest> | 战利品认领请求(Reaction 并行段收集;排序后串行仲裁,每战利品最小 CollectorUID 获胜,取代循环内竞争写)。Loot claim requests (gathered from Reaction's parallel section; arbitrated serially with a deterministic sort — min CollectorUID per loot wins, replacing the racy in-loop Collector write). |
PressureGatherer | FParallelGatherer<FPressureDeposit> | 压力场沉积(MoveProcessor GridReg 并行收集,确定性排序后串行 flush)。Pressure-field deposits (gathered in parallel from MoveProcessor GridReg; flushed serially with a deterministic sort). |
CommanderSnapshots | TArray<FCommanderSnapshot> | 指挥中心共享目标快照(Reinforce 串行填充,Behavior 并行只读)。Commander shared-target snapshots (populated serially by Reinforce, read-only in Behavior parallel sections). |
调试绘制队列 Debug Draw Queues
| 名称 Name | 类型 Type | 说明 Description |
|---|---|---|
DebugPointQueue / DebugLineQueue / DebugSphereQueue / DebugCapsuleQueue / DebugSectorQueue / DebugCircleQueue / DebugBoxQueue / DebugConeQueue / DebugArrowQueue / DebugStringQueue | FParallelGatherer<对应配置> | 9 类 DrawDebug 图元队列(字符串为编辑器专属)。Nine DrawDebug primitive queues (strings are editor-only). |
LineBatchLineQueue / LineBatchCircleQueue / LineBatchSphereQueue / LineBatchArrowQueue | FParallelGatherer<对应配置> | LineBatcher 镜像队列——经 ULineBatchComponent 绘制,Shipping 可见(编队可视化等常驻绘制)。LineBatcher mirror queues — drawn via ULineBatchComponent, Shipping-visible (formation visualization etc.). |
CachedDebugCameraLocation / CachedDebugCameraRotation / bHasCachedDebugCameraLocation | FVector / FRotator / bool | 每 tick 缓存的相机位姿(入队时调试绘制距离过滤;标签偏移经相机轴向投影)。Per-tick cached camera pose (enqueue-time draw distance filter; label offsets project through camera axes). |
资产注册 Asset Registration
| 名称 Name | 类型 Type | 说明 Description |
|---|---|---|
RegisteringAgentConfigDataAssetSoftPtrs / RegisteringProjectileDataAssetSoftPtrs / RegisteringLootConfigDataAssetSoftPtrs / RegisteringActorClassSoftPtrs / RegisteringNiagaraSystemSoftPtrs / RegisteringParticleSystemSoftPtrs / RegisteringSoundSoftPtrs | TQueue<TSoft…, EQueueMode::Mpsc> × 7 | 7 个软引用注册队列(多生产者入队,ProcessAssetRegistrationQueues 游戏线程排空)。Seven soft-ref registration queues (multi-producer enqueue; drained on the game thread by ProcessAssetRegistrationQueues). |
RegisteredAgentConfigDataAssetPtrs … RegisteredSoundPtrs | TMap<软引用, 硬引用> × 7 (UPROPERTY) | 7 个已注册硬引用映射(防止 GC,热循环免 LoadSynchronous)。Seven registered hard-ref maps (GC protection; no LoadSynchronous in the hot loop). |
RegisteredRuntimeObjectPtrs | TMap<FSoftObjectPath, TObjectPtr<UObject>> (UPROPERTY) | 运行时解析的软→硬指针注册表,防止 agent runtime fragment 引用的对象被 GC;以 FSoftObjectPath 为键跨类型通用。Runtime soft→hard ptr registry preventing GC of objects referenced by agent runtime fragments; keyed by FSoftObjectPath for cross-type genericity. |
处理器持有与派发(私有) Processor Ownership (private)
| 名称 Name | 类型 Type | 说明 Description |
|---|---|---|
OwnedProcessors | TArray<UMassProcessor*> (UPROPERTY) | 13 个处理器实例的唯一 GC 根(仅靠 Outer 不够——UE GC 不自动标记子对象)。The SINGLE GC root for all 13 processor instances (Outer alone is not enough — UE GC does not auto-mark children). |
SimStages | TArray<TArray<UMassProcessor*>> | 6 阶段模拟链(裸指针视图):[0]Trace+Behavior [1]Projectile [2]Debuff+Reaction [3]Loot [4]Move/MoveFP [5]Host。Six-stage sim chain (raw view): [0]Trace+Behavior [1]Projectile [2]Debuff+Reaction [3]Loot [4]Move/MoveFP [5]Host. |
RenderProcessors | TArray<UMassProcessor*> | 渲染组(FxRender/AgentRender),帧末排空后运行。Render group (FxRender/AgentRender), run after the end-of-frame drain. |
HostMonoProcessor / MoveProcessor / MoveProcessorFP / GridUpdateProcessor / NetworkProcessor | TObjectPtr<…> (UPROPERTY) | 类型化引用:每帧 TickCpuInterp、快照应用后立即网格注册、帧起始网格重建、post-sim 派发。Typed refs: per-frame TickCpuInterp, immediate grid registration after snapshot apply, start-of-frame grid rebuild, post-sim dispatch. |
BP 异步任务注册表(私有) BP Async Task Registry (private)
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
ActiveMoveToTasks / ActiveChaseAttackTasks | TArray<TWeakObjectPtr<…>> | 空 | 已注册的 BP 异步任务(弱引用,访问时惰性清理)。Registered BP async tasks (weak refs, pruned lazily on access). |
TaskTemplateCache | TMap<FName, TObjectPtr<UMassBattleBPTaskTemplateBase>> (UPROPERTY) | 空 | 任务模板实例缓存(键 = BP 类路径,强引用,每模板类一个实例,生命周期 = 本子系统,隔离 PIE 多窗口)。Task template instance cache (key = BP class path; strong refs, one per template class; lifetime = this subsystem, isolated per PIE window). |
SortedTemplateKeys | TArray<FName> (mutable) | 空 | TaskTemplateCache 键的插入排序缓存(折叠/采集路径每 tick 迭代;模板终身注册不删除)。Insert-sorted keys of TaskTemplateCache (the fold/capture paths iterate it every tick; templates are never removed). |
bTaskRebuildInProgress | bool | false | resync 任务重建进行中标志(期间拒绝 BP 侧任务创建)。True while RebuildTasksFromSnapshot runs (BP-side task creation rejected during the window). |
子系统缓存(私有) Subsystem Caches (private)
| 名称 Name | 类型 Type | 说明 Description |
|---|---|---|
CurrentWorld / MassAPISubsystem / MassBattleHashGridSubsystem / MassBattleProjectileSubsystem / MassBattleAgentSubsystem / MassBattleHostSubsystem / MassBattleNetworkSubsystem / MassBattleDebuffSubsystem / MassBattleLootSubsystem / MassBattleObstSubsystem / MassBattleFxSubsystem | TObjectPtr (UPROPERTY, mutable) | 11 个惰性解析缓存(见子系统 Getters)。Eleven lazily-resolved caches (see Subsystem Getters). |
管线角色 Pipeline Role
UMassBattleSubsystem 是 MassBattle 全部模拟与网络流程的调度中枢(调用关系均经 grep 验证):
- 帧控制上游:
FCoreDelegates::OnBeginFrame(Initialize 注册)→OnBeginFrameSetup→PreProcessorFrameSetup——每引擎帧先于任何 tick 组运行,含网络接收(Net->TickSnapshotTcpTransport)、失步恢复(Net->ProcessDeferredSnapshot/ServerRequestResync)、锁步上限(Net->UpdateNetworkClientPacing)、锁步指令执行(DequeueNetCommandsForTick→NetGS->ExecuteNetCommand)、网格重建(GridUpdateProcessor->RebuildAllGrids)与同步生成(AgentSub->ExecuteTick)。 - 处理器派发:
Tick(TG_PostUpdateWork)按 6 阶段 SimStages 手动派发 13 个处理器(各处理器IsSubFrameScheduled自门控),阶段间ResolvePendingSpawns()冲刷延迟命令与资源注册;渲染组(FxRender/AgentRender)帧末运行。 - 帧末下游:Subtick3 段驱动 6 个子系统
ExecuteTick(Projectile/HashGrid/Host/Loot/Debuff/Fx)、HostSub->ProcessHostOpsQueues/ProcessProjectileRecycleQueue/ProcessLootRecycleQueue/UpdateHostRenderInterp、HostMonoProcessor->TickCpuInterp;再派发NetworkProcessor在帧末真态采集 hash+snapshot,随后应用延迟快照(Net->ProcessDeferredSnapshot,其内部调用RebuildTasksFromSnapshot与ResolveAgentRuntimeObjectPtrs)、维护TickHashHistory、触发Net->OnTickCompleted网络桥接、按间隔门控Net->CacheLatestSnapshot(其内部调用CaptureTaskRecords)。 - 数据消费者:处理器并行段写入本子系统的 gatherer(
DmgGatherer/LaunchGatherer/事件队列/调试队列),由ProcessEventQueues向接口接收者(Agent/Projectile/Loot 接口)派发 BP 事件;QueueText被MassBattleAgentReactionProcessor调用;伤害 API(Apply*DamageAndDebuff)被MassBattleFuncLib、AgentBehaviorProcessor、ProjectileMonoProcessor调用。 - 外部入口:
SetSimConfig/PauseGame/ResumeGame经MassBattleFuncLib供蓝图;UID 注册/查询(RegisterUIDEntity/UnregisterUIDEntity/FindEntityByUID/FindUIDByEntity)被组件(AgentComponent 等)、MassBattleNetworkProcessor、AgentSubsystem、HostSubsystem等全系统调用;MassBattleTick委托在 Subtick0 广播。
UMassBattleSubsystem is the dispatch hub of all MassBattle simulation and network flows (call relationships grep-verified):
- Frame-control upstream:
FCoreDelegates::OnBeginFrame(registered in Initialize) →OnBeginFrameSetup→PreProcessorFrameSetup— runs before any tick group each engine frame: network receive (Net->TickSnapshotTcpTransport), desync recovery (Net->ProcessDeferredSnapshot/ServerRequestResync), lockstep ceiling (Net->UpdateNetworkClientPacing), lockstep command execution (DequeueNetCommandsForTick→NetGS->ExecuteNetCommand), grid rebuild (GridUpdateProcessor->RebuildAllGrids) and synchronous spawns (AgentSub->ExecuteTick). - Processor dispatch:
Tick(TG_PostUpdateWork) manually dispatches the 13 processors through the 6 SimStages (each self-gating onIsSubFrameScheduled), withResolvePendingSpawns()flushing deferred commands and asset registration between stages; the render group (FxRender/AgentRender) runs at frame end. - End-of-frame downstream: the Subtick3 block drives six subsystem
ExecuteTickcalls (Projectile/HashGrid/Host/Loot/Debuff/Fx),HostSub->ProcessHostOpsQueues/ProcessProjectileRecycleQueue/ProcessLootRecycleQueue/UpdateHostRenderInterp, andHostMonoProcessor->TickCpuInterp; then dispatchesNetworkProcessorto capture hash+snapshot at the true end-of-frame state, applies deferred snapshots (Net->ProcessDeferredSnapshot, which internally callsRebuildTasksFromSnapshotandResolveAgentRuntimeObjectPtrs), maintainsTickHashHistory, fires theNet->OnTickCompletedbridge, and gatesNet->CacheLatestSnapshoton its interval (internally callingCaptureTaskRecords). - Data consumers: processors write this subsystem's gatherers from parallel sections (
DmgGatherer/LaunchGatherer/event queues/debug queues);ProcessEventQueuesdispatches BP events to interface receivers (Agent/Projectile/Loot interfaces);QueueTextis called byMassBattleAgentReactionProcessor; the damage APIs (Apply*DamageAndDebuff) are called byMassBattleFuncLib,AgentBehaviorProcessorandProjectileMonoProcessor. - External entries:
SetSimConfig/PauseGame/ResumeGameare exposed to Blueprint viaMassBattleFuncLib; UID registration/query (RegisterUIDEntity/UnregisterUIDEntity/FindEntityByUID/FindUIDByEntity) is used across the whole system (components like AgentComponent,MassBattleNetworkProcessor,AgentSubsystem,HostSubsystem); theMassBattleTickdelegate broadcasts at Subtick0.
补充说明 Notes
① MBParallelToggle 命名空间(头文件顶部):逐位置并行/串行切换系统——每个 ParallelFor 位置一个 bool,置 true 强制该位置单线程;主开关 ForceAllSingleThread 强制全部单线程。为确定性调试工具,全部默认为 false(并行)。其中 FuncLib_DeselectAgents/FuncLib_SelectAgentsPrep 当前为 true(禁用)——worker 线程的 Mass API 写访问在 MassEntity.dll 中触发访问违规,阈值 64 以下自动串行。Network_HashSnapshot 有注释警告:快照捕获块一直是并行的,勿翻为 true 除非重新实测。② MBParallelFor/MBForEachEntityChunk 模板:并行循环包装器,编译期按 toggle 选择串行/并行;全库统一经此派发。③ SortByPreExtractedKeys 模板:Schwartzian 式确定性排序——调用方先 O(N) 预提取 UID 键,比较器变 O(1) 数组索引(键语义必须逐字沿用原比较器,排序结果逐位相同,确定性零影响)。④ 头文件中 CVarAgentPhysicsIterations 控制台变量与 AgentPhysicsIterations 配置项被注释掉(WIP),GetAgentPhysicsIterations() 恒返回 1。⑤ LogMassBattle 日志类别在本文件定义(DEFINE_LOG_CATEGORY),全插件共用。
① The MBParallelToggle namespace (top of the header): a per-location parallel/serial toggle system — one bool per ParallelFor site; true forces that site single-threaded; the master switch ForceAllSingleThread forces everything serial. A determinism-debug tool; all default to false (parallel). Notably FuncLib_DeselectAgents/FuncLib_SelectAgentsPrep are currently true (disabled) — worker-thread Mass API writes cause access violations inside MassEntity.dll; below 64 agents they fall back to serial automatically. Network_HashSnapshot carries a warning: the capture blocks have always been parallel; do not flip to true without re-measuring. ② The MBParallelFor/MBForEachEntityChunk templates: parallel-loop wrappers that choose serial/parallel at compile time per toggle; the whole codebase dispatches through them. ③ The SortByPreExtractedKeys template: Schwartzian-style deterministic sort — the caller pre-extracts UID keys once (O(N)) so the comparator becomes an O(1) array index (keys must replicate the old comparator semantics verbatim; the sort result is then bit-identical, so determinism is untouched). ④ The CVarAgentPhysicsIterations console variable and AgentPhysicsIterations config member in the header are commented out (WIP); GetAgentPhysicsIterations() always returns 1. ⑤ The LogMassBattle log category is defined in this file (DEFINE_LOG_CATEGORY) and shared across the plugin.