> 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/player-model.md).

# 添加玩家逻辑

在 All Out 中，玩家是一级游戏对象。你的 `Player :: 类 : Player_Base` 这里是你放置 **每个玩家的状态** （生命值、装备配置、冷却时间、UI 开关、进度等）。

{% hint style="warning" %}
假设有多个玩家已连接。避免使用在玩家超过一名时会失效的全局状态。
{% endhint %}

## 每个玩家的状态

将游戏状态存储在玩家或玩家拥有的对象上。

```go
Player :: class : Player_Base {
    health: int;
    inventory_open: bool;
}
```

## 服务器 + 客户端：哪些内容在哪儿运行？

All Out 会自动将游戏状态从服务器同步到客户端。游戏方法会在预测客户端和服务器上都运行，因此不要用 `Game.is_server()`.

两种常见检查：

* `is_local_or_server()`：所有玩家 UI 及其产生的输入
* `is_local()`：仅玩家特定的视觉覆盖

```go
Player :: class : Player_Base {
    ao_late_update :: method(dt: float) {
        if is_local_or_server() {
            // 在这里绘制所有玩家 UI 并处理其输入。
        }

        if is_local() {
            // 在这里应用仅对玩家生效的可见性，但不要更改字段。
        }
    }
}
```

{% hint style="info" %}
所有玩家 UI 都应绘制自 `Player.ao_late_update` 下的 `is_local_or_server()`。仅在 `is_local()` 内部更改的字段会在协调期间被替换。
{% endhint %}

## 玩家身份和资料数据

`Player_Base` 公开你会经常使用的身份字段：

* `p.get_username() -> string`
* `p.get_user_id() -> string`
* `p.avatar_color`
* `p.device_kind` (`.PHONE`, `.TABLET`, `.PC`)
* `p.is_admin()`, `p.is_vip()`, `p.is_moderator()`, `p.is_youtuber()`
* `p.is_chat_open()` 以及 UI 矩形辅助函数，例如 `p.get_chat_rect()`

```go
Player :: class : Player_Base {
    ao_start :: method() {
        log_info("玩家加入：% (%)", {this.get_username(), this.get_user_id()});
    }
}
```

## 持久化：将玩家进度存储在哪里

* **经济系统**：货币（金币/宝石/xp），支持自动持久化 + 创作者门户编辑\
  参见 [经济系统](/all-out-docs/docs-zh/shu-ju-yu-chi-jiu-hua/economy.md).
* **存档**：通用键值持久化（设置、任务状态、解锁列表等）\
  参见 [保存系统](/all-out-docs/docs-zh/shu-ju-yu-chi-jiu-hua/save.md).
* **Inventory**：玩家库存中的物品堆叠/实例（可选自动保存）\
  参见 [Inventory](/all-out-docs/docs-zh/he-xin-yin-qing-gai-nian/inventory.md).

## 常见模式：在 `ao_start`

```go
Player :: class : Player_Base {
    xp: s64;
    selected_skin: string;

    ao_start :: method() {
        xp = Save.get_int(this, "xp", 0);
        selected_skin = Save.get_string(this, "selected_skin", "default");
    }
}
```

## 最佳实践

* **将每个玩家的状态保存在 `Player`.** 不要为任何玩家特定内容使用全局变量。
* **在共享的预测路径中运行游戏逻辑。** 在 `is_local_or_server()` 并将 `is_local()` 保留用于玩家特定的视觉覆盖。
* **优先使用内置持久化 API** 而不是自己另造一套（Economy/Save/Inventory）。

## Player\_Base 参考

参见 `api_references/core/ao/core.csl_engine` 在项目文件夹中查看完整的 `Player_Base` API。
