跳到主要内容

离线模式

在 MCE 中,"离线"有两种完全不同的含义,把它们混为一谈,最快的后果就是花上一整天去调试一个本来就不该存在的连接。

是什么适用于谁
没有联机层引擎在编译时没有 MCE_ONLINE 脚本定义,Nakama 层根本不会被编译进去。所有单机作品。这是默认情况。
离线回退联机层确实编译进去了,但此刻没有服务器响应。服务器宕机的联机作品,或没有网络的玩家。

单机作品完全不需要这一页:没有 MCE_ONLINE,就没有可以丢失的连接。下文讲的是第二列。

什么会让一次会话进入离线​

NakamaManager 只有一个状态机,有四种不同情形会把它置为 Offline:

情形会发生什么
找不到 OnlineConfig 资源进入 Offline,日志中出现 No OnlineConfig found. Online features disabled.
配置中 EnableOnline 被关闭进入 Offline,连接调用返回 false 而不是抛出异常
连接失败且 AllowOfflineFallback 开启(默认)进入 Offline,日志中出现 Falling back to offline mode.
连接失败且 AllowOfflineFallback 关闭进入 Failed——一个独立状态,留给宁可停下也不愿半联机运行的作品

最后一行正是这个开关存在的理由。进度必须由服务器裁定的作品——竞技排位、共享经济——与其让玩家玩一场服务器永远不会接受的会话,不如干脆拒绝启动。而联机只是加分项的作品需要的恰恰相反。开关就在 OnlineConfig 资源里,紧挨着 EnableOnline。

IsOffline 对 Offline 和 Disconnected 都为真,因为提问"我现在能发送吗?"的代码,在两种情况下要的是同一个答案。

还能工作的部分​

每个联机服务都可以在完全没有 manager 的情况下构造。这不是副作用,而是契约:服务在启动时就被创建,那时谁都还不知道服务器会不会响应,而一个在构造函数里抛异常的服务会把整个游戏一起拖垮。

所以 WorldSyncService、BattleMatchmaker、SpectatorService、RaidBattleService、FriendService、TradeService、GTLService、WalletService、ShopService、CloudSaveService、HousingService 和 ChannelManager 在离线会话中都存在。它们不做的事只有一件:不与任何东西通信——需要服务器的调用会报告失败,而不是阻塞。CloudSaveService.HasCloudSave 为 false,而本地存档系统——与单机作品用的是同一套——让游戏继续运转。

守住这条线的是编辑器模式测试 OnlineServices_HandleOfflineMode:它用空 manager 构造全部十二个服务,任何一个抛出异常就判失败。

重新上线​

当状态已经是 Disconnected 或 Offline 时,DisconnectAsync 会立即返回,所以在离线会话里调用它既安全又廉价。重连就是一次普通的连接调用,事前不需要拆除任何东西。

这一页没有展示的内容​

这里还没有一张在离线回退中进行游戏的截图。状态、开关和那十二个服务都是从代码中读出的,并由上面提到的测试覆盖;故意停掉服务器后录下的实跑仍待完成。