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

# Adding Player Logic

In All Out, the player is a first-class gameplay object. Your `Player :: class : Player_Base` is where you put **per-player state** (health, loadouts, cooldowns, UI toggles, progression, etc).

{% hint style="warning" %}
Assume multiple players are connected. Avoid global state that would break when there’s more than one player.
{% endhint %}

## Per-player state

Store gameplay state on the player or objects owned by the player.

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

## Server + client: what runs where?

All Out automatically syncs gameplay state from the server to clients. You still need to decide **what code should run on server** vs **what can be local-only**.

Two common checks:

* `is_local_or_server()`: gameplay UI + input handling (runs on server + local client)
* `is_local()`: purely cosmetic UI/effects (runs only on the local client)

```go
Player :: class : Player_Base {
    ao_late_update :: method(dt: float) {
        // Gameplay UI + input handling (server + local client)
        if is_local_or_server() {
            // draw_ability_button(this, Shoot_Ability, 0);
            // Handle taps/presses that change game state
        }

        // Cosmetic-only UI (local client only)
        if is_local() {
            // UI.text(..., "Waiting for host...");
            // Particles, screen shake, etc.
        }
    }
}
```

{% hint style="info" %}
If something affects the world (damage, rewards, spawning, win conditions), treat it as **server-authoritative**. If it’s just presentation (UI/particles), keep it local.
{% endhint %}

## Player identity and profile data

`Player_Base` exposes identity fields you’ll use often:

* `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()` and UI rect helpers such as `p.get_chat_rect()`

```go
Player :: class : Player_Base {
    ao_start :: method() {
        log_info("player joined: % (%)", {this.get_username(), this.get_user_id()});
    }
}
```

## Persistence: where to store player progress

* **Economy**: currencies (coins/gems/xp) with automatic persistence + creator portal editing\
  See [Economy](/data-and-persistence/economy.md).
* **Save**: general key/value persistence (settings, quest state, unlock lists, etc)\
  See [Save System](/data-and-persistence/save.md).
* **Inventory**: item stacks/instances in a player inventory (optionally auto-saved)\
  See [Inventory](/core-engine-concepts/inventory.md).

## Common pattern: load saved values in `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");
    }
}
```

## Best practices

* **Keep per-player state on `Player`.** Avoid globals for anything player-specific.
* **Separate gameplay vs cosmetics.** Use `is_local_or_server()` for gameplay input/UI, `is_local()` for local-only visuals.
* **Prefer the built-in persistence APIs** instead of rolling your own (Economy/Save/Inventory).

## Player\_Base reference

See the `Player_Base` class in `core:ao` (inherits from `AO_Player : Component`) for commonly used fields and methods.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.allout.game/scripting/player-model.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
