
参考文档
Iris 网络复制系统技术分析指南 - 大纲
本文档为 Iris 系统完整技术分析指南的大纲结构,分为多个独立部分,便于分步骤深入研究。
🔄 第零部分:概念对照表
💡 0.1 为什么需要概念对照?
从传统系统到 Iris 的"翻译表"
快速建立新旧概念对应关系
📊 0.2 核心概念对照表
🏗️ 架构层面对照(NetDriver → ReplicationSystem, ActorChannel → 已移除)
🎯 对象管理对照(bReplicates → FNetRefHandle, NetPriority → Prioritizer)
🔍 过滤与相关性对照(IsNetRelevantFor → Filter, NetViewer → ReplicationView)
⚡ 优先级对照(GetNetPriority → Prioritizer, 优先级累积机制)
📦 序列化对照(FArchive → NetBitStreamWriter, NetSerialize → NetSerializer)
🔄 脏数据检测对照(属性比较 → Poll + PushModel)
😴 休眠对照(NetDormancy → SetObjectWantsToBeDormant)
📡 RPC 对照(Server/Client/NetMulticast → SendRPC)
🌐 关卡流送对照(Level 可见性 → 组过滤状态)
🏗️ 0.3 架构对照图解
传统系统架构图(Actor → NetDriver → ActorChannel → NetConnection)
Iris 架构图(Actor → Bridge → ReplicationSystem → DataStream → NetConnection)
🔀 0.4 关键差异说明
1️⃣ Channel 概念的移除
2️⃣ 相关性检查的变化(虚函数 → 过滤器策略)
3️⃣ 优先级计算的变化(属性 → 可替换优先级器)
4️⃣ 脏数据检测的优化(每帧比较 → Push Model)
5️⃣ 序列化的专用化(FArchive → NetSerializer)
📋 0.5 迁移映射速查表
从传统代码迁移到 Iris 的等效代码对照
🎯 0.6 概念理解检查清单
🌐 第一部分:系统概述与架构设计
💡 1.1 Iris 简介
什么是 Iris(Iris Replication System)
⚙️ 如何启用 Iris
启用 Iris 插件(Engine/Plugins/Experimental/Iris/)
IrisCore 模块自动加载
插件配置文件(Iris.uplugin)
ShouldUseIrisReplication() / SetUseIrisReplication() API
🎯 设计目标与动机(高性能/可扩展性/灵活架构/精细控制/低延迟)
⚖️ 与传统 NetDriver 复制系统的对比
架构基础(Actor Channel → ReplicationSystem + Bridge)
状态管理(直接操作属性 → ReplicationState + Fragment)
序列化(FArchive → NetSerializer 专用量化)
过滤机制(IsNetRelevantFor() → 可替换 Filter 系统)
优先级机制(NetPriority → 可替换 Prioritizer 系统)
脏数据检测(每帧比较 → Push Model + 轮询频率控制)
内存布局(分散 → 连续内存块)
并行处理(有限支持 → 原生并行任务支持)
增量压缩(不支持 → 原生支持)
🎮 适用场景
大规模开放世界游戏
大逃杀/Battle Royale 类型
MMO 类型游戏
竞技类游戏
🏗️ 1.2 整体架构层次
架构分层图解(七层架构)
📋 各层职责划分
🎮 Layer 1: Game Layer(AActor, UActorComponent)
🔌 Layer 2: Engine Bridge(UEngineReplicationBridge)
🧩 Layer 3: Object Bridge(UObjectReplicationBridge)
🔗 Layer 4: Replication Bridge(UReplicationBridge)
🧠 Layer 5: Replication System(UReplicationSystem)
📦 Layer 6: Data Streams(UDataStream)
🌐 Layer 7: Network Transport(UNetConnection)
层级速查表
🔄 数据流向概览
📤 服务器端发送流程(PreSendUpdate → SendUpdate → PostSendUpdate)
📥 客户端接收流程(PreReceiveUpdate → ReadData → ApplyReplicatedState → PostReceiveUpdate)
💡 1.3 核心设计理念
📊 数据驱动设计(逻辑与对象分离)
🧱 缓存友好的内存布局(连续内存块 vs 分散数据)
⚡ 并行处理支持(PollAndCopy/过滤/优先级/序列化)
🔧 模块化可替换架构
UNetObjectFilter 过滤器接口
UNetObjectPrioritizer 优先级策略接口
内置过滤器(NopNetObjectFilter/FilterOutNetObjectFilter/NetObjectGridFilter/NetObjectConnectionFilter)
内置优先级策略(SphereNetObjectPrioritizer/SphereWithOwnerBoostNetObjectPrioritizer/FieldOfViewNetObjectPrioritizer/LocationBasedNetObjectPrioritizer/NetObjectCountLimiter)
📁 1.4 关键源文件索引
IrisConfig.h / ReplicationSystem.h / ReplicationBridge.h
ObjectReplicationBridge.h / EngineReplicationBridge.h
NetObjectFilter.h / NetObjectPrioritizer.h
NetRefHandle.h / ReplicationFragment.h
NetSerializer.h / DataStream.h / WorldLocations.h
🏗️ 第二部分:架构层次
2.1 七层架构总览
📦 从一个国际快递中心说起(物流类比)
七层架构图解
📦 快递物流比喻对照表
❓ 为什么要分层?(分层的好处)
📌 Bridge 层说明(第 2-4 层的继承关系)
🎮 2.2 游戏层 (Game Layer)
🤔 这一层是什么?
📋 游戏层的职责(声明属性/修改属性/处理通知)
🙅 你不需要关心的事情
🔄 游戏层与复制系统的交互
💻 代码示例:一个完整的可复制 Actor
🔌 2.3 引擎桥接层 (Engine Replication Bridge)
🤔 这一层是什么?(翻译官类比)
📋 UEngineReplicationBridge 的核心职责
Actor 生命周期管理
Component 管理
与 NetDriver 集成
🔄 Actor 生命周期管理(创建/销毁流程)
🔗 与 NetDriver 的集成(传统 vs Iris 复制路径、共存机制)
🔧 关键接口
🧩 2.4 对象桥接层 (Object Replication Bridge)
🤔 这一层是什么?(继承关系图解)
📋 UObjectReplicationBridge 的核心职责
过滤/优先级配置
轮询/脏数据检测
根对象与子对象管理
休眠 (Dormancy) 管理
🌳 根对象 vs 子对象
⚙️ 过滤和优先级配置(类型配置示例)
🔍 脏数据检测(轮询 vs 推送)
😴 休眠管理
🔗 2.5 复制桥接层 (Replication Bridge)
🤔 这一层是什么?(继承关系)
📋 UReplicationBridge 的核心职责
网络对象创建/销毁
子对象管理
关卡组管理
复制协议管理
🔧 关键概念(NetRefHandle/ReplicationProtocol/关卡组)
🧠 2.6 复制系统层 (Replication System)
🤔 这一层是什么?(快递分拣中心类比)
📋 UReplicationSystem 的核心职责
主更新循环 (NetUpdate)
连接管理
过滤系统
优先级系统
组管理
RPC 处理
🔄 主更新循环 (NetUpdate)(5 步流程)
🔗 连接管理(每个连接独立的状态)
🔍 过滤系统工作原理(大逃杀示例)
⭐ 优先级系统工作原理(带宽受限场景)
📦 2.7 数据流层 (Data Streams)
🤔 这一层是什么?(快递打包员类比)
📋 UDataStream 的核心职责
数据序列化
可靠/不可靠传输
带宽管理
🔄 序列化过程
✍️ ReplicationWriter 和 📖 ReplicationReader
✅ 可靠 vs ⚡ 不可靠传输
📊 带宽管理
🌐 2.8 网络传输层 (Network Transport)
🤔 这一层是什么?(快递员类比)
📋 UNetConnection 的职责
底层网络传输
连接状态管理
数据包管理
📨 网络数据包结构
🔗 连接状态(连接生命周期/心跳机制)
🔄 与上层的关系
🔄 2.9 数据流向概览
📤 发送流程(自上而下)- 7 层详细流程
📥 接收流程(自下而上)- 7 层详细流程
🌍 完整数据包旅程
📚 本章小结
七层架构总结表
🔑 核心要点
🏗️ 第三部分:核心数据结构
📦 前言:这些数据结构是干什么的?
🚚 快递公司 vs Iris 网络复制的类比
快递单号 → FNetRefHandle
包裹清单 → FReplicationStateDescriptor
快递员 → FReplicationFragment
配送协议 → FReplicationProtocol
📋 四个核心数据结构一句话总结表
🏷️ 3.1 FNetRefHandle(网络对象句柄)
📌 概述(网络对象的"身份证")
❓ 为什么需要 FNetRefHandle?(解决内存地址不同的问题)
🔢 位掩码常量详解
什么是位掩码?为什么需要它?
IdMask 的计算过程(60 位)
MaxReplicationSystemId 的计算过程(4 位)
位操作应用示例
为什么使用这种位布局设计?
🗂️ 句柄结构与位布局(64 位结构图解)
Id(60 位)、ReplicationSystemId(4 位)、Static Bit(1 位)
🔀 静态句柄 vs 动态句柄
静态句柄(关卡预放置对象,奇数 ID)
动态句柄(运行时生成对象,偶数 ID)
为什么要区分静态和动态?
🎮 ReplicationSystemId 的作用(PIE 多实例支持)
♻️ 句柄的生命周期管理
FNetRefHandleManager 管理器
AllocateNetRefHandle/CreateNetObject/DestroyNetObject
🎰 AllocateNetRefHandle 分配过程详解
MakeNetRefHandleId - 生成句柄 ID
MakeNetRefHandle - 组装完整句柄
GetNextNetRefHandleId - 获取下一个索引
分配流程图解
静态与动态句柄的 ID 序列
🎮 完整使用场景:服务器生成敌人 Actor
服务器端生成 Actor 并开始复制
服务器端发送数据给客户端
客户端接收并创建对象
后续同步
销毁对象
关键点总结
📝 3.2 ReplicationState(复制状态)
📌 概述(对象的"体检报告模板")
❓ 为什么需要 ReplicationStateDescriptor?
🔄 实际使用流程:检测和发送变化
轮询阶段 (Poll)
序列化阶段 (Serialize)
反序列化阶段 (Deserialize)
🔍 FReplicationStateDescriptor 结构详解
引用计数、状态查询
成员描述符数组(6 种描述符)
调试信息、大小和对齐
计数信息、标识符
构造/析构函数、特性标志
📍 MemberDescriptors 成员描述符
ExternalMemberOffset vs InternalMemberOffset
为什么有两个偏移?(示意图)
🔄 MemberSerializerDescriptors 序列化器描述符
为什么需要不同的序列化器?
常见序列化器类型(Int/Float/Vector/Rotator/Object/String)
✅ MemberChangeMaskDescriptors 变化掩码
变化掩码的工作原理(bit 位对应属性)
位流(BitStream)传输优势
🏷️ EReplicationStateTraits 特性标志
常用特性标志解释(InitOnly/HasLifetimeConditionals/HasObjectReference 等)
平凡构造/析构(Trivially Constructible/Destructible)详解
🔧 成员特性描述符(EReplicationStateMemberTraits)
🔗 对象引用描述符(FNetReferenceInfo/FReplicationStateMemberReferenceDescriptor)
🚚 3.3 ReplicationFragment(复制片段)
📌 概述(数据的"搬运工/快递员")
❓ 为什么需要 Fragment?
🔄 Fragment 的实际工作流程
服务器端 Poll(轮询检测变化)
客户端 Apply(应用接收到的状态)
🔗 Fragment 与其他组件的关系(完整关系图)
⚙️ Fragment 的作用与职责
ApplyReplicatedState/CollectOwner/CallRepNotifies/PollReplicatedState
🏷️ EReplicationFragmentTraits 特性
关键特性解释(CanReplicate/CanReceive/NeedsPoll/HasRepNotifies 等)
🔑 与游戏对象的绑定关系
FFragmentRegistrationContext 注册流程
📦 Fragment 类型
FPropertyReplicationFragment(标准 UPROPERTY 复制)
TFastArrayReplicationFragment(FastArray 增量更新)
FastArray Fragment 的优势
📖 3.4 ReplicationProtocol(复制协议)
📌 概述(整本说明书)
❓ 为什么需要 Protocol?(多种状态类型的组织)
📋 协议的定义与作用(FReplicationProtocol 结构)
🏷️ 协议特性(EReplicationProtocolTraits)
🎯 实例协议(FReplicationInstanceProtocol/EReplicationInstanceProtocolTraits)
🔗 协议匹配机制
匹配流程图解
为什么需要协议匹配?
🔄 版本兼容性处理
FReplicationStateIdentifier
兼容性检查流程
🏭 3.5 描述符构建器(Descriptor Builder)
📌 概述(从 UClass/UStruct 到 Descriptor 的工厂)
❓ 为什么需要 Builder?
🏗️ Builder 的两层结构(公开 API + 内部实现)
📖 FReplicationStateDescriptorBuilder(公开 API)
FParameters 参数结构
三种静态工厂方法(CreateDescriptorsForClass/CreateDescriptorForStruct/CreateDescriptorForFunction)
为什么 Class 会产生多个描述符(Init/Regular/Conditional 拆分)
🔧 FPropertyReplicationStateDescriptorBuilder(内部实现)
FMemberProperty 成员属性信息
FMemberCacheEntry 构建缓存
🔄 构建流程详解(9 阶段流程图)
BuildMemberCache / BuildMemberDescriptors / BuildMemberChangeMaskDescriptors 等
完整构建示例(AEnemy 类)
🔑 关键设计亮点(描述符复用/一次分配/引用计数/状态拆分/递归处理)
🔗 四个核心数据结构的关系总结
完整关系图
一句话总结每个结构的作用
🗺️ 数据结构关系图
Protocol → Descriptor → Fragment → Handle 关系图解
📁 关键源文件索引
NetRefHandle.h / ReplicationStateDescriptor.h
ReplicationStateDescriptorBuilder.h
ReplicationFragment.h / PropertyReplicationFragment.h
FastArrayReplicationFragment.h / ReplicationProtocol.h
NetRefHandleManager.h
📝 小结
FNetRefHandle(网络对象句柄)要点
FReplicationStateDescriptor(复制状态描述符)要点
FReplicationFragment(复制片段)要点
FReplicationProtocol(复制协议)要点
FReplicationStateDescriptorBuilder(描述符构建器)要点
🎓 下一步学习建议
第四部分:核心组件详解
4.1 UReplicationSystem
创建参数与初始化
主更新循环 (NetUpdate)
连接管理接口
对象管理接口
RPC 发送接口
4.2 UReplicationBridge
Bridge 的桥接作用
网络对象的创建与销毁
子对象管理
关卡组管理
4.3 UObjectReplicationBridge
UObject 复制管理
RootObject 与 SubObject
休眠 (Dormancy) 管理
轮询频率控制
依赖对象管理
4.4 UEngineReplicationBridge
Actor 复制接口
Component 复制接口
与 NetDriver 的集成
关卡流送支持
4.5 NetRefHandleManager
句柄分配与回收
对象索引管理
内部数据结构
第五部分:过滤系统 (Filtering)
5.1 过滤系统概述
过滤的目的与意义
过滤器类型分类
过滤流程时序
5.2 UNetObjectFilter 基类
Filter 接口定义
AddObject / RemoveObject
PreFilter / Filter / PostFilter
FilterTraits 特性
5.3 内置过滤器
NopNetObjectFilter(空操作过滤器)
FilterOutNetObjectFilter(始终过滤)
NetObjectGridFilter(空间网格过滤)
NetObjectConnectionFilter(连接过滤)
5.4 空间过滤器详解 (GridFilter)
网格划分算法
视图位置更新
剔除距离配置
性能优化策略
5.5 组过滤 (Group Filtering)
组的创建与销毁
包含组 vs 排除组
连接级别的组状态控制
关卡流送中的应用
5.6 过滤器配置
配置文件格式
类级别过滤器配置
FilterProfile 的使用
5.7 过滤系统内部实现
ReplicationFiltering(复制过滤核心)
ObjectScopeHysteresisUpdater(对象范围滞后更新器)
SharedConnectionFilterStatus(共享连接过滤状态)
第六部分:优先级系统 (Prioritization)
6.1 优先级系统概述
优先级的作用
静态优先级 vs 动态优先级
优先级计算时机
优先级值的含义
优先级累积机制
6.2 UNetObjectPrioritizer 基类
Prioritizer 接口定义
FNetObjectPrioritizationInfo(8字节设计)
Prioritize 参数详解
优先级计算流程
与过滤系统的协作
6.3 内置优先级器
LocationBasedNetObjectPrioritizer(位置基础类)
位置来源:WorldLocations vs RepTag_WorldLocation
位置分配与释放
SIMD 优化的位置操作
SphereNetObjectPrioritizer(球形距离优先级)
球形优先级原理(内球/外球/球外)
批处理架构
单视图/双视图/多视图 SIMD 优化实现
SphereWithOwnerBoostNetObjectPrioritizer(所有者加成)
FieldOfViewNetObjectPrioritizer(视野优先级)
视野锥优先级
视线胶囊(Line of Sight)
内球/外球区域
NetObjectCountLimiter(对象数量限制)
RoundRobin 模式(轮询)
Fill 模式(饥饿预防)
快速通道(OwnedObjectsFastLane)
两种模式对比
6.4 ReplicationView(复制视图)
视图定义(FReplicationView::FView)
视图更新流程
与 PlayerController 的关联
多视图支持(分屏游戏)
6.5 优先级配置
配置文件格式
类级别优先级器配置
6.6 优先级系统内部实现
ReplicationPrioritization(复制优先级核心)
TChunkedArrayWithChunkManagement(分块数组)
FPrioritizerBatchHelper(批处理辅助类)
FUpdateDirtyObjectsBatchHelper(脏对象批处理)
NotifyPrioritizersOfDirtyObjects 实现
UpdatePrioritiesForNewAndDeletedObjects 实现
InitPrioritizers 实现
Prioritize 主方法(5阶段流程)
PrioritizeForConnection 实现
连接管理方法(AddConnection/RemoveConnection)
SetStaticPriority 和 SetPrioritizer 实现
优先级累积机制
视图目标高优先级设置
性能优化策略(SIMD、批量处理、视图优化)
6.7 实际应用案例
FPS射击游戏配置
开放世界RPG配置
竞速游戏配置
大逃杀游戏配置
6.8 小结
知识点总结
优先级器继承关系
选择优先级器的建议
性能优化要点
内部实现关键点
调试技巧
第七部分:序列化系统 (Serialization)
📖 7.1 序列化系统概述
什么是序列化(乐高城堡类比)
Iris 内置序列化器分类(57个文件)
序列化 vs 量化的区别
序列化流程图解
🏗️ 7.2 FNetSerializer 结构详解
核心结构定义与元信息
核心序列化函数指针(Serialize / Deserialize)
增量压缩函数指针(SerializeDelta / DeserializeDelta)
量化函数指针(Quantize / Dequantize)
辅助函数指针(IsEqual / Validate)
动态状态管理(CloneDynamicState / FreeDynamicState)
引用收集(CollectNetReferences)
函数调用流程图解
ENetSerializerTraits 特性标志详解
函数参数结构详解
📐 7.3 量化 (Quantization) 深入解析
量化的目的与原理
量化的必要性分析(float 精度分析)
Rotator 量化实战案例
量化精度对照表
📦 7.4 内置序列化器详解
7.4.1 整数序列化器(IntNetSerializers)
整数序列化器家族
序列化实现 - 零值优化
位数分析
7.4.2 打包整数序列化器(PackedIntNetSerializers)
智能压缩原理
字节数编码
7.4.3 浮点数序列化器(FloatNetSerializers)
零值优化
7.4.4 Rotator 序列化器
标志位编码
位数分析
📝 7.5 自定义 NetSerializer 实现指南
实现步骤概览
完整示例:自定义血量序列化器
定义配置(头文件)
实现序列化器(源文件)
在游戏代码中使用
📡 7.6 BitStream 读写详解
BitStream 的设计理念
字节对齐 vs 比特对齐
FNetBitStreamWriter 详解
FNetBitStreamReader 详解
🔄 7.7 增量压缩 (Delta Compression) 深入解析
什么是增量压缩
增量压缩原理详解
全量序列化 vs 增量序列化对比
Delta 位计数表详解
编码流程
🎭 7.8 ChangeMask (变化掩码) 系统
ChangeMask 的作用
ChangeMask 工作原理
ChangeMask 数据结构
智能存储(内联 vs 堆分配)
内存布局优化
📦 7.9 数组序列化器深入解析 (FArrayPropertyNetSerializer)
数组序列化器的设计挑战
元素级脏检测
数组增删改的处理
性能优化策略
📝 7.10 字符串与名称序列化器详解
FStringNetSerializer
动态状态管理
UTF-8 编码优化
FNameNetSerializer
EName 优化(硬编码名称)
名称缓存机制
🔄 7.11 Rotator 序列化器变体详解
FRotatorNetSerializer(Short 精度)
FRotatorAsByteNetSerializer(Byte 精度)
精度与带宽权衡
📦 7.12 打包整数序列化器实现细节
自适应位宽编码
增量压缩支持
位计数表配置
🔧 7.13 序列化器注册与宏系统
序列化器声明宏
宏展开示例
TNetSerializerBuilder 模板
序列化器构建流程
数组序列化中的 ChangeMask 使用
ChangeMask 序列化优化(RLE 编码)
📋 7.14 序列化器速查表
内置序列化器完整一览(26种)
选择序列化器的完整决策树
带宽优化效果总结
🎮 7.15 实际游戏场景案例
案例 1: FPS 游戏角色状态
案例 2: 赛车游戏车辆状态
案例 3: MMO 游戏 NPC 状态
案例 4: 卡牌游戏手牌状态
🔧 7.16 自定义序列化器开发指南
创建自定义序列化器的完整步骤
完整代码示例(FHealthNetSerializer)
位数分析
序列化器开发最佳实践
开发检查清单
🐛 7.17 序列化调试与故障排除
常见问题与解决方案
客户端收到的值与服务器不一致
数据包大小异常
动态状态内存泄漏
调试命令与工具
调试输出示例
📈 7.18 性能优化建议
序列化性能优化金字塔(基础/中级/高级)
带宽预算规划
FPS 游戏带宽预算示例
MMO 游戏带宽预算示例
📚 7.19 总结与要点回顾
核心概念总结
关键序列化器分类
优化技术列表
推荐学习路径
第八部分:数据流与传输
8.1 DataStream 系统
UDataStream 基类
WriteData / ReadData
包投递状态处理
8.2 DataStreamManager
数据流管理
多数据流协调
带宽分配
8.3 ReplicationWriter(发送端)
脏对象收集
序列化流程
可靠 vs 不可靠数据
增量压缩写入
8.4 ReplicationReader(接收端)
数据包解析
对象创建与更新
反序列化流程
RepNotify 调用
8.5 ChunkedDataStream(分块数据流)
大数据分块传输
分块组装
可靠性保证
第九部分:NetBlob 系统
9.1 NetBlob 概述
NetBlob 的作用与设计目标
与普通复制数据的区别
适用场景
9.2 NetBlobManager
Blob 管理器职责
Blob 生命周期管理
9.3 NetBlobHandler 体系
NetBlobHandler 基类
NetBlobHandlerManager
自定义 Handler 注册
9.4 Blob 分片与组装
PartialNetBlob 分片机制
NetBlobAssembler 组装器
分片传输策略
9.5 特殊 Blob 类型
RawDataNetBlob(原始数据)
ShrinkWrapNetBlob(压缩包装)
ReliableNetBlobQueue(可靠队列)
第十部分:增量压缩 (Delta Compression)
10.1 增量压缩概述
增量压缩的原理
适用场景
性能收益分析
10.2 DeltaCompressionBaselineManager
基线管理
基线存储
基线失效追踪
10.3 增量序列化
SerializeDelta / DeserializeDelta
差异计算
压缩率优化
10.4 增量压缩配置
启用条件
类级别配置
内存开销权衡
🔍 第十一部分:轮询与脏数据检测
📖 详细内容请参阅:Part11_Polling_DirtyDetection.md
🎯 11.1 脏数据检测机制概述
💡 什么是"脏数据"?(快递追踪系统类比)
🔄 Poll 模式 vs Push 模式对比
🏗️ Iris 的智能混合策略
📂 关键源文件索引
📊 11.2 DirtyNetObjectTracker(脏对象追踪器)
💡 追踪器的职责(待办事项清单类比)
🏗️ 核心数据结构(三个位数组)
📝 核心 API 详解(MarkNetObjectStateDirty / ForceNetUpdate)
🔄 更新流程与时序图
🌐 全局脏对象追踪器(多 Poller 支持)
📢 11.3 Push Model(推送模型)
💡 什么是 Push Model?(微信消息 vs 邮件检查类比)
⚙️ 启用 Push Model(三种模式对比)
📝 MARK_PROPERTY_DIRTY 宏家族详解
🏗️ 完整的 Push Model 使用示例
⚠️ 常见陷阱与解决方案
🔄 LegacyPushModel 兼容层
📊 性能优势分析(10x 提升)
🔄 11.4 ObjectPoller(对象轮询器)
💡 轮询器的职责(图书馆管理员类比)
🏗️ 核心结构与参数
🔄 轮询流程图解
📝 两种轮询策略实现(ForcePoll / PushModelPoll)
⏱️ 11.5 ObjectPollFrequencyLimiter(轮询频率限制器)
💡 频率限制的目的(体检频率类比)
🏗️ 核心数据结构
📊 轮询周期配置建议表
🔄 SIMD 优化的 Update 方法
🎭 11.6 ChangeMask(变化掩码)
💡 什么是 ChangeMask?(购物清单勾选类比)
🏗️ 智能存储(内联 vs 堆分配)
📊 带宽节省示例(86% 节省)
📋 11.7 总结与最佳实践
🎯 核心概念回顾
✅ 最佳实践清单
📊 性能优化建议表
第十二部分:对象引用与依赖
12.1 ObjectReferenceCache
对象引用缓存
引用解析
循环引用处理
12.2 NetDependencyData
依赖关系定义
依赖调度
EDependentObjectSchedulingHint
12.3 NetTokenStore
Token 存储机制
名称 Token
字符串 Token
结构体 Token
12.4 对象工厂 (NetObjectFactory)
NetActorFactory
NetSubObjectFactory
自定义工厂注册
第十三部分:条件复制 (Conditionals)
13.1 复制条件概述
条件复制的作用
条件类型
13.2 ReplicationConditionals
生命周期条件
角色条件 (COND_OwnerOnly, COND_SkipOwner 等)
自定义条件
13.3 条件评估流程
条件检查时机
条件缓存
性能影响
第十四部分:RPC 系统
14.1 RPC 概述
Iris 中的 RPC 处理
与传统 RPC 的区别
14.2 RPC 发送
SendRPC 接口
多播 vs 单播
可靠性保证
14.3 RPC 接收
RPC 分发
参数反序列化
执行上下文
14.4 RPC 传输实现
NetRPC(RPC 数据包)
NetRPCHandler(RPC 处理器)
NetObjectBlobHandler(对象 Blob 处理器)
PartialNetObjectAttachmentHandler(分片附件处理器)
🔧 第十五部分:调试与性能分析
📖 详细内容请参阅:Part15_Debug_Performance.md
🎯 15.1 为什么需要调试与性能分析?
💡 网络游戏的"隐形杀手"(餐厅服务质量类比)
🔍 常见的网络复制问题清单
📂 关键源文件索引
📝 15.2 日志系统:网络复制的"黑匣子"
💡 什么是日志系统?(飞机黑匣子类比)
📊 Iris 日志类别(LogIris 及子类别)
⚙️ 日志级别配置(7 级别详解)
🔍 日志分析实战案例(敌人消失问题排查)
🔧 15.3 调试工具:网络复制的"X光机"
💡
IrisDebugHelper:断点条件 + 调试器可调用导出函数Net.Iris.DebugName/Net.Iris.DebugRPCName/Net.Iris.DebugNetRefHandle
🖥️ 控制台调试命令(按 UE5.5 源码校准)
对象清单:
Net.Iris.PrintReplicatedObjects相关性:
Net.Iris.PrintRelevantObjects/Net.Iris.PrintRelevantObjectsToConnection WithFilterAlwaysRelevant:
Net.Iris.PrintAlwaysRelevantObjects裁剪距离:
Net.Iris.PrintNetCullDistancesPushBased 状态:
Net.Iris.PrintPushBasedStatuses动态过滤配置:
Net.Iris.PrintDynamicFilterClassConfig
🧩 常用参数:
RepSystemId=X/ConnectionId=1,5,7/WithSubObjects/SortByClass🎨 "可视化"主要靠日志打印 + Unreal Insights 时间线
📈 15.4 性能分析:找出网络复制的"瓶颈"
💡 性能分析的重要性(体检报告类比)
📊 关键性能指标 (KPIs)
时间指标(NetUpdateTime、FilteringTime 等)
数量指标(ReplicatedObjects、DirtyObjects)
带宽指标(BandwidthUsage、PacketsPerSecond)
📊 IrisProfiler 性能分析器使用
🔍 使用 Unreal Insights 分析
📊 IrisCsv 统计输出
📊 NetStats / NetStatsContext 网络统计
💾 15.5 内存追踪:找出内存"黑洞"
💡 为什么需要内存追踪?(家庭开支记账类比)
📊 IrisMemoryTracker(LLM Tag 注册:Iris / State / Initialization / Connection)
🧾 如何用 LLM 读懂内存上涨(按 Tag 找“科目”)
🚨 15.6 常见问题排查指南
💡 问题排查的"望闻问切"(中医四诊法类比)
🔍 问题 1:对象未复制(排查步骤)
🔍 问题 2:属性不同步(排查步骤)
🔍 问题 3:性能瓶颈定位(排查步骤)
📋 问题排查快速参考表
📋 15.7 总结与最佳实践
🎯 核心概念总结
✅ 最佳实践清单(开发/测试/发布阶段)
📊 调试命令速查表
⚙️ 第十六部分:配置与集成
📖 详细内容请参阅:Part16_Configuration_Integration.md
🎯 16.1 启用 Iris
💡 什么是"启用 Iris"?(输入法切换类比)
🔌 启用 Iris 插件(Engine/Plugins/Experimental/Iris/)
⚙️ 三种启用方式详解(命令行/控制台变量/配置文件)
🔄 模块加载流程(IrisCoreModule)
📂 关键源文件索引
📋 16.2 配置文件详解
💡 配置系统概述(汽车仪表盘类比)
📦 UObjectReplicationBridgeConfig(对象复制桥接配置)
🔄 轮询频率配置(PollConfig)
🔍 过滤器配置(FilterConfig)
⚡ 优先级器配置(PrioritizerConfig)
📦 增量压缩配置(DeltaCompressionConfig)
🗺️ UNetObjectGridFilterConfig(空间网格过滤配置)
🔄 UReplicationFilteringConfig(滞后过滤配置)
📝 UReplicationStateDescriptorConfig(序列化配置)
🔌 16.3 与 NetDriver 集成
💡 NetDriver 检测机制(双系统电脑类比)
🔄 ReplicationSystem 创建流程
🔀 混合模式支持
📋 迁移策略(5 阶段清单)
🎮 16.4 PIE 多实例支持
💡 什么是 PIE 多实例?(多窗口游戏类比)
🆔 ReplicationSystemId 的作用
🔒 实例隔离机制
🐛 PIE 调试注意事项
🔧 PIE 调试命令
📊 16.5 完整配置示例
🎮 FPS 射击游戏配置
🌍 开放世界 RPG 配置
🏎️ 竞速游戏配置
📋 16.6 总结与最佳实践
🎯 核心概念回顾
✅ 最佳实践清单
📊 配置参数速查表
🔧 常见问题排查
🚀 第十七部分:高级主题
📖 详细内容请参阅:Part17_Advanced_Topics.md
🎯 17.0 为什么需要"高级定制"?
💡 从"买成品"到"自己造"(装修房子类比)
🤔 什么时候需要自定义?(决策树)
📊 自定义难度等级表
📂 关键源文件索引
🔍 17.1 自定义 Filter:打造你的"VIP 通道"
💡 Filter 是什么?(演唱会安检口类比)
🎯 什么时候需要自定义 Filter?(隐身系统案例)
🏗️ Filter 工作原理揭秘(餐厅订座类比)
Filter 生命周期图解
Filter 接口详解
接口调用时序图
🛠️ 手把手实现:隐身系统过滤器
需求分析
头文件定义
核心逻辑实现
注册和配置
游戏代码使用
⚡ 性能优化技巧(早期退出/批量处理/缓存)
🐛 常见问题与解决方案
⚡ 17.2 自定义 Prioritizer:打造你的"VIP 排队系统"
💡 Prioritizer 是什么?(医院分诊台类比)
🎯 什么时候需要自定义 Prioritizer?(大逃杀案例)
🏗️ Prioritizer 工作原理
优先级值的含义(0.0-1.0)
🛠️ 手把手实现:战斗优先级器
🤝 Filter 和 Prioritizer 的协作流程
🧩 17.3 自定义 ReplicationFragment:打造你的"特殊快递包裹"
💡 Fragment 是什么?(快递包装类比)
🎯 什么时候需要自定义 Fragment?(技能系统案例)
🏗️ Fragment 工作原理(生命周期图解)
🛠️ 简化示例:技能系统 Fragment
🔄 动态状态管理
🌍 17.4 大规模多人游戏优化:当 1000 人同时在线
💡 大规模游戏面临的挑战(数字分析)
🚀 对象数量优化策略
空间分区(城市分区类比)
兴趣管理 AOI(新闻订阅类比)
对象池化与休眠(图书馆类比)
📡 带宽管理策略
优先级驱动的带宽分配
自适应更新频率(心跳监测类比)
增量压缩(视频压缩类比)
🖥️ 服务器分片考虑(连锁超市类比)
🎮 17.5 与 Gameplay 系统集成
⚔️ 与 GAS (Gameplay Ability System) 集成
Push Model 优化属性复制
技能预测与回滚
🎱 物理复制策略(台球类比)
关键帧同步
客户端预测 + 服务器校正
确定性物理
🤖 AI 复制策略
只复制结果不复制过程
分层复制
客户端 AI 代理
📋 17.6 总结与最佳实践
🎯 核心概念回顾
✅ 最佳实践清单
🐛 常见问题速查表
📚 推荐学习路径
📂 关键源文件速查
🏆 第十八部分:最佳实践与实战案例
📖 详细内容请参阅:Part18_BestPractices_Cases.md
🎯 18.0 为什么需要"最佳实践"?
💡 从"能跑"到"跑得好"的距离(学开车 vs 老司机类比)
🤔 "最佳实践"能帮你解决什么?
📂 本章结构导航
🚀 18.1 性能优化最佳实践:让服务器"轻装上阵"
💡 性能优化的"黄金法则"(快递公司效率类比)
📢 Push Model:从"主动检查"到"被动通知"
什么是 Push Model?(邮件 vs 微信消息类比)
性能对比(10 倍提升!)
如何启用 Push Model?
⚠️ 常见陷阱:忘记标脏、错误位置标脏、过度标脏
⏱️ 轮询频率优化:该快的快,该慢的慢
为什么需要分级轮询?(医院巡房类比)
📊 轮询频率配置建议表
🛠️ 配置示例
😴 休眠策略:让不动的对象"睡觉"
什么是休眠?(手机省电模式类比)
📊 休眠模式类型详解
🛠️ 休眠使用示例
📊 休眠策略效果对比
📦 增量压缩:只发"变化的部分"
什么是增量压缩?(视频压缩类比)
📊 增量压缩效果示例
📊 何时启用/禁用增量压缩?
📋 性能优化检查清单
🔍 18.2 过滤策略最佳实践:只发"该发的"
💡 过滤的核心思想(邮件订阅系统类比)
🗺️ 关卡流送过滤:大世界的"分区管理"
什么是关卡流送?(城市分区管理类比)
🛠️ 关卡流送配置
📍 空间过滤配置:距离远的不用管
空间过滤的工作原理(望远镜视野类比)
📊 空间过滤配置建议
📊 不同游戏类型的空间过滤配置
👥 组过滤应用:分组管理更高效
什么是组过滤?(学校班级管理类比)
🛠️ 组过滤使用示例
📋 过滤策略检查清单
🎮 18.3 实战案例分析:从理论到实践
🔫 案例 1:FPS 射击游戏
📋 游戏特点分析
🛠️ 完整配置方案
💡 FPS 游戏优化要点
🌍 案例 2:开放世界 RPG
📋 游戏特点分析
🛠️ 完整配置方案
💡 开放世界优化要点
🎯 案例 3:大逃杀游戏(百人同服)
📋 游戏特点分析
📊 百人同服的带宽计算(数学挑战)
🛠️ 配置方案
💡 大逃杀优化要点
🏰 案例 4:MMO 场景(千人级别)
📋 游戏特点分析
🏗️ MMO 架构设计(区域分服图解)
💡 MMO 优化策略
🔄 18.4 从传统系统迁移:平稳过渡指南
💡 为什么要迁移?(换新车类比)
📋 迁移前的准备工作(检查清单)
🔄 五阶段迁移策略
阶段 1:并行测试
阶段 2:配置优化
阶段 3:代码适配
阶段 4:测试验证
阶段 5:正式上线
⚠️ 常见陷阱与解决方案
陷阱 1:Push Model 忘记标脏
陷阱 2:过滤配置不当
陷阱 3:自定义 NetSerialize 不兼容
陷阱 4:RPC 行为变化
陷阱 5:性能反而下降
📋 18.5 总结与快速参考
✅ 性能优化检查清单
✅ 过滤策略检查清单
✅ 迁移检查清单
📊 游戏类型配置速查表
📊 对象类型配置速查表
附录
A. 关键源文件索引
按模块分类的文件列表
核心类文件位置
目录结构:
Core/Public/Iris/- 公开头文件Core/Private/Iris/- 私有实现Core/Private/Iris/ReplicationSystem/Filtering/- 过滤系统Core/Private/Iris/ReplicationSystem/Prioritization/- 优先级系统Core/Private/Iris/ReplicationSystem/DeltaCompression/- 增量压缩Core/Private/Iris/ReplicationSystem/Conditionals/- 条件复制Core/Private/Iris/ReplicationSystem/NetBlob/- NetBlob 系统Core/Private/Iris/ReplicationSystem/Polling/- 轮询系统Core/Private/Iris/Serialization/- 序列化器Core/Private/Iris/Stats/- 统计系统Stub/- 存根模块(用于禁用 Iris 时)
B. 配置参数速查表
所有配置项汇总
默认值与推荐值
C. API 速查表
常用接口列表
使用示例
D. 术语表
Iris 专有术语解释
E. 版本变更记录
UE5 各版本 Iris 变化
文档结构说明
部分 | 内容定位 | 目标读者 |
|---|---|---|
第 0 部分 | 概念对照与迁移指南 | 熟悉传统 UE 网络系统的开发者 |
第 1-2 部分 | 入门概念与架构 | 所有开发者 |
第 3-4 部分 | 核心数据结构与组件 | 网络程序员 |
第 5-9 部分 | 核心子系统 | 网络程序员 |
第 10-14 部分 | 高级特性 | 高级网络程序员 |
第 15-16 部分 | 调试与配置 | 项目集成者 |
第 17-18 部分 | 深度定制与最佳实践 | 引擎开发者 |
本文档基于 Unreal Engine 5.5.0 Iris 源代码分析(源码目录:Engine/Source/Runtime/Experimental/Iris/)
