6.7 KiB
6.7 KiB
Lua-рантайм Source RS
1. Базовая линия
- GMod использует LuaJIT (семантика Lua 5.1) → берём
mluaс featureluajit+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).
- дампы клиентского Lua с реальных серверов через
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 (защита от крашедла)
Цель: аддон/сервер не может уронить клиент.
- Память: лимит на Lua-state (аллокатор-встрел), счётчики по аддонам.
- Время/инструкции: count-hook (например, каждые N тысяч инструкций) + watchdog-поток; превышение → ошибка «больше функций недоступно этому файлу», файл помечается опасным. Примечание: включение хуков на функциях отключает JIT для них — поэтому хуки активны только для недоверенного серверного кода; локальный код может исполняться без хуков (конвар).
- Запреты:
io,os(кроме безопасного минимума),ffi,requireвне whitelist,debug(или строго ограниченный), path traversal при любых файловых API. - Лимиты ресурсов: размеры render targets, количество материалов/мешей/партиклов/ таймеров на аддон; квоты на кадр.
- Изоляция ошибок: каждый hook/колбек в
catch_unwind; ошибка Lua не роняет кадр; после N ошибок колбек отключается (как в GMod сообщение в консоль). - Safe mode: перед загрузкой файла пишем маркер «сейчас грузится X»; если прошлый запуск завершился нечисто — X в чёрный список, клиент стартует без него и сообщает.
- 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 сразу» — идём по приоритетам и дампам.