codePrimeros pasos con CSL

CSL es el lenguaje de programación personalizado de All Out, creado para hacer que escribir juegos multijugador sea tan fácil como crear juegos para un solo jugador.

CSL es el lenguaje de scripting personalizado de All Out. Es de tipado estático y se parece más a Go/Odin — excepto el estado de la jugabilidad se sincroniza automáticamente del servidor a los clientes.

circle-info

No necesitas escribir RPCs, SyncVars ni replicación personalizada. Concéntrate en la lógica de juego; la plataforma se encarga de la red por ti.

Tu primer script (main.csl)

Cuando creas un proyecto nuevo, All Out genera un main.csl en la scripts/ carpeta de tu proyecto.

import "core:ao"

// ============================================================================
// Ciclo de vida global
// ============================================================================

ao_before_scene_load :: proc() {
    // Registrar definiciones de objetos, monedas, etc.
    // Se ejecuta antes de que se cree la escena.
}

ao_start :: proc() {
    // Se llama una vez cuando la escena comienza.
}

ao_update :: proc(dt: float) {
    // Se llama en cada fotograma.
}

ao_late_update :: proc(dt: float) {
    // Se llama en cada fotograma después de ao_update.
}

// ============================================================================
// Ciclo de vida del jugador
// ============================================================================

Player :: class : Player_Base {
    ao_start :: method() {
    }

    ao_update :: method(dt: float) {
    }

    ao_late_update :: method(dt: float) {
    }

    ao_end :: method() {
    }
}

Por ejemplo, registra un mensaje cuando se una cada jugador:

Si quieres una explicación más profunda de cuándo se ejecutan estas funciones, consulta Ciclo de vida del juego/fotograma.

Importaciones

Tu main.csl debe importar core:ao y cualquier carpeta que crees (como ui/, abilities/, etc.).

circle-exclamation

Declaraciones (variables y constantes)

Las declaraciones vinculan un nombre a un valor.

Variables

O bien <tipo> o <expresión> puede omitirse:

Constantes

Las constantes usan :: y deben ser constantes en tiempo de compilación:

Esto no es válido (porque a no es una constante en tiempo de compilación):

Tipos

Tipos primitivos

  • Enteros con signo: s8, s16, s32, s64

  • Enteros sin signo: u8, u16, u32, u64

  • Booleanos: b8, b16, b32, b64

  • Flotantes: f32, f64

  • Alias:

    • int == s64

    • uint == u64

    • bool == b8

    • float == f32

  • Vectores: v2, v3, v4

  • string

  • typeid

  • cualquier

Los tipos Vector

v2 tiene .x, .y; v3 añade .z; v4 añade .w — todos campos float:

Structs y clases

Los structs son tipos por valor (se copian en la asignación). Las clases son tipos por referencia (las asignas con new).

Structs (tipos por valor)

Clases (tipos por referencia)

Herencia

Los structs/clases pueden heredar de otros structs/clases:

Procedimientos y métodos

Procedimientos (proc)

Los procedimientos son valores normales y pueden asignarse/almacenarse como cualquier otro valor:

Métodos (method)

Usa method() dentro de un struct/class. Los métodos tienen un parámetro de referencia implícito this .

Acceso a campos vs llamadas a métodos

Usa . para campos, -> para métodos:

circle-info

Cualquier procedimiento puede llamarse como un “método” si su primer parámetro coincide con el tipo receptor. Este es un patrón común en CSL.

Matrices

CSL tiene unos cuantos tipos “tipo arreglo” que usarás constantemente:

  • Arrays fijos: [4]int

  • Slices / arrays gestionados: []T (a menudo usado como “vista de solo lectura” de un arreglo)

  • Arrays dinámicos: [..]T (lista redimensionable)

  • Arreglos no gestionados: [^]T (usado en firmas de API встроadas como format_string, log_info, etc. — pasa valores como {a, b, c})

Los arreglos dinámicos exponen .data, .count, y .capacity, y usan sintaxis de llamada a método para las operaciones:

Para una guía completa (incluidos patrones de eliminación), consulta Arrays y colecciones.

Flujo de control

If / else

Switch

While / for / foreach

Conversión de tipos

Usa expr.(T) para convertir:

Pasar por referencia: ref (preferido)

Cuando necesitas modificar un parámetro, prefiere ref sobre los punteros sin procesar.

Callbacks: punteros a funciones + userdata (sin cierres)

CSL no tiene cierres. Los proc(...) { ... } en línea no pueden capturar variables circundantes.

Para transportar contexto, combina los callbacks con un userdata: Object campo:

Información de tipos (tipos como valores)

typeid los valores pueden pasarse a procedimientos polimórficos:

Mejores prácticas (CSL en All Out)

  • Evita el estado global de jugabilidad. Se conectan varios jugadores — guarda el estado por jugador en Player en su lugar.

  • Separa la lógica cosmética de la lógica de jugabilidad. Usa is_local() para UI/partículas solo locales, y is_local_or_server() para entradas de jugabilidad que deben ejecutarse en el servidor + cliente local.

  • Valores predeterminados para móvil. No dependas de la entrada de teclado/ratón a menos que tu juego esté explícitamente enfocado en PC.

  • Si no estás seguro sobre la sintaxis o las APIs, consulta la api_reference/ carpeta generada en tu proyecto (contiene la última core.csl superficie).

Última actualización