network-wired网络基础

All Out 是以多人优先设计的,但 CSL 的设计让你几乎可以像写单人游戏一样编写玩法。

核心思想是:

circle-info

所有玩法状态都会自动从服务器同步到客户端。你不需要编写 RPC 或“网络生成”之类的东西。

权限(谁来决定什么?)

一般来说:

  • 服务器:决定玩法状态(伤害、奖励、生成、胜负、基于查询的碰撞等)

  • 客户端:渲染并播放特效表现(UI、粒子、屏幕震动、声音)

实际上,你的大部分代码都会在服务器和客户端两边运行——你只需要区分 哪些工作 在哪边执行。

本地与服务器检查

你会经常用到两个检查:

  • is_local_or_server():用于玩法 UI 和输入处理(在服务器 + 本地客户端上运行)

  • is_local():用于纯视觉效果(仅在本地客户端上运行)

示例:

Player :: class : Player_Base {
    ao_late_update :: method(dt: float) {
        // 用于玩法 UI 和输入(在服务器 + 本地客户端上运行)
        if is_local_or_server() {
            // draw_ability_button(this, Shoot_Ability, 0);
            // 处理会影响游戏状态的输入
            // 移动由系统自动处理
        }

        // 用于纯视觉效果(仅在本地客户端上运行)
        if is_local() {
            // UI.text(..., "等待主机开始游戏...");
            // 粒子效果、视觉 UI 等。
        }
    }
}
circle-exclamation

客户端特定状态

有时你需要 本地 状态,这些状态不应影响玩法,也不需要同步:

  • UI 打开/关闭切换

  • 镜头震动计时器

  • 物品栏 UI 中的“上一个悬停物品”

把这些作为字段保留,但只在 is_local() 检查后读写它们。

多人游戏安全规则

  • 避免使用全局变量存储玩家状态。 如果每个玩家都需要自己的值,请把它存到 Player.

  • 谨慎使用“单例”。 如果你确实需要一个全局管理器,确保它不会意外存储每个玩家的数据。

  • 优先使用确定性的服务器状态。 客户端应该响应服务器的状态,而不是自己编造状态。

调试网络问题

  • 添加 log_info(...) 在服务器路径上(不只是本地)输出,这样你就能看到权威决策。

  • 如果某些东西“本地能用”但其他玩家不行,通常是:

    • is_local() 保护的代码本应由服务器权威决定,或者

    • 一个全局变量被多个玩家覆盖了。

相关文档

最后更新于