gmod-rs/docs/LUA.md

6.7 KiB
Raw Blame History

Lua-рантайм Source RS

1. Базовая линия

  • GMod использует LuaJIT (семантика Lua 5.1) → берём mlua с feature luajit + vendored, JIT включён.
  • Понимание реальности: PAC3 и Starfall — это аддоны, исполняемые в GMod Lua. Starfall дополнительно тащит внутрь собственный Lua-интерпретатор. Значит, «поддержать Starfall/PAC3» = реализовать движковый API (render, RT, кости, материалы, meshes), который эти аддоны вызывают; их собственную логику пишем не мы.
  • Источники требований:
    • дампы клиентского Lua с реальных серверов через ~/glua-steal (gluasteal);
    • wiki.facepunch.com/gmod;
    • базовые lua-файлы из установки GMod (референс bootstrap-порядка);
    • наш инструмент lua-api-report (сканирует дампы и строит рейтинг используемых, но не реализованных API).

2. Порядок реализации

Очередь Цель Ключевые модули
1 HUD/UI аддоны сервера hook, net, timer, util, concommand, surface, draw, render, cam, input, render targets
2 Derma-меню vgui, derma, шрифты, layout, анимации, клиппинг, скролл
3 PAC3 кости/аттачменты моделей, RT, материал-оверрайды, цвет/материалы, бюджеты
4 Starfall (клиентсайд) API-паритет с тем, что использует аддон; усиленный sandbox

Правило: API строится «рельсами» — каждый модуль регистрируется декларативно (функции, сигнатуры, проверки аргументов), чтобы добавлять покрытие быстро и единообразно.

3. Sandbox (защита от крашедла)

Цель: аддон/сервер не может уронить клиент.

  1. Память: лимит на Lua-state (аллокатор-встрел), счётчики по аддонам.
  2. Время/инструкции: count-hook (например, каждые N тысяч инструкций) + watchdog-поток; превышение → ошибка «больше функций недоступно этому файлу», файл помечается опасным. Примечание: включение хуков на функциях отключает JIT для них — поэтому хуки активны только для недоверенного серверного кода; локальный код может исполняться без хуков (конвар).
  3. Запреты: io, os (кроме безопасного минимума), ffi, require вне whitelist, debug (или строго ограниченный), path traversal при любых файловых API.
  4. Лимиты ресурсов: размеры render targets, количество материалов/мешей/партиклов/ таймеров на аддон; квоты на кадр.
  5. Изоляция ошибок: каждый hook/колбек в catch_unwind; ошибка Lua не роняет кадр; после N ошибок колбек отключается (как в GMod сообщение в консоль).
  6. Safe mode: перед загрузкой файла пишем маркер «сейчас грузится X»; если прошлый запуск завершился нечисто — X в чёрный список, клиент стартует без него и сообщает.
  7. Chaos-тесты: бесконечный цикл, рекурсия, гигабайтный mesh, битый RT, thousands of timers, path traversal — всё в CI.

4. Загрузка кода с сервера

  • Lua-файлы приходят по сетевому каналу GMod (LZMA); храним в download-кэше по хэшу.
  • Загрузка — только из разрешённых корней («lua/», «addons/…»), никаких абсолютных путей.
  • Порядок bootstrap — как в GMod: engine/gamemode-файлы сервера, затем lua/autorun, затем клиентские аддоны; ошибки любого файла — не фатальны.
  • Повторный заход на сервер не качает то, что уже в кэше (см. NETWORK.md).

5. Мосты к движку

  • Vector/Angle: userdata с метатаблицами как в GMod (арифметика, методы).
  • Entity-фасад: ленивое создание Lua-объекта сущности; GetPos/SetPos/GetAngles…; в hot paths — никаких аллокаций, если аддон не трогает сущность.
  • net: net.Start/Write/Read/Receive с совместимой сериализацией и stringtable-сжатием имён.
  • render targets: объекты с лимитами и учётом VRAM; cam.Start3D2D, render.SetRenderTarget.
  • Материалы: Material(), CreateMaterial, render.SetMaterial, blend-режимы — строго с compat-семантикой рендера.
  • Meshes (для Starfall/аддонов): VertexBuffer/ObjectBuffer API (если требуется аддонами).

6. Производительность Lua

  • LuaJIT + минимум C-мостов в hot paths (batch-вызовы, кэш userdata).
  • Hooks: быстрый вызов по числовому ID; списки — массивы без аллокаций.
  • Тяжёлые аддоны: опционально выносить в отдельные состояния/потоки (архитектурная заготовка с M7), но по умолчанию — как в GMod (главный поток).

7. Что честно не обещаем

  • 1:1 Derma во всех деталях с первого раза — итерации по реальным аддонам.
  • Нативные бинарные модули Lua (.dll/.so аддонов) — не поддерживаем.
  • Полный паритет API «всё из wiki сразу» — идём по приоритетам и дампам.