CSL — собственный язык программирования All Out, созданный, чтобы писать многопользовательские игры было так же просто, как создавать одиночные игры.
CSL — это собственный скриптовый язык All Out. Он статически типизирован и по ощущениям ближе всего к Go/Odin — за исключением состояние игрового процесса автоматически синхронизируется с сервера на клиенты.
Вам не нужно писать 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/, и т.д.).
В большинстве проектов импорт в main.csl только. Не разбрасывайте импорты по множеству файлов — в конце концов вы получите запутанные проблемы с порядком/видимостью.
Объявления (переменные и константы)
Объявления связывают имя со значением.
Переменные
Либо <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 вызов метода
Используйте . для полей — -> для методов:
Любую процедуру можно вызвать как «метод», если её первый параметр совпадает с типом приёмника. Это распространённый шаблон в CSL.
Массивы
В CSL есть несколько типов «похожих на массив» структур, которые вы будете постоянно использовать:
Фиксированные массивы: [4]int
Срезы / управляемые массивы: []T (часто используются как «просмотр только для чтения» в массиве)
Динамические массивы: [..]T (изменяемый список)
Неуправляемые массивы: [^]T (используются в сигнатурах встроенного API, таких как format_string, log_info, и т.д. — передавайте значения как {a, b, c})
Динамические массивы предоставляют .data, .count, и .capacity, и используют синтаксис вызова метода для операций:
Когда нужно изменить параметр, предпочитайте ref сырым указателям.
Обратные вызовы: указатели на функции + userdata (замыканий нет)
В CSL нет замыканий. Встроенные proc(...) { ... } не могут захватывать внешние переменные.
Чтобы нести контекст, сочетайте колбэки с userdata: Object полем:
Информация о типах (типы как значения)
typeid значения могут передаваться в полиморфные процедуры:
Лучшие практики (CSL в All Out)
Избегайте глобального состояния игрового процесса. К нескольким игрокам подключаются — храните состояние на игрока в Player вместо этого.
Разделяйте косметическую и игровую логику. Используйте is_local() для локального UI/частиц, и is_local_or_server() для игровых вводов, которые должны выполняться на сервере и локальном клиенте.
По умолчанию ориентируйтесь на мобильные устройства. Не полагайтесь на ввод с клавиатуры/мыши, если ваша игра явно не ориентирована на ПК.
Если вы не уверены в синтаксисе или API, проверьте api_reference/ папку, сгенерированную в вашем проекте (она содержит актуальную версию core.csl surface).