> 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/random-math-and-more.md).

# Случайность, математика и многое другое

Эта страница — сборная солянка из утилит, которыми вы будете пользоваться постоянно: RNG, форматирование, время и несколько основных подсистем, которые встречаются в большинстве игр.

{% hint style="info" %}
Если вы ищете массивы/срезы, см. [Массивы и коллекции](/all-out-docs/ru/skripting/arrays-and-collections.md).
{% endhint %}

## Случайные числа (RNG)

Случайность использует явный `u64` seed. Передавайте seed по `ref` ссылке, чтобы он обновлялся.

```go
rng: u64 = rng_root_seed();
// или детерминированно для каждой сущности:
// rng: u64 = rng_seed(entity.id);

// Значения диапазона включительные
roll := rng_range_int(ref rng, 1, 10);
chance := rng_range_float(ref rng, 0, 1);

// Случайные точки и перемешивание
offset := rng_disk(ref rng, 0.5, 2.0);
spawn_points: [..]v2;
spawn_points.append({0, 0});
spawn_points.append({4, 0});
rng_shuffle(ref rng, spawn_points);
```

{% hint style="warning" %}
Игровая случайность должна выполняться в общей предсказанной игровой ветке. Начинайте с `rng_root_seed()` или другого стабильного seed; не задавайте seed для игрового процесса из данных, доступных только локально.
{% endhint %}

## Математические функции

Общие математические помощники:

```go
angle_sin := sin(x);
angle_cos := cos(x);
angle := atan2(dir.y, dir.x);
degrees := to_degrees(angle);
radians := to_radians(degrees);

result := pow(2.0, 3.0);   // 8.0
root := sqrt(16.0);        // 4.0

value := lerp(0.0, 100.0, 0.5);  // 50.0
clamped := clamp(value, 0.0, 10.0);
stepped := linear_step(0.0, 1.0, value);

absolute := abs(-5);
minimum := min(5, 10);
maximum := max(5, 10);
direction_sign := sign(-12);

len := length(v);
len_sq := length_squared(v);
normalized := normalize(v);
facing := dot(normalized, {1, 0});
```

## Форматирование строк

Используйте `%` плейсхолдеры с массивом аргументов:

```go
format_string("Value: %", {42});
format_string("health: 100%");
```

Если вам нужен аргумент рядом со знаком процента (или рядом с другим аргументом), используйте `%0` как псевдоним для `%`:

```go
hp := 67;
format_string("health: %0%%", {hp}); // "health: 67%"
```

Для округления десятичных чисел используйте `format_float`:

```go
value := 3.14159;
format_string("pi: %", {format_float(value, decimals=2)}); // "pi: 3.14"
```

Общие строковые помощники:

```go
clean := string_trim("  hello  ");
parts := string_split("a,b,c", ",");
name_lower := to_lower(player.get_username());
name_upper := to_upper("ready");
short := string_substring("abcdef", 1, 3); // "bcd"
```

## Логирование

Логирование использует те же правила форматирования:

```go
log_info("Name: %, age: %", {player.get_username(), 12});
```

## Время

```go
current_time := get_time();       // float-секунды с начала игры
frame := get_frame_number();      // номер текущего кадра
now_ns := get_nanoseconds_since_epoch();
utc := get_utc_datetime();
```

## SFX

```go
sound := get_asset(SFX_Asset, "sfx/click.wav");

desc := SFX.default_sfx_desc();
desc.entity_to_follow = entity.id;
desc.delay = 0.25;

sound_id := SFX.play(sound, desc);
SFX.stop(sound_id);
```

{% hint style="warning" %}
Вызывайте игровые звуки из общей игровой ветки. Движок согласует предсказанное воспроизведение. Для звука, который должен слышать только один игрок, задайте `desc.specific_to_player = player`; не оборачивайте `SFX.play` в `is_local()`.
{% endhint %}

## Краткое начало работы с экономикой (валюты)

Валюты экономики — это **для каждого игрока** и **автоматически сохраняется**.

```go
ao_before_scene_load :: proc() {
    coin_icon := get_asset(Texture_Asset, "ui/coin.png");
    Economy.register_currency("Coins", coin_icon);
}

Economy.deposit_currency(player, "Coins", 10);
coins := Economy.get_balance(player, "Coins");

COST :: 50;
if Economy.can_withdraw_currency(player, "Coins", COST) {
    Economy.withdraw_currency(player, "Coins", COST);
}
```

Суммы пополнения и снятия должны быть неотрицательными.

См. [Экономика](/all-out-docs/ru/dannye-i-sokhranenie/economy.md) в полном руководстве.
