服务器 Mod 结构
网络游戏 Mod 和单机 Mod 最大的不同,是明确区分服务端和客户端。这一篇讲清楚一个网络游戏 Mod 的目录结构,以及 developer_mods、behavior_packs、resource_packs、worlds 各是干什么的。
Mod 类型
服务器 Mod 按所在服分为四类:
| 类型 | 组成 |
|---|---|
| 控制服 Mod | master 的 developer_mods 下所有 mod |
| 功能服 Mod | service 的 developer_mods 下所有 mod |
| 大厅服 Mod | lobby 的 behavior_packs + resource_packs + developer_mods + worlds |
| 游戏服 Mod | game 的 behavior_packs + resource_packs + developer_mods + worlds |
标准目录结构
以一个游戏服 Mod tutorialApolloMod 为例:
tutorialApolloMod # Mod 根目录
├── behavior_packs # 客户端行为包(会下发给客户端)
│ └── tutorialBehavior
├── developer_mods # 服务端 Mod(只跑在服务器,不下发)
│ └── tutorialDev
│ └── tutorialScripts # Python 脚本根目录
├── resource_packs # 客户端资源包
│ └── tutorialResource
└── worlds # 地图
└── level
├── world_behavior_packs.json # 配置下发的行为包
└── world_resource_packs.json # 配置下发的资源包developer_mods(服务端)
服务端加载的 Mod 目录,不下发给客户端。以 neteaseAnnounce 为例的结构:
neteaseAnnounceDev
├── netease_require.json # 控制 Mod 加载顺序(非必须)
├── neteaseAnnounceScript # 行为包目录,import 起点
│ ├── __init__.py # module 标识,可空但必须有
│ ├── announceConsts.py # 宏定义
│ ├── announceServerSystem.py # 业务逻辑
│ └── modMain.py # Mod 初始化入口,文件名不可改
└── mod.json # 配置 Mod 功能细节(非必须)developer_mods支持多个 mod,每个 mod 一个目录- 服务端脚本可用 Apollo SDK 全部接口 + Mod SDK 服务端组件/事件
import从脚本根目录起,如import neteaseAnnounceScript.announceConsts as announceConsts
behavior_packs(客户端行为)
- 存放客户端 Mod,会下发给客户端
- 只允许有一个目录(多个只用第一个),按
*behavior命名(大小写不敏感) - 脚本放在
*scripts目录内,只允许一个 - 必须含
manifest.json,并在worlds/level/world_behavior_packs.json配置 pack id 和 version 才会下发
resource_packs(客户端资源)
- 存放客户端资源(材质、模型等)
- 版本信息在
manifest.json - 需把
manifest.json的 header uuid 配置到world_resource_packs.json才会被客户端下载
json
// world_resource_packs.json
[
{ "pack_id": "1c850d23-64f4-46be-aec0-16c8e4618072", "version": [0, 0, 1] }
]worlds(地图)
- 只允许一个子目录(如
level),目录名即地图名,不能用中文 - 别忘了配置
world_behavior_packs.json和world_resource_packs.json
worlds/level
├── db # 地图存档
├── level.dat # 地图全局信息
├── levelname.txt # 地图名
├── world_behavior_packs.json # 下发的行为包
└── world_resource_packs.json # 下发的资源包客户端与服务端分离
游戏服 Mod 的客户端脚本(behavior_packs)和服务端脚本(developer_mods)分开存储、不能相互 import:
| 客户端脚本 | 服务端脚本 | |
|---|---|---|
| 位置 | behavior_packs | developer_mods |
| 运行环境 | 玩家手机 | Linux 服务器 |
| 能用的 API | Mod SDK 客户端组件/事件 | Mod SDK 服务端 + Apollo SDK 全部 |
| 处理 | 界面、特效、entity 行为 | 数据库存取、玩家交互、全局逻辑 |
强烈建议逻辑严格分离
客户端脚本只放客户端逻辑,服务端脚本只放服务端逻辑。除了便于管理,更重要的是——万一客户端脚本被破解,也不会泄露服务端代码。分离做法:在客户端 modMain.py 里注释掉 InitServer/DestroyServer 并删服务端 System 文件;服务端反之。
命名建议
behavior_packs、developer_mods、resource_packs 下的 Mod 脚本根目录建议用 [团队名][Mod名][Scripts] 格式(如 SDKTeamTestScripts),避免与他人 Mod 冲突。
理解了结构,下一篇从单机 Mod 到网络游戏 Mod——把已有 Mod 改造成网络游戏 Mod。回到基岩版网络游戏首页。
