codeНачало работы с CSL

CSL — собственный язык программирования All Out, созданный, чтобы писать многопользовательские игры было так же просто, как создавать одиночные игры.

CSL — это собственный скриптовый язык All Out. Он статически типизирован и по ощущениям ближе всего к Go/Odin — за исключением состояние игрового процесса автоматически синхронизируется с сервера на клиенты.

circle-info

Вам не нужно писать RPC, SyncVar'ы или собственную репликацию. Сосредоточьтесь на логике игрового процесса; платформа позаботится о сетевом взаимодействии.

Ваш первый скрипт (main.csl)

Когда вы создаёте новый проект, All Out генерирует main.csl в каталоге вашего проекта scripts/ папку.

import "core:ao"

// ============================================================================
// Глобальный жизненный цикл
// ============================================================================

ao_before_scene_load :: proc() {
    // Регистрирует определения предметов, валюты и т.д.
    // Выполняется до создания сцены.
}

ao_start :: proc() {
    // Вызывается один раз при старте сцены.
}

ao_update :: proc(dt: float) {
    // Вызывается каждый кадр.
}

ao_late_update :: proc(dt: float) {
    // Вызывается каждый кадр после ao_update.
}

// ============================================================================
// Жизненный цикл игрока
// ============================================================================

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

    ao_update :: method(dt: float) {
    }

    ao_late_update :: method(dt: float) {
    }

    ao_end :: method() {
    }
}

Например, выводите сообщение в лог, когда каждый игрок присоединяется:

Если вам нужно более подробное объяснение того, когда эти функции выполняются, см. Жизненный цикл игры/кадра.

Импорты

Ваш main.csl должен импортировать core:ao и любые папки, которые вы создаёте (например ui/, abilities/, и т.д.).

circle-exclamation

Объявления (переменные и константы)

Объявления связывают имя со значением.

Переменные

Либо <type> или <expression> можно опустить:

Константы

Константы используют :: и должны быть вычислены во время компиляции:

Это недопустимо (потому что a не является константой времени компиляции):

Типы

Примитивные типы

  • Знаковые целые: s8, s16, s32, s64

  • Беззнаковые целые: u8, u16, u32, u64

  • Булевы: b8, b16, b32, b64

  • Вещественные: f32, f64

  • Псевдонимы:

    • int == s64

    • uint == u64

    • bool == b8

    • float == f32

  • Векторы: v2, v3, v4

  • string

  • typeid

  • any

Типы векторов

v2 имеют .x, .y; v3 добавляют .z; v4 добавляют .w — все поля типа float:

Структуры и классы

Структуры являются типами-значениями (копируются при присваивании). Классы являются ссылочными типами (вы их выделяете с помощью new).

Структуры (типы-значения)

Классы (ссылочные типы)

Наследование

Структуры/классы могут наследоваться от других структур/классов:

Процедуры и методы

Процедуры (proc)

Процедуры — обычные значения и могут быть присвоены/храниться как любые другие значения:

Методы (method)

Используйте method() внутри структуры/класса. У методов есть неявный this параметр-ссылка.

Доступ к полю vs вызов метода

Используйте . для полей — -> для методов:

circle-info

Любую процедуру можно вызвать как «метод», если её первый параметр совпадает с типом приёмника. Это распространённый шаблон в CSL.

Массивы

В CSL есть несколько типов «похожих на массив» структур, которые вы будете постоянно использовать:

  • Фиксированные массивы: [4]int

  • Срезы / управляемые массивы: []T (часто используются как «просмотр только для чтения» в массиве)

  • Динамические массивы: [..]T (изменяемый список)

  • Неуправляемые массивы: [^]T (используются в сигнатурах встроенного API, таких как format_string, log_info, и т.д. — передавайте значения как {a, b, c})

Динамические массивы предоставляют .data, .count, и .capacity, и используют синтаксис вызова метода для операций:

Для полного руководства (включая шаблоны удаления) см. Массивы и коллекции.

Управление потоком выполнения

If / else

Switch

While / for / foreach

Приведение типов

Используйте expr.(T) для приведения:

Передача по ссылке: ref (предпочтительно)

Когда нужно изменить параметр, предпочитайте ref сырым указателям.

Обратные вызовы: указатели на функции + userdata (замыканий нет)

В CSL нет замыканий. Встроенные proc(...) { ... } не могут захватывать внешние переменные.

Чтобы нести контекст, сочетайте колбэки с userdata: Object полем:

Информация о типах (типы как значения)

typeid значения могут передаваться в полиморфные процедуры:

Лучшие практики (CSL в All Out)

  • Избегайте глобального состояния игрового процесса. К нескольким игрокам подключаются — храните состояние на игрока в Player вместо этого.

  • Разделяйте косметическую и игровую логику. Используйте is_local() для локального UI/частиц, и is_local_or_server() для игровых вводов, которые должны выполняться на сервере и локальном клиенте.

  • По умолчанию ориентируйтесь на мобильные устройства. Не полагайтесь на ввод с клавиатуры/мыши, если ваша игра явно не ориентирована на ПК.

  • Если вы не уверены в синтаксисе или API, проверьте api_reference/ папку, сгенерированную в вашем проекте (она содержит актуальную версию core.csl surface).

Последнее обновление