深入拆解 World of ClaudeCraft
World of ClaudeCraft —— 由 Claude Fable 5 自主实现的完整魔兽世界游戏,一个纯 TypeScript 写成的微 MMO,以同一套确定性仿真核心同时驱动在线多人、离线单机和 Gym 风格强化学习训练三种截然不同的运行上下文。本文从架构、渲染管线、网络协议、AI 集成到过程化生成,层层拆解其设计哲学与实现细节。
一、项目概述
World of ClaudeCraft(WoCC)是一个开源的经典 MMO 风味微 MMO,全部使用 TypeScript 编写。它在浏览器中呈现实时 3D 多人游戏——包含 9 个职业、130+ 技能、怪物 AI、地下城、团本、竞技场、交易系统,以及完整的经典风格 UI——全部由单一权威 Node.js 服务器和 PostgreSQL 数据库支撑。
它最厉害的设计在于:同一套确定性仿真核心同时驱动三种截然不同的运行上下文——在线多人(WebSocket 连接共享服务器)、离线模式(整个世界在浏览器内运行,无需服务器)、无头 RL 训练(仿真暴露为 Gym 风格环境,供 Python 训练强化学习代理)。
二、完整项目结构
world-of-claudecraft/
├── .env.example # 60+ 环境变量模板
├── docker-compose.yml # 4 服务栈: postgres + game + mediawiki-db + mediawiki
├── Dockerfile
├── vite.config.ts # Vite 8 配置
├── tsconfig.json
├── package.json # v0.7.0, ESM 模块
├── README.md # 12 种语言多语言支持
│
├── src/
│ ├── main.ts # 客户端入口, 世界种子, 场景设置 (~110KB)
│ ├── world_api.ts # IWorld 接口, Sim 和 ClientWorld 共享
│ │
│ ├── sim/ # ★ 确定性游戏核心 (无 DOM/Three 导入)
│ │ ├── sim.ts # ~5,000+ 行 — tick 循环, 战斗, AI, 一切
│ │ ├── types.ts # 35KB 共享类型 + 所有调优常量 + 原版公式
│ │ ├── entity.ts # Entity 工厂 + recalcPlayerStats (单一真相源)
│ │ ├── rng.ts # Mulberry32 PRNG + FBM 噪声 (地形)
│ │ ├── world.ts # 地形高度 + 装饰生成
│ │ ├── colliders.ts # 静态碰撞 + 滑动解析
│ │ ├── dungeon_layout.ts # 整数地下城布局
│ │ ├── pathfind.ts # 局部 A* 寻路
│ │ ├── threat.ts # 原版仇恨表数学
│ │ ├── spatial.ts # SpatialGrid 半径查询
│ │ ├── obs.ts # RL 观察表面
│ │ └── content/ # 13 个文件 — 所有游戏内容数据
│ │ ├── classes.ts # 73KB — 9 职业, 130+ 技能, 天赋树
│ │ ├── zone1.ts # 32KB — Eastbrook 区域
│ │ ├── zone2.ts # 44KB — Glimmermere 区域
│ │ ├── zone3.ts # 52KB — 额外区域
│ │ ├── dungeons.ts # 16KB — 地下城怪物/Boss/掉落
│ │ └── temple.ts # Drowned Temple 团本
│ │
│ ├── render/ # ★ Three.js 3D 渲染管线
│ │ ├── models.ts # 12 个生物族 + 动画
│ │ ├── props.ts # 过程化建筑生成
│ │ ├── textures.ts # 41KB — 过程化纹理 (零资源文件!)
│ │ ├── terrain.ts # 高度图 → 几何体
│ │ ├── water.ts # 动画水面 (自定义着色器)
│ │ └── vfx.ts # 18KB — 技能特效, 粒子, 阴影
│ │
│ ├── game/ # 输入, 相机, 音频
│ │ ├── audio.ts # WebAudio 过程化音效 (零音频文件!)
│ │ ├── music.ts # 动态音乐系统
│ │ ├── input.ts # 键盘/鼠标输入
│ │ └── camera.ts # 第三人称相机
│ │
│ ├── ui/ # HTML/CSS UI 层
│ │ ├── actionbar.ts # 动作条
│ │ ├── unitframes.ts # 单位框架
│ │ ├── chat.ts # 聊天窗口
│ │ └── ... # 15+ UI 组件
│ │
│ └── net/ # 网络层
│ ├── connection.ts # WebSocket 客户端
│ └── protocol.ts # 消息类型定义
│
├── server/ # ★ 权威游戏服务器
│ ├── main.ts # 入口, WebSocket 处理, 玩家管理
│ └── db.ts # PostgreSQL 持久化
│
├── headless/ # ★ 无头 RL 训练环境
│ └── env.ts # Gym 风格环境包装器
│
└── python/ # Python RL 训练脚本
└── train.py # 训练循环 + 算法
src/sim/ 目录下的所有代码不得导入 DOM、Three.js 或任何浏览器 API。这是确定性保证的核心——同一份 Sim 代码在浏览器、服务器和无头环境中的行为完全一致。
三、确定性仿真核心:架构基石
3.1 为什么确定性是第一约束
在传统 MMO 中,客户端只负责渲染,所有游戏逻辑运行在服务器上。WoCC 走了一条更激进的路:同一套仿真代码运行在三个完全不同的上下文中——浏览器(客户端预测 + 离线模式)、Node.js 服务器(权威游戏状态)、无头环境(RL 训练)。
这要求仿真必须是比特级确定性的:给定相同的初始种子和相同的输入序列,输出必须完全一致,无论运行环境如何。
3.2 确定性保证机制
1. 固定种子 PRNG
使用 Mulberry32 算法——一个 32 位种子确定性伪随机数生成器。所有随机性(暴击、掉落、地形生成、仇恨波动)都通过这个单一 RNG 流。服务器和客户端用相同种子初始化,保证随机序列完全一致。
2. 固定步长 Tick
游戏循环以固定时间步长运行(通常 100ms/tick),与帧率完全解耦。不使用 requestAnimationFrame 或 Date.now() 推进逻辑。每次 tick 接收确定性输入,产出确定性输出。
3. 有序实体迭代
所有实体在每个 tick 中按固定 ID 顺序迭代处理。JavaScript 的 Map 和 Set 迭代顺序在 ES6+ 中已规范化,但 WoCC 仍显式排序以确保跨环境一致性。
4. 模块依赖隔离
sim/ 目录严格禁止导入 render/、ui/、net/ 或任何浏览器 API。ESLint no-restricted-imports 规则在 CI 中强制执行这一约束。
3.3 Tick 循环内部
每次 tick() 调用按以下顺序处理:
每一步都是纯函数式变换:接收当前状态和输入,产出新状态和事件。这种设计使得仿真可以在任何地方重放、快照和分支。
四、Three.js 与 WebGL 渲染管线深度拆解
4.1 整体渲染架构
WoCC 使用 Three.js r165 作为 3D 渲染引擎,配合 n8ao(GPU SSAO 环境光遮蔽)和 postprocessing 6.36.0(Bloom 泛光 + 色调映射)构建完整的后处理管线。渲染代码集中在 src/render/ 目录,与仿真核心完全解耦——渲染只消费 Sim 产生的状态快照,不参与任何游戏逻辑。
渲染管线概览:
4.2 Three.js r165 技术细节
Three.js 是对 WebGL API 的高层抽象。它不直接暴露 WebGL 的 gl.drawArrays(),而是提供 Scene Graph(场景图)、Material(材质)、Geometry(几何体)等高层概念。r165 版本引入了多项关键优化:
- WebGPU 后端支持:除 WebGL 2.0 外,r165 实验性支持 WebGPU,在支持的浏览器上提供更低的 draw call 开销
- GPUParticleSystem:粒子计算完全在 GPU 上完成,WoCC 的
vfx.ts大量使用此特性来渲染法术效果 - InstancedMesh:草、树木、石头等重复对象使用实例化渲染,将数千个对象的 draw call 合并为一次 GPU 调用
- SkeletonHelper + AnimationMixer:骨骼动画系统——
models.ts中 12 个生物族的行走、攻击、死亡动画通过关键帧插值实现
4.3 n8ao — GPU 加速的环境光遮蔽
n8ao(N8AO, v1.10.1)是一种屏幕空间环境光遮蔽(SSAO)实现,与传统的 SAO/HBAO 不同,它完全在 GPU 上通过计算着色器执行:
- 深度重建法线:从深度缓冲重建世界空间法线,避免 G-Buffer 的额外显存开销
- 自适应采样:根据深度不连续性动态调整采样半径和采样数,减少噪点
- 时间抗锯齿(TAA):利用上一帧的 AO 结果进行时域滤波,消除闪烁
- 低延迟设计:总耗时 <1ms @ 1080p,适合实时 MMO 场景
4.4 postprocessing 库 — Bloom 与色调映射
postprocessing 6.36.0 是一个基于 EffectComposer 模式的后处理框架。WoCC 使用以下 effect pass:
| Effect | 用途 | 关键参数 |
|---|---|---|
| BloomEffect | 法术光晕、UI 高亮、阳光散射 | threshold=0.8, intensity=1.2, mipmapBlur |
| ToneMappingEffect | HDR → LDR 转换 | ACES Filmic 模式 |
| VignetteEffect | 屏幕边缘暗角 | darkness=0.3, offset=0.5 |
| SMAAEffect | 子像素形态学抗锯齿 | 比 FXAA 更锐利 |
4.5 Canvas 2D 在 UI 中的角色
虽然 3D 世界使用 WebGL,但 WoCC 的 UI 层大量使用 Canvas 2D API 进行过程化绘制。具体场景:
- 过程化图标:法术图标、物品图标、Buff/Debuff 图标全部在
<canvas>上通过 2D API 实时绘制(形状、渐变、阴影),而非加载 PNG 文件 - 迷你地图:世界地形的俯视图通过 Canvas 2D 绘制,实时反映玩家位置和可见实体
- 血条和状态条:单位头顶的生命条、施法条使用 Canvas 2D 绘制以实现像素级精确控制
五、过程化生成全栈技术深挖
WoCC 的激进理念是:一切能由代码生成的,绝不用资源文件。纹理、图标、建筑、地形、水体、动画、后处理全部过程化生成,WebAudio 零音频文件合成。下面逐一拆解每个子系统的实现原理。
5.1 过程化纹理 — textures.ts (41KB)
textures.ts 是整个项目中最大的渲染文件之一,实现了完全无外部资源文件的纹理管线。核心思路:使用 Canvas 2D API 离线渲染纹理到 OffscreenCanvas,然后转换为 Three.js CanvasTexture。
这种方式的优势:纹理完全平铺(tileable)、分辨率可动态调整、视觉变化完全由种子控制、无需任何磁盘资源或网络请求。
5.2 过程化地形 — terrain.ts + rng.ts
地形高度图使用 FBM(Fractal Brownian Motion,分形布朗运动)算法生成。核心在 rng.ts 中实现:
FBM 的原理:将多个不同尺度的噪声叠加,模拟自然界中"大尺度山脉 + 中尺度丘陵 + 小尺度岩石"的自相似分形结构。octaves 参数控制细节层数(越高越精细但计算越昂贵),persistence 控制每层振幅衰减速度。
高度图通过 PlaneGeometry 映射为 Three.js BufferGeometry——每个顶点的 Y 坐标根据高度图偏移,形成起伏的地形。不同高度区间使用不同的纹理混合(草皮→岩石→雪线),通过 MeshStandardMaterial 的 vertexColors 或自定义着色器实现。
5.3 水体渲染 — water.ts
WoCC 的水面使用自定义 GLSL 着色器实现,完全不依赖外部纹理或资源文件:
- 顶点着色器:使用多层正弦波叠加进行顶点位移,模拟水面波动。振幅和频率由世界种子派生
- 片元着色器:实现菲涅尔反射(Fresnel Effect)、次表面散射近似(用于浅水区)、泡沫边缘效果(基于深度缓冲检测岸边)
- 法线扰动:通过两层不同方向、不同速度的噪声纹理叠加来模拟水面波纹法线,全部在着色器中过程化生成
- 反射/折射:使用 Three.js 的
WebGLCubeRenderTarget实时渲染环境立方体贴图,着色器中采样实现反射效果
5.4 过程化建筑 — props.ts
props.ts 实现了一个过程化建筑生成器。建筑不是预制模型,而是在运行时通过参数化规则构建:
- 建筑轮廓:随机生成矩形或多边形底面,大小随区域类型变化(城镇→大建筑,村庄→小建筑)
- 墙体:BoxGeometry 叠加,高度随机变化,墙面使用过程化砖块纹理
- 屋顶:ConeGeometry(尖顶)或 BoxGeometry 旋转(平顶),颜色从调色板中随机抽取
- 门窗:墙体上的布尔裁剪或独立 PlaneGeometry 贴附
- 变化控制:所有随机参数由种子控制,同一区域每次生成的结果完全一致
5.5 WebAudio 零音频文件合成 — audio.ts + music.ts
WoCC 最令人惊叹的技术之一:整个游戏的音频完全通过 WebAudio API 实时合成,没有任何 .mp3/.wav/.ogg 文件。这一设计决策消除了数百 MB 的音频资源,使客户端体积几乎为零,且音效可以随游戏参数动态变化。
音效合成架构
各音效类型的合成策略
| 音效类型 | 合成方式 | 关键参数 |
|---|---|---|
| 脚步声 | 短噪声脉冲 + 带通滤波器 | 截止频率(草地低/石板高), 持续时间 |
| 法术施放 | 振荡器扫频 + 噪声爆发 | 起始/终止频率, 扫频曲线, 泛音列 |
| 击中/受击 | 冲击噪声 + 低频振荡 | 攻击时间, 衰减速度, 失真量 |
| 环境音(风/雨/火) | 长时间噪声 + 缓慢调制 | 滤波器扫频, 音量 LFO, 立体声展宽 |
| UI 交互音 | 短正弦脉冲 + 频率跳变 | 音高, 持续时间, 谐波数 |
| 背景音乐 | 多层振荡器 + 序列器 (music.ts) | 音阶, 和弦进行, 节奏模式, 乐器包络 |
music.ts — 动态音乐系统
music.ts 实现了一个过程化音乐序列器,能根据游戏状态动态改变音乐:
- 分层系统:音乐由多个独立层组成(打击乐层、和声层、旋律层),每层可独立淡入/淡出
- 游戏状态响应:进入战斗→打击乐层音量 +30%、和声转小调;Boss 战→旋律层增加紧张音程
- 多区域主题:每个区域有独立的音阶、节奏和乐器组合(通过不同波形模拟不同乐器音色)
- 种子驱动变化:旋律的装饰音、节奏填充、和声转位由种子控制,保证每次进入同一区域听到相同的音乐动机
5.6 动画与后处理过程化 — vfx.ts (18KB)
vfx.ts 管理所有视觉特效。粒子系统完全在 GPU 上运行(通过 Three.js GPUParticleSystem),每个粒子的生命周期为:发射→参数更新(由 GPU 计算着色器处理)→渲染→死亡回收。
法术特效的参数化设计:每个法术定义一组视觉参数(颜色渐变、粒子形状、发射速率、生命周期、重力影响、尾迹长度),vfx.ts 在法术命中时实例化对应的粒子发射器。整个过程无需任何预制资源。
阴影方面,WoCC 使用 CSM(Cascaded Shadow Maps,级联阴影贴图)——将视锥体分割为多个深度层,近处高精度、远处低精度,在质量和性能间取得平衡。
六、WebSocket 通信协议深度拆解
6.1 整体通信架构
WoCC 使用 ws 8.21.0 库实现 WebSocket 通信。这是一个轻量级、高性能的 WebSocket 实现(客户端和服务端均使用同一库)。通信模型采用客户端→服务器单向发送操作意图 + 服务器→客户端广播权威状态的模式。
[浏览器] [Node.js 服务器]
| |
|-- WebSocket 连接 ----------------->| ws.Server(:8787)
| |
|-- PlayerAction (JSON) ------------>| 验证 → Sim.applyAction()
| { type: "move", dx: 1, dy: 0 } |
| { type: "cast", spellId: 42 } |
| { type: "interact", target: X } |
| |
|<- WorldState (JSON) ---------------| tick() → 广播状态差异
| { entities: [...], events: [...] } (全量或增量, 可配置)
| |
|<- ChatMessage (JSON) --------------| 聊天广播
|<- SystemEvent (JSON) --------------| 系统通知
6.2 消息协议设计
客户端通过 connection.ts 管理 WebSocket 生命周期,protocol.ts 定义了强类型的消息接口。所有消息以 JSON 格式编码:
6.3 关键设计决策
客户端只发意图,不发状态
客户端从不声称"我现在在坐标 (x,y)"。它只发送"我想向这个方向移动"。服务器在 Sim 中验证并执行,然后告知客户端真实结果。这从根本上消除了位置欺骗。
状态差异而非全量同步
服务器每次 tick 后广播的是状态差异(delta)而非全量世界状态。只发送自上次同步以来变化的实体属性,将典型消息体从 50KB 压缩到 2-5KB。
客户端预测 + 服务器和解
客户端在发送移动意图后立即在本地 Sim 中应用预测,不等待服务器确认。当服务器状态到达时,如果预测与实际不同,客户端平滑修正到权威位置。
心跳与断线重连
客户端每 5 秒发送 ping,服务器回复 pong。超过 15 秒未收到 pong 即触发重连。重连时服务器发送全量世界状态快照以重新同步。
七、强化学习集成:实践向深挖
7.1 整体架构
WoCC 的强化学习集成是其最独特的设计之一。headless/ 目录将游戏仿真包装成标准 Gym 风格环境,使 RL 研究者可以使用熟悉的 API(env.reset() / env.step(action) / env.render())来训练代理。
Python 训练脚本通过 Node.js 子进程与无头仿真通信,使用进程间通信(IPC)或标准输入/输出管道交换观察和动作数据。
┌─────────────────────────────────────────────────┐
│ Python 训练脚本 (python/train.py) │
│ ├─ PPO / DQN 算法 │
│ ├─ 经验回放缓冲 │
│ └─ 神经网络 (PyTorch) │
└──────────────┬──────────────────────────────────┘
│ stdin/stdout JSON
▼
┌─────────────────────────────────────────────────┐
│ Node.js 无头环境 (headless/env.ts) │
│ ├─ Sim 实例 (与游戏服务器相同代码) │
│ ├─ 观察构建 (obs.ts → 观察向量) │
│ └─ 奖励计算 │
└─────────────────────────────────────────────────┘
7.2 观察空间 (Observation Space)
obs.ts 将游戏状态编码为一个固定维度的浮点向量。观察向量的结构:
7.3 动作空间 (Action Space)
动作空间设计为离散动作空间,每个动作是一个整数 ID。动作分为几大类:
| 动作类别 | ID 范围 | 描述 |
|---|---|---|
| 移动 | 0–8 | 8 方向 + 停止 |
| 法术施放 | 9–138 | 130 个可用法术/技能 |
| 目标选择 | 139–146 | 切换目标 (最近/最低血/最高威胁等) |
| 物品使用 | 147–166 | 药水, 食物, 绷带等 |
| 社交 | 167–170 | 跟随, 交易, 决斗等 |
7.4 奖励函数设计
奖励函数是 RL 训练的核心。WoCC 的奖励设计采用多目标加权求和:
7.5 训练挑战
在 WoCC 中训练 RL 代理面临几个独特挑战:
- 稀疏奖励:击杀怪物需要一系列正确的动作序列(移动→接近→施法→维持距离→击杀),中间几乎没有正向信号
- 大动作空间:130+ 法术的离散动作空间远大于典型 Atari 游戏,需要有效的动作空间剪枝(根据当前可用法术动态mask掉无效动作)
- 部分可观察性:代理只能看到附近的实体和自身状态,无法观察整个游戏世界
- 长期规划:成功的游戏需要跨多个 tick 的规划(资源管理、冷却协调),单步奖励信号弱
八、CLAUDE.md 体系:AI 原生文档的实践
8.1 什么是 CLAUDE.md
WoCC 仓库包含约 20 个 CLAUDE.md 文件,分布在几乎所有主要目录中。这不是给人类开发者看的 README,而是面向 AI 编码代理(Claude、Codex、Copilot 等)的机器可读操作手册。
每个 CLAUDE.md 文件告诉 AI 代理:这个目录做什么、架构不变量是什么、修改这个目录时永远不能做的事、添加新功能的标准步骤。
8.2 CLAUDE.md 分布地图
| 位置 | 主要内容 |
|---|---|
/CLAUDE.md | 根级项目全景:技术栈、架构原则、目录约定、构建命令 |
src/sim/CLAUDE.md | 确定性规则(禁止 DOM/Date.now()/Math.random())、tick 顺序、添加新法术的步骤 |
src/render/CLAUDE.md | 渲染管线架构、Three.js 版本约束、性能预算(draw call 上限)、纹理分辨率上限 |
src/game/CLAUDE.md | 输入处理、音频系统、相机行为 |
src/ui/CLAUDE.md | UI 组件规范、CSS 约定、事件冒泡规则 |
src/net/CLAUDE.md | WebSocket 协议、消息类型、重连策略、服务器验证规则 |
server/CLAUDE.md | 服务器启动流程、数据库模式、迁移步骤、速率限制 |
headless/CLAUDE.md | 无头环境配置、RL 集成点、观察/动作空间约定 |
python/CLAUDE.md | Python 训练脚本约定、依赖管理、日志格式 |
8.3 CLAUDE.md 的内容结构
典型的 CLAUDE.md 包含以下标准化部分:
8.4 为什么这是 AI 时代的最佳实践
传统的代码注释和 README 是为人类设计的——期望读者有上下文、能推断未书写的内容、能容忍歧义。AI 代理恰好相反:它字面理解每个指令,不推断未明确说明的约束,会在任何未设边界的地方自由发挥。
CLAUDE.md 体系解决了这个根本问题:用 AI 代理能精确遵循的格式,编码架构规则、禁止事项和操作流程。这不是"给 AI 写文档",而是把架构约束正式化为一组可被自动执行的规则。
这一实践与 Codex 的 AGENTS.md 规范一脉相承——两者都基于同一核心理念:代码库应该能"教"AI 代理如何在其中工作。
九、服务器架构
9.1 部署拓扑
WoCC 使用 Docker Compose 编排四个服务:
docker-compose.yml ┌──────────────────────────────────────────────┐ │ game-server (Node.js ESM) │ │ ├─ WebSocket 服务器 (:8787) │ │ ├─ Sim 实例 (权威游戏状态) │ │ └─ tick 循环 (100ms) │ │ │ │ │ ▼ │ │ postgres (PostgreSQL 16-alpine) │ │ ├─ 玩家账号/角色数据 │ │ ├─ 物品/装备持久化 │ │ └─ 经济系统数据 │ │ │ │ mediawiki (MediaWiki) │ │ ├─ 游戏 Wiki │ │ └─ 玩家贡献内容 │ │ │ │ │ ▼ │ │ mediawiki-db (MariaDB 11) │ └──────────────────────────────────────────────┘
9.2 服务器入口 — server/main.ts
服务器的核心职责:
- WebSocket 连接管理:接受客户端连接、认证(JWT token)、会话管理
- 玩家加入/离开:玩家上线时创建 Sim 实体、加载持久化数据;下线时保存状态
- 输入验证:每一个客户端操作在进入 Sim 之前都经过字段级验证——法术 ID 是否存在、目标是否有效、冷却是否就绪
- Tick 回路:以固定 100ms 间隔调用
sim.tick(),将产生的SimEvent[]广播给相关玩家 - 速率限制:每个客户端每秒最多 N 条消息,超出则断开连接
9.3 数据库 — server/db.ts + PostgreSQL
pg 8.21.0 客户端连接 PostgreSQL 16-alpine。数据库存储玩家账号(bcrypt 哈希密码)、角色数据(等级/装备/物品栏/技能书)、经济数据(金币/拍卖行)。设计原则:游戏运行时完全在内存中,数据库仅用于启动加载和定期持久化——模拟 tick 循环不做 I/O。
十、测试策略
10.1 测试层级
| 层级 | 工具 | 覆盖范围 | 文件数 |
|---|---|---|---|
| 单元测试 | Vitest 4.1.8 | 战斗公式、仇恨表、寻路、碰撞、RNG | 123 个 test 文件 |
| 集成测试 | Vitest | 多 tick 场景、地城流程、交易流程 | 包含在 123 个文件中 |
| E2E 测试 | Puppeteer 25.1 | 完整用户路径(登录→移动→战斗→拾取) | 51 个自动化脚本 |
| RL 环境测试 | PyTest | 观察/动作空间一致性、奖励函数正确性 | python/tests/ 目录 |
10.2 确定性测试
确定性仿真核心使得一个强大的测试模式成为可能:录制回放测试。记录一段输入序列 → 在浏览器中运行 Sim → 在服务器中运行 Sim → 在无头环境中运行 Sim → 断言三者产生的所有事件流完全一致(位级比对)。
十一、工程哲学
确定性即架构
确定性不是事后优化的特性,而是中心架构约束。每个设计决策——从模块边界到实体迭代顺序——都服务于"同一代码在三个上下文中的行为完全一致"这一需求。
过程化即效率
通过运行时代码生成纹理、图标、音效、建筑和世界几何体,项目避免了传统 MMO 500MB+ 的资源包,实现了几乎无限的变化,并大幅降低了客户端带宽需求。
单一真相源
代码库强制执行多个"一处定义"规则:recalcPlayerStats() 是角色属性的唯一计算位置,types.ts 是所有调优常量的唯一来源,tick() 是整个游戏循环的唯一入口。
永不信任客户端
服务器在将每个输入字段传给 Sim 方法之前进行验证。这不是安全剧场——这是让游戏在无服务器入侵的情况下无法作弊的架构基础。
十二、技术栈参考表
| 技术 | 版本 | 用途 |
|---|---|---|
| TypeScript | 5.5 | 整个代码库语言 |
| Vite | 8.0 | 开发服务器, HMR, 生产打包 |
| Three.js | r165 | 3D 渲染引擎 |
| n8ao | 1.10.1 | GPU SSAO (环境光遮蔽) |
| postprocessing | 6.36.0 | Bloom, 色调映射, 后处理特效 |
| ws | 8.21.0 | WebSocket 服务器 + 客户端 |
| pg | 8.21.0 | PostgreSQL 客户端 |
| esbuild | 0.28.1 | 服务器打包器 |
| obscenity | 0.4.6 | 用户名 + 聊天脏话过滤器 |
| Vitest | 4.1.8 | 单元 + 集成测试 |
| Puppeteer | 25.1 | 浏览器 E2E 测试 |
| PostgreSQL | 16-alpine | 游戏数据库 |
| MariaDB | 11 | Wiki 数据库 |
| Node.js | ESM | 服务器运行时 |
| @gltf-transform/cli | 4.4.0 | 3D 模型优化 |
| 强化学习 | PyTorch | Python RL 训练 (PPO/DQN) |
十三、为什么这个项目重要
- 它是一个真实的、可玩的 MMO——884 stars, 248 forks, 活跃的 Discord 社区,具有真正的多人持久化和游戏机制。
- 一套代码,三种截然不同的执行上下文——浏览器游戏、权威服务器和 RL 训练环境共享同一确定性核心,零代码修改。
- 过程化生成的完整展示——纹理、图标、音效、建筑、地形和世界布局全部由代码生成。唯一非代码资源是 CC0 3D 模型。
- 真实还原经典 WoW 机制——命中表、仇恨数学、怒气公式、经验曲线、GCD 机制、地下城布局、竞技场 Elo——全部正确实现。
- AI 原生开发实践——20 个 CLAUDE.md 文件教会 AI 编码代理如何在代码库中工作,RL 训练环境将游戏本身变成了 AI 研究平台。
- 大规模确定性设计——固定种子、固定步长、零挂钟依赖、有序实体迭代——可复现仿真设计的典范。
- 全面的测试覆盖——123 个 vitest 文件 + 51 个 E2E/自动化脚本,覆盖游戏的每个系统。
十四、潜在应用场景
游戏开发教育
一套完整的 MMO 实现,适合端到端学习游戏架构
强化学习研究
包含战斗、任务、经济和社交机制的复杂多智能体环境
自托管游戏服务器
为朋友或社区运行私有的类 WoW 世界
TypeScript 架构参考
具有严格模块边界约束的大型单体仓库最佳实践
过程化生成研究
生产级运行时代码生成技术——纹理/音频/建筑的完整范例
AI 代理文档
机器可读代理指令(CLAUDE.md 体系)的参考实现