MassBattle Docsv1.19.20

UMassBattleHostSubsystem

UCLASS WorldSubsystem

Source/MassBattle/Public/Subsystems/MassBattleHostSubsystem.h

概述 Overview

Host 实体(Actor / Fx / Sound / Projectile / Agent / Loot)的世界子系统总管。拥有操作队列(ops queues)、按类型实体池、按 archetype 的弹丸/战利品池、音频组件池与延迟 Spawn*Host 助手。核心模式与 Debuff 子系统相同:并行收集、串行排空——处理器在并行段把 host 生成请求推入 FParallelGatherer,由 ProcessHostOpsQueues 在游戏线程按确定性键(TriggerUID → Sequence)排序后串行弹池/分配 UID/构建实体,保证锁步双端 UID 消费序一致。池采用按 UniqueID 的大根堆:弹池恒取最大 UID 槽,结果只取决于池内容(锁步同步),因此无需任何每帧全量排序。

World subsystem managing host entities (Actor / Fx / Sound / Projectile / Agent / Loot). Owns ops queues, per-type entity pools, per-archetype projectile/loot pools, audio component pools, and the deferred Spawn*Host helpers. Core pattern, like the Debuff subsystem: parallel gather, serial drain — processors push host spawn requests into FParallelGatherers from parallel sections; ProcessHostOpsQueues drains them on the game thread sorted by a deterministic key (TriggerUID → Sequence), popping pools / allocating UIDs / building entities serially so lockstep peers consume the global UID space in the same order. Pools are max-heaps keyed by UniqueID: a pop always takes the largest-UID slot, so the result depends only on pool content (lockstep-synchronized) — no per-tick full sort is ever needed.

继承 Inheritance

UWorldSubsystem → UMassBattleHostSubsystem

结构体 Structs

FAudioComponentPool USTRUCT

按 Sound 资产分组的 UAudioComponent 池包装。UE 的 UPROPERTY TMap 值类型必须是 USTRUCT 或简单类型——裸 TArray<TObjectPtr<UAudioComponent>> 无法被反射,包装后即可通过 TObjectPtr 获得 GC 根引用。2D 与 3D 池分离(见成员变量)。

Per-sound wrapper around the pooled UAudioComponent array. UE's UPROPERTY TMap requires a USTRUCT or simple value type — a bare TArray<TObjectPtr<UAudioComponent>> won't reflect properly; wrapping it gets GC-rooting through the TObjectPtrs while staying reflectable. 2D and 3D pools are separate (see members).

成员变量 Members
名称 Name类型 Type默认值说明 Description
ComponentsTArray<TObjectPtr<UAudioComponent>>—已停止(stopped)的音频组件,供下次播放复用。Stopped audio components available for the next play.
CooldownsTArray<float>—与 Components 等长的并行冷却数组(非 UPROPERTY,纯 float 无 GC 需求)。每次 Recycle 时重置为统一的 PoolIdleLifeSpan,由 TickEntityPoolCooldowns 递减,过期条目无条件销毁(无下限,池可缩到 0)。Parallel cooldown array, same length as Components. Reset to the unified PoolIdleLifeSpan on each Recycle (push); decremented by TickEntityPoolCooldowns; expired entries are destroyed unconditionally (no Min floor).
FSpawnFrame

一批同类型生成(同一帧、同一属主)的共享输入。由调用方填充,连同配置数组与触发实体内序列计数器一起传给 SpawnXxxBatch 系列,避免处理器重复循环/过滤/拷贝/变换样板。含自身帧与目标帧两套坐标系输入,以及随机源(每配置推进)、通用字段(行为状态/速度倍率/动画过滤)与类型专属字段(仅对应助手读取)。

Shared inputs for a batch of same-type spawns from one owner in one frame. The caller fills it and passes it with the config array and a per-trigger sequence counter to the SpawnXxxBatch helpers, which wrap the loop/filter/copy/transform boilerplate. Carries both self-frame and target-frame coordinate inputs, the random source (advanced per config), common fields (behavior state / speed multiplier / anim filter) and type-specific fields (read only by the matching helper).

成员变量 Members
名称 Name类型 Type默认值说明 Description
ContextFMassExecutionContext*nullptr调用方执行上下文。Caller's execution context.
OwnerEntityFEntityHandle—触发实体(属主),写入每个 Config 的 OwnerEntity 并作为 TriggerUID 排序键来源。Triggering entity (owner); written into each Config's OwnerEntity and used as the TriggerUID sort-key source.
AttachEntityFEntityHandle—附着目标;无效时自身帧用 OwnerEntity、AtTarget 用 TargetEntity。Attach target; invalid => OwnerEntity for self-frame, TargetEntity for AtTarget.
SelfQuatFQuatIdentity自身坐标系旋转,LocalOffsetToWorld 的基准。Self-frame rotation, base of LocalOffsetToWorld.
SelfLocationFVectorZeroVector附着帧位置。Attached-frame location.
NotAttachedLocationFVectorZeroVector非附着时仅位置生成(通常等于 SelfLocation,唯 Loot OnCollectEnd 例外)。Location-only spawn when !bAttached (== SelfLocation except Loot OnCollectEnd).
SelfRelativeQuatFQuatIdentityAtSelf 相对变换参考旋转(相同时调用方设为 SelfQuat)。AtSelf InitialRelative reference rotation (caller sets = SelfQuat when same).
SelfRelativeScalefloat1.0fAtSelf 相对变换参考缩放(ProjectileMono 传弹丸缩放,其余 1)。AtSelf InitialRelative reference scale (ProjectileMono passes projectile Scale; others 1).
TargetEntityFEntityHandle—目标实体;无效则 AtTarget 分支跳过。Target entity; invalid => AtTarget skipped.
TargetLocationFVectorZeroVector调用方提供的目标点(命中点或实体原点),仅 WithOrigin 系列使用。Caller-provided target point (hit point or entity origin); used by the WithOrigin series only.
RandSourceconst FRandomStream*nullptr随机源,每配置以 RandHelper(MAX_int32) 推进;空则不初始化随机流(Loot)。Random source, advanced per config via RandHelper(MAX_int32); null => no init (Loot).
BehaviorStateEAgentBehaviorStateNone行为状态,仅在 != None 时覆写配置(依赖自身默认值的配置得以保留)。Behavior state, overridden only when set (!= None) so configs relying on their own default are preserved.
SpeedMultiplierfloat1.0f速度倍率,!= 1 时 Delay /= 此值。Speed multiplier; Delay /= this when != 1.
bFilterByAnimboolfalse为 true 时跳过 BindToAnimIndex != SelectedAnimIndex 的配置。When true, skips configs whose BindToAnimIndex != SelectedAnimIndex.
SelectedAnimIndexint32INDEX_NONE仅 bFilterByAnim 为 true 时使用。Used only when bFilterByAnim is true.
ToPointFVectorZeroVectorProjectile 专属:目标点。Projectile-specific: target point.
LaunchSpeedfloat-1.0fFX 专属:发射速度,负值不设置(仅 Death FX 使用)。FX-specific: launch speed; <0 means don't set (Death FX only).
FromPointFVectorZeroVectorLoot 专属:生成起点。Loot-specific: spawn origin point.
FlowFieldPtrTObjectPtr<AFlowField>nullptrLoot 专属:流场指针(运行时)。Loot-specific: flow field pointer (runtime).
FlowFieldSoftPtrTSoftObjectPtr<AFlowField>—Loot 专属:流场软引用,FlowFieldPtr 的快照友好来源。Loot-specific: soft flow field reference, snapshot-friendly source for FlowFieldPtr.
FActorHostSpawnRequest / FFxHostSpawnRequest / FSoundHostSpawnRequest / FProjectileHostSpawnRequest / FLootHostSpawnRequest

五类 host 生成请求,字段形状相同:TriggerUID 为确定性排序键(触发实体的 FDeterminism.UniqueID),Sequence 为触发实体内单调计数器,使 (TriggerUID, Sequence) 在一次 drain 内构成全序(UE Sort 不稳定——唯一键保证结果唯一);Config 为完整值拷贝,含入队时已播种的 RandomStream(RandHelper 在入队处消耗,与重构前 batch helper 同位置同顺序)。由并行处理器收集,ProcessHostOpsQueues 串行排空。

Five host spawn request kinds sharing one shape: TriggerUID is the deterministic sort key (triggering entity's FDeterminism.UniqueID); Sequence is a per-trigger monotonic counter making (TriggerUID, Sequence) a total order within one drain (UE Sort is unstable — unique keys make the result unique); Config is a full value copy including the already-seeded RandomStream (RandHelper consumed at enqueue time). Gathered in parallel from processors, drained serially by ProcessHostOpsQueues.

成员变量 Members
名称 Name类型 Type默认值说明 Description
TriggerUIDint32-1触发实体 UniqueID,确定性排序主键(-1 = 无效)。Triggering entity's UniqueID, primary deterministic sort key (-1 = invalid).
Sequenceint320触发实体内单调计数,排序次键。Per-trigger monotonic counter, secondary sort key.
ConfigFXxxConfig_Final—完整配置值拷贝(按类别为 FActorSpawnConfig_Final / FFxConfig_Final / FSoundConfig_Final / FProjectileConfig_Final / FLootConfig_Final)。Full config value copy (FActorSpawnConfig_Final / FFxConfig_Final / FSoundConfig_Final / FProjectileConfig_Final / FLootConfig_Final per kind).
FFxEntitySpawnRequest

FX 配对实体(FxEntity)fallback 请求——并行 lane 计算快照字段,串行排空执行 UID 分配与模板构建。由 MassBattleHostMonoProcessor 在需要非池 FX 实体时推入 FxEntitySpawns。

FX paired-entity (FxEntity) fallback request — snapshot fields computed in the parallel lane, drained serially so UID allocation and template build run on the game thread. Pushed into FxEntitySpawns by MassBattleHostMonoProcessor when a non-pool FX entity is needed.

成员变量 Members
名称 Name类型 Type默认值说明 Description
HostUniqueIDint32-1主键——宿主 FDeterminism.UniqueID,确定性排序链首键。Primary key — host UniqueID; first key of the deterministic sort chain.
HostEntityFMassEntityHandle—宿主实体,构建后写回 PairedFxEntity。Host entity; PairedFxEntity written back after build.
SpawnWorldTransformFTransform3f—生成世界变换。Spawn world transform.
SpawnOrientationFQuat4fIdentity生成朝向。Spawn orientation.
SpawnScalefloat1.fFX 自身缩放。The FX's own scale.
ParentGTScaleFVector3fOneVector父级(附着实体)缩放——非 FX 自身 SpawnScale。Parent (attached entity) scale — NOT the FX's own SpawnScale.
bAttachedboolfalse是否附着到父实体。Whether attached to a parent entity.
bBurstFxboolfalseBurst FX 标记,设置 BurstFxFlag。Burst FX flag; sets BurstFxFlag.
bCpuInterpboolfalse宿主插值模式,写入 FFxVisualizing.bCpuInterpMode。Host interp mode; written to FFxVisualizing.bCpuInterpMode.
bNetworkedboolfalse是否携带 FNetworkTag 并消耗全局 UID(纯表现宿主派生时为 false)。Whether to carry FNetworkTag and consume the global UID (false when derived from a local-only host).
AttachToEntityFEntityHandle—附着目标实体(仅 bAttached 时有效)。Attach target entity (valid only when bAttached).
InitialRelativeTransformFTransform3f—初始相对变换。Initial relative transform.
EventParentTransformFTransform3fIdentity事件时刻锚点(拷贝自 FFxConfig_Final 的 SpawnEvent*Transform)——池耗尽回退路径此前仅从激活时刻变换播种,锁步下激活晚于事件 1+ tick(父级已移动)。由 SpawnFxEntitySerial → FFxVisualizing 的 EventParentLoc/EventWorldLoc → FxRenderProcessor 注册分支消费。Event-time anchor (copied from FFxConfig_Final's SpawnEvent*Transform) — the pool-exhausted fallback used to seed only from the activation-time transform, which in lockstep is 1+ ticks after the event (parent already moved). Consumed by SpawnFxEntitySerial → FFxVisualizing's EventParentLoc/EventWorldLoc → the FxRenderProcessor registration branch.
EventWorldTransformFTransform3fIdentity事件时刻世界变换锚点,与 EventParentTransform 配套消费。Event-time world-transform anchor, consumed together with EventParentTransform.
SubType_Indexint32-1子类型索引;-1 = None(渲染器键空间从 0 开始)。Subtype index; -1 = None (renderer key space starts at 0).
StyleType_Indexint320风格索引;0 = Style0(无 None 值)。Style index; 0 = Style0 (no None value).
FDeferredUObjectDestroyOp

ProcessHostOpsQueues 的 Destroy op 延迟收集的 UObject 释放,由 ProcessDeferredUObjectDestroys() 在渲染后统一移除阶段执行(见 UMassBattleSubsystem::Tick)——渲染前拆解的宿主仍须渲染最后一帧。组件指针在延迟时捕获;配置片段在执行时置空(先于 ProcessDestroyQueues 执行,片段仍在)。

UObject releases deferred by ProcessHostOpsQueues' Destroy op cases, executed by ProcessDeferredUObjectDestroys() in the unified post-render removal phase (see UMassBattleSubsystem::Tick) — a host torn down pre-render must still render its final frame. Component pointers are captured at defer time; config fragments are nulled at execution time (executed before ProcessDestroyQueues, so fragments still exist).

成员变量 Members
名称 Name类型 Type默认值说明 Description
EntityFMassEntityHandle—宿主实体,执行时用于读取配置片段并置空 Spawned* 指针。Host entity; used at execution time to read the config fragment and null the Spawned* pointers.
Typeuint80类别:0=Actor,1=Fx,2=Sound。Kind: 0=Actor, 1=Fx, 2=Sound.
ActorTWeakObjectPtr<AActor>—Actor 情况捕获的宿主 Actor(执行时 Destroy)。Host actor captured for the Actor kind (Destroy at execution).
NiagaraCompTWeakObjectPtr<UNiagaraComponent>—Fx 情况捕获的 Niagara 组件(Manual Release 归还池)。Niagara component captured for the Fx kind (Manual Release back to the pool).
CascadeCompTWeakObjectPtr<UParticleSystemComponent>—Fx 情况捕获的 Cascade 组件。Cascade component captured for the Fx kind.
AudioCompTWeakObjectPtr<UAudioComponent>—Sound 情况捕获的音频组件(Stop 后归还组件池)。Audio component captured for the Sound kind (stopped and returned to the component pool).
SoundTWeakObjectPtr<USoundBase>—音频组件池路由用的声音资产。Sound asset for audio-component pool routing.
b2Dboolfalse音频组件池 2D/3D 路由。2D/3D routing for the audio component pool.
FRecycleRequest

host 实体回收请求。并行线程通过 RecycleHostEntity 将其推入 HostEntityRecycleQueue(FParallelGatherer),由 ProcessHostOpsQueues 末端串行消费——不经锁直接改主池数组。

Host entity recycle request. Parallel threads enqueue it into HostEntityRecycleQueue (an FParallelGatherer) via RecycleHostEntity; drained serially at the tail of ProcessHostOpsQueues — no lock touches the main pool arrays.

成员变量 Members
名称 Name类型 Type默认值说明 Description
EntityFMassEntityHandle—待回收实体。Entity to recycle.
TypeEHostEntityType—实体类别,决定入哪个池数组。Entity type; selects the pool array.
FProjectileRecycleRequest / FLootRecycleRequest

弹丸/战利品实体回收请求。由 MassBattleProjectileMonoProcessor / MassBattleLootMonoProcessor 并行推入各自回收队列,在 MB tick 末端(ProcessProjectileRecycleQueue / ProcessLootRecycleQueue)按 DA 分组推入按 archetype 池。注释说明:入池刻意保留 UID 映射——池内实体是快照状态,宿主按真实 UID 引用(诚实恢复),残留条目经每 tick 幂等注册与 UID 复用覆盖自愈。

Projectile/loot entity recycle requests. Pushed in parallel by MassBattleProjectileMonoProcessor / MassBattleLootMonoProcessor into their recycle queues, drained at the end of the MB tick (ProcessProjectileRecycleQueue / ProcessLootRecycleQueue) and pushed into the per-DA pools. Note: UID mapping is deliberately KEPT on pool-in — pooled entities are snapshot state; hosts reference them by real UID (honest restore); stale entries self-heal via the per-tick idempotent register pass + TMap overwrite on UID reuse.

成员变量 Members
名称 Name类型 Type默认值说明 Description
EntityFMassEntityHandle—待回收实体。Entity to recycle.
DataAssetTObjectPtr<UMassBattleXxxConfigDataAsset>—数据资产,决定入哪个按 archetype 池桶;无效时实体直接 DestroyEntity。Data asset selecting the per-archetype pool bucket; if invalid the entity is destroyed outright.
UniqueIDint32-1实体 UID,堆键(创建时定死)。Entity UID, heap key (fixed at creation).
FPoolTickStats

逐 tick 分配统计(调试用)。FromPool = 弹池命中数,Fresh = 新建数。Pop/Allocate 路径在并行处理器 chunk 中运行,故用 volatile 原子加;不调用打印函数时零运行时成本。

Per-tick allocation accounting (debug). FromPool = pool hits, Fresh = fresh builds. Pop/Allocate paths run from parallel processor chunks, so the increments are thread-local atomic adds; zero runtime cost when the print function isn't called.

成员变量 Members
名称 Name类型 Type默认值说明 Description
FromPoolvolatile int320本 tick 弹池次数。Pool pops this tick.
Freshvolatile int320本 tick 新建次数。Fresh builds this tick.
Reset()void—清零两个计数。Zeroes both counters.

公开方法 Public Methods

UMassBattleHostSubsystem 构造函数

空构造函数,无初始化逻辑。

Empty constructor; no initialization logic.

Input

无参数。

No parameters.

Output

无。

None.

Initialize virtual void

USubsystem 生命周期入口。调用父类实现后预热两个子系统缓存(GetMassAPISubsystem / GetMassBattleSubsystem)。

USubsystem lifecycle entry. Calls the parent implementation, then warms two subsystem caches (GetMassAPISubsystem / GetMassBattleSubsystem).

Input
参数 Param类型 Type说明 Description
CollectionFSubsystemCollectionBase&子系统集合,由引擎传入。Subsystem collection provided by the engine.
Output

无返回值。副作用:填充 MassAPISubsystem / MassBattleSubsystem 缓存。

No return value. Side effects: fills the MassAPISubsystem / MassBattleSubsystem caches.

Deinitialize virtual void

USubsystem 生命周期出口。清空:八个 host 实体池、两个 spawn 缓存(内含失效 fragment 指针)、五个操作 gatherer、六个生成 gatherer、两个回收队列;显式 Stop + DestroyComponent 拆除 2D/3D 音频组件池;清空按 archetype 的弹丸/战利品池与模板缓存;最后清空三个子系统缓存指针。注释说明:按 archetype 池跨世界重置保留(实体随实体管理器 GC),但快照边界不再调用本函数。

USubsystem lifecycle exit. Empties: the eight host entity pools, both spawn caches (holding now-invalid fragment pointers), five op gatherers, six spawn gatherers, both recycle queues; explicitly stops and destroys the 2D/3D audio component pools; clears the per-archetype projectile/loot pools and template caches; finally nulls the subsystem cache pointers. Per-archetype pools survive world resets (entities GC alongside the entity manager); the function is no longer called at snapshot boundaries.

Input

无参数。

No parameters.

Output

无返回值。副作用:释放全部池/队列/缓存持有的句柄与组件。

No return value. Side effects: releases all handles and components held by pools/queues/caches.

ExecuteTick void

每帧 tick 入口(由 UMassBattleSubsystem::Tick 在模拟阶段之后调用)。当前仅含 profiling 标记与 TickEntityPoolCooldowns 调用。注释说明:协调器单独驱动 ProcessHostOpsQueues 与 ProcessProjectileRecycleQueue,因为它们的槽序(order)承载确定性;ResetPoolTickStats 已移至模拟阶段之前。

Per-frame tick entry (called by UMassBattleSubsystem::Tick after the sim stages). Currently only a profiling scope plus TickEntityPoolCooldowns. The coordinator drives ProcessHostOpsQueues and ProcessProjectileRecycleQueue separately because their slot order is load-bearing; ResetPoolTickStats was moved to before the sim stages.

Input
参数 Param类型 Type说明 Description
DeltaTimefloat本帧时间步长(秒),传给池冷却递减。Frame delta time in seconds; forwarded to the pool cooldown tick.
Output

无返回值。副作用:过期池条目被逐出(销毁或入销毁队列)。

No return value. Side effects: expired pool entries are evicted (destroyed or queued for destroy).

UpdateHostRenderInterp void

逐帧 CPU 侧预测插值,作用于附着(Actor/FX/Sound)宿主的 UObject。仅处理 bAttached 且 FHostHierarchy.bResolvedThisTick 的实体:读取层级解析出的世界变换/线速度/角速度与 ResolvedInterpParams,经 FInterpParams 配置调用 Hierarchy->InterpState.Tick 得到插值结果,再按类型应用到 SpawnedActor->SetActorTransform / Niagara 与 Cascade SetWorldTransform / AudioComponent->SetWorldLocationAndRotation。遍历三个追踪数组时即时移除孤立实体(实体失效或 fragment 缺失)。由 UMassBattleSubsystem::Tick 帧末调用。

Per-frame CPU-side prediction interp for attached (Actor/FX/Sound) host UObjects. Processes only entities that are bAttached and whose FHostHierarchy.bResolvedThisTick is set: reads the resolved world transform / linear and angular velocity plus ResolvedInterpParams, runs Hierarchy->InterpState.Tick with FInterpParams, then applies the result per type — SpawnedActor->SetActorTransform / Niagara and Cascade SetWorldTransform / AudioComponent->SetWorldLocationAndRotation. Orphaned entries (invalid entity or missing fragment) are removed from the tracking arrays on the fly. Called at the end of the frame by UMassBattleSubsystem::Tick.

Input
参数 Param类型 Type说明 Description
EngineDeltaTimefloat引擎帧时间(秒),传给插值状态 Tick。Engine frame time in seconds; forwarded to the interp state Tick.
Output

无返回值。副作用:更新宿主 UObject 的世界变换;修剪三个 RenderInterp 追踪数组。

No return value. Side effects: updates host UObject world transforms; trims the three render-interp tracking arrays.

GetPtr static UMassBattleHostSubsystem*

静态访问器:从任意世界上下文对象解析 UWorld 并取其 Host 子系统。世界无效时返回 nullptr。

Static accessor: resolves UWorld from any world-context object and returns its Host subsystem; nullptr when the world is invalid.

Input
参数 Param类型 Type说明 Description
WorldContextconst UObject*任意 UObject 世界上下文(经 GEngine->GetWorldFromContextObject 解析)。Any UObject world context (resolved via GEngine->GetWorldFromContextObject).
Output

返回子系统指针;上下文无效时返回 nullptr。

Returns the subsystem pointer, or nullptr when the context is invalid.

GetRef static UMassBattleHostSubsystem&

静态访问器的引用版本:失败即 checkf 断言崩溃——用于「子系统必须存在」的不变式场景。

Reference version of the static accessor: fails via checkf assertion — for invariant paths where the subsystem must exist.

Input
参数 Param类型 Type说明 Description
WorldContextconst UObject*任意 UObject 世界上下文。Any UObject world context.
Output

返回子系统引用;取不到时触发 checkf 断言("Failed to get UMassBattleHostSubsystem from world context.")。

Returns a subsystem reference; triggers a checkf assertion ("Failed to get UMassBattleHostSubsystem from world context.") when unavailable.

GetMassAPISubsystem / GetMassBattleSubsystem / GetMassBattleLootSubsystem / GetMassBattleProjectileSubsystem / GetMassBattleFxSubsystem UMassAPISubsystem* / UMassBattleSubsystem* / …

五个同构的惰性访问器:命中缓存直接返回;否则从当前世界取对应子系统并写入缓存(CurrentWorld 首次解析)。Loot / Projectile / Fx 三个在 Host 内部用于弹丸/战利品 spawn 与 FxEntity 注册。

Five isomorphic lazy accessors: return the cache on hit; otherwise fetch the subsystem from the current world and fill the cache (CurrentWorld resolved on first use). The Loot / Projectile / Fx ones are used internally for projectile/loot spawns and FxEntity registration.

Input

无参数。

No parameters.

Output

返回对应子系统指针(世界缺失时可能为 nullptr)。副作用:写入缓存成员。

Returns the subsystem pointer (may be nullptr when the world is missing). Side effects: fills the cache members.

ProcessHostOpsQueues void

宿主系统的核心串行排空入口(约 1900 行,由 UMassBattleSubsystem::Tick 每帧在阶段边界调用,空闲时快速路径零成本——每帧 5 次调用)。固定段序:① debuff 生成请求(ProcessDebuffSpawnQueues,最早并行阶段产生,最先消费);② 五类 host 生成请求(Actor/Fx/Sound/Projectile/Loot)各自 Merge → 确定性排序(TriggerUID → Sequence,非 Shipping 下校验重复键)→ 批量弹池(AllocateHostEntityBatch:每 (类型,网络类) 单锁单趟降序扫描,指派结果与逐请求分配逐字节一致;Sound 段裁决拒绝的尾段经 ReleaseBatchSlots 归还)+ 并行写 fragment(每实体唯一写者,零 mutation;池空/脏槽回落串行构建,批耗尽后的回落传 bSkipPoolRetry=true 跳过弹池重试);③ FxEntity 配对实体(按 HostUID → AttachUID → SubType → StyleType 确定性链排序后 SpawnFxEntitySerial);④ 五类延迟 UObject 操作队列(ActorOps/FxOps/SoundOps/ProjectileOps/LootOps)——先并行预校验(实体/片段/资产注册表解析),再串行执行 Spawn/Destroy/Transform(资产 LoadSynchronous、Actor SpawnActor、Niagara/Cascade ManualRelease、音频组件池命中或新建;Destroy op 的 UObject 释放延迟收集到 DeferredUObjectDestroys,由渲染后统一移除阶段的 ProcessDeferredUObjectDestroys 执行);⑤ FX 完成检查(串行,UObject 访问);⑥ 弹丸/战利品 ops 段:每 Config 分配 UID → 并行计算轨迹/散布/偏移 → 按 archetype 分组 → 串行弹池/BatchCreate 补齐 → 单次全局并行写 fragment → 注册 UID 映射;⑦ host 实体回收队列入池(无需排序——池为大根堆,弹池序只取决于内容)。Sound 段内嵌模拟层并发裁决:按 Sound 资产分组(RetriggerTime 节流 / MaxCount 上限,PreventNew 拒绝、StopOldest 逐最老、StopLowestPriority 逐最低优先级,MinPlayTime 保护),裁决前先 PrescanSoundRecycles 预扫。

The core serial drain entry of the host system (~1900 lines, called each frame at stage boundaries by UMassBattleSubsystem::Tick; the all-empty fast path costs nothing — 5 calls per frame). Fixed stage order: ① debuff spawn requests (ProcessDebuffSpawnQueues — produced by the earliest parallel stages, consumed first); ② five host-spawn request kinds (Actor/Fx/Sound/Projectile/Loot), each Merge → deterministic sort (TriggerUID → Sequence; duplicate keys log errors in non-Shipping) → batch pool pop (AllocateHostEntityBatch: ONE lock + ONE descending scan per (type, network class), assignment byte-identical to sequential per-request allocation; the Sound segment's adjudication-rejected tail is returned via ReleaseBatchSlots) + parallel fragment write (unique writer per entity, no mutation; pool-empty/dirty slots fall back to serial build with bSkipPoolRetry=true, skipping the pool retry); ③ FxEntity paired entities (sorted by the HostUID → AttachUID → SubType → StyleType deterministic chain, then SpawnFxEntitySerial); ④ five deferred UObject op queues (ActorOps/FxOps/SoundOps/ProjectileOps/LootOps) — parallel pre-pass (entity/fragment/asset-registry resolution) then serial Spawn/Destroy/Transform (LoadSynchronous, Actor SpawnActor, Niagara/Cascade ManualRelease, audio component pool hit or fresh spawn; UObject releases from the Destroy ops are deferred into DeferredUObjectDestroys, executed by ProcessDeferredUObjectDestroys in the unified post-render removal phase); ⑤ FX completion checks (serial, UObject access); ⑥ projectile/loot ops stages: per-Config UID allocation → parallel trajectory/spread/offset computation → archetype grouping → serial pool pop / BatchCreate shortfall → single global parallel fragment write → UID registration; ⑦ host entity recycle queue into pools (no sort — pools are max-heaps, pop order depends only on content). The Sound stage embeds simulation-layer concurrency adjudication: grouped per sound asset (RetriggerTime throttle / MaxCount cap with PreventNew reject, StopOldest evict, StopLowestPriority evict, MinPlayTime protection), preceded by PrescanSoundRecycles.

Input

无参数(请求来自成员 gatherer 与回收队列)。

No parameters (requests come from the member gatherers and recycle queues).

Output

无返回值。副作用:消费全部排队请求并清空各 gatherer、分配若干全局 UID、写入实体 build 命令、创建/销毁/移动 UObject 宿主、将回收实体推入池、写回 SpawnedXxx 指针。

No return value. Side effects: consumes all queued requests and resets the gatherers, allocates global UIDs, writes entity build commands, spawns/destroys/moves UObject hosts, pushes recycled entities into pools, writes back SpawnedXxx pointers.

ProcessDeferredUObjectDestroys void

执行 ProcessHostOpsQueues 的 Destroy op 延迟收集的 UObject 释放(DeferredUObjectDestroys)。每逻辑帧一次,在渲染后统一移除阶段调用——渲染处理器之后、ProcessDestroyQueues 之前(见 UMassBattleSubsystem::Tick):渲染前拆解的宿主仍须渲染最后一帧;先于实体销毁执行时配置片段仍可读取以清理指针。按类别分派:Actor → Destroy() 并置空 SpawnedActor;Fx → Niagara/Cascade 组件 Manual Release 归还池并置空 SpawnedNiagaraSystem/SpawnedCascadeSystem;Sound → Stop() 后经 RecycleAudioComponent 归还组件池并置空 SpawnedSound。顺序 = 收集序(确定性 drain 序,双端一致)。MA 无效时直接清空队列返回。

Executes the UObject releases deferred by ProcessHostOpsQueues' Destroy op cases (DeferredUObjectDestroys). Called once per logic frame in the unified post-render removal phase — after the render processors, before ProcessDestroyQueues (see UMassBattleSubsystem::Tick): a host torn down pre-render must still render its final frame, and running before the entity destroy queue keeps config fragments readable for pointer cleanup. Dispatched per kind: Actor → Destroy() + null SpawnedActor; Fx → Niagara/Cascade components released to their pools (Manual Release) + null SpawnedNiagaraSystem/SpawnedCascadeSystem; Sound → Stop() then RecycleAudioComponent back to the component pool + null SpawnedSound. Order = gather order (deterministic drain order, identical on all peers). Resets the queue and returns early when MA is invalid.

Input

无参数(操作来自成员 DeferredUObjectDestroys)。

No parameters (ops come from the DeferredUObjectDestroys member).

Output

无返回值。副作用:Destroy Actor / 归还 FX 与音频组件入池、置空对应配置片段的 Spawned 指针、清空队列。

No return value. Side effects: destroys actors / returns FX and audio components to their pools, nulls the matching Spawned pointers in the config fragments, resets the queue.

ProcessProjectileRecycleQueue / ProcessLootRecycleQueue void

弹丸/战利品回收队列的串行排空(由 UMassBattleSubsystem::Tick 帧末调用)。Merge 后逐条处理:DA 无效或实体已失效 → 直接 DestroyEntity;否则把 PoolCountdown 重置为统一的 PoolIdleLifeSpan 并按其 UniqueID 推入对应按 archetype 池桶(大根堆)。无需排序——弹池序只取决于池内容。

Serial drains of the projectile/loot recycle queues (called at the end of the frame by UMassBattleSubsystem::Tick). After Merge: an invalid DA or dead entity is destroyed outright; otherwise PoolCountdown is reset to the unified PoolIdleLifeSpan and the entity is pushed into its per-archetype pool bucket (max-heap) by UniqueID. No sort needed — pop order depends only on pool content.

Input

无参数(请求来自 ProjectileRecycleQueue / LootRecycleQueue)。

No parameters (requests come from ProjectileRecycleQueue / LootRecycleQueue).

Output

无返回值。副作用:实体入池或延迟销毁;清空回收队列。

No return value. Side effects: entities enter pools or are deferred-destroyed; the recycle queues are reset.

AllocateHostEntity FMassEntityHandle

从指定类型池弹一个宿主实体。持 PoolAllocationLock 自旋锁,并行处理器可安全调用。逐项弹出最大 UID 槽直至匹配:FNetworkTag 状态与 bNetworkSync 不符的槽暂存放回(槽的 tag 创建时定死——同步生成不复用纯表现槽、反之亦然,双向都会破坏 hash/UID 状态;弹池结果与形状无关,各端仍选同一槽);失效句柄直接丢弃(实体已被处理器销毁,如 TTL)。命中时 FromPool 计数 +1;池空或全失效时 Fresh 计数 +1 并返回无效句柄(调用方回落 BuildEntityDefer)。

Pops a host entity from the pool of the given type. Holds the PoolAllocationLock spin lock, so parallel processors may call it safely. Pops the largest-UID slot repeatedly until a match: slots whose FNetworkTag state differs from bNetworkSync are stashed and re-pushed (a slot's tag is fixed at creation — sync spawns never reuse local-only slots and vice versa; both directions would corrupt hash/UID state; the pop result is shape-independent, so peers still pick the same slot); stale handles are discarded (entity already destroyed by a processor, e.g. TTL). On hit, FromPool is incremented; when the pool is empty or all-stale, Fresh is incremented and an invalid handle is returned (caller falls back to BuildEntityDefer).

Input
参数 Param类型 Type说明 Description
TypeEHostEntityType实体类别,选择池数组(索引匹配枚举,FxCPU=6)。Entity type selecting the pool array (index matches the enum, FxCPU=6).
bNetworkSyncbool按 FNetworkTag 过滤槽位——true 只弹带网络 tag 的槽。Filters slots by FNetworkTag — true pops only networked slots.
Output

返回池中实体句柄;池空/全失效时返回无效句柄。副作用:修改池堆、更新 tick 统计。

Returns the pooled entity handle, or an invalid handle when the pool is empty/all-stale. Side effects: mutates the pool heap, updates tick stats.

AllocateHostEntityBatch void

drain 段的批量弹池变体:每 (类型, 网络类) 每 tick 持一次 PoolAllocationLock、单趟降序扫描,收集至多 Wanted 个匹配槽;反类槽(FNetworkTag 状态不符)单次暂存到 BatchMismatchScratch、单趟回插。逐请求分配每请求重复弹插同一批反类槽(O(N*M) 空转)——批量单趟弹出同一降序序列,指派结果(drain 序请求获得 UID 降序匹配槽)与逐请求 AllocateHostEntity 调用逐字节一致;弹池结果与堆形状无关(见 HostEntityPools 注释)。函数内不计统计——drain 循环按消费逐请求计 FromPool/Fresh(同时消除逐请求路径池空重试的 Fresh 双计)。

Batch pool-pop variant for the drain segments: ONE lock on PoolAllocationLock + ONE descending scan per (Type, network class) per tick, collecting up to Wanted matching slots; opposite-class slots are stashed once into BatchMismatchScratch and re-pushed in a single pass. Per-request allocation re-pops those mismatches on EVERY request (O(N*M) churn) — the batch pops the identical descending sequence in one pass, so the assignment (drain-order requests receive matching slots in descending-UID order) is byte-identical to sequential AllocateHostEntity calls; pop results stay shape-independent (see the HostEntityPools note). No stats inside — the drain loops tally FromPool/Fresh per consumed request (also removing the per-request path's double Fresh tally on pool-miss retries).

Input
参数 Param类型 Type说明 Description
TypeEHostEntityType实体类别,选择池数组(索引匹配枚举,FxCPU=6)。Entity type selecting the pool array (index matches the enum, FxCPU=6).
bNetworkSyncbool按 FNetworkTag 过滤槽位——true 只收带网络 tag 的槽。Filters slots by FNetworkTag — true collects only networked slots.
Wantedint32本段需要的匹配槽数上限(通常 = 该段请求数)。Upper bound on matching slots to collect (usually the segment's request count).
OutSlotsTArray<FMassEntityHandle>&输出收集到的匹配槽(drain 序指派循环按序消费)。Output receiving the collected matching slots (consumed in order by the drain assignment loop).
Output

无返回值。副作用:修改池堆;反类槽经 BatchMismatchScratch 单趟回插;失效句柄直接丢弃;Wanted ≤ 0 或 MA 无效时不动作。

No return value. Side effects: mutates the pool heap; opposite-class slots re-pushed in one pass via BatchMismatchScratch; stale handles discarded; no-op when Wanted ≤ 0 or MA is invalid.

ReleaseBatchSlots void

归还批量未消费的尾段入池。Sound 段专用——并发裁决在批量按请求总数(上限)取数后拒绝部分请求,尾段由此归还。与回收 drain 同款 push 纪律(UID 键取自 FDeterminism;失效句柄防御性丢弃——实际 drain 中不会失效)。

Returns the unconsumed tail of a batch to the pool. Used by the Sound segment, where adjudication rejects requests after the batch was sized to the full request count (upper bound). Same push discipline as the recycle drain (UID key from FDeterminism; stale handles dropped defensively — cannot go stale mid-drain in practice).

Input
参数 Param类型 Type说明 Description
TypeEHostEntityType实体类别,选择池数组。Entity type selecting the pool array.
Slotsconst TArray<FMassEntityHandle>&批量弹池结果。The batch pop result.
FromIdxint32从该索引起为未消费尾段。First unconsumed index of the tail.
Output

无返回值。副作用:尾段实体按 UID 重新入堆(持锁);FromIdx 越界或 MA 无效时不动作。

No return value. Side effects: tail entities pushed back into the heap by UID (locked); no-op when FromIdx is out of range or MA is invalid.

RecycleHostEntity void

把宿主实体归还池以待复用。仅入队 HostEntityRecycleQueue(FParallelGatherer,无锁)——实际入池由 ProcessHostOpsQueues 末端串行执行。并行处理器可安全调用。

Returns a host entity to the pool for reuse. Only enqueues into HostEntityRecycleQueue (FParallelGatherer, lock-free) — the actual pool push happens serially at the tail of ProcessHostOpsQueues. Safe to call from parallel processors.

Input
参数 Param类型 Type说明 Description
EntityFMassEntityHandle待回收实体(无效则直接返回)。Entity to recycle (invalid handles return immediately).
TypeEHostEntityType实体类别。Entity type.
Output

无返回值。副作用:向回收 gatherer 追加一条请求。

No return value. Side effects: appends a request to the recycle gatherer.

VerifySyncHostAttachTarget void (const)

[RULE8] 锁步宿主生成前的附着目标校验:目标无效、非宿主实体(agent/projectile/loot——均为锁步实体)或带 FNetworkTag 的同步宿主均放行;仅「本地宿主父级(UID=-1,从不注册)」违规——此时 fail loud 打 Error 日志(生成继续,日志标出开发者/配置错误),因为快照恢复的父引用修复会悬挂。由所有锁步 spawn 分支调用。

[RULE8] Attach-target validation before lockstep host spawns: invalid targets, non-host parents (agent/projectile/loot — all lockstep entities) and sync hosts carrying FNetworkTag all pass; only a local-only host parent (UID=-1, never registered) violates the rule — fail loud with an Error log (spawn proceeds; the log marks the developer/config error), because the snapshot-restore parent fixup would dangle. Called by every lockstep spawn branch.

Input
参数 Param类型 Type说明 Description
AttachToEntityconst FEntityHandle&附着目标实体。Attach target entity.
MAUMassAPISubsystem*Mass API 子系统(为 nullptr 或目标无效时直接返回)。Mass API subsystem (returns immediately when null or the target is invalid).
Output

无返回值。违规时输出 Error 日志(含父级 UID)。

No return value. Logs an Error (with the parent UID) on violation.

SpawnActorHostSerial / SpawnFxHostSerial / SpawnSoundHostSerial / SpawnProjectileHostSerial / SpawnLootHostSerial FMassEntityHandle

五类 host 的串行构建入口(由 ProcessHostOpsQueues drain 段的池空/脏槽分支调用;drain 现经 AllocateHostEntityBatch 批量弹池,批耗尽后的回落构建传 bSkipPoolRetry=true 跳过内部弹池重试)。流程:先 AllocateHostEntity 弹池——命中则经 WriteXxxHostSerialClean 串行清理残留 UObject 后写 fragment;池空则构建模板:FMainType(Host) + FDeterminism(恒分配 UID,AllocNextUID 并 RandomStream.Initialize(UID)) + FHostHierarchy(延迟期间始终追踪父级:AttachToEntity 优先,否则 OwnerEntity) + FHostControllerTag + 类别 fragment + 网络标记(仅 bNetworkedMode && bLockstepNetworked:FNetworkTag + FNetworking.Key 命中对应骨架模板;Actor/Sound 恒带 FCpuInterpTag;Fx 依 InterpMode==CPU || (SubType_Index<0 && bAttached) 条件带),最后 BuildEntityDefer。SpawnProjectileHostSerial 与 SpawnLootHostSerial 的网络参与条件为整局 bNetworkedMode(无 per-config 开关)。

Serial build entries for the five host kinds (called by the pool-empty / dirty-slot branches of the ProcessHostOpsQueues drain; the drain now batch-pops via AllocateHostEntityBatch, and the fallback build right after a batch exhausted the class pool passes bSkipPoolRetry=true to skip the internal pool retry). Flow: first AllocateHostEntity — on hit, WriteXxxHostSerialClean cleans leftover UObjects serially then writes fragments; on pool-empty, build a template: FMainType(Host) + FDeterminism (always allocates a UID via AllocNextUID and RandomStream.Initialize(UID)) + FHostHierarchy (parent always tracked during delay: AttachToEntity preferred, else OwnerEntity) + FHostControllerTag + the kind's fragment + network markers (only when bNetworkedMode && bLockstepNetworked: FNetworkTag + FNetworking.Key hitting the matching skeleton template; Actor/Sound always carry FCpuInterpTag; Fx adds it on InterpMode==CPU || (SubType_Index<0 && bAttached)), then BuildEntityDefer. SpawnProjectileHostSerial / SpawnLootHostSerial gate network participation on the whole-session bNetworkedMode (no per-config switch).

Input
参数 Param类型 Type说明 Description
Configconst FXxxConfig_Final&完整生成配置(Actor/Fx/Sound/Projectile/Loot 各自类型)。Full spawn config (per-kind type).
bSkipPoolRetrybool(默认 false)drain 调用点在批量刚耗尽该类池后传 true——批量与指派循环之间无入池,内部重试只会重扫反类槽后再失败(纯浪费);直接调用方保留重试(默认)。Drain call sites pass true right after their batch exhausted the class pool — nothing pushes between the batch and the assignment loop, so an internal retry can only re-scan mismatched slots and fail (pure waste); direct callers keep the retry (default).
Output

返回宿主实体句柄(MA 缺失时返回无效句柄)。副作用:池命中时消费池槽;池空时分配一个全局 UID 并向命令缓冲写入实体 build 命令。

Returns the host entity handle (invalid when MA is missing). Side effects: consumes a pool slot on hit; allocates one global UID and writes a build command into the command buffer on pool-empty.

SpawnActorHost / SpawnFxHost / SpawnSoundHost / SpawnProjectileHost / SpawnAgentHost / SpawnLootHost FMassEntityHandle

六类 host 的即时生成入口(锁步外调用点也可用)。Actor/Fx/Sound 为「无 Context 重载」:按是否处于锁步命令窗口(UMassBattleNetworkSubsystem::IsInCommandExecution)自动分流——锁步窗口内 → 同步版(分配 UID + 网络 fragment);锁步外(BP 直调)→ 纯表现版(UID=-1 哨兵、无网络 fragment,一次锁步外生成就会偏移各端 UID 空间 → 永久失步,故刻意跳过两个游标)。bAllocIdentity = !bNetworkMode || (bLockstepPath && bLockstepNetworked),bSyncParticipant = bNetworkMode && bLockstepPath && bLockstepNetworked。SpawnProjectileHost / SpawnLootHost / SpawnAgentHost 直接以整局网络模式决定。四元分流:弹池命中 → 串行清理+写;池空 → 构建模板(BuildEntityDefer)。

Immediate spawn entries for the six host kinds (usable from off-lockstep call sites too). Actor/Fx/Sound are context-free overloads that auto-split on whether the lockstep command window is open (UMassBattleNetworkSubsystem::IsInCommandExecution): inside the window → sync version (UID allocated + network fragments); off-lockstep (BP direct call) → local-only version (UID=-1 sentinel, no network fragments — a single off-lockstep spawn would shift every peer's UID space → permanent desync, so both cursors are deliberately skipped). bAllocIdentity = !bNetworkMode || (bLockstepPath && bLockstepNetworked); bSyncParticipant = bNetworkMode && bLockstepPath && bLockstepNetworked. SpawnProjectileHost / SpawnLootHost / SpawnAgentHost gate on the session-wide network mode directly. Four-way split: pool hit → serial clean + write; pool-empty → template build (BuildEntityDefer).

Input
参数 Param类型 Type说明 Description
Configconst FXxxConfig_Final&完整生成配置(Agent 版为 FAgentHostConfig_Final)。Full spawn config (FAgentHostConfig_Final for the Agent variant).
Output

返回宿主实体句柄(MA 缺失时无效)。副作用:弹池槽 / 分配全局 UID(锁步路径)或写 -1(纯表现路径)/ 写命令缓冲。

Returns the host entity handle (invalid when MA is missing). Side effects: pool pop / global UID allocation (lockstep path) or -1 (local-only path) / command buffer write.

SpawnFxEntitySerial FMassEntityHandle

FX 配对实体(fallback,非池)的串行构建。模板与池实体同 archetype(永不迁移):FBatchedFxTag + FSubType + FStyleType + FLocating + FRotating + FScaling + FEntityFlagFragment(Activated/BurstFx)+ FFxVisualizing + FMainType(FxEntity) + FDeterminism。关键细节:非池路径必须播种 ParentGT(否则 ParentLocArray 原点拉丝),且 ParentGTScale 必须是父级缩放而非 FX 自身 SpawnScale(播种 SpawnScale 会使首帧按 SpawnScale 倍渲染);UID 仅当 bNetworked(或非网络模式)时分配,纯表现宿主派生的 FX 实体保持 -1;构建后写回宿主的 PairedFxEntity,并延迟(实体 build 完成后)经 FMassDeferredSetCommand 注册 UID 映射。

Serial build of an FX paired entity (fallback, non-pool). Template shares the pool archetype (never migrates): FBatchedFxTag + FSubType + FStyleType + FLocating + FRotating + FScaling + FEntityFlagFragment (Activated/BurstFx) + FFxVisualizing + FMainType(FxEntity) + FDeterminism. Key details: the non-pool path must seed ParentGT (else the ParentLocArray renders a ribbon from the origin), and ParentGTScale must be the PARENT's scale, not the FX's own SpawnScale (seeding SpawnScale flashes first-frame renders at SpawnScale×); UID is allocated only when bNetworked (or in non-networked mode) — FX entities derived from local-only hosts keep -1; after build, PairedFxEntity is written back to the host and the UID mapping is registered deferred (after the entity is built) via FMassDeferredSetCommand.

Input
参数 Param类型 Type说明 Description
Reqconst FFxEntitySpawnRequest&并行 lane 计算的请求(快照字段已在入队前算好)。Request computed in the parallel lane (snapshot fields already resolved at enqueue).
Output

返回新实体延迟句柄。副作用:写回宿主 PairedFxEntity;可能分配全局 UID;注册 UID 映射(延迟)。

Returns the deferred handle of the new entity. Side effects: writes back PairedFxEntity; may allocate a global UID; registers the UID mapping (deferred).

GetFxTemplateKey static FName

FX 骨架模板键映射,镜像 SpawnFxHost 的 FCpuInterpTag 条件:InterpMode==CPU || (SubType_Index<0 && bAttached) → "FxHost_CPU",否则 "FxHost"。每个 archetype 解析到自己的 key,保证快照 TemplateKey 恢复时总能命中对应骨架。

FX skeleton template key mapping, mirroring the FCpuInterpTag condition in SpawnFxHost: InterpMode==CPU || (SubType_Index<0 && bAttached) → "FxHost_CPU", else "FxHost". Each archetype resolves to its own key so the snapshot TemplateKey always hits the matching skeleton at restore.

Input
参数 Param类型 Type说明 Description
Configconst FFxConfig_Final&FX 配置,读取 InterpMode / SubType_Index / bAttached。FX config; reads InterpMode / SubType_Index / bAttached.
Output

返回 FName("FxHost") 或 FName("FxHost_CPU")。

Returns FName("FxHost") or FName("FxHost_CPU").

GetFxEntityTemplateKey static FName

FxEntity 骨架模板键,固定返回 "FxEntity"。

FxEntity skeleton template key; always returns "FxEntity".

Input

无参数。

No parameters.

Output

返回 FName("FxEntity")。

Returns FName("FxEntity").

MakeFxSkeletonTemplate static FEntityTemplateData

构建 FX 骨架模板——仅身份(archetype 组合),运行时字段恢复时被快照 blob 覆盖。按 Key 分两支:"FxEntity" 组合 FBatchedFxTag + FNetworkTag + FSubType + FStyleType + FLocating + FRotating + FScaling + FEntityFlagFragment + FFxVisualizing + FMainType(FxEntity) + FDeterminism + FNetworking(Key);"FxHost"/"FxHost_CPU" 组合 FHostControllerTag + FNetworkTag + FMainType(Host) + FFxConfig_Final + FHostHierarchy + FDeterminism + FNetworking(Key)(CPU 变体带 FCpuInterpTag)。纪律:组合必须与网络 spawn 分支(SpawnFxHost 新建分支 / HostMonoProcessor fallback FxEntity 分支)完全一致,否则恢复出的实体掉出处理器查询。

Builds an FX skeleton template — identity only (archetype composition); runtime fields are overwritten by the snapshot blob on restore. Two branches by Key: "FxEntity" composes FBatchedFxTag + FNetworkTag + FSubType + FStyleType + FLocating + FRotating + FScaling + FEntityFlagFragment + FFxVisualizing + FMainType(FxEntity) + FDeterminism + FNetworking(Key); "FxHost"/"FxHost_CPU" compose FHostControllerTag + FNetworkTag + FMainType(Host) + FFxConfig_Final + FHostHierarchy + FDeterminism + FNetworking(Key) (the CPU variant adds FCpuInterpTag). Rule: the composition MUST match the networked spawn branches (SpawnFxHost new branch / HostMonoProcessor fallback FX-entity branch) exactly, otherwise restored entities fall out of processor queries.

Input
参数 Param类型 Type说明 Description
KeyFName骨架键("FxHost" / "FxHost_CPU" / "FxEntity")。Skeleton key ("FxHost" / "FxHost_CPU" / "FxEntity").
Output

返回 FEntityTemplateData(内部 FMassEntityTemplateData 以 MakeShared 共享)。

Returns FEntityTemplateData (inner FMassEntityTemplateData shared via MakeShared).

MakeProjectileSkeletonTemplate / MakeLootSkeletonTemplate / MakeActorSkeletonTemplate / MakeSoundSkeletonTemplate / MakeAgentSkeletonTemplate static FEntityTemplateData

五类单 key 骨架模板构建,组合模式一致:FHostControllerTag + FNetworkTag + FMainType(Host) + 类别 fragment(FProjectileConfig_Final / FLootConfig_Final / FActorSpawnConfig_Final / FSoundConfig_Final / FAgentHostConfig_Final) + FHostHierarchy + FDeterminism + FNetworking(Key)。Actor/Sound 恒带 FCpuInterpTag(宿主恒 CPU 插值);Agent 无。纪律:组合必须与对应 SpawnXxxHost 网络新建分支完全一致,否则恢复出的宿主掉出处理器查询。

Five single-key skeleton template builders with one composition pattern: FHostControllerTag + FNetworkTag + FMainType(Host) + the kind's fragment (FProjectileConfig_Final / FLootConfig_Final / FActorSpawnConfig_Final / FSoundConfig_Final / FAgentHostConfig_Final) + FHostHierarchy + FDeterminism + FNetworking(Key). Actor/Sound always carry FCpuInterpTag; Agent does not. Rule: the composition MUST match the corresponding networked SpawnXxxHost new branch exactly, otherwise restored hosts fall out of processor queries.

Input
参数 Param类型 Type说明 Description
KeyFName骨架键("ProjectileHost" / "LootHost" / "ActorHost" / "SoundHost" / "AgentHost")。Skeleton key ("ProjectileHost" / "LootHost" / "ActorHost" / "SoundHost" / "AgentHost").
Output

返回 FEntityTemplateData(内部模板 MakeShared 共享)。

Returns FEntityTemplateData (inner template shared via MakeShared).

RegisterFxSkeletonTemplates / RegisterProjectileSkeletonTemplates / RegisterLootSkeletonTemplates / RegisterActorSkeletonTemplates / RegisterSoundSkeletonTemplates / RegisterAgentSkeletonTemplates static void

六个骨架模板幂等注册入口:把各自骨架(FxHost / FxHost_CPU / FxEntity; ProjectileHost; LootHost; ActorHost; SoundHost; AgentHost)经 RegisterNetworkTemplateData 注册进网络快照注册表(重复进入返回已有注册)。全部由 UMassBattleNetworkSubsystem::Initialize 调用一次——先于任何 peer 应用任何快照。

Six idempotent skeleton registration entries: register their skeletons (FxHost / FxHost_CPU / FxEntity; ProjectileHost; LootHost; ActorHost; SoundHost; AgentHost) into the network snapshot registry via RegisterNetworkTemplateData (re-entry returns the existing registration). All called once from UMassBattleNetworkSubsystem::Initialize — before any snapshot is applied on any peer.

Input
参数 Param类型 Type说明 Description
NetUMassBattleNetworkSubsystem&网络子系统,提供 RegisterNetworkTemplateData。Network subsystem providing RegisterNetworkTemplateData.
WorldContextconst UObject*世界上下文,透传。World context, forwarded.
Output

无返回值。副作用:注册表获得对应骨架模板 Key。

No return value. Side effects: the registry gains the skeleton template keys.

ClearAllPools void

销毁所有池内实体并清空全部池与回收队列(工具方法,如关卡拆除)。收集所有休眠句柄后经 UMassAPIFuncLib::DestroyEntities 批量销毁;同时丢弃 pending 回收条目与 host 生成 gatherer 中可能携带快照前帧的过期句柄。注释:不再于快照边界调用——池已是快照状态(恢复放回 pass 重建)。

Destroys every pooled entity and empties all pools + recycle queues (utility, e.g. level teardown). Collects all dormant handles, destroys them via UMassAPIFuncLib::DestroyEntities, and drops pending recycle entries and pre-snapshot stale handles in the spawn gatherers. No longer called at the snapshot boundary — pools are snapshot state now (restore push-back pass rebuilds them).

Input

无参数。

No parameters.

Output

无返回值。副作用:全部池与回收队列清空,池内实体销毁。

No return value. Side effects: all pools and recycle queues cleared; pooled entities destroyed.

ReturnPooledHost void

快照恢复路径:把重建的休眠宿主放回对应类型池。堆 push 序无关紧要——等内容的双端 max-heap 弹池恒取同一最大 UID 实体(恢复放回 = 快照内容 = 服务器池内容);恢复端按 (类型, UID) 升序调用 = 服务器 UID 升序池序 → LIFO 弹池对齐。

Snapshot restore path: pushes a rebuilt dormant host back into its pool. Heap push order is irrelevant — max-heap pops pick the same largest-UID entity from equal content (restore push-back = snapshot content = server pool content); restore iterates (type, UID) ascending = the server's UID-sorted pool order → LIFO pop parity.

Input
参数 Param类型 Type说明 Description
TypeEHostEntityType实体类别。Entity type.
EntityFMassEntityHandle重建的休眠宿主。Rebuilt dormant host.
Output

无返回值。副作用:实体入池(持锁)。

No return value. Side effects: entity pushed into the pool (locked).

ReturnPooledProjectile / ReturnPooledLoot void

快照恢复路径:把重建的休眠弹丸/战利品实体放回其按 DA 分组的池(镜像回收段的池推入,单线程)。DA 非空时按实体 UID 推入对应桶。

Snapshot restore paths: push a rebuilt dormant projectile/loot entity back into its per-DA pool (mirrors the recycle-drain pool push, single-threaded). Pushed into the bucket keyed by the DA when the DA is non-null.

Input
参数 Param类型 Type说明 Description
DataAssetUMassBattleXxxConfigDataAsset*数据资产,池桶键。Data asset, pool bucket key.
EntityFMassEntityHandle重建的休眠实体。Rebuilt dormant entity.
Output

无返回值。副作用:实体入池(持锁)。

No return value. Side effects: entity pushed into the pool (locked).

ClearPoolArraysForRestore void

恢复路径:resync 的 DestroyQuery 已销毁全部带 FNetworkTag 的池内实体,池数组全是失效句柄——清空它们(三个池族),让放回 pass 纯粹按 (类型, UID) 从 payload 重建池。

Restore path: the resync DestroyQuery destroyed every pooled entity (they carry FNetworkTag), so all pool arrays hold stale handles — empty them (all three pool families) so the push-back pass rebuilds pools purely from the payload in (type, UID) order.

Input

无参数。

No parameters.

Output

无返回值。副作用:清空全部池数组(持锁)。

No return value. Side effects: all pool arrays emptied (locked).

PopProjectileFromPool / PopLootFromPool FMassEntityHandle

从按 archetype 池弹一个休眠实体。仅限单线程上下文(调用方分别是 ProcessHostOpsQueues 的弹丸/战利品段与 TryReuseProjectileFromPool)——确定性弹池序。max-heap 弹最大 UID 实体,锁步同步内容下双端一致。池空或 DA 无效返回无效句柄(调用方回落新建)。

Pops one dormant entity from the per-archetype pool. Single-threaded only (callers are the projectile/loot stages of ProcessHostOpsQueues and TryReuseProjectileFromPool) — deterministic pop order. The max-heap pops the largest-UID entity, identical on both peers from lockstep-synchronized content. Returns an invalid handle when the pool is empty or the DA is null (caller falls back to building fresh).

Input
参数 Param类型 Type说明 Description
DataAssetUMassBattleXxxConfigDataAsset*数据资产,选择池桶。Data asset selecting the pool bucket.
Output

返回休眠实体句柄;池空时无效句柄。副作用:FromPool 统计 +1。

Returns the dormant entity handle, or an invalid handle when the pool is empty. Side effects: FromPool stat +1.

PopAudioComponentFromPool UAudioComponent*

为给定 Sound 资产弹一个已停止的 UAudioComponent(2D/3D 池按参数选择)。逐项弹出直至找到有效组件或池空——组件可能在回收与复用之间被 GC(Sound 资产被卸载),顺带以同锁步方式弹出 Cooldowns 保持双数组等长不变量。池空返回 nullptr(调用方回落 UGameplayStatics::SpawnSound*)。仅游戏线程。

Pops a stopped UAudioComponent for the given Sound asset (2D/3D pool selected by argument). Pops entries until a live one is found or the pool empties — components may have been GC'd between recycle and reuse (sound asset unloaded); Cooldowns is popped in lockstep to keep the twin-array invariant. Returns nullptr when the pool is empty (caller falls back to UGameplayStatics::SpawnSound*). Game-thread only.

Input
参数 Param类型 Type说明 Description
SoundUSoundBase*声音资产,池键;空指针直接返回 nullptr。Sound asset, pool key; null returns nullptr immediately.
b2Dbooltrue 用 2D 池,false 用 3D 池。true = 2D pool, false = 3D pool.
Output

返回可用组件或 nullptr。副作用:FromPool 统计 +1。

Returns the reusable component or nullptr. Side effects: FromPool stat +1.

RecycleAudioComponent void

把已停止的音频组件推回池。调用方须已对组件调用 Stop()。池无上限增长,冷却 drain 回收空闲条目。每次 push 把冷却重置为统一的 PoolIdleLifeSpan。

Pushes a stopped audio component back to the pool. The caller is responsible for having already called Stop() on the component. The pool grows unbounded; the cooldown drain reclaims idle entries. Cooldown resets to the unified PoolIdleLifeSpan on every push.

Input
参数 Param类型 Type说明 Description
SoundUSoundBase*声音资产,池键。Sound asset, pool key.
CompUAudioComponent*已停止的组件(无效则返回)。Stopped component (invalid ones return).
b2Dbool选择 2D/3D 池。Selects the 2D/3D pool.
Output

无返回值。副作用:组件入池,双数组同步追加。

No return value. Side effects: component pooled; both arrays appended in lockstep.

GetPoolCount int32

返回指定池当前可用实体数。注意:读取的 TArray 可能正被 ProcessSpawnQueues 或 AllocateHostEntity 修改——在 spawn 处理器(并行)上下文中这是启发式检查,非严格值。

Returns the current number of available entities in the specified pool. Note: this reads a TArray that may be modified by ProcessSpawnQueues or AllocateHostEntity — in the spawn processor (parallel) context this is a heuristic check, not strict.

Input
参数 Param类型 Type说明 Description
TypeEHostEntityType实体类别。Entity type.
Output

返回池内条目数(含可能失效的句柄)。

Returns the pool entry count (may include stale handles).

AddRestoredActiveSoundHost void

快照重建(resync)期间收集一个恢复的活跃(非池)Sound 宿主。重建 pass 已遍历全部宿主,无需独立查询。键组装必须与 MakeSoundConcurrencyKey 完全一致("A:" + 路径 + bLimitToOwner 时的 "|O:" + 属主 UID)。由 UMassBattleNetworkSubsystem 恢复循环调用。

Collects one restored ACTIVE (non-pooled) Sound host during snapshot rebuild (resync). The rebuild pass already walks every host, so no standalone query is needed. Key assembly must mirror MakeSoundConcurrencyKey exactly ("A:" + path + "|O:" + owner UID when bLimitToOwner). Called by the UMassBattleNetworkSubsystem restore loop.

Input
参数 Param类型 Type说明 Description
SoftPathconst FString&Sound 资产软路径。Sound asset soft path.
bLimitToOwnerbool是否按属主分组计数。Whether to count per owner.
OwnerUIDint32属主实体 UID。Owner entity UID.
UIDint32宿主自身 UID。The host's own UID.
StartTimefloat创建时刻(SimulationTime)。Creation time (SimulationTime).
Output

无返回值。副作用:向 ActiveSoundHostUIDs 对应组追加 (UID, StartTime) 对。

No return value. Side effects: appends a (UID, StartTime) pair to the matching ActiveSoundHostUIDs group.

FinalizeSoundConcurrencyRebuild void

重建循环结束后提交并发状态:清空触发历史(LastTriggerTimeByOwner——触发历史不跨 resync),并把每组按 (StartTime, UID) 排序——与捕获端插入保持的顺序一致,StopOldest 双端扫描同序。

Commits the concurrency state after the rebuild loop: clears the trigger history (LastTriggerTimeByOwner — trigger history does not survive a resync) and sorts every group by (StartTime, UID) — the same order the capture side maintains on insert, so StopOldest scans identically on both peers.

Input

无参数。

No parameters.

Output

无返回值。副作用:清空触发历史,各组排序。

No return value. Side effects: trigger history cleared; groups sorted.

TickEntityPoolCooldowns void

对按 archetype 弹丸/战利品池与按 Sound 音频组件池逐条目递减冷却。弹丸/战利品桶:两遍清扫(先递减、后删除)保证每条目恰好递减一次(堆形状双端本就不同,就地删除会把已访问条目换入未访问槽 → 重复/漏递减 → PoolCountdown 失步);失效句柄直接丢弃;冷却到期条目无条件移除并入 EntitiesToDestroyQueue(无下限,桶可缩到 0)。音频池:逐条目递减,过期组件无条件 DestroyComponent,Components/Cooldowns 双数组同锁步移除;防御性对齐双数组长度。由 ExecuteTick 每 MB tick 调用一次,仅游戏线程。

Ticks each entry's cooldown across the per-archetype projectile/loot pools and per-sound audio component pools. Projectile/loot buckets: a two-phase sweep (decrement pass, then removal pass) so every entry is decremented exactly once (heap shape legitimately differs per peer; in-place removal would swap already-visited entries into unvisited slots → double/missed decrements → PoolCountdown desync); stale handles are discarded; expired entries are removed unconditionally and queued into EntitiesToDestroyQueue (no floor — buckets can shrink to 0). Audio pools: each cooldown is decremented; expired components get DestroyComponent unconditionally and both arrays are trimmed in lockstep; array lengths are defensively re-synced. Called once per MassBattle tick from ExecuteTick. Game-thread only.

Input
参数 Param类型 Type说明 Description
DeltaTimefloat本 tick 步长(秒)。Tick step in seconds.
Output

无返回值。副作用:过期实体入销毁队列;过期组件被销毁;池桶收缩。

No return value. Side effects: expired entities queued for destroy; expired components destroyed; buckets shrink.

ResetPoolTickStats void

清零 tick 统计(实现中循环索引 0..5 共 6 个 host 池统计,加弹丸/战利品/音频各一)。由 UMassBattleSubsystem::Tick 在模拟阶段之前调用,先于级间生成,使统计反映本帧活动。

Resets the pool tick stats (the implementation loops indices 0..5 — six host pool stats — plus projectile/loot/audio). Called by UMassBattleSubsystem::Tick before the sim stages, preceding inter-stage spawns so the stats reflect this frame's activity.

Input

无参数。

No parameters.

Output

无返回值。副作用:清零统计。

No return value. Side effects: stats zeroed.

RecordProjectileEntityFreshBuild / RecordLootEntityFreshBuild / RecordAudioComponentFreshSpawn FORCEINLINE void

三个 Fresh 计数记录器(原子加/自增),供实体级池的新建路径(ProcessHostOpsQueues 的补齐分支与音频新建分支)记账——这类池的新建不在 AllocateHostEntity 内,故需单独记录。

Three atomic Fresh-counter recorders for the entity-level pool fresh-build paths (the ProcessHostOpsQueues shortfall branches and the audio fresh-spawn branch) — these builds don't flow through AllocateHostEntity, so they are tallied separately.

Input
参数 Param类型 Type说明 Description
Countint32新增数量,默认 1(仅实体级两个记录器有)。Fresh count, default 1 (entity-level recorders only).
Output

无返回值。副作用:对应统计 +Count/+1。

No return value. Side effects: the matching stat is incremented.

GetTotalProjectileEntityPoolSize / GetTotalLootEntityPoolSize / GetTotalAudioComponentPoolSize int32 (const)

三个总计查询:汇总所有按 archetype 桶 / 2D+3D 音频池的休眠条目数,供调试打印(非热路径)。

Three total queries summing dormant entries across all per-archetype buckets / 2D+3D audio pools for the debug printer (not a hot-path call).

Input

无参数。

No parameters.

Output

返回对应池族总条目数。

Returns the total entry count of the pool family.

GetOrCreateProjectileArchetypeTemplate / GetOrCreateLootArchetypeTemplate FMassEntityTemplateData*

按数据资产缓存 archetype-only 模板(DA 静态状态,无逐生成数据)。首次访问经 MakeProjectileTemplateFromDataAsset / MakeLootTemplateFromDataAsset 构建并缓存,供 ProcessHostOpsQueues 的 BatchCreate 复用——消除逐 Config 模板构建。缓存失效(IsValid 为假)时重建。调用方不得在下次世界重置后保留返回指针。

Caches an archetype-only template per data asset (DA-driven static state, no per-spawn data). Built lazily from MakeProjectileTemplateFromDataAsset / MakeLootTemplateFromDataAsset on first access and reused by ProcessHostOpsQueues for BatchCreate — eliminates per-Config template construction. Rebuilt when the cache entry goes invalid. Callers must not retain the pointer past the next world reset.

Input
参数 Param类型 Type说明 Description
DataAssetUMassBattleXxxConfigDataAsset*数据资产;无效返回 nullptr。Data asset; null returns nullptr.
Output

返回缓存模板指针;DA 无效或构建失败返回 nullptr。

Returns the cached template pointer, or nullptr when the DA is invalid or the build fails.

SpawnActorBatch / SpawnFxBatch / SpawnSoundBatch void

自身帧(尊重 bAttached)批量生成助手(Appear/Hit/Death Actor/FX/Sound)。逐配置:动画过滤(BindToAnimIndex)、bEnable 与资产非空过滤;拷贝为 XxxConfig_Final 并覆写 OwnerEntity、按 RandHelper(MAX_int32) 播种随机流、可选覆写行为状态、Delay /= SpeedMultiplier;附着时经 LocalOffsetToWorld 计算 SpawnTransform 与 InitialRelativeTransform,否则仅位置。随后走并行池直取路径(仅非确定性 !bDeterministic):弹池命中且槽干净 → 仅写 fragment(每实体唯一写者,零 mutation;池实体已带固定 UID,弹取不消费全局计数器,顺序无关);脏槽回收回落 gatherer;池空回落 gatherer。Sound 版带并发配置的请求必须走串行 drain(裁决在游戏线程,池直取在 worker 线程不能碰 ActiveSoundHostUIDs)。最终以 (TriggerUID, SeqInOut++) 入队对应生成 gatherer。

Self-frame (bAttached-respecting) batch spawn helpers (Appear/Hit/Death Actor/FX/Sound). Per config: anim filter (BindToAnimIndex), bEnable and asset-non-null filters; copies into XxxConfig_Final and overwrites OwnerEntity, seeds the random stream via RandHelper(MAX_int32), optionally overrides the behavior state, applies Delay /= SpeedMultiplier; attached configs get SpawnTransform + InitialRelativeTransform via LocalOffsetToWorld, otherwise location-only. Then the parallel pool-direct path (non-deterministic only): pool hit with a clean slot → fragment write only (unique writer, no mutation; pooled entities carry a fixed UID, so popping never consumes the global counter — order-independent); dirty slots are recycled back to the gatherer; pool-empty falls through to the gatherer. The Sound variant routes concurrency-enabled requests through the serial drain (adjudication lives on the game thread; worker threads cannot touch ActiveSoundHostUIDs). Finally enqueues (TriggerUID, SeqInOut++) into the matching spawn gatherer.

Input
参数 Param类型 Type说明 Description
Fconst FSpawnFrame&批次共享输入(坐标系/随机源/通用字段)。Batch-shared inputs (frames/random/common fields).
Configsconst TArray<FXxxConfig>&配置数组。Config array.
SeqInOutint32&触发实体内序列计数器,每次入队 ++(保证同触发实体内全序)。Per-trigger sequence counter, incremented per enqueue (total order within one trigger).
Output

无返回值。副作用:非确定性路径可能直接复用池槽;其余请求入生成 gatherer 供串行 drain 消费。

No return value. Side effects: the non-deterministic path may reuse pool slots directly; other requests enter the spawn gatherers for the serial drain.

SpawnActorBatchWithOrigin / SpawnFxBatchWithOrigin / SpawnSoundBatchWithOrigin / SpawnProjectileBatchWithOrigin void

ESpawnOrigin 驱动(AtSelf/AtTarget)的批量生成助手(Attack 系列,由 MassBattleAgentBehaviorProcessor 调用)。AtSelf:附着 OwnerEntity,以自身帧计算变换;AtTarget:目标实体须有效且带 FRotating(目标完整旋转,统一),附着 TargetEntity,以目标位置+自身帧旋转计算变换。过滤、随机播种、池直取与入队逻辑同 SpawnActorBatch 系列。Projectile 版额外写入 TargetEntity / ToPoint,并从目标 FMoving 读 TargetVelocity;弹丸无 UObject,无脏守卫。

Origin-driven (AtSelf/AtTarget) batch spawn helpers (the Attack series, called by MassBattleAgentBehaviorProcessor). AtSelf: attaches to OwnerEntity and computes the transform in the self frame. AtTarget: requires a valid target with FRotating (full target rotation, unified), attaches to TargetEntity and computes the transform from the target location plus the self-frame rotation. Filtering, seeding, pool-direct and enqueue logic match the SpawnActorBatch series. The Projectile variant additionally writes TargetEntity / ToPoint and reads TargetVelocity from the target's FMoving; projectile slots carry no UObject, so there is no dirty guard.

Input
参数 Param类型 Type说明 Description
Fconst FSpawnFrame&批次共享输入。Batch-shared inputs.
Configsconst TArray<FXxxConfig_Attack>&带 SpawnOrigin 的配置数组(Projectile 版为 FProjectileConfig)。Config array with SpawnOrigin (FProjectileConfig for the Projectile variant).
SeqInOutint32&触发实体内序列计数器。Per-trigger sequence counter.
Output

无返回值。副作用:同 SpawnActorBatch 系列(池直取或入队)。

No return value. Side effects: same as the SpawnActorBatch series (pool-direct or enqueue).

SpawnLootBatch void

战利品批量生成助手(自身帧,无附着——战利品自由掉落;Death loot,由 MassBattleAgentReactionProcessor 调用)。无动画过滤(FLootConfig 无 BindToAnimIndex);写入 FromPoint / FlowFieldPtr / FlowFieldSoftPtr(快照友好软来源);SpawnTransform 恒为 LocalOffsetToWorld 结果。

Loot batch spawn helper (self-frame, no attach — loot drops free; Death loot, called by MassBattleAgentReactionProcessor). No anim filter (FLootConfig has no BindToAnimIndex); writes FromPoint / FlowFieldPtr / FlowFieldSoftPtr (snapshot-friendly soft source); SpawnTransform is always the LocalOffsetToWorld result.

Input
参数 Param类型 Type说明 Description
Fconst FSpawnFrame&批次共享输入。Batch-shared inputs.
Configsconst TArray<FLootConfig>&战利品配置数组。Loot config array.
SeqInOutint32&触发实体内序列计数器。Per-trigger sequence counter.
Output

无返回值。副作用:同 SpawnActorBatch 系列。

No return value. Side effects: same as the SpawnActorBatch series.

LinkHostChild bool

把已有 Host 实体链接为另一 Host 实体的子节点。校验:两句柄有效、非同一实体、均带 FHostControllerTag;子节点必须尚无父级(AttachmentSource == WorldAnchor);从 ParentHost 向上遍历检测环(遇到 ChildHost 或重复访问即拒绝)。成功后写子节点的层级字段(AttachmentSource = ParentHost + AttachmentEntity + ParentHost),把相对变换写入子节点所属类别配置(InitialRelativeTransform + bAttached = true),并以头插维护父级的侵入式子链表。

Links an existing Host entity as a child of another Host entity. Validates: both handles valid, not the same entity, both carry FHostControllerTag; the child must not already have a parent (AttachmentSource == WorldAnchor); walks up from ParentHost to detect cycles (rejects when ChildHost or an already-visited handle is encountered). On success writes the child's hierarchy fields (AttachmentSource = ParentHost + AttachmentEntity + ParentHost), writes the relative transform into whichever config fragment the child has (InitialRelativeTransform + bAttached = true), and inserts at the head of the parent's intrusive child list.

Input
参数 Param类型 Type说明 Description
ParentHostFMassEntityHandle父宿主。Parent host.
ChildHostFMassEntityHandle子宿主(须尚无父级)。Child host (must be parentless).
RelativeTransformconst FTransform&子节点相对父级的变换。Child's transform relative to the parent.
Output

返回是否成功链接(校验失败/环/子已有父级 → false)。副作用:修改子节点层级与配置 fragment、父级子链表。

Returns whether the link succeeded (false on validation failure / cycle / child already parented). Side effects: mutates the child's hierarchy and config fragments, and the parent's child list.

UnlinkHostChild bool

把子 Host 从父级解绑,提升为新 WorldAnchor 根;其子树保持不变(子节点仍通过 ParentHost 指向此 Host)。校验:句柄有效、带 FHostControllerTag、确为 ParentHost 子节点。经 O(1) 拼接从父级侵入式子链表移除(含头指针更新),随后清空子节点的全部层级字段。

Unlinks a child Host from its parent, promoting it to a new WorldAnchor root; its subtree remains intact (children still point to this Host via ParentHost). Validates: valid handle, carries FHostControllerTag, is a ParentHost child. Removes from the parent's intrusive child list via O(1) splice (including the head-pointer update), then clears all of the child's hierarchy fields.

Input
参数 Param类型 Type说明 Description
ChildHostFMassEntityHandle待解绑子宿主。Child host to unlink.
Output

返回是否成功解绑(校验失败/非 ParentHost 子节点 → false)。副作用:修改父级子链表与子节点层级。

Returns whether the unlink succeeded (false on validation failure / not a ParentHost child). Side effects: mutates the parent's child list and the child's hierarchy.

成员变量 Members

子系统缓存 (UPROPERTY, mutable)

名称 Name类型 Type默认值说明 Description
CurrentWorldTObjectPtr<UWorld>nullptr当前世界缓存,首次惰性访问时记录。Current world cache, recorded on first lazy access.
MassAPISubsystemTObjectPtr<UMassAPISubsystem>nullptrMass API 子系统缓存。Cached Mass API subsystem.
MassBattleSubsystemTObjectPtr<UMassBattleSubsystem>nullptrMassBattle 主子系统缓存。Cached MassBattle main subsystem.
MassBattleLootSubsystemTObjectPtr<UMassBattleLootSubsystem>nullptrLoot 子系统缓存。Cached Loot subsystem.
MassBattleProjectileSubsystemTObjectPtr<UMassBattleProjectileSubsystem>nullptrProjectile 子系统缓存。Cached Projectile subsystem.
MassBattleFxSubsystemTObjectPtr<UMassBattleFxSubsystem>nullptrFx 子系统缓存。Cached Fx subsystem.

操作与生成队列 (FParallelGatherer)

名称 Name类型 Type默认值说明 Description
ActorOpsFParallelGatherer<FActorOptCommand>—Actor UObject 操作队列(Spawn/Destroy/Transform),每 tick 由 ProcessHostOpsQueues 排空。Actor UObject op queue (Spawn/Destroy/Transform), drained each tick by ProcessHostOpsQueues.
FxOpsFParallelGatherer<FFxOptCommand>—FX UObject 操作队列。FX UObject op queue.
DeferredUObjectDestroysTArray<FDeferredUObjectDestroyOp>—Destroy op 延迟收集的 UObject 释放——由 ProcessDeferredUObjectDestroys 在渲染后统一移除阶段排空。仅游戏线程(串行填充/排空)。UObject releases deferred from the Destroy op cases — drained by ProcessDeferredUObjectDestroys in the unified post-render removal phase. Game-thread only (filled/drained serially).
FxCompletionCheckEntitiesFParallelGatherer<FMassEntityHandle>—须在游戏线程检查 UObject 组件完成状态(HasCompleted/IsComplete)的实体(由 MassBattleHostMonoProcessor 推入)。Entities whose UObject component completion (HasCompleted/IsComplete) must be checked on the game thread (pushed by MassBattleHostMonoProcessor).
SoundOpsFParallelGatherer<FSoundOptCommand>—Sound UObject 操作队列。Sound UObject op queue.
ProjectileOpsFParallelGatherer<FProjectileOptCommand>—弹丸操作队列。Projectile op queue.
ProjectileSpawnCacheTArray<FProjectileConfig_Final*>—弹丸 ops 段按排序序填充的配置指针缓存。Config pointer cache filled in sorted order by the projectile ops stage.
LootOpsFParallelGatherer<FLootOptCommand>—战利品操作队列。Loot op queue.
LootSpawnCacheTArray<FLootConfig_Final*>—战利品 ops 段的配置指针缓存。Config pointer cache for the loot ops stage.
ActorHostSpawns … FxEntitySpawnsFParallelGatherer<FXxxHostSpawnRequest>—六类 host 生成请求 gatherer(Actor/Fx/Sound/Projectile/Loot/FxEntity),并行收集、ProcessHostOpsQueues 按 (TriggerUID, Sequence) 排序串行排空。Six host spawn request gatherers (Actor/Fx/Sound/Projectile/Loot/FxEntity); gathered in parallel, drained serially by ProcessHostOpsQueues sorted by (TriggerUID, Sequence).
ActorRenderInterpEntities / FxRenderInterpEntities / SoundRenderInterpEntitiesTArray<FMassEntityHandle>—逐帧渲染插值追踪——需 CPU 侧预测的附着宿主实体。生成时加入,销毁时移除。Per-frame render interp tracking — entities of attached hosts needing CPU-side prediction. Populated at spawn, removed at destroy.
HostEntityRecycleQueueFParallelGatherer<FRecycleRequest>—宿主回收请求队列,MB tick 末端入池。Host recycle request queue; drained into pools at the end of the MB tick.
ProjectileRecycleQueueFParallelGatherer<FProjectileRecycleRequest>—弹丸回收队列,按 DA 分组入池。Projectile recycle queue; drained into per-DA pools.
LootRecycleQueueFParallelGatherer<FLootRecycleRequest>—战利品回收队列。Loot recycle queue.

池配置 (UPROPERTY Config, 策划可调)

名称 Name类型 Type默认值说明 Description
PoolIdleLifeSpanfloat15.0f所有 MassBattle 池的统一闲置倒计时(取代旧的 7 个 PoolLifeSpan* 与 3 个 Cooldown* 配置)——宿主池(HostMonoProcessor 全部 6 类 Reset(float) 调用点经 PoolCountdown 打点)、按原型的弹丸/战利品实体池(回收推入时写 FProjectileParamsRT/FLootParamsRT 的 PoolCountdown)与音效组件池(推入时写 Cooldowns)。过期条目无条件销毁(无下限,池可缩到 0)。锁步双端 ini 必须保持同值——池内状态生命周期参与快照/hash。单位:秒。UNIFIED idle countdown for ALL MassBattle pools (replacing the former 7 PoolLifeSpan* and 3 Cooldown* configs) — host pools (all 6 host config Reset(float) call sites in HostMonoProcessor stamp it via PoolCountdown), per-archetype projectile/loot entity pools (FProjectileParamsRT/FLootParamsRT PoolCountdown on recycle push), and the audio component pools (Cooldowns on push). Expired entries are destroyed unconditionally (no Min floor, pools shrink to 0). Lockstep peers MUST keep this value identical in their ini — pooled-state lifetimes feed the snapshot/hash. Unit: seconds.

音频组件池 (UPROPERTY)

名称 Name类型 Type默认值说明 Description
AudioComponentPool2DBySoundTMap<TObjectPtr<USoundBase>, FAudioComponentPool>—2D 音频组件池(SpawnSound2D 产生的非空间化组件)。组件 Stop() 后保留而非 DestroyComponent + 重新 Spawn。2D audio component pool (non-spatialized components from SpawnSound2D). Components are kept after Stop() instead of DestroyComponent + fresh spawn.
AudioComponentPool3DBySoundTMap<TObjectPtr<USoundBase>, FAudioComponentPool>—3D 音频组件池(SpawnSoundAtLocation 产生的空间化组件)。与 2D 分离,因为底层设置在运行时切换不便。3D audio component pool (spatialized components from SpawnSoundAtLocation). Separate from 2D because the underlying setup differs in ways awkward to switch at runtime.

私有池数据结构

名称 Name类型 Type默认值说明 Description
HostEntityPoolsTArray<TPair<int32, FMassEntityHandle>>[8]—八个按 EHostEntityType 索引的宿主实体池(FxCPU=6)。按 UniqueID 的大根堆:弹池恒选最大 UID 槽,pop 结果只取决于池内容而非 push 历史——双端无需每帧排序即弹同一实体。Eight host entity pools indexed by EHostEntityType (FxCPU=6). Max-heap by UniqueID: a pop always takes the largest-UID slot, so the result depends only on pool content, not push history — both peers pop the same entity without any per-tick sort.
PoolAllocationLockFCriticalSection—并行弹池临界区。Critical section for parallel pool allocation.
BatchMismatchScratchTArray<TPair<int32, FMassEntityHandle>>—AllocateHostEntityBatch 批量弹池的反网络类槽暂存(PoolAllocationLock 保护);成员级避免逐调用分配。仅 drain 路径使用。AllocateHostEntityBatch stash for opposite-network-class slots (guarded by PoolAllocationLock); member-level so the batch takes no per-call allocation. Drain path only.
ProjectilePoolsByDataAssetTMap<TObjectPtr<UMassBattleProjectileConfigDataAsset>, TArray<TPair<int32, FMassEntityHandle>>>—按 archetype 弹丸池。Key = 数据资产(唯一决定 archetype:MovementMode/DamageMode/SubType 全在资产上)。push(回收 drain)与 pop(ops 段)都在 MB tick 内游戏线程执行——纯 TArray;并行写经回收队列中转。桶 = 按 UID 大根堆。Per-archetype projectile pool. Key = data asset (uniquely determines the archetype: MovementMode/DamageMode/SubType all live on the asset). Both push (recycle drain) and pop (ops stage) run on the game thread inside the MB tick — a plain TArray; parallel writes go through the recycle queue. Bucket = max-heap by UniqueID.
ProjectileArchetypeTemplateCacheTMap<TObjectPtr<UMassBattleProjectileConfigDataAsset>, FEntityTemplateData>—按 DA 缓存的 archetype-only 模板(DA 静态状态,无逐生成数据),供 BatchCreate;逐生成 fragment 在并行写 pass 用 GetFragmentRef 写入,不经 BatchSetEntityFragmentValues。Cached archetype-only templates (DA-static state, no per-spawn data) for BatchCreate; per-spawn fragments are written via GetFragmentRef in the parallel write pass instead of BatchSetEntityFragmentValues.
LootPoolsByDataAssetTMap<TObjectPtr<UMassBattleLootConfigDataAsset>, TArray<TPair<int32, FMassEntityHandle>>>—按 archetype 战利品池,ProjectilePoolsByDataAsset 的镜像(一个 DA = 一个战利品 archetype)。Per-archetype loot pool; mirror of ProjectilePoolsByDataAsset (one DA = one loot archetype).
LootArchetypeTemplateCacheTMap<TObjectPtr<UMassBattleLootConfigDataAsset>, FEntityTemplateData>—按 DA 缓存的 archetype-only 战利品模板。Cached archetype-only loot templates per DA.
ActiveSoundHostUIDsTMap<FString, TArray<TPair<int32, float>>>—模拟层音效并发状态(派生,resync 重建):SoundKey("A:" + SoftSound 路径,跨端一致)→ 活跃(非池)Sound 宿主 (UniqueID, 创建 SimulationTime) 对,按激活序(Active[0] 最老)。回收移除、弹池重加。Simulation-layer sound concurrency state (derived, rebuilt on resync): SoundKey ("A:" + SoftSound path, deterministic across peers) → active (non-pooled) sound hosts as (UniqueID, creation SimulationTime) pairs, in activation order (Active[0] = oldest). Removed on recycle, re-added on pop.
LastTriggerTimeByOwnerTMap<FString, double>—RetriggerTime 门控:SoundKey(+ bLimitToOwner 时的属主后缀)→ 最后触发 SimulationTime。RetriggerTime gate: SoundKey (+ owner suffix when bLimitToOwner) → last trigger SimulationTime.

池 tick 统计 (调试)

名称 Name类型 Type默认值说明 Description
HostPoolTickStatsFPoolTickStats[8]—按 EHostEntityType 索引的宿主池统计。Host pool stats indexed by EHostEntityType.
ProjectileEntityPoolTickStatsFPoolTickStats—弹丸实体池统计。Projectile entity pool stats.
LootEntityPoolTickStatsFPoolTickStats—战利品实体池统计。Loot entity pool stats.
AudioComponentPoolTickStatsFPoolTickStats—音频组件池统计。Audio component pool stats.

管线角色 Pipeline Role

被谁驱动:UMassBattleSubsystem::Tick 是唯一协调器——模拟阶段前 ResetPoolTickStats;阶段边界调用 ProcessHostOpsQueues(每帧 5 次,全空快速路径零成本);随后各子系统 ExecuteTick 中 HostSub->ExecuteTick(内部调 TickEntityPoolCooldowns);帧末 ProcessProjectileRecycleQueue + ProcessLootRecycleQueue,再 UpdateHostRenderInterp。 渲染后统一移除阶段:渲染处理器(FxRender/AgentRender)画完垂死宿主的最后一帧后,Tick 依次调用 ProcessDeferredUObjectDestroys(UObject 释放先于实体销毁——配置片段仍在以便清理指针)→ ProcessDestroyQueues → FlushCommandBuffer,之后才采集 hash/快照(快照不含「尸体」)。 谁向它投递:处理器并行段直接写成员 gatherer——MassBattleHostMonoProcessor 向 ActorOps/FxOps/SoundOps/ProjectileOps/LootOps、FxCompletionCheckEntities、FxEntitySpawns、三条回收队列投递,并调用 UnlinkHostChild 解除已销毁宿主的父子链;MassBattleAgentBehaviorProcessor(Appear/Attack)、MassBattleAgentReactionProcessor(Hit/Death)、MassBattleLootMonoProcessor(OnBirth/OnCollectBegin)调用 SpawnXxxBatch 系列(经 GetRef 访问);ProcessHostOpsQueues 自身还调用 Debuff 子系统的 ProcessDebuffSpawnQueues(debuff 最先消费)。 骨架模板注册:六个 RegisterXxxSkeletonTemplates 由 UMassBattleNetworkSubsystem::Initialize 一次性调用,先于任何快照应用。 快照恢复:UMassBattleNetworkSubsystem 恢复 pass 调用 ClearPoolArraysForRestore + ReturnPooledHost/ReturnPooledProjectile/ReturnPooledLoot(按 (类型, UID) 升序)+ AddRestoredActiveSoundHost + FinalizeSoundConcurrencyRebuild 重建池与音效并发状态。

Driven by: UMassBattleSubsystem::Tick is the sole coordinator — ResetPoolTickStats before the sim stages; ProcessHostOpsQueues at stage boundaries (5×/frame, all-empty fast path costs nothing); then among the subsystem ExecuteTicks, HostSub->ExecuteTick (which calls TickEntityPoolCooldowns); end-of-frame ProcessProjectileRecycleQueue + ProcessLootRecycleQueue, then UpdateHostRenderInterp. Unified post-render removal phase: after the render processors (FxRender/AgentRender) draw every dying host's final frame, Tick calls ProcessDeferredUObjectDestroys (UObject releases first, while config fragments still exist for pointer cleanup) → ProcessDestroyQueues → FlushCommandBuffer, and only then captures hash/snapshot (the snapshot contains no "corpses"). Fed by: processors write the member gatherers directly from parallel sections — MassBattleHostMonoProcessor feeds ActorOps/FxOps/SoundOps/ProjectileOps/LootOps, FxCompletionCheckEntities, FxEntitySpawns and the three recycle queues, and calls UnlinkHostChild for destroyed attached hosts; MassBattleAgentBehaviorProcessor (Appear/Attack), MassBattleAgentReactionProcessor (Hit/Death) and MassBattleLootMonoProcessor (OnBirth/OnCollectBegin) call the SpawnXxxBatch series (via GetRef); ProcessHostOpsQueues itself calls the Debuff subsystem's ProcessDebuffSpawnQueues (debuffs consumed first). Skeleton registration: the six RegisterXxxSkeletonTemplates are called once from UMassBattleNetworkSubsystem::Initialize, before any snapshot is applied. Snapshot restore: the UMassBattleNetworkSubsystem restore pass calls ClearPoolArraysForRestore + ReturnPooledHost/ReturnPooledProjectile/ReturnPooledLoot (in (type, UID) ascending order) + AddRestoredActiveSoundHost + FinalizeSoundConcurrencyRebuild to rebuild pools and sound-concurrency state.

补充说明 Notes

① 池确定性纪律:所有池(max-heap)的弹池序只由内容决定——双端无需排序、无需逐帧全量排序(旧实现每帧 5 次,数千池内弹丸时每次 ~1ms);UID 分配只允许发生在固定的 drain 段序内,并行 lane 禁止直接调 AllocNextUID(原失步根因:同 tick 多死亡在并行线程以不同顺序分配 UID)。 ② 纯表现宿主(UID=-1、无 FNetworkTag)不消耗全局 UID 游标、不进 hash/快照/恢复;[RULE8] 禁止锁步宿主附着到纯表现宿主。 ③ 快照语义:池是快照状态——入池刻意保留 UID 映射,恢复端按 (类型, UID) 升序放回;resync 的 DestroyQuery 会销毁全部带网络 tag 的池内实体,故恢复前须 ClearPoolArraysForRestore。 ④ Sound 并发裁决在模拟层进行(按资产分组计数、StopOldest/StopLowestPriority 逐出 + MinPlayTime 保护),渲染完成时间(IsComplete/HasCompleted)跨端可能不同,故回收时机由确定性 LifeSpan 决定而非渲染状态。

① Pool determinism discipline: all pools (max-heaps) pop purely by content — no sort needed on either peer, no per-tick full sort (the old sort ran 5×/frame, ~1ms with thousands of pooled projectiles); UID allocation is allowed only inside the fixed drain stage order — parallel lanes must never call AllocNextUID directly (the original desync root cause: same-tick deaths allocated UIDs in divergent cross-thread order). ② Local-only hosts (UID=-1, no FNetworkTag) skip both global cursors, hash, snapshot and restore; [RULE8] forbids lockstep hosts attaching to local-only hosts. ③ Snapshot semantics: pools are snapshot state — UID mapping is deliberately kept on pool-in; the restore side pushes back in (type, UID) ascending order; the resync DestroyQuery destroys every networked pooled entity, so ClearPoolArraysForRestore must precede the push-back pass. ④ Sound concurrency adjudication lives in the simulation layer (per-asset group counting, StopOldest/StopLowestPriority eviction with MinPlayTime protection); render completion (IsComplete/HasCompleted) can differ across peers, so recycle timing is owned by the deterministic LifeSpan, never render state.