gmod-rs/docs/PLAN.md
Niko Marmeladkov d6b213cecc formats: VVD/VTX — меш-данные моделей (вершины, fixup, LOD-дерево)
- VVD (IDSV v4): заголовок 64 байта, mstudiovertex_t 48 байт (веса/кости/позиция/нормаль/UV),
  тангенты, таблица fixup
- VTX (packed): BodyPart→Model→LOD→Mesh→StripGroup→Strip, валидация индексов и смещений;
  смещения вложенных структур относительны своей структуры
- fs inspect: для .mdl показывает VVD/VTX-статистику и сверку checksum
- тесты: oildrum (270 вершин/756 индексов), 51 пара VVD/VTX с совпадающим checksum
- docs: прогресс M1 (остался ANIM, PCF/PHY/SND, GMA/mount.cfg)
2026-10-11 23:15:46 +03:00

22 KiB
Raw Blame History

Source RS — план проекта

Статус: план зафиксирован (2026-10-11). Следующий шаг — спринт 0 (§7). Каталог: ~/garrysmod-rs · Цель №1: ClassicBox (194.147.90.27:24215).


1. Видение

Source RS — клиент Garry's Mod, написанный с нуля на Rust. Цель — комфортно и красиво играть на сандбокс-серверах с десятками игроков, тысячами сущностей (пропы, констрейны, эффекты) и кучей аддонов, оставаясь совместимым с реальными серверами эпохи Source 2013 (net protocol 24 + GMod-расширения).

Сверх-цели (из постановки задачи пользователя):

  1. Сандбокс-масштаб: оптимизация под много игроков / пропов / констрейнов.
  2. Современные технологии: wgpu/Vulkan, Jolt, SDL3, LuaJIT (через mlua), steamworks.
  3. Современный рендеринг (HDR, AA, SSAO, SSR, тени) — при строгой совместимости семантики материалов, иначе аддоны (PAC3/Starfall) визуально ломаются.
  4. Починка болячек GMod-клиента — см. PROBLEMS.md.
  5. Быстрые заходы: в игру и на сервер.
  6. Устойчивость к крашам от зловредных/кривых аддонов и серверов (Starfall, PAC3...).
  7. Полноценные анимации моделей игроков — главный видимый пробел Source.NET.

2. Рамки

В рамках первой фазы

  • Клиент, подключающийся к реальным GMod-серверам (Source 2013 protocol 24 + GMod-расширения).
  • Рендер GMod-контента: BSP, модели, материалы, партиклы, декали, звук.
  • Полный анимационный стек студийных моделей (скелеты, IK, procedural bones, flex, blends).
  • Клиентский Lua (LuaJIT) с движковым API в объёме, достаточном для аддонов (порядок и объём — см. LUA.md).
  • Steam: тикет для серверов с VAC, workshop-контент, монтирование.
  • Современный рендер по умолчанию + строгий compat-слой семантики материалов.

Вне рамок (первая фаза)

  • Свой dedicated-сервер и серверный Lua (геймоды, ULX, DarkRP...) — отдельная вселенная.
  • Нативные бинарные Lua-модули аддонов (.dll/.so внутри addons) — несовместимы by design.
  • Перераспространение ассетов и Lua-файлов Garry's Mod / Valve.
  • Windows-сборка (код кроссплатформенный, сборка и CI — позже).
  • HTML/Chromium-панели (небольшая часть дюжины аддонов).

3. Принципы

  1. Совместимость — контракт. Форматы, сетевой протокол и Lua-семантика важнее «как удобнее написать код».
  2. Modern-by-default, compat-семантика всегда. Освещение и пост — современные; render-state и семантика материалов ($additive, $translucent, $alphatest, render targets, lightwarps, eyes, skinning) — ровно как в Source.
  3. Принцип сандбокс-масштаба. Мелкое и далёкое можно вообще не рисовать и не анимировать. Дефолты агрессивные, всё регулируется конварами. Детали — PROBLEMS.md §P2.
  4. Never-crash. Никакой ввод из сети/диска и никакой аддон не может уронить клиент: bounded-парсеры, лимиты, catch_unwind на границах, safe mode.
  5. Speed-first. Быстрый заход в игру и на сервер — фича №1: параллельный декод, дисковые кэши, монтирование локального контента, pipeline cache.
  6. Data-oriented hot paths. ECS-подобное хранение сущностей, инстансинг, бюджетные очереди; без аллокаций в кадровом цикле.
  7. Clean-room. SDK 2013 / Source.NET / прочие референсы — спецификация, не код.
  8. Linux-first. wgpu/SDL3/Jolt кроссплатформенные, но отладка и CI — Linux.

4. Критерии успеха

Рубеж Критерий
M4 «Играбельно» Заход на ClassicBox, видим 36+ игроков, ходим, стабильный FPS
M6 «Как надо» Играем: движение, оружие, звук, HUD
M6+ «Сандбокс-масштаб» 64 игрока + 2000 пропов + 500 констрейнов → 60+ FPS на RTX 3060; карта без PVS не убивает кадр
M8 «Аддоны» HUD-аддоны, Derma, PAC3, Starfall работают; их сбои не крашат клиент
Итог Заходы заметно быстрее GMod; картинка современнее; ноль киллов клиента на Chaos-тестах

5. Этапы (обзор)

Этап Название Главный результат
M0 Каркас Workspace, tier-слой, конфиг ассетов, окно+wгpu «пустое»
M1 Форматы и FS VPK/GMA/BSP/VTF/VMT/MDL/PCF/PHY/SND парсятся, fuzz-тесты
M2 Сеть + Steam + dump/replay Подключение к серверу, лог мира, Steam-тикет, workshop, replay-стенд
M3 Рендер мира + interest v1 BSP-мир «как в GMod», современный конвейер, куллинг/инстансинг, pipeline cache
M4 Онлайн: мир и игроки ClassicBox онлайн: 36 игроков, интерполяция, смена карт; стресс-полигон 2000 пропов
M5 StudioRender + анимации Полноценные анимации игроков/рагов, animation LOD, статик-батчи
M6 Геймплей-клиент Prediction, оружие, звук, физика/Jolt, база HUD
M7 Lua: машинерия + HUD/UI LuaJIT-рантайм, sandbox, safe mode, серверные HUD-аддоны
M8 Derma → PAC3 → Starfall Меню, PAC3-модели, Starfall-экраны, стойкость к Chaos
M9 Перф, кэши, полировка Texture streaming, дисковые кэши, импосторы, тюнинг, бенчмарки CI

6. Детализация этапов

M0 — Каркас

  • Cargo workspace; crates/tier: tracing-логи, конвары, CommandLine, конфиг, время, interning строк.
  • Авто-детект корня ассетов: настроенный путь → ~/gmod_server/server (DS) → Steam-инсталлы.
  • .gitignore, CI-скелет (fmt/clippy/test), README/docs, AGENTS.md.
  • steamworks в зависимостях (feature на будущее, выключен по умолчанию до M2).
  • Приёмка: cargo run -p client открывает окно SDL3 + wgpu (clear), в логе — найденные пути ассетов и список конваров.

M1 — Форматы и файловая система

Сделано (2026-10-11/12):

  • KeyValues: толерантный bounded-парсер (VMT/gameinfo/entities), лимиты, тесты
  • BSP: заголовок + 64 лумпа, LZMA-лумпы, ENTITIES (KeyValues), TEXDATA/имена текстур, game lumps, PAKFILE (ZIP: Store/Deflate, CRC)
  • Геометрия BSP v20: вершины/рёбра/surfedges/грани/texinfo/узлы/листья/модели, validate() по перекрёстным ссылкам (gm_construct/gm_flatgrass — валидно)
  • VTF 7.0–7.5: заголовок (+таблица ресурсов 7.3+), раскладка мипов, миниатюра, декод в RGBA8 (DXT1/3/5, RGBA/BGRA/ABGR/ARGB, RGB/BGR, I8/A8/IA88, RGB565/BGR565)
  • VMT: шейдер, параметры, patch (include/replace/insert), Proxies, render-modes
  • MDL: заголовок (v44–49, studiohdr2), кости, аттачменты, хитбоксы, текстуры, бодипарты, include-модели, $keyvalues, surfaceprop (проверено на реальных моделях)
  • VVD/VTX: вершины (позиция/нормаль/UV/веса костей), fixup'ы, полное дерево BodyPart→Model→LOD→Mesh→StripGroup→Strip с валидацией индексов (51 пара на реальных моделях)
  • CLI: fs doctor, fs list, fs cat, fs inspect (BSP/VTF/VMT/MDL + VVD/VTX)
  • Тесты на реальных данных: 2 карты, 200 VTF, 200 VMT, 53 MDL, 51 пара VVD/VTX, pakfile 599 записей
  • MDL: ANIM (анимации) — следующая итерация
  • PCF, PHY (collision), WAV/MP3/OGG
  • crates/fs: GMA (workshop), mount.cfg, aliases |all_source_engine_paths|, mmap, кэш индексов VPK
  • fuzz-таргеты на kv/bsp/vtf/pakfile (пока есть VPK)

Приёмка (частично достигнута): fs doctor/fs inspect работают на реальных ассетах.

M2 — Сеть + Steam + dump/replay

  • UDP-netchan: последовательность/надёжность, фрагментация, bz2, лимиты.
  • Signon: server info, stringtables, server classes/datatables, baselines, знаковые данные.
  • Игра: delta-снапшоты (по классам, PVS-интерес), usermessages, clc_*, usercmd.
  • GMod-расширения: передача Lua/LZMA, каналы net.*, usermessage-регистрация скриптами, userinfo (steamid/имя/модель).
  • Steam: steamworks-rs — AuthSessionTicket; ISteamUGC — подписка/скачивание workshop и монтирование локально. Fallback noSteam — конваром.
  • A2S-info (для отладки/меню позже). Идентификация клиента (версия из garrysmod.ver).
  • Packet capture + replay стенд: сырые UDP-дампы с метаданными → оффлайн-реплей в декодер.
  • Приёмка: подключение к локальному srcds и ClassicBox; в консоли — корректные игроки/энтити/строки; replay дампа воспроизводит ту же картину без сервера.

M3 — Рендер мира + interest-система (v1)

  • SDL3 (окно/ввод) + wgpu: swapchain, HDR-таргет (RGBA16F), композитор, tonemap, bloom.
  • BSP-рендер: worldspawn, lightmaps (+2-lightmap), displacement, вода, скайбокс, туман, detail-спрайты, прозрачные проходы.
  • Материалы: два слоя — compat-семантика (render state как в Source) и современный shading; стартовый набор шейдеров: LightmappedGeneric, VertexLitGeneric, UnlitGeneric, вода, спрайт.
  • Видимость: PVS + frustum + octree; screen-size пороги; инстансинг повторяющихся моделей; многопоточный куллинг; fallback для карт без PVS.
  • Pipeline cache на диске (первый запуск компилирует — дальше мгновенно).
  • Приёмка: оффлайн-полёт по gm_mobenix_v3_final; 200+ FPS; на втором запуске — ни одного шейдерного стуттера.

M4 — Онлайн: мир и игроки

  • Применение снапшотов к сцене: модели/позиции/углы, интерполяция; скины, аттачменты.
  • Игроки как модели (пока без анимаций).
  • Смена карт, загрузочный экран, реконнект, базовые уведомления.
  • Стресс-полигон: локальный srcds + скрипт-спавнер (2000 пропов, 500 констрейнов); replay busy-сессий ClassicBox.
  • Приёмка: заход на ClassicBox; видим 36 игроков; стресс-полигон держит бюджет кадра (v1 — без анимаций и полной физики).

M5 — StudioRender + анимации (главный фикс Source.NET)

  • Полный скелетный пайплайн: VVD/VTX/ANIM, blend-граф, $sequence, activity layers, gestures.
  • IK-цепочки, procedural bones ($bonefollowers), flex/eyeballs, аттачменты, bodygroups.
  • GPU-скиннинг (storage buffers), morph targets.
  • Animation LOD (60/20/0 Гц по важности), статик-батчи спящих моделей, начало авто-импосторов.
  • Приёмка: игроки ходят/прыгают/приседают/держат оружие; ragdoll-позы; анимации не бьют по FPS при 64 игроках.

M6 — Геймплей-клиент

  • Prediction движения игрока (по SDK), usercmd, viewmodel, оружие, прицелы.
  • Звук: kira + WAV/MP3/OGG, пространственность, звуковые скрипты, шаги/выстрелы.
  • Физика: Jolt, hibernation островов, интерполяция физики, рагдоллы; визуальные ропы/бимы/эффекты констрейнов.
  • HUD-рамка: консоль, чат, уведомления (до Lua-аддонов — базовое).
  • Приёмка: полноценная игра на ClassicBox; 60+ FPS в замесе.

M7 — Lua: машинерия + HUD/UI

  • mlua + vendored LuaJIT (семантика 5.1, как в GMod); загрузка lua с сервера из download-кэша.
  • Bootstrap геймода как в GMod; ядро API: hook, net, timer, util, concommand, surface, draw, render, cam, input; render targets.
  • Sandbox v1: лимиты памяти, instruction-watchdog, запреты (io/os/ffi/debug), изоляция ошибок; safe mode — чёрный список упавшего файла при следующем запуске.
  • Инструмент lua-api-report: скан дампов (gluasteal) → рейтинг недостающих API.
  • Приёмка: серверные HUD-аддоны (HP/чат/killfeed) работают; сбоящий аддон не роняет клиент и отключается при следующем запуске.

M8 — Derma → PAC3 → Starfall

  • Derma/VGUI API: панели, layout, шрифты (TTF), анимации; «достаточно для типовых меню».
  • PAC3: compat API (кости, RT, материалы, вложения), бюджеты, safe mode.
  • Starfall: поддержка API, который использует аддон (он тащит свой Lua-интерпретатор внутрь GMod Lua), усиленный sandbox, лимиты.
  • Приёмка: F1-меню сервера открывается; PAC3-модели видны и анимируются; Starfall-экраны рисуются; Chaos-тесты (бесконечные циклы, гигантские меши/RT, битые данные) не крашат клиент.

M9 — Перф, кэши, полировка

  • Texture streaming и VRAM-бюджет; дисковые кэши: VPK-индексы, обработанные текстуры/меши, импосторы, pipeline cache; инвалидация по content-hash + версии парсера.
  • Авто-импосторы и merge спящих пропов с дисковым кэшем.
  • Тюнинг конваров interest-системы; бенчмарки-регрессии в CI.
  • Опции рендера: SSAO, SMAA (TAA опцией), SSR воды, динамические тени пропов/игроков; дефолты.
  • Приёмка: второй запуск и заход — секунды; страница бенчмарков; гайд по конварам.

7. Спринт 0

  • git init + .gitignore + README + docs (первый коммит)
  • Cargo workspace ~/garrysmod-rs: crates/tier (логи/конвары/конфиг/CLI), crates/fs (VPK v1/v2, листинг, CRC-проверка)
  • crates/math (базовый Vec3/Angle/Aabb)
  • client: окно SDL3 + wgpu clear + FPS в заголовке и логе (проверено: NVIDIA RTX 3060, Vulkan, ~58–63 FPS, чистое завершение)
  • Тесты: реальные VPK из ~/gmod_server/server парсятся, CRC-выборка проходит; мусор не роняет парсер
  • CI-скелет (fmt/clippy/test для tier/math/fs), fuzz-заглушка (fuzz/fuzz_targets/vpk_parse.rs)

Спринт 0 завершён (2026-10-11): fs doctor — 9 VPK, 77 933 записи, 41 архив, 0 ошибок CRC; fs cat читает MDL/текст из VPK; окно открывается на Vulkan.

8. Тестовая стратегия

  • Локальный srcds (~/gmod_server/server) — контролируемые сценарии (sv_lan).
  • Стресс-полигон: консольный спавнер на srcds + replay: 2000 пропов, 500 констрейнов, боты/игроки; отдельный тест «карта без PVS».
  • Packet dump/replay: клиент пишет сырые сетевые потоки; replay в декодер без сервера; регрессии и стресс-сцены.
  • Fuzz: VPK/BSP/MDL/VTF/PCF/снапшоты — cargo-fuzz, ночные прогоны.
  • Chaos-тесты: зловредный Lua (бесконечный цикл, гигабайтные меши, битые RT, path traversal), кривые снапшоты, огромные строки — клиент обязан выживать.
  • Бенчмарки: сцены стресс-полигона, регрессии кадра, логи в CI.

9. Риски

Риск Митигация
GMod-специфика протокола недокументирована Референс Source.NET/leysourceengineclient/SDK, packet capture, replay-стенд; изоляция слоя net
Огромный объём Lua API Рельсы + приоритеты по аддонам; lua-api-report по дампам gluasteal
Steam-лицензия/клиент на машине не установлены (только заглушка) Проверка в M2; fallback noSteam; при необходимости установить Steam+лицензию
1:1 Derma сложен Сначала «достаточно для типовых меню», итерации по реальным аддонам
Производительность при 64 игроках interest-система с M3, бенчмарки с M4, animation LOD с M5, физика-хайбернейт с M6
Юридические ограничения SDK Код — свой; SDK/референсы только как спека; ассеты — локально
Нет реального клиента GMod для captures DS-ассеты + srcds; при появлении клиента (Proton) — tcpdump; иначе дампы нашего клиента

10. Зафиксированные решения

# Решение Статус
D1 Каталог проекта — ~/garrysmod-rs принято
D2 Первая фаза — только клиент (сервер — потом) принято
D3 Linux-first, x86_64, wgpu/Vulkan принято
D4 Lua: все 4 цели, порядок HUD/UI → Derma → PAC3 → Starfall принято
D5 Рендер: современный по умолчанию; семантика материалов Source — контракт принято
D6 Steam (steamworks-rs) с M2; noSteam fallback конваром принято
D7 Стек: wgpu, SDL3, Jolt, mlua (LuaJIT), kira/symphonia, steamworks принято
D8 Принцип сандбокс-масштаба: агрессивные дефолты, всё конварами подтверждено

11. Процесс

  • Каждый этап заканчивается демо + бенчмарком + обновлением docs/.
  • Коммиты — по этапам/подсистемам, сообщения на русском.
  • Отклонения от плана фиксируются в §10 и в PROBLEMS.md.