游戏场景之大世界架构设计构想

架构拆分

  • 网关Gate
  • 游戏服务Game
  • 登录服务Login
  • 中心服务Center
  • 全局服务Chat、Rank
    各部分都可以用一个单独进程或一个Actor来表示

使用场景

🎯 必须用(尺度决定了不得不拆)

  • 开放世界 RPG / Action RPG:原神、塞尔达、巫师 3、上古卷轴、黑神话方向

    • 原因:几 km² ~ 几十 km² 连续地图,全装内存不可能 → 必须 Chunk 流式
  • 生存沙盒 / 建造类:Rust、方舟、我的世界(理论无限)、幻兽帕鲁

    • 原因:地图甚至程序化无限生成,尺度没上限 → 必须空间分块 + 按需生成
  • MMO(现代派):FF14(虽然老但地图大)、新倩女幽魂、逆水寒

    • 原因:几千人同图 + 地图大 → 必须 AOI + Zone 分片
  • 赛车 / 飞行开放世界:极品飞车:无界、微软飞行模拟

    • 原因:移动速度极快(飞行 200+ km/h)→ 预测加载 + 极低 Pop-in 要求

🤔 可选(中小世界也能做,但大世界是卖点)

  • 大逃杀 / 百人吃鸡类:PUBG、APEX(地图其实不算特别大,但 100 人 + 高速载具 → 也要 AOI + 流式,但比原神那种"真·大世界"轻)

  • FPS / TPS 开放世界:地平线:西之绝境、孤岛惊魂 ------ 单图大,但人不太多(纯 PvE),服务端压力小,客户端流式压力大

❌ 一般不用

  • MOBA(王者、LOL)→ 单局一张小地图,3 条路,没必要

  • 传统 FPS 竞技(CS2、OW 占点)→ 图小、人数固定

  • 卡牌 / 回合制 RPG → 根本没有"走地图"这件事

技术选型

客户端

后端

核心问题

前置语境:大世界和普通关卡的差别

  • 普通关卡:一张地图 200m×200m,全部塞内存,所有玩家互相看得见,服务端一帧把所有人的位置广播给所有人------没问题,因为总量小。

  • 大世界:8km×8km 甚至更大,几千玩家同时在,地图本身几百 MB 到 GB 级。

于是下面 5 个问题一个个蹦出来。

视野同步怎么做到不丢也不炸?

起因:你站在大世界里,地图上其实有 2000 个玩家、3000 个怪。如果你的手机/电脑要把这 5000 个实体的位置每帧都收一遍------

  • 带宽炸:每秒几十 MB,4G/WiFi 都扛不住

  • 但你根本看不见他们:大部分人在地图另一头,跟你半毛钱关系没有

解决方案

  • AOI(Area of Interest,兴趣区域):服务端给每个玩家划一个"我关心这个范围",只把范围内的事发给他。类似"你只订阅自己周围的新闻"。

    AOI学习笔记

  • 九宫格:把地图切成象棋盘一样的格子,你在中间那格,服务端只发你 + 上下左右 + 四个对角这 9 格里的实体给你。

  • Diff(增量):你从格子 A 走到格子 B,不用重新发"你周围所有人",只发"刚才那 9 格里没了谁、新进了谁"------这就是上一轮伪代码里 leave/ enter的由来。

跨 Chunk / 跨 Zone 怎么无感?​

起因:客户端把地图切成了 Chunk(比如 128m×128m 一块)。你走路"1 号 Chunk → 2 号 Chunk"本来是内部小事,但有两件事会露馅:

  • 客户端侧:2 号 Chunk 还没 Load 完,你眼前一片空白 → "Loading 感"

  • 服务端侧:2 号 Chunk 属于另一个 DS 进程(Zone B),你走过去如果让客户端断线重连 → 屏幕中间一个"正在连接..." → 体验崩了

玩家期待的是:骑马从草原冲进森林,不停、不卡、不 Loading。

解决方案

客户端 Chunk 边界重叠 + 服务端 DS 切流协议

  • Chunk(客户端):地图切块的基本单位,流式加载/卸载的最小颗粒。

  • Zone / DS 分片(服务端):服务端把大地图切成几块,每块跑一个 DS 进程。比如左半边 Zone A(DS-1),右半边 Zone B(DS-2)。

  • 热迁移 / 切流:玩家从 Zone A 走到 Zone B 时,服务端把"这个玩家的状态快照"从 DS-1 拷到 DS-2,客户端悄悄把网络连接从 DS-1 切到 DS-2------你还在骑马,完全不知道背后换了台服务器。

高速移动 Chunk 来不及 Load 怎么办?​

起因:

你走路 → Chunk 加载来得及(人速 ~6m/s)。

你骑马 → 还行(马速 ~15m/s)。

你开载具 / 滑翔翼 → 50--80 m/s。

流式加载的逻辑是"你走到哪、加载到哪"。如果你速度太快,等你踩到 Chunk 边界时,那个 Chunk 的美术资源(地形、树、房子)还在硬盘→内存→GPU 的路上 → 你眼前突然"地没刷出来,掉下去了"或者"树啪一下冒出来"。

解决方案

预测加载(速度向量 × 系数)+ 低模占位

  • 预测性预加载(Predictive Streaming):不光加载"你脚下这格",还加载"你面朝方向再往前 N 格"。类似你开车,导航不光显示你车轮底下,还显示前面 500m。

  • 速度向量 × 系数:Client 拿你的朝向 + 速度,算出"你 2 秒后会到哪",提前发 Load 请求。

  • 低模占位(Proxy / Impostor):真资源没到之前,先摆一个超低模的"假房子"顶着,资源到了再换真身------玩家不至于看到空气。

内存碎片 / GC spike?​

起因:

你玩游戏时偶尔会"突然卡一下,0.5 秒画面不动"------这叫 Spike。

大世界里,你走一步就可能有:

  • 旧的 Chunk 卸载 → 几百个 GameObject 销毁

  • 新的 Chunk 加载 → 几百个 GameObject + Texture + Mesh 新建

如果每次都真的 new/ delete(C++)或让 GC(C#/Java)去回收:

  • 频繁 new/delete​ → 内存像被咬了很多小洞(碎片),后来想申请一块大内存申请不到

  • GC 触发​ → 虚拟机暂停所有线程去扫垃圾,画面就卡住一帧 → 玩家:"又卡了?"

解决方案

对象池 + BufferGeometry 复用 + 异步分帧,绝不主线程 Instantiate

  • 对象池(Object Pool):Chunk 里的树、石头、怪物,别真 Destroy,丢回池子里下次拿来改个坐标复用 → 零分配,GC 就安静了。

  • Buffer / Mesh 复用:地形、植被的 GPU 资源也别反复创建销毁,池化。

万人同图服务端怎么扛?​

起因:

假设 8km×8km 大世界,在线 1w 人,每人带宠物/坐骑,地图上还有 2w 个野怪、采集物------3w 实体。

如果一个服务端进程全扛:

  • 每帧要遍历 3w 实体算 AI、算物理

  • AOI 广播就算九宫格剪过,CPU 还是爆

  • 一个进程崩 → 全图 1w 人掉线

解决方案

空间分 Zone + AOI 剪枝 + 云原生按 Key 闪回

  • Zone 分片(Space Sharding):把地图按空间切成几块,每块一个 DS 进程,各管各的 → 问题 2 里的"跨 Zone 热迁移"就是为了把这个切分藏起来不让玩家看见。

  • 云原生扩缩容:大世界白天 2k 人在线、晚上 1w 人,Zone 数可以动态加(比如把原来 1 个 Zone 拆成 2 个)------但要配合"按 Key 分片"的数据层(Redis/Mongo 按 Zone ID 或 Player ID hash)。

  • DS(Dedicated Server):专职跑游戏逻辑的服务器进程,不带渲染,纯算。

相关推荐
AI科技星5 小时前
基于全域数学公理体系的三元极值题最简求解法【乖乖数学】
线性代数·算法·游戏·决策树·机器学习·乖乖数学·全域数学
玖玥拾7 小时前
Unity 3D 基础(一)Unity基础架构、物理系统、视觉渲染、空间变换与对象查询
笔记·游戏·3d·unity·游戏引擎
可爱系程序猿8 小时前
dinput8.dll 缺失导致游戏启动失败?DirectInput 和模组冲突排查记录
程序人生·游戏·电脑
言乐61 天前
Python实现可运行解密游戏游戏框架
python·游戏·小程序·游戏程序·关卡设计
user-猴子1 天前
不会写代码,做小游戏教程
人工智能·游戏
河南花仙子科技1 天前
花仙子科技|游戏出海发行与本地化运营避雷指南
科技·游戏
qq_380651331 天前
xu0713#True贪吃蛇经典的游戏
python·游戏·pygame
科技每日热闻1 天前
三模同屏,主宰战局!EVNIA弈威全球首款三模电竞显示器27M4N5500PT锋芒面世
科技·游戏·计算机外设
makise-1 天前
剑星2026最新版免费下载+修改器
网络·游戏