> 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/ru/skripting/game-frame-lifecycle.md).

# Жизненный цикл игры/кадра

В отличие от скриптинга на основе событий, как в Roblox, игры в All Out используют модель жизненного цикла кадров, которая позволяет запускать код при старте игры, на каждом кадре и в конце сессии.

Игры All Out работают по простому жизненному циклу: некоторые колбэки вызываются один раз при запуске, а некоторые — каждый кадр.

Вы будете реализовывать эти колбэки либо:

* **Глобально** (на верхнем уровне `ao_*` процедуры в `main.csl`), или
* **На компонентах** (методы вроде `ao_update` внутри `Player` или ваших собственных `Component` подклассов)

{% hint style="info" %}
Если вы ищете «шаблон» `main.csl`, см. [Начало работы с CSL](/all-out-docs/ru/skripting/syntax.md).
{% endhint %}

## Глобальный жизненный цикл (на уровне сцены)

Это процедуры верхнего уровня в `main.csl`:

### `ao_before_scene_load`

Выполняется после того, как пустая `сцена` создана, но до того, как загружаются её сериализованные сущности и компоненты. Здесь обычно регистрируют определения, нужные во время загрузки сцены:

* Определения предметов (система инвентаря)
* Валюты (экономическая система)
* Глобальные значения конфигурации/константы

### `ao_start`

Выполняется один раз при запуске сцены.

Типичные случаи использования:

* Создавать сущности/префабы во время выполнения
* Инициализировать глобальные системы
* Читать данные сохранений на уровне всей игры

### `ao_update(dt)`

Выполняется каждый кадр.

Типичные случаи использования:

* Игровые таймеры, менеджеры волн
* Логика спавна, зависящая от времени
* Правила геймплея

### `ao_late_update(dt)`

Выполняется каждый кадр после `ao_update`.

Типичные случаи использования:

* Работа на уровне сцены, зависящая от финальных позиций/состояния за кадр
* Работа по «очистке» после обновлений

Интерфейс игрока относится к `Player.ao_late_update`, а не к этому глобальному колбэку.

### `ao_draw(dt)`

Только косметика; выполняется при отправках, которые могут рендериться, и пропускает ресимуляцию. `dt` — это отправленный дельта-тайм симуляции; используйте `get_time()` для абсолютного времени.

Никогда не размещайте здесь игровой процесс или интерактивный UI. Используйте `ao_update`/`ao_late_update` (обычно `Player.ao_late_update` для UI).

## Жизненный цикл компонента (на уровне сущности)

Компоненты (включая `Player`) могут реализовывать:

* `ao_start()`
* `ao_update(dt)`
* `ao_late_update(dt)`
* `ao_draw(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/ru/skripting/player-model.md))
* **Поведение сущностей, пригодное для повторного использования**: поместите их в пользовательские компоненты (см. [Сущности и компоненты](/all-out-docs/ru/skripting/entities-and-components.md))
* **Глобальная координация / правила**: поместите это в глобальный жизненный цикл (`ao_*` процедуры)

## Сервер против локального

Глобальные и компонентные игровые колбэки выполняются и на предсказывающем клиенте, и на сервере. Не оборачивайте игровой процесс в `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`).
