Разработка кастомных игр на C#: Гайд по использованию CSharp.lua и VScript

dEN5

Пользователь
10 Фев 2019
27
1
steamcommunity.com
Проект
MADNESS: PROJECT ABADDON
Вступление

Всем привет. Традиционно кастомки в Доте пишутся на Lua через VScripts. Но если вы, как и я, привыкли к строгой типизации и возможностям C#, то есть способ не мучиться( или заняться дибилизмом ). Благодаря проекту CSharp.lua можно писать всю логику на Шарпе, компилить её в Луа и спокойно запускать в дотовской песочнице.

Я разобрался с тем, как это всё завести, пропатчить под ограничения API Доты и выстроить нормальный воркфлоу. Делюсь опытом.

---

1. Что нам понадобится (Инструментарий)

Для начала нужно понимать, как это работает «под капотом».

  • CSharp.lua — это не просто транспайлер, это мощный компилятор на базе Roslyn. Он превращает ваш C# код в читаемый Lua.
  • CoreSystem.lua — это мини-фреймворк, который идет в комплекте. Он эмулирует привычные типы .NET (LINQ, коллекции, делегаты) внутри Lua.
  • VScript — это наша среда исполнения. В Доте используется урезанная Lua 5.1. Там нет доступа к файловой системе (io), ограничена библиотека os и полностью вырезана debug.

Важный нюанс: Чтобы всё работало в Доте, при компиляции обязательно используем флаги -c (совместимость с Lua 5.1) и -p (отключение вызовов debug.setmetatable).

---

2. Структура проекта

Я организовал проект так, чтобы исходники лежали отдельно, а готовый скрипт сам улетал в папку аддона.

Примерная структура:
my-addon/src/ — тут весь ваш C#.
my-addon/output/ — сюда падает готовый out.lua.
compile.bat — скрипт для сборки одной кнопкой.

В самой папке аддона (game/dota_addons/имя/scripts/vscripts/) нам по сути нужен только один файл — out.lua (ваш код + CoreSystem) и стартовый addon_game_mode.lua.

---

3. Патчим CoreSystem (ОЧЕНЬ ВАЖНО)

Поскольку Valve сильно ограничили Lua в игре, стандартная библиотека CoreSystem будет выдавать ошибки, пытаясь обратиться к os.time или debug. Нужно внести пару правок ручками.

Правка DateTime.lua:
Нужно обернуть вызовы os в проверки, чтобы аддон не падал при инициализации:
local ostime = os and os.time
Если os недоступен, ставим заглушку (fallback) на UTC+0.

Правка Core.lua:
В Доте есть команда script_reload. По умолчанию CoreSystem кидает ассерт, если класс пытается определиться дважды. Чтобы перезагрузка скриптов работала, закомментируйте проверку:
-- assert(rawget(scope, name) == nil, className)
rawset(scope, name, cls)

---

4. Связка C# и API Доты

Самое интересное — как вызывать функции Доты из Шарпа. Мы используем атрибут @CSharpLua.Template.

Пример базового модификатора на C#:

C#:
namespace MyAddon.Base {
    public abstract class BaseModifier {
        // Обертка над методом из Lua
        /// @CSharpLua.Template = "{this}:GetParent()"
        protected extern object GetParent();

        /// @CSharpLua.Template = "IsServer()"
        protected static extern bool IsServer();
        
        public virtual bool IsHidden() => false;
    }
}

Теперь в наследнике вы просто пишете чистую логику на C#, а компилятор сам подставит нужные вызовы API Доты.

---

5. Точка входа и регистрация

В addon_game_mode.lua мы просто пишем require("out").
А внутри C# создаем класс EntryPoint, который прокинет ссылки на функции Activate и Precache.

C#:
public static class EntryPoint {
    /// @CSharpLua.Template = "Activate = {0}"
    private static extern void SetActivate(Action fn);

    public static void Setup() {
        SetActivate(GameMode.OnActivate);
        // Регистрация кастомных абилок в глобальной области Lua
        RegisterModifier(typeof(MyModifier));
    }
}

---

6. Процесс разработки (Воркфлоу)

1. Пишем код в Visual Studio / Rider (с поддержкой C# 10+).
2. Запускаем compile.bat. Он прогоняет компилятор и копирует out.lua в папку с Дотой.
3. В игре открываем консоль и пишем script_reload.
4. Всё! Изменения подхватились без перезапуска инструментария.

Итог:
Да, настройка требует времени, но на выходе мы получаем мощь Шарпа, типизацию и нормальную структуру кода, чего на чистом Lua в больших проектах добиться сложно.

Репозиторий с реализацией
 
  • Нравится
Реакции: fabio_longo
Мужик, ты легенда, такую тулзу открыть для нашего комьюнити - заслуживает отдельного уважения
 
Реклама: