aboutsummaryrefslogtreecommitdiff
path: root/docs/tomes/01-guide.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tomes/01-guide.md')
-rw-r--r--docs/tomes/01-guide.md371
1 files changed, 371 insertions, 0 deletions
diff --git a/docs/tomes/01-guide.md b/docs/tomes/01-guide.md
new file mode 100644
index 0000000..cc4e4c0
--- /dev/null
+++ b/docs/tomes/01-guide.md
@@ -0,0 +1,371 @@
+# I. Путеводитель и методика
+
+Первый том задаёт язык и правила всей документации. Он объясняет, как читать
+технические главы, какие термины используются для игрового runtime, как
+разделяются уровни уверенности и какие требования предъявляются к реализации,
+которая должна работать с оригинальными данными без потери информации.
+
+Документация рассчитана на разработчика, который уже умеет читать C/C++,
+байтовые форматы, PE-модули и графические pipeline, но не обязательно знаком с
+Iron3D. Поэтому этот том не описывает один конкретный crate, package или
+физическое деление будущего кода. Он фиксирует контракты: что должно быть
+прочитано, сохранено, рассчитано и показано.
+
+## Назначение книги
+
+Книга ведёт от общей архитектуры Iron3D к точным форматам данных и алгоритмам
+исполнения. Практическая цель -- реализация, способная открыть оригинальный
+каталог *Parkan: Iron Strategy*, загрузить миссию, создать мир, провести
+игровой шаг и сформировать кадр.
+
+Форматы в главах описываются как байтовые контракты. Если указано поле
+`+0x10`, это означает расположение в потоке или структуре данных, а не
+разрешение читать файл прямым `reinterpret_cast`. Для постоянных layouts
+используются offsets, проверки размеров, bounded cursor и явное сохранение
+неизвестных байтов. Для versioned и variable-length записей приоритет имеет
+последовательный parser с контролем границ.
+
+Игровое поведение описывается не только размером структур. Совместимая
+реализация должна учитывать порядок событий, время, fallback-правила,
+идентификаторы объектов, численные ограничения, состояние материалов,
+границы кадра и правила завершения операций.
+
+## Маршруты чтения
+
+**Читатель, новый для игровой разработки**, начинает с базовых понятий этого
+тома, затем переходит к архитектуре, игровому циклу и вводу в рендер. После
+этого имеет смысл читать главы о миссиях, мире и ресурсных форматах.
+
+**Разработчик совместимого движка** читает тома II-VII линейно. Технические
+главы имеют одинаковую логику: назначение подсистемы, данные на диске,
+представление в памяти, алгоритм работы, проверки и требования к новой
+реализации.
+
+**Аналитик оригинальной программы** использует этот том вместе с разделами о
+доказательной базе, ABI, результатах корпусных проверок и границах знания.
+Факты, согласованные выводы и открытые вопросы должны оставаться разделёнными:
+это позволяет расширять реализацию без подмены проверенных контрактов
+удобными догадками.
+
+## Состав документации
+
+1. **Путеводитель и методика** -- язык предметной области, правила чтения и
+ процедура проверки.
+2. [**Запуск, архитектура и игровой цикл**](02-architecture.md) -- от
+ `iron_3d.exe` до расчёта и вывода кадра.
+3. [**Ресурсная система и форматы**](03-resources.md) -- архивы, кэши, реестры
+ и служебные данные.
+4. [**Мир, миссии и игровой runtime**](04-world.md) -- TMA, ландшафт, ареалы и
+ создание объектов.
+5. [**Геометрия, материалы и рендер**](05-render.md) -- от вершины модели до
+ изображения на экране.
+6. [**Поведение, управление, звук и сеть**](06-behavior.md) -- интерактивные
+ подсистемы.
+7. [**Руководство по полной реализации**](07-implementation.md) -- предлагаемая
+ архитектура и порядок работ.
+8. [**Справочник и доказательная база**](08-evidence.md) -- ABI,
+ конфигурация, статистика и открытые вопросы.
+
+Дополнительные краткие определения собраны в
+[глоссарии](../appendices/glossary.md). Технические области, где контракт ещё
+не закрыт полностью, перечислены в
+[границах знания](../appendices/knowledge-boundaries.md).
+
+## Условные обозначения
+
+`+0x10` означает смещение поля относительно начала структуры или записи.
+`RVA 0x13B60` -- адрес относительно базы PE-модуля. `u16`, `u32`, `i16` и
+`float32` обозначают типы фиксированной ширины. `LE` означает little-endian.
+`payload` -- полезные данные записи после метаданных контейнера. `EOF` -- точное
+завершение файла или ограниченного блока.
+
+Если в тексте указан hash, RVA или ordinal, значение относится к явно
+обозначенному binary profile. Адреса разных сборок не объединяются по имени
+функции. При публикации функции нужны минимум модуль, SHA-256 сборки и RVA.
+
+Размеры структур выражаются в байтах. Счётчики и offsets считаются частью
+формата, даже когда их можно восстановить из длины файла. Padding, reserved
+поля, неизвестные хвосты и gaps не нормализуются без доказанного правила.
+
+## Совместимость
+
+Слово "совместимость" в этой книге имеет несколько уровней.
+
+**Reader** умеет открыть файл, проверить границы, извлечь известные поля и
+сохранить неизвестные bytes так, чтобы данные можно было записать обратно.
+
+**Viewer** умеет показать ресурс: модель, texture, material, эффект или карту.
+Viewer может быть полезен для анализа, но он не доказывает поведение runtime.
+
+**Runtime** умеет создать мир, зарегистрировать объекты, исполнять события,
+обновлять время, применять контроллеры, выбирать видимое состояние и передавать
+его рендеру.
+
+**Полноценный движок** дополнительно воспроизводит порядок операций, численные
+правила, fallback-поведение, resource lifetime, reference ownership, pause,
+manual input, сетевые идентификаторы, boundaries кадра и состояние
+интерактивных подсистем.
+
+Поэтому файл может быть "прочитан правильно", но всё ещё не быть реализованным
+на уровне движка. Например, reader MSH может восстановить вершины и индексы,
+viewer может нарисовать mesh, а runtime обязан ещё сохранить material slots,
+animation state, bounds, LOD, visibility, collision и связи с объектом мира.
+
+## Движок как программа длительного действия
+
+Обычная прикладная программа получает запрос, вычисляет результат и заканчивает
+работу. Игра живёт в цикле: прочитать ввод, обновить состояние мира,
+сформировать звук и изображение, показать кадр и повторить. Движок -- набор
+подсистем и соглашений, которые делают этот цикл устойчивым.
+
+**Simulation** отвечает на вопрос "что произошло в мире": куда переместился
+объект, кого он видит, сколько у него здоровья, сработал ли эффект, изменился
+ли маршрут или приказ. **Rendering** отвечает на другой вопрос: "как текущее
+состояние показать". В корректной архитектуре рендер не решает игровые правила,
+а читает подготовленное состояние.
+
+**Tick** -- один шаг расчёта. **Frame** -- одно изображение. Они могут
+выполняться с разной частотой: игра способна рассчитать несколько шагов между
+двумя показами или временно не рисовать, не останавливая логику. Поэтому время,
+накопление input, порядок callbacks и момент удаления объектов считаются частью
+контракта.
+
+## Мир, сцена и объект
+
+**Мир** -- долгоживущее состояние миссии: ландшафт, объекты, время, погода,
+принадлежность к кланам и глобальные сервисы. **Сцена** -- представление той
+части мира, которую можно обработать для текущей камеры. **Игровой объект** --
+сущность с идентификатором, положением, набором свойств и поведением.
+
+В Iron3D объектами управляет World3D. Объекты регистрируются в общей очереди,
+получают события, участвуют в расчёте и могут быть удалены отложенно, чтобы не
+разрушить обход коллекции посреди шага. Это важнее, чем конкретный контейнер в
+новой реализации: совместимость определяется моментом наблюдаемого добавления,
+обновления и удаления.
+
+Мир не равен renderer scene graph. Один объект может иметь runtime state,
+controller, сетевой mirror, визуальную модель, collision bounds и script state.
+Часть этих данных нужна для gameplay, часть -- для вывода, часть -- для
+сохранения и воспроизведения.
+
+## Ресурс, модель и материал
+
+**Ресурс** -- именованный блок данных, который можно найти и загрузить. Архивы
+`NRes` и `RsLi` содержат таблицы таких блоков. Имя, индекс, размер, offset,
+compression method и fallback-правило являются частью контракта загрузки.
+
+**Модель** описывает форму объекта. Она состоит из вершин, индексов, узлов,
+групп треугольников, слотов материалов и auxiliary streams. **Vertex** хранит
+положение и обычно дополнительные атрибуты: нормаль для освещения и
+UV-координату для выборки texture. **Triangle** -- три вершины, образующие
+примитив. **Index buffer** хранит номера вершин и позволяет переиспользовать их
+между треугольниками. **Batch** -- непрерывный диапазон индексов, который
+рисуется одним материалом и одним набором состояний.
+
+**Материал** описывает способ отображения поверхности: texture references,
+цвет, прозрачность, режимы смешивания и анимацию параметров. **Texture** --
+изображение в памяти графической системы. **Mip-уровни** -- уменьшенные копии
+изображения для дальних объектов. **Lightmap** -- дополнительная texture с
+заранее рассчитанным освещением.
+
+Runtime должен связывать эти уровни по цепочке: миссия выбирает объект, объект
+ссылается на prototype, prototype приводит к модели, модель -- к WEAR,
+материалам, textures и lightmaps. Ошибка на любом участке этой цепочки может
+не проявиться в parser-е, но проявится в игровом кадре.
+
+## Пространственные понятия
+
+**Transform** переводит точку из локальных координат модели в координаты мира,
+камеры и экрана. **Иерархия узлов** позволяет одному элементу наследовать
+движение другого. **LOD** выбирает менее подробную геометрию вдали. **Culling**
+отбрасывает то, что не видно. **Bounds** -- упрощённая оболочка объекта,
+обычно сфера или AABB, используемая для быстрых тестов.
+
+**Collision** отвечает на геометрические пересечения. **Navigation** ищет
+допустимый маршрут. В Iron3D эти задачи разделены: Control обслуживает
+физическую модель и столкновения, а ArealMap хранит пространственные области и
+связи между ними.
+
+Важно не смешивать визуальные и игровые упрощения. Render bounds могут быть
+достаточны для отсечения, но не обязаны совпадать с collision shape. Навигация
+может использовать areal graph, который не является ни mesh-ем модели, ни
+геометрией ландшафта в renderer-е.
+
+## Графический конвейер
+
+Процессор выбирает видимые объекты, готовит матрицы, материалы и списки
+примитивов. Графический backend передаёт вершины, индексы, textures и state
+драйверу. Видеокарта преобразует вершины в координаты экрана, разбивает
+треугольники на фрагменты, проверяет глубину, смешивает цвет и записывает
+результат в буфер кадра. После завершения буфер становится видимым
+пользователю.
+
+Для совместимости важны не только данные draw call. Контракт включает frame
+boundaries, viewport, camera state, порядок world traversal, material resolve,
+shadow/transparent/FX subpasses, завершение renderer-а, восстановление state и
+callbacks после рендера. Если часть имён vtable slots ещё не доказана, новая
+реализация должна фиксировать крупный порядок операций и оставлять
+детализацию проверяемой.
+
+## Практический словарь реализации
+
+**Handle** -- компактная ссылка на управляемый объект. **Cache** -- сохранённый
+результат загрузки или декодирования. **Reference count** -- число владельцев
+ресурса. **Fallback** -- предписанный запасной вариант при отсутствии данных.
+**Invariant** -- условие, которое всегда должно быть истинным для корректного
+файла или runtime-состояния. **Determinism** -- повторяемость результата при
+одинаковых входных данных и порядке событий.
+
+**Strict mode** -- режим parser-а, который принимает только корректный файл:
+верные magic, версии, размеры, ranges, индексы и точный EOF. **Lossless mode**
+-- режим чтения/записи, который сохраняет неизвестные поля, padding, gaps и raw
+payload без нормализации. **Quirk** -- именованное отклонение, разрешённое
+только после проверки на реальных данных или исполняемом коде.
+
+Эти слова используются как технические термины. Если глава называет значение
+fallback-ом, invariant-ом или quirk-ом, это должно иметь проверяемое
+последствие в reader-е, writer-е или runtime.
+
+## Как читать C/C++-схемы структур
+
+Структуры в главах описывают байтовый layout, а не переносимый C++ object
+model. Если поля на диске идут без padding, reader должен читать их по offsets
+либо использовать явно проверенный packed layout. Прямое отображение native
+struct допустимо только при доказанном размере, выравнивании и endian-правиле.
+
+`sizeof` обязательно проверяется `static_assert` или эквивалентным compile-time
+test. Это особенно важно для records, где 32-битное поле начинается после
+нечётного числа 16-битных или 8-битных полей: стандартное выравнивание
+современного compiler-а может вставить скрытые bytes и изменить offsets.
+
+Для variable-length форматов предпочтителен bounded cursor:
+
+1. Прочитать header и проверить минимальный размер.
+2. Проверить, что offsets и sizes лежат внутри текущего блока.
+3. Прочитать таблицы до объявленного count, не до "пока получается".
+4. Проверить ссылки между таблицами.
+5. Дойти до точного EOF или сохранить явно разрешённый trailing payload.
+
+Writer пересчитывает только производные значения: размеры, offsets, число
+записей, сортировочные таблицы и padding, если правило доказано. Unknown fields
+и reserved ranges сохраняются побайтно.
+
+## Иерархия доказательств
+
+Документация использует четыре уровня уверенности.
+
+**Прямое наблюдение** -- поле, значение или последовательность видны в
+инструкции программы, таблице PE, экспорте, строке, обработчике файла или в
+самом ресурсе. Это самый сильный уровень.
+
+**Корпусное подтверждение** -- правило проверено на всех подходящих файлах
+одного или нескольких явно названных наборов: демоверсии, Части 1 и Части 2.
+Например, базовый корпус содержит 435 моделей MSH, 518 textures Texm и 923
+эффекта FXID, прошедших структурные проверки без ошибок; полные части расширяют
+эту матрицу вариантов.
+
+**Согласованный вывод** -- назначение восстановлено по нескольким независимым
+признакам: вызывающим функциям, vtable slots, строкам ошибок, диапазонам
+значений и связям между форматами. Такой вывод пригоден для реализации, но его
+численные детали следует проверять тестами.
+
+**Открытый вопрос** -- данные можно читать и сохранять, однако предметный смысл
+поля или редкой ветки не доказан. Такие bytes нельзя обнулять,
+переупорядочивать или превращать в authoring API.
+
+Уровень уверенности должен быть виден из формулировки. "Поле равно" означает
+проверенный layout или значение. "Вероятно отвечает за" означает согласованный
+вывод. "Неизвестно" означает сохранять без изменения и не строить вокруг этого
+публичный контракт.
+
+## Проверенные материалы
+
+Локальный набор проверки включает демоверсию, полные каталоги Частей 1 и 2,
+исполняемые файлы, 15 DLL каждой сборки и игровые ресурсы. DLL из
+первоначального архива и DLL демоверсии совпали по SHA-256: `15/15`, поэтому
+выводы по этому коду и demo-ресурсам образуют один доказательный профиль.
+
+Исполняемый файл демоверсии `iron_3d.exe` имеет размер 36 864 байта, PE32/x86,
+entry RVA `0x141E`, image base `0x400000` и SHA-256
+`b0a8b0db1c3a8698c4d4604d89c655496bd91ac1f8859a455e8a45838aebfbd6`.
+
+Исполняемые файлы Частей 1 и 2 также имеют размер 36 864 байта и побайтно
+совпадают между собой, но относятся к другому binary profile: entry RVA
+`0x147E`, SHA-256
+`f476af85c034a4b4f34f49d0806e4dff397b5da0ee26d382a7674231144979f7`.
+
+Полные каталоги Частей 1 и 2 суммарно включают 60 TMA, 1 101 unit DAT, 254
+NRes-файла и 14 975 NRes entries. Все контейнеры и TMA прошли bounded parser до
+точного EOF; полный достижимый граф обеих частей разрешился без ошибок.
+
+## Процедура проверки
+
+Проверка строится как воспроизводимая цепочка:
+
+1. Снять PE-метаданные, хэши, импорты, экспорты, ordinals, RTTI и строки.
+2. Построить граф вызовов между модулями и отметить фабрики подсистем.
+3. Разобрать функции запуска, загрузчики файлов, главный цикл и критические
+ vtable-вызовы.
+4. Проверить форматы независимыми reader-скриптами с контролем границ и точного
+ завершения файла.
+5. Построить цепочку миссия -> объект -> прототип -> модель -> материал ->
+ texture.
+6. Сравнить счётчики, диапазоны, ссылки и размеры на всём доступном корпусе.
+
+Ключевой результат сквозной проверки демо-миссий: все 201 объектов шести
+миссий разрешились в 501 запрос прототипов, затем в 501 модель, 501 таблицу
+WEAR, 3 879 слотов материалов и 5 085 ссылок на textures или lightmaps. Ошибок
+в фактически исполняемом пути нет.
+
+## Что не считается доказательством
+
+Удобное имя поля не доказывает его назначение. Совпадение layout с текущей
+реализацией не доказывает поведение оригинального runtime. Успешный viewer не
+доказывает writer. Успешный reader одного файла не доказывает формат всего
+корпуса. Совпадение ABI не доказывает побайтную идентичность всех сборок.
+
+Если локальные данные и предположение расходятся, приоритет имеют исполняемый
+код, реальные ресурсы и взаимные invariants между форматами. Неизвестное поле
+лучше оставить без имени, чем дать ему ложное предметное значение.
+
+## Требования к воспроизводимости
+
+Каждая новая реализация должна иметь strict parser mode, lossless roundtrip
+mode и набор corpus tests. Неизвестные поля сохраняются побайтно. Любое
+присвоенное полю имя должно сопровождаться наблюдаемым поведением или тестом.
+Численные правила -- округление, порядок умножения, RNG и время -- считаются
+частью формата исполнения, даже если файл читается правильно.
+
+Минимальный отчёт проверки должен фиксировать:
+
+1. build profile и hashes модулей;
+2. путь или ключ ресурса;
+3. размер входного файла и hash входных bytes;
+4. версию parser-а или commit реализации;
+5. список включённых quirks;
+6. число прочитанных записей и точку EOF;
+7. ошибки, предупреждения и unknown ranges;
+8. результат roundtrip, если writer участвует в проверке.
+
+Для runtime-проверок дополнительно нужны mission key, configuration, device
+profile, начальное состояние, input/time script и trace значимых callbacks.
+
+## Разделение профилей
+
+Binary profile описывает исполняемый код: PE-метаданные, exports/imports,
+ordinals, hashes, RVA и layout функций. Corpus profile описывает набор файлов:
+каталог, миссии, ресурсы, размеры, counts, variants и статистику parser-а.
+
+Эти профили нельзя смешивать без явной пометки. Один и тот же формат может
+иметь общий смысл в разных сборках, но отличаться редкими ветками, адресами
+функций или набором встреченных вариантов. Один и тот же address может иметь
+смысл только внутри конкретного module hash.
+
+При расширении документации новое утверждение должно отвечать на три вопроса:
+
+1. Где это видно напрямую?
+2. На каком корпусе это проверено?
+3. Что должна сделать реализация, если правило нарушено?
+
+Если на один из вопросов нет ответа, утверждение остаётся согласованным выводом
+или открытым вопросом, а не закрытым контрактом.