在线会话、对象同步与服务适配
范围:network/、glassPaneSyncing/,关联网络脚本与多人内容。总入口:Summary。
1. 三种不同的在线职责#
在线系统包含实时游戏会话、世界对象复制以及账户/内容/商城等服务适配。底层连接、传输、同步树框架和平台服务由 RAGE/Rockstar 服务接口提供;游戏层定义 GTA 的对象、规则和业务流程。
源码有 player ownership、remote clones、control migration 和多种 host 接口,足以说明实体权责不是统一集中在一个游戏服务器对象上。与此同时,云端、交易和账户功能明确依赖外部服务。不能将架构概括为“全部纯 P2P”,也不能认定仓库包含完整权威游戏服务器和后台服务。
2. 子模块全景#
| 子模块 | 职责与主要关系 |
|---|---|
| Network / NetworkInterface | 生命周期与面向游戏的统一查询/操作 |
| Sessions / Party | 查找、创建、加入、过渡、离开及社交组队 |
| Players | 本地/远端玩家身份与状态 |
| Objects / Entities | 游戏实体的网络身份、拥有者和复制生命周期 |
| Synchronisation | 按对象类型组织 sync tree 与数据节点 |
| Prediction | 远端位置、姿态、速度预测与平滑 |
| Events / Arrays | 离散事件和脚本/共享数组类数据 |
| Bandwidth | 带宽测量、玩家更新等级与重发节奏 |
| Cloud / Tunables / UserContent | 异步请求、缓存、可调参数与 UGC |
| Commerce / Shop | 平台商城与游戏目录、库存、交易流程 |
| Live / SocialClubServices / Crews / Stats | 平台登录、邀请、presence、社群和在线统计 |
| Voice / Chat | 语音与文字通信,连接音频/前端 |
| Debug / General / Roaming / 工具 | 诊断、公共协议辅助与跨状态支持 |
3. 会话与 Transition 是并存状态机#
CNetworkSession 的 session state 包括 Finding、Hosting、Joining、Establishing、Established、Bail、HandleKick、Leaving、Destroying。transition state 又有独立的 Hosting/Joining/Establishing 等状态,说明在线玩法切换存在过渡流程,不只是销毁再重建一个连接。
会话 established 不自动意味着脚本、资源和世界对象都已就绪;还要经过在线玩法和 streaming 准备。失败、被踢与离开也有独立状态,不能让 UI 在连接刚断开时立即假定所有对象和请求都已清理。
4. 区分三种“主机/拥有者”#
| 概念 | 作用 | 常见误读 |
|---|---|---|
| 会话 host | 会话建立和会话协调相关角色 | 不应推断其拥有全部实体 |
| script host | 一个网络脚本的主持执行/资源语义 | 同一会话内不同脚本的职责不能混为全局 host |
| object owner | 特定实体的控制和同步责任 | ownership 可以迁移,远端 clone 不等于本地权威 |
CREATE_VEHICLE 的 host-object 校验查询 script handler network component 的 IsHostLocal;CNetObjGame 则有 CanPassControl、CanAcceptControl、ChangeOwner、PostMigrate。这些接口属于不同抽象层。
5. 实体注册、复制和容量#
CNetworkObjectMgr : netObjectMgrBase 负责注册/注销网络对象、玩家加入离开、按类型获取 sync tree、随机对象转脚本对象,以及 movement/scripts 后的更新。RegisterGameObject 返回 bool,容量失败必须可处理。
对象管理器区分过多本地拥有对象、starving updates、远端不能接受新对象以及 too-many-objects ACK。NetworkObjectPopulationMgr 根据网络对象可用量调整 Ped、Vehicle、Object 目标数量,并检查是否能接收某类型所有权。
因此多人实体数量受本地池、远端容量、网络更新与玩法保留共同约束。某玩家附近车辆减少,不一定只是渲染 LOD;也可能是网络人口策略。增加单个池大小未必解除其他端的限制。
6. SyncTree 的结构化同步#
对象类型有独立同步树:Ped、Player、Vehicle 及其子类、Object、Door、Pickup、PickupPlacement、GlassPane 等。ProjectSyncTrees.cpp 明确构造 create、migrate、frequent、infrequent、game state、script state 等父节点,并为节点登记带宽记录器。
CProjectSyncTree::Write 接受 serialise mode、activation flags、目标对象、bit buffer、时间和目标玩家;ApplyNodeData 将数据应用到对象。写入并非无条件复制整个 C++ 对象内存,而是根据模式、节点状态和接收者选择内容。
初始状态缓冲用于比较并 dirty 不同于初始值的节点,可只对特定玩家标记。ResetScriptState 在脚本对象转回环境对象时重置脚本节点并应用,防止脚本约束永久残留。这一细节把资源所有权转换与网络状态清理联系起来。
PhysicalSyncNodes.cpp 中速度和角速度使用 packed 分量与 SERIALISE_VELOCITY,部分字段仅在状态指示下序列化,并提供 default-state 判断。可确认有压缩、条件字段和默认值优化,但具体精度、位数和频率必须逐字段核对,不能声称所有变换统一用某个固定位宽。
7. 预测与平滑是对象相关的#
Prediction 目录为 Physical、Vehicle、Ped、Boat、Heli、Train 分别实现 blender。CPhysicalBlenderData 包含位置阈值、速度平滑时间、最大预测时间、姿态混合、ramp/stop 时间,以及 on-screen/off-screen 允许误差。
这些参数在网络更新稀疏或有延迟时折中连续性和误差纠正。预测后的显示位置不是最新网络样本的逐字重现;强制 teleport、所有权迁移或碰撞可能需要不同纠正路径。默认构造值不代表所有对象最终配置,因为类型和状态可以调整参数。
对象同步有 UpdateAfterAllMovement 和 UpdateAfterScripts,说明采样/提交与游戏移动和脚本更改的顺序有明确依赖。过早发送会漏掉同帧最后修改,过晚应用又可能与本地物理竞争。
8. 事件、数组与玻璃#
对象状态适合表达持续属性,NetworkEventTypes 表达 request control、伤害及其他离散游戏事件。事件提供 Handle、Decide 和 bit buffer 处理,意味着收到数据后仍要做上下文判断,而非直接执行任意状态变更。数组同步则由 ArrayMgr 和 handler types 管理,服务脚本或共享结构。
玻璃同步有专门的 network object 和 sync nodes;CGlassPaneManager 分 owner/clone 注册接口,记录几何 hash、命中位置、组件等,并提供 migrate/destroy。细碎破坏也需要稳定身份与迁移协议,不能只广播一次视觉特效就认为后加入玩家会自动看到正确状态。
本报告不对所有消息处理做安全审计;这里仅说明架构边界与一致性要求,不声称已验证整个协议的输入防护。
9. 带宽与重发#
CNetworkBandwidthManager : netBandwidthMgr 计算 low/medium/high player update levels,并在 upstream bandwidth 改变时调整。UpdatePlayerBaseResendFrequencies 的注释明确按 ping 调整,避免高延迟连接持续过早重发。
这与 AI/渲染 LOD 类似,是分配有限更新能力,而非简单固定全员同频广播。带宽应拆为对象创建/销毁、节点更新、可靠事件、数组、语音与其他控制消息;平均吞吐无法解释加入场景或大规模生成时的峰值。
10. 在线服务是异步业务系统#
CloudManager 定义请求 ID、完成事件、success/result code、返回数据、修改时间和 from-cache 标志;CloudCache、Tunables、UGC 和视频上传是不同消费者。请求结束和业务成功必须区分,缓存命中也不等于最新服务端状态。
Shop 包含 Catalog、Inventory、TransactionsSessionMgr、transaction tasks、NetworkGameTransactions 和 NetworkShopping。transaction base 保存 request、checkout 等状态,服务端返回数据区分 balance 与 inventory application。交易不是客户端直接修改余额的同步函数,必须协调请求结果与本地应用状态。
Live、SocialClubServices、Crews、Party、Voice 和 Chat 则连接账户、社交与通信。目录只能证明客户端适配存在,不能证明外部服务可用、协议环境完整或具备本地端到端测试条件。
11. 维护与验证方向#
优先覆盖加入时对象创建、资源未就绪、拥有者离开、script host 迁移、远端容量不足、场景切换、迟到事件、断线重连与服务回调晚于 UI 销毁。修改字段还要核对 create/update/migrate/default-state、录制、调试与版本兼容路径。
本文未连接任何服务、抓包或运行联机测试,所有性能建议均为源码驱动的观察维度。
12. 源码依据#
| 源码 | 重点 |
|---|---|
| NetworkSession.h | session/transition 状态机 |
| NetworkObjectMgr.h | 注册、容量、玩家与分阶段同步 |
| NetObjGame.h | clone 与 ownership migration |
| ProjectSyncTree.h | write/apply、初始状态、script reset |
| ProjectSyncTrees.cpp | 数据节点组织 |
| PhysicalSyncNodes.cpp | 条件字段和压缩速度 |
| NetBlenderPhysical.h | 预测、平滑和误差参数 |
| NetworkBandwidthManager.h | 更新等级与 ping 重发策略 |
| CloudManager.h | 异步结果与缓存信息 |
| NetworkShopping.h | 交易、余额与库存应用 |
| GlassPaneManager.h | owner/clone 注册及迁移 |