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

# Aleatorio, matemáticas y más

Esta página es un conjunto variado de utilidades de “las usarás constantemente”: RNG, formato, tiempo y algunos subsistemas básicos que aparecen en la mayoría de los juegos.

{% hint style="info" %}
Si buscas arreglos/slices, consulta [Arreglos y colecciones](/all-out-docs/docs-es/programacion/arrays-and-collections.md).
{% endhint %}

## Números aleatorios (RNG)

Random utiliza una `u64` semilla explícita. Pasa la semilla por `ref` para que se actualice.

```go
rng: u64 = rng_root_seed();
// o determinístico por entidad:
// rng: u64 = rng_seed(entity.id);

// Los valores del rango son inclusivos
roll := rng_range_int(ref rng, 1, 10);
chance := rng_range_float(ref rng, 0, 1);

// Puntos aleatorios y barajado
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" %}
La aleatoriedad de la jugabilidad debe ejecutarse en la ruta compartida de jugabilidad predicha. Comienza desde `rng_root_seed()` o cualquier otra semilla estable; no inicialices la jugabilidad con datos solo locales.
{% endhint %}

## Funciones matemáticas

Funciones matemáticas comunes:

```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});
```

## Formato de cadenas

Usa `%` marcadores de posición con un arreglo de argumentos:

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

Si necesitas un argumento junto a un signo de porcentaje (o junto a otro argumento), usa `%0` como alias de `%`:

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

Para redondear decimales, usa `format_float`:

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

Funciones comunes de cadenas:

```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"
```

## Registro

El registro sigue las mismas reglas de formato:

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

## Tiempo

```go
current_time := get_time();       // segundos en coma flotante desde el inicio del juego
frame := get_frame_number();      // número de fotograma actual
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" %}
Llama a los sonidos de jugabilidad desde la ruta compartida de jugabilidad. El motor reconcilia la reproducción predicha. Para un sonido que solo un jugador debe oír, establece `desc.specific_to_player = player`; no envuelvas `SFX.play` en `is_local()`.
{% endhint %}

## Inicio rápido de Economy (monedas)

Las monedas de Economy son **por jugador** y **persisten automáticamente**.

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

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

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

Los importes de depósito y retirada deben ser no negativos.

Ver [Economy](/all-out-docs/docs-es/datos-y-persistencia/economy.md) para la guía completa.
