126 lines
9.1 KiB
Markdown
126 lines
9.1 KiB
Markdown
# Реестр проблем: болячки GMod/Source и что с ними делаем
|
||
|
||
Формат: **симптом → почему так у Source/GMod → решение → этап**.
|
||
|
||
---
|
||
|
||
## P1. Нет анимаций игроков (пробел Source.NET)
|
||
|
||
- **Симптом:** модели видны, но статичны (замечено в Source.NET на ClassicBox).
|
||
- **Почему:** нет реализованного studio-анимационного стека.
|
||
- **Решение:** полный StudioRender (**M5**): VVD/VTX/ANIM, blend-граф, `$sequence`,
|
||
activity layers/gestures, IK, procedural bones (`$bonefollowers`), flex/eyeballs,
|
||
аттачменты, GPU-скиннинг, animation LOD.
|
||
- **Этап:** M5.
|
||
|
||
## P2. Сандбокс-масштаб: кучи пропов, энтити, констрейнов ⭐
|
||
|
||
- **Симптом:** 2000+ пропов, кучи констрейнов и аддоновых сущностей превращают клиент
|
||
в слайдшоу; открытые карты (gm_mobenix и подобные) — худший случай.
|
||
- **Почему Source «не задумывался»:**
|
||
- draw call на каждый проп — без инстансинга/батчинга;
|
||
- PVS — единственный механизм видимости; нет LOD от экранного размера;
|
||
- нет animation LOD: все скелеты обновляются, пока модель в кадре;
|
||
- клиентская физика тикает независимо от близости игрока;
|
||
- один поток на запись рендера;
|
||
- констрейны = шторм сетевых сущностей + аллокации + ребилд ропов.
|
||
- **Принцип сандбокс-масштаба (подтверждён пользователем):**
|
||
> Мелкое и далёкое можно вообще не рисовать. Дефолты агрессивные,
|
||
> всё регулируется конварами.
|
||
- **Решение — Interest & Visibility subsystem:**
|
||
1. Состояния: `Static → Sleeping → Dynamic → Impostor → Skipped` (обратимо).
|
||
2. Screen-space importance: `pixels ≈ r / dist · (h / 2·tan(fov/2))`.
|
||
Пороги (черновые): skip < 1–2 px, impostor < 8 px, low-LOD < 24 px.
|
||
3. Инстансинг одинаковых моделей (indirect draw); merge спящих физикой пропов
|
||
в статические батчи (пробуждение возвращает в dynamic).
|
||
4. Animation LOD: 60/20/0 Гц + фриз костей; критерии: дистанция, в кадре ли,
|
||
движение, свежесть сетевых апдейтов, взаимодействие.
|
||
5. Physics hibernation: island sleep + принудительная заморозка дальних островов;
|
||
пробуждение по сети/подходу/взаимодействию; Jolt на worker-пулах.
|
||
6. Авто-импосторы с дисковым кэшем для дальних мелких пропов.
|
||
7. Сеть под шторм: интернирование, пул сущностей без аллокаций, параллельный дельта-декод.
|
||
8. **Совместимость:** куллинг не трогает существование сущностей и Lua-draw
|
||
(PAC3/Starfall/HUD получают всё; у их рисования свои бюджеты).
|
||
- **Черновые конвары:** `r_imp_minscreen`, `r_imp_impostor_screen`, `r_imp_lod_screen`,
|
||
`r_animlod_hz`/`r_animlod_dist`, `phys_hibernate_dist`/`phys_hibernate_delay`,
|
||
`r_nopvs_maxdist` (для карт без PVS).
|
||
- **Этапы:** M3 (каркас) → M4 (стресс-полигон) → M5 (anim LOD, статик-батчи) →
|
||
M6 (hibernation) → M9 (импосторы-кэш, тюнинг).
|
||
- **Вне нашей власти (клиент):** серверный CPU от констрейнов и серверного Lua,
|
||
серверный сетевой бюджет. У нас «констрейны» — это сеть/декод/визуал.
|
||
|
||
## P3. Долгий заход в игру и на сервер
|
||
|
||
- **Симптом:** GMod грузит аддоны и контент минутами; вход на сервер — минуты
|
||
(UDP-скачивание Lua/карты даже при наличии контента локально).
|
||
- **Решение:**
|
||
- параллельная LZMA-декомпрессия и запись в постоянный download-кэш;
|
||
- приоритет локального контента: workshop/аддоны, что уже есть, не качаем;
|
||
- стриминг-парсинг BSP по мере прихода;
|
||
- фоновый precache ассетов во время коннекта (загрузочный экран без чёрного экрана);
|
||
- быстрый старт меню: ленивое монтирование и фоновый warmup в игре.
|
||
- **Этап:** M2/M4/M9.
|
||
|
||
## P4. Шейдерные стуттеры и подгрузки на ходу
|
||
|
||
- **Почему:** компиляция шейдеров в рантайме; синхронный декод текстур/моделей;
|
||
отсутствие streaming.
|
||
- **Решение:** wgpu pipeline cache + прогрев; асинхронный декод в worker-пулах;
|
||
VRAM-бюджет и деградация; дисковый кэш обработанных ассетов; mip-стриминг.
|
||
- **Этап:** M3/M9.
|
||
|
||
## P5. 32-битность, OOM и лимиты
|
||
|
||
- **Почему:** исторически 32-битный клиент (есть 64-битная бета).
|
||
- **Решение:** сразу x86_64; собственные лимиты по бюджету RAM/VRAM с деградацией
|
||
(скип/импостор/уменьшение качества), а не падение.
|
||
- **Этап:** архитектурно с M0.
|
||
|
||
## P6. Однопоточный рендер
|
||
|
||
- **Решение:** параллельная запись команд, worker-пулы (куллинг/декод/скиннинг),
|
||
многопоточная физика Jolt.
|
||
- **Этап:** M3/M6.
|
||
|
||
## P7. PVS-only и дырявые открытые карты
|
||
|
||
- **Симптом:** карты с плохим/отсутствующим PVS рендерят всё.
|
||
- **Решение:** PVS + frustum + octree + screen-size пороги; fallback по дистанции
|
||
для плохих PVS (`r_nopvs_maxdist`).
|
||
- **Этап:** M3.
|
||
|
||
## P8. Краши от злоумышленников (Starfall/PAC3) и кривых данных
|
||
|
||
- **Векторы:** бесконечные/вложенные циклы Lua, OOM Lua, гигантские RT/меши/материалы,
|
||
path traversal при загрузке файлов, битые снапшоты, огромные строки.
|
||
- **Решение:**
|
||
- Lua-sandbox: лимит памяти, instruction-watchdog, запрет `io/os/ffi/debug`,
|
||
изоляция ошибок, лимиты на таймеры/RT/меши;
|
||
- защита путей как требования gluasteal (никаких `..`, абсолютных путей, NaN);
|
||
- bounded-парсеры + fuzz; никаких `unwrap` на внешних данных;
|
||
- `catch_unwind` на границах; краш одного аддона не убивает клиент;
|
||
- **safe mode**: пометка «загружался файл X» → при нечистом завершении X
|
||
добавляется в чёрный список следующего запуска.
|
||
- **Этап:** cross-cutting; ядро — M7; PAC3/Starfall — M8.
|
||
|
||
## P9. Качество картинки (HDR/AA/вода/тени)
|
||
|
||
- **Решение:** HDR-конвейер (RGBA16F, tonemap, bloom), SMAA (TAA опцией), SSAO,
|
||
анизотропия 16x, SSR воды, динамические тени моделей/игроков (опция), корректные
|
||
color-space и alpha.
|
||
- **Контракт:** семантика материалов Source (`$additive`, RT, lightwarps, alpha)
|
||
не меняется — иначе аддоны визуально ломаются.
|
||
- **Этап:** M3; тюнинг дефолтов — M9.
|
||
|
||
## P10. VGUI тяжёлый и медленный
|
||
|
||
- **Решение:** нативный UI-слой (меню/консоль/HUD-рамка) на Rust; Derma — совместимый
|
||
слой поверх быстрого бэкенда; шрифты TTF вместо медленного VGUI-пути.
|
||
- **Этап:** M7/M8.
|
||
|
||
## P11. UX-мелочи
|
||
|
||
- Быстрый старт без чёрного экрана; информативный загрузочный экран; реконнект без
|
||
перезапуска; стабильные alt-tab и курсор; громкость/аудио-устройства; консольные
|
||
команды как в Source.
|
||
- **Этап:** по мере появления соответствующих систем.
|