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

262 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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):**
- [x] KeyValues: толерантный bounded-парсер (VMT/gameinfo/entities), лимиты, тесты
- [x] BSP: заголовок + 64 лумпа, LZMA-лумпы, ENTITIES (KeyValues), TEXDATA/имена текстур,
game lumps, PAKFILE (ZIP: Store/Deflate, CRC)
- [x] Геометрия BSP v20: вершины/рёбра/surfedges/грани/texinfo/узлы/листья/модели,
`validate()` по перекрёстным ссылкам (gm_construct/gm_flatgrass — валидно)
- [x] VTF 7.0–7.5: заголовок (+таблица ресурсов 7.3+), раскладка мипов, миниатюра,
декод в RGBA8 (DXT1/3/5, RGBA/BGRA/ABGR/ARGB, RGB/BGR, I8/A8/IA88, RGB565/BGR565)
- [x] VMT: шейдер, параметры, patch (include/replace/insert), Proxies, render-modes
- [x] MDL: заголовок (v44–49, studiohdr2), кости, аттачменты, хитбоксы, текстуры,
бодипарты, include-модели, `$keyvalues`, `surfaceprop` (проверено на реальных моделях)
- [x] VVD/VTX: вершины (позиция/нормаль/UV/веса костей), fixup'ы, полное дерево
BodyPart→Model→LOD→Mesh→StripGroup→Strip с валидацией индексов (51 пара на реальных моделях)
- [x] CLI: `fs doctor`, `fs list`, `fs cat`, `fs inspect` (BSP/VTF/VMT/MDL + VVD/VTX)
- [x] Тесты на реальных данных: 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
- [x] `git init` + `.gitignore` + README + docs (первый коммит)
- [x] Cargo workspace `~/garrysmod-rs`: `crates/tier` (логи/конвары/конфиг/CLI), `crates/fs` (VPK v1/v2, листинг, CRC-проверка)
- [x] `crates/math` (базовый Vec3/Angle/Aabb)
- [x] `client`: окно SDL3 + wgpu clear + FPS в заголовке и логе (проверено: NVIDIA RTX 3060, Vulkan, ~58–63 FPS, чистое завершение)
- [x] Тесты: реальные VPK из `~/gmod_server/server` парсятся, CRC-выборка проходит; мусор не роняет парсер
- [x] 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`.