GM 模式
GM 模式是让你用你的线上服务器测试你的游戏的方式。
一旦服务器成为权威,你在离线时用过的那些小把戏就不灵了。你 无法通过编辑存档文件给自己一只 40 级的怪物,因为存档 文件不再是真相所在 —— 服务器才是。在本地设置等级, 下一次队伍同步就会把它覆盖,或者更糟,它没有被覆盖,于是你花一个 下午去追一个只存在于你机器上的错误。
这就是它存在的全部理由。在服务器是权威时向本地存档写入的调试工具 不是工具:它是幻影错误的制造机。所以每一个 GM 操作都是服务器 RPC,由服务器解析、 由服务器持久化,并且对每个发出请求的客 户端可见。
GM 模式是给运营服务器的人准备的 —— 开发期间的你, 以及上线后运行你的游戏的人。它不是玩家功能,也 不是一个开启着就发布的作弊菜单。参见锁定。
两种进入方式
同样的八个 RPC 可以从两个地方访问,因为有两种不同的工作 需要它们。
| 游戏内面板 | Hub 的 GM 选项卡 | |
|---|---|---|
| 位置 | 运行中的游戏,F9 | Tools → MCE → OpenMon Hub → GM |
| 用于 | 边玩边测试 | 无需启动游戏就能运营 |
| 需要 | 一个已登录的在线会话 | 它自己的邮箱/密码登录 |
游戏内面板(F9)
该快捷键会自行安装 —— 没有任何东西需要拖进场景,这是 有意为之:运营者工具必须在任何场景中都能工作,包括你在购买引擎之后 创建的场景,而手工接线的场景到下一个场景就会被忘掉。
它并非一直如此。GmModeHotkey 作为一个零引用的组件发布 —— 没有
预制体、场景或资产提到过它,所以没有任何东西实例化它,F9 在
任何游戏中都无法工作。这是通过实际操作而不是阅读发现的:在一个在线会话中按下 F9,
以真正的游戏管理员身份登录,根本没有向服务器发送 gamemaster_status。

这是在线世界之上的面板,用服务器认可的账户按 F9 打 开。底部的那一行 ——
"10 verbos disponibles" —— 不是客户端写的标签:它是服务器
对 gamemaster_status 的自己的回答,这就是为什么没有权限的账户
会看到面板拒绝打开,而不是空着打开。
F9 是默认值,因为它在 MCE 用于游玩的范围之外 —— 移动键、
Z/X 和菜单绑定都不受影响,所以面板不会吞掉游戏需要的输入。
该绑定位于 GmModeHotkey.cs 中,是一个普通的 Key 字段,所以你可以改动它。
面板只会为服务器认定为游戏管理员的账户出现。它是
询问,而不是假定。打开时它调用 gamemaster_status,答案
是关于调用者的:无法询问“那个账户是 GM 吗”,
这就是为什么不能用这个 RPC 来枚举你的服务器上谁拥有权力。
Hub 的 GM 选项卡

Hub 选项卡使用邮箱和密码登录,与玩家完全一样, 并获得一个真正的会话令牌。这是一个有意的选择,值得 解释,因为 Hub 的其余部分并不是这样工作的。
其他每个与服务器通信的 Hub 面板 —— 尤其是播种 —— 都使用 Nakama 运行时的 http_key 进行
服务器对服务器通信。该密钥没有关联的用户。而所有七个执行性动词都需要
ctx.userId,因为它们每一个都会写入一行记录,指明是谁做的。
我们本可以添加 使用 http_key 的动词变体。我们拒绝了,理由只有一句话:
审计记录会写着*“是 http_key 干的”*,而日志
就会失去它的主语 —— 而这正是任何人向管理员日志询问的唯一内容。
http_key 不是游戏管理员它们是两种含义不同的凭据。持有播种密钥让你可以 以服务器对服务器的方式写入存储。它不会让你成为游戏管理员, 也绝不会授予 GM 动词。不要混为一谈,也不要把它们中的任何一个放进 你的仓库。
该选项卡还区分四种状态,而不是把它们并成一种 失败。“你尚未登录”、“你已登录但不是 GM”、“你 是 GM 但此服务器开启了紧急开关”以及“就绪”,会把你带到四个 不同的地方。单一的“无法连接”会让你去检查 凭据,而你真正需要的是一次授权 —— 或者让你去播种一个你 已经拥有的权限,而你需要的是联系运营服务器的人。
该选项卡不会在编辑器会话之间记住你的密码。主机、端口、 服务器密钥和邮箱会保留;密码不会。
八个动词
一个提问,七个行动。
| RPC | 作用 |
|---|---|
gamemaster_status | 我是游戏管理员吗?这里启用了 GM 模式吗?有哪些动词? |
gamemaster_mint_monster | 在服务器上创建指定物种的怪物,由服务器分配 ID |
gamemaster_set_level | 修改怪物的等级 |
gamemaster_set_hp | 设置当前 HP —— 包括降到零,以便到达濒死路径 |
gamemaster_heal_party | 完全恢复队伍 |
gamemaster_force_encounter | 强制下一次野生遭遇 |
gamemaster_set_dex | 把某个物种标记为已见或已捕捉 |
gamemaster_set_variable | 写入一个游戏变量 |
gamemaster_mint_monster 值得说明一下。它在服务器上创建怪物,
并由服务器分配 ID。没有任何客户端路径可以铸造
怪物 —— 上行链路只能更新玩家通过游玩而改变的七个字段,
仅此而已。如果你需要让一只怪物存在,这是唯一的门。
为什么这比重玩内容更好
gamemaster_set_level 之所以存在,是因为验证一个进化动画过去
需要 126 场战斗。它所取代的功能不是绕过测试的捷径;
它是会被运行的测试与不会被运行的测试之间的区别。
锁定
在一个动词执行之前,必须同时满足三个独立的条件。其中任何一个 都足以阻止它。
1. 游戏管理员表。 只有在该表中的账户才是 GM。该表 一开始是空的,而空意味着没有人 —— 不是“所有人”,不是“第一个 账户”,也不是“持有密钥的人”。全新的服务器根本没有游戏管理员。
2. 紧急开关。 设置环境变量
MCE_GM_MODE_DISABLED=true 会在不动该表的情况下关闭所有动词。在生产节点上
使用它:授权保持原样,并且什么也无法
调用。再次关闭它会恢复你原来拥有的一切,所以你永远不必
在事故中凭记忆重建该表。
3. 按动词的闸门。 requireGameMasterVerb 在每次调用时运行,包括
gamemaster_status。被拒绝的调用也会被记录。
两条审计记录,有意为之
每个 GM 操作都会写入两条记录,它们为两种不同的读者而存在。
gm_audit 是运营者的日志。它归系统所有,记录游戏
管理员、动词和目标,并且每次调用都会写入 —— 包括
被拒绝的那些。拒绝恰恰是管理员日志所要记录的事件。
第二条记录放在目标玩家自己的账户之下,该玩家可以读取。 这是容易被跳过的那一半,也是在伦理上重要的那一半: 玩家总是能得知有权限的人动过他们的数据。“被动过却从未被告知” 这种状态是该系统无法表示的 —— 玩家可见的那一行与效果本身在同一次 存储写入中一起提交,所以不存在其中一个生效而另一个没有生效的窗口。
设置
- 让服务器运行起来 —— 参见设置。
- 创建你想用来运营的账户(玩一次游戏,或注册)。
- 在
game_masters表中授予它游戏管理员权限。客户端无法做到这一点:服务器对服务器的调用mce_gamemaster_seed接受{ "grant": [userId, ...], "revoke": [userId, ...] },并且和其他播种调用一样需要 Nakama 运行时的http_key。它是幂等的,并且绝不会撤销未列在revoke中的账户。 - 打开 Hub 的 GM 选项卡,登录,并确认状态行显示你是 GM。
- 在游戏中按 F9。
如果面板没有出现,要读的是状态调用:它会告诉你 是三道闸门中的哪一道拦住了你。
发布之前
- 在玩家可以访问的任何节点上设置
MCE_GM_MODE_DISABLED=true,除非你 有意要在生产环境中启用实时 GM 工具。 - 保持游戏管理员表小而且经过审计。其中的每个账户都可以写入 任何玩家的数据。
- 事故之后阅读
gm_audit。它正是为那一刻而写的。