> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/all-out-docs/docs-zh/jiao-ben-bian-xie/game-frame-lifecycle.md).

# 游戏/帧生命周期

All Out 游戏采用简单的生命周期：有些回调只在启动时执行一次，有些则每帧执行。

你可以通过以下任一方式实现这些回调：

* **全局** （顶层 `ao_*` 中的过程 `main.csl`），或者
* **在组件上** （诸如以下方法 `ao_update` 内部 `Player` 或你自己的 `组件` 子类）

{% hint style="info" %}
如果你在找“模板” `main.csl`，请参见 [CSL 入门](/all-out-docs/docs-zh/jiao-ben-bian-xie/syntax.md).
{% endhint %}

## 全局生命周期（场景级）

这些是以下内容中的顶层过程： `main.csl`:

### `ao_before_scene_load`

在空的 `场景` 创建之后、但在其序列化的实体和组件加载之前运行。通常你会在这里注册场景加载期间所需的定义：

* 物品定义（背包系统）
* 货币（经济系统）
* 全局配置值/常量

### `ao_start`

在场景开始时运行一次。

常见用途：

* 生成运行时实体/预制件
* 初始化全局系统
* 读取全局存档数据

### `ao_update(dt)`

每帧运行。

常见用途：

* 游戏计时器、波次管理器
* 依赖时间的生成逻辑
* 游戏规则

### `ao_late_update(dt)`

在以下之后每帧运行： `ao_update`.

常见用途：

* 依赖本帧最终位置/状态的场景级工作
* 更新后的“清理”工作

玩家 UI 应放在 `Player.ao_late_update`，而不是这个全局回调中。

## 组件生命周期（每个实体）

组件（包括 `Player`）可以实现：

* `ao_start()`
* `ao_update(dt)`
* `ao_late_update(dt)`
* `ao_end()`
* `ao_on_state_sync()` （在网络状态同步时调用）

{% hint style="warning" %}
`ao_start()` 不会为每个客户端重新播放。当某个对象已在服务器上开始运行后，客户端才加入时，同步后的组件可能在到达时其启动生命周期已完成。不要使用 `ao_start()` 用于每个加入的客户端都必须执行的客户端本地展示初始化；应在以下位置根据同步状态重建该展示： `ao_on_state_sync()` 其上，而不是全局变量中。
{% endhint %}

示例：

```go
Orbiter :: class : Component {
    ao_start :: method() {
        // 初始化
    }

    ao_update :: method(dt: float) {
        // 每帧行为
    }

    ao_end :: method() {
        // 清理（销毁时）
    }
}
```

## 代码放在哪里：经验法则

* **每个玩家的状态/逻辑**：放在 `Player` （参见 [添加玩家逻辑](/all-out-docs/docs-zh/jiao-ben-bian-xie/player-model.md))
* **可复用的实体行为**：放在自定义组件上（见 [实体与组件](/all-out-docs/docs-zh/jiao-ben-bian-xie/entities-and-components.md))
* **全局协调 / 规则**：放在全局生命周期（`ao_*` 过程）中

## 服务器端 vs 本地

全局和组件的游戏回调会在预测客户端和服务器上都运行。不要用 `Game.is_server()`.

将该玩家的所有 UI 绘制都来自 `ao_late_update` 调用栈，并包裹在 `is_local_or_server()`。请使用 `is_local()` 仅用于玩家特定的视觉覆盖。仅在以下情况下更改的状态 `is_local()` 会被下一次服务器同步替换。

这些是以下对象上的方法： `Player_Base`。可在玩家引用上调用它们，或作为 `is_local_or_server()` / `is_local()` 在一个 `Player` 方法中（隐式 `this`).
