aboutsummaryrefslogtreecommitdiff
path: root/docs/tomes/07-implementation.md
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-06-22 00:58:51 +0300
committerValentin Popov <valentin@popov.link>2026-06-22 00:58:51 +0300
commit78fc5f1debf1395d5df0bab7cc0dde54351205cb (patch)
treeef8f7c72a183723fcbea0b2d1fefd7c28ca7bc18 /docs/tomes/07-implementation.md
parent50c2cf4686b53ebd2b76318223096660e92305a4 (diff)
downloadfparkan-78fc5f1debf1395d5df0bab7cc0dde54351205cb.tar.xz
fparkan-78fc5f1debf1395d5df0bab7cc0dde54351205cb.zip
docs: rewrite MkDocs documentation
Diffstat (limited to 'docs/tomes/07-implementation.md')
-rw-r--r--docs/tomes/07-implementation.md674
1 files changed, 674 insertions, 0 deletions
diff --git a/docs/tomes/07-implementation.md b/docs/tomes/07-implementation.md
new file mode 100644
index 0000000..968d61b
--- /dev/null
+++ b/docs/tomes/07-implementation.md
@@ -0,0 +1,674 @@
+# VII. Руководство по полной реализации
+
+Этот том описывает инженерный путь к совместимому движку FParkan. Он опирается
+на доказанные форматы и runtime-контракты, но не требует повторять физическое
+деление оригинала на пятнадцать DLL. Повторить нужно наблюдаемое поведение:
+форматы, имена, fallback, object IDs, порядок событий, численную политику,
+границы кадра, сохранения и воспроизводимость прохождения.
+
+Предложенные ниже modules, handles, snapshots, queues и scheduler phases являются
+целевой архитектурой новой реализации, а не восстановленным внутренним layout
+оригинального Iron3D. Главная практическая цель: запускаться из неизменённого
+оригинального каталога игры, проходить corpus gates для демоверсии, Части 1 и
+Части 2, а затем измеримо двигаться от archive compatibility к полной игровой
+совместимости.
+
+## Целевая архитектура
+
+Практичная форма новой реализации -- модульный монолит с узкими интерфейсами и
+отдельными platform adapters. Внутренние границы должны соответствовать ролям
+Iron3D, а не обязательно его DLL. Это упрощает перенос на современные платформы
+и оставляет возможность поддерживать разные compatibility profiles для разных
+сборок данных.
+
+```text
+application запуск, окно, конфигурация, shutdown
+platform filesystem, clocks, input, threads, dynamic libraries
+resources NRes, RsLi, paths, archives, cache and diagnostics
+assets MSH, WEAR, MAT0, Texm, FXID and auxiliary formats
+mission TMA, unit DAT, prototype graph, scenario data
+world ObjectId, queue, lifecycle, time, messages, mirrors
+terrain Land.msh, Land.map, surface and spatial queries
+navigation areals, graph search, corridors
+behavior unit state machines, target and path requests
+physics control systems, collision proxies and contacts
+animation pose sampling, hierarchy and blending
+audio sample cache, sources, listener and buses
+render legacy-state compatibility and modern backend
+network game message schema plus transport adapters
+tools validators, extractors, viewers, captures and editors
+```
+
+Каждый модуль зависит от нижележащих интерфейсов, а не от concrete managers.
+Behavior видит `INavigation` и `IPhysicsCommandSink`, но не включает headers
+renderer-а. Render получает immutable snapshot, а не mutable world. Network
+receive не меняет мир напрямую: validated messages попадают в очередь следующей
+calculation boundary.
+
+### Центральные идентичности
+
+Resource identity хранит и исходное написание, и нормализованный ASCII-key для
+поиска:
+
+```c
+struct ResourceKey {
+ NormalizedRelativePath archive;
+ FixedAsciiName name;
+ uint32_t type_id;
+};
+```
+
+Normalization сохраняет исходную строку для diagnostics и roundtrip, а отдельный
+ASCII-casefold key используется только для lookup. Эта граница важна для
+архивов [NRes](../reference/nres.md), таблиц [RsLi](../reference/rsli.md),
+prototype references и fallback-путей материалов.
+
+Object identity разделяет внутреннюю защиту от dangling references и исходную
+сетевую/script-семантику:
+
+```c
+struct ObjectHandle { uint32_t generation; uint32_t slot; };
+struct OriginalObjectId { uint32_t raw; };
+```
+
+`ObjectHandle` нужен для безопасного внутреннего владения, deferred deletion и
+weak references. `OriginalObjectId` сохраняет наблюдаемую семантику исходной
+игры: scripts, mirrors, network messages и savegame references должны видеть
+логический ID, а не адрес объекта или номер slot в новом allocator-е.
+
+Frame snapshot отделяет simulation от render. Simulation пишет mutable state;
+renderer читает опубликованное состояние или строго ограниченную фазу
+`in_render`. Deferred deletion применяется между фазами, а не во время traversal.
+Командный контур renderer-а должен сверяться с [описанием кадра](../reference/render-frame.md)
+до pixel comparison.
+
+### Владение ресурсами
+
+Ресурс проходит несколько уровней:
+
+```text
+ArchiveHandle -> EntryView -> DecodedBlob -> ParsedAsset -> RuntimeResource
+```
+
+`EntryView` ссылается на metadata архива, `DecodedBlob` владеет подготовленными
+bytes, `ParsedAsset` является CPU-представлением, `RuntimeResource` может
+дополнительно владеть GPU/audio objects. Eviction верхнего уровня не закрывает
+архив, если он ещё нужен другому entry. Ссылки идут вниз только через явные
+handles.
+
+Для shared objects допустимы reference counting или generation handles.
+Intrusive refcount нужен только в ABI-shim; внутренний современный код
+предпочтительно держит понятное владение и weak handles. Архивы, decoded blobs,
+CPU assets и GPU resources имеют отдельные бюджеты и отдельные diagnostics.
+
+### Backend adapters
+
+Render, audio, input и network получают отдельные adapters. Legacy compatibility
+state живёт выше Vulkan, D3D11 или Metal backend; DirectPlay compatibility живёт
+отдельно от modern transport. Так можно заменить платформу, не меняя форматы,
+игровую семантику и regression corpus.
+
+Backend adapter не должен быть местом, где исправляются данные. Если
+[MSH](../reference/msh.md), [MAT0](../reference/materials.md) или
+[Texm](../reference/texm.md) требуют fallback, это фиксируется в asset/runtime
+слое и попадает в trace. Backend получает уже выбранные resources, states и
+draw items.
+
+### Scheduler phases
+
+```text
+collect_platform_events
+build_input_snapshot
+advance_game_clock
+calculate_world_queue
+apply_deferred_operations
+update_navigation_physics_animation_fx
+publish_render_snapshot
+render_world
+render_ui
+end_frame_callbacks
+maintenance_and_eviction
+```
+
+Фазы имеют стабильный порядок и запрещённые операции. Registry mutation
+запрещена во время world traversal, GPU upload не изменяет simulation state, а
+maintenance не влияет на gameplay. Script timers, material animation и FX
+lifetime относятся к game time, если обратное не доказано.
+
+Сначала реализуется однопоточный эталон. Параллелизм добавляется только внутри
+фаз с детерминированным merge: decoding независимых assets, culling chunks или
+подготовка immutable draw items. Это снижает риск скрытых race conditions и
+расхождений replay.
+
+### Структурированные ошибки
+
+Каждая ошибка должна содержать фазу, путь, archive entry, object/prototype key,
+offset и цепочку причины.
+
+```text
+MissionLoadError
+ mission: Campaign.00/Mission.02
+ object: 17
+ resource_name: UNITS/.../unit.dat
+ component: e_tur_...
+ prototype: objects.rlb::e_tur_...
+ cause: model archive missing
+```
+
+Логическое отсутствие необязательного lightmap, отсутствующий entry в архиве,
+неизвестное opaque поле, выход ссылки за диапазон и повреждённый offset имеют
+разный severity и разные способы исправления. Ошибка данных должна быть
+actionable chain, а не строка вида `failed to load resource`.
+
+## Порядок работ
+
+Движок строится от данных к поведению и от детерминированных CPU-компонентов к
+аппаратным. Каждый этап заканчивается исполняемым инструментом и тестовым
+критерием. Нельзя начинать полноценный gameplay, пока ресурсный граф и
+model/material path не дают воспроизводимый результат.
+
+### Этап 0. Corpus harness
+
+- индексировать оригинальный каталог и вычислить hashes;
+- реализовать bounded binary cursor и structured diagnostics;
+- создать CLI для массового запуска parser-ов;
+- сохранять JSON-отчёт с counts, variants, warnings и failures;
+- зафиксировать демоверсию, Часть 1 и Часть 2 как независимые baselines.
+
+Готовность: повторный запуск на каждом неизменённом каталоге даёт идентичный
+отчёт. Любой parser умеет завершиться контролируемой ошибкой с offset и
+контекстом, а не crash или allocation по непроверенному count.
+
+### Этап 1. Архивы и пути
+
+- реализовать strict/lossless [NRes](../reference/nres.md) reader/writer;
+- реализовать [RsLi](../reference/rsli.md) mapping, table transform, lookup,
+ LZSS и Deflate;
+- добавить адаптивный decoder для методов `0x080` и `0x0A0`;
+- воспроизвести overlay и известные compatibility quirks;
+- реализовать archive-handle cache и ASCII name policy.
+
+Готовность: неизменённые архивы проходят byte-identical roundtrip; поиск всех
+имён совпадает с каталогом; malformed corpus отклоняется без выхода за память.
+NRes с ненулевым unindexed region обязательно остаётся regression case.
+
+### Этап 2. Граф ресурсов
+
+- разобрать `objects.rlb` и unit DAT;
+- построить resolver прямой MSH, рекурсивного parent prototype через
+ `objects.rlb` и отдельного BASE payload;
+- реализовать dependency graph с reachability от миссии;
+- добавить parsers CTPT, NDPR и остальных служебных форматов в lossless-режиме;
+- создать инспектор прототипа, показывающий все связанные ресурсы.
+
+Готовность: 201 demo-объект раскрывается в 501 прототип. Затем все миссии
+Частей 1 и 2 дают 4 701 и 5 845 prototype requests без failures. Недостижимые
+отсутствующие ресурсы отмечаются отдельно от критических ошибок в reachable
+graph.
+
+### Этап 3. Статический asset viewer
+
+- реализовать [MSH](../reference/msh.md) core streams, slots и batches;
+- декодировать Texm во все подтверждённые pixel formats;
+- разобрать WEAR и [MAT0](../reference/materials.md) с точными fallback;
+- построить современный renderer compatibility layer;
+- добавить wireframe, normals, bounds, LOD/group и material debug views.
+
+Готовность: открываются 435/511 моделей, 518/631 textures и 905/1 127 materials
+Частей 1/2; batch/index bounds не нарушаются; viewer показывает корректно
+текстурированную статическую модель из исходного архива. Красивый viewer всё ещё
+означает только asset compatibility, а не готовую игру.
+
+### Этап 4. Анимация и эффекты
+
+- реализовать MSH type 8/type 19 sampling и hierarchy;
+- добавить x87-compatible reference path для чувствительных формул;
+- реализовать material phase animation;
+- разобрать FXID header/commands и runtime instances;
+- сначала поддержать все opcodes, встречающиеся в корпусе, сохраняя raw body;
+- добавить deterministic RNG stream и effect capture.
+
+Готовность: frame-by-frame poses совпадают с golden reference своей части; все
+923/1 065 FXID создаются без parser errors; перезапуск одинакового effect seed
+даёт идентичный список emitted primitives.
+
+### Этап 5. Карта и мир
+
+- реализовать `Land.msh` и corrected `TerrainFace28` layout;
+- построить terrain rendering и CPU surface queries;
+- реализовать `Land.map`, cell grid и graph links;
+- визуализировать areals и найденные маршруты;
+- разобрать [TMA](../reference/tma.md) и выполнять staged mission loading;
+- создать World3D queue, ObjectId и deferred deletion.
+
+Готовность: 65 карт и 60 TMA Частей 1 и 2 загружаются до EOF; все areal links
+валидны; objects появляются в правильных transforms; мир выдерживает расчётные
+шаги без рендера.
+
+### Этап 6. Gameplay controllers
+
+- подключить input snapshot и camera controller;
+- реализовать navigation corridor, Behavior state machine и Wizard boundary;
+- создать physical controller и collision manager;
+- загрузить control resources в lossless typed model;
+- внедрить game time, pause, event queue и end-of-frame callbacks;
+- подключить AI layer и symbol/event layer сценариев.
+
+Готовность: юнит получает цель, строит маршрут, движется по terrain, реагирует
+на collision и исполняет базовые миссионные события в детерминированном replay.
+На этом этапе вводится differential branch для изменённых `AniMesh`, `Control` и
+`Effect`; неизменённые DLL используют общий reference path.
+
+### Этап 7. Полный кадр, звук и UI
+
+- реализовать render phases, sorting, lighting, shadows и atmosphere;
+- подключить 3D listener, sample cache, FX sounds и mission audio;
+- воспроизвести shell/UI loading и post-world pass;
+- добавить frame capture до UI и после UI;
+- зафиксировать capability fallback profiles.
+
+Готовность: миссия визуально и звуково проходима; каждый draw и sound event
+имеет trace; одинаковый replay создаёт одинаковые command lists. На этом этапе
+вводится differential branch для `iron3d` и `services`.
+
+### Этап 8. Сеть, сохранения и динамическая совместимость
+
+- реализовать modern transport над versioned game-message schema;
+- отдельно исследовать DirectPlay wire и `netZipData` для native compatibility;
+- добавить mirrors, ownership transfer и disconnect cleanup;
+- восстановить save/campaign state и dispatcher;
+- выполнить динамические captures оригинала для render states, script VM и
+ physics edge cases.
+
+Готовность: одиночная кампания запускается из оригинального каталога,
+сохраняется и продолжается; multiplayer replay согласован между peers; full
+corpus не создаёт новых parser variants без явной регистрации.
+
+## Тестовый контур
+
+Совместимость нельзя подтвердить одним screenshot. Нужны тесты на уровне bytes,
+структур, ссылок, simulation state, команд renderer-а и конечного изображения.
+Каждый слой локализует свой класс ошибки.
+
+```text
+unit tests
+ -> parser/property tests
+ -> corpus validation
+ -> cross-resource integration
+ -> deterministic simulation replay
+ -> render/audio command captures
+ -> pixel and gameplay parity
+```
+
+Failure верхнего уровня всегда должен позволять спуститься к меньшему тесту и
+понять причину.
+
+### Unit, property и fuzz tests
+
+Для каждого binary primitive проверяются little-endian чтение, bounded strings,
+checked arithmetic и cursor boundaries. Для структур -- минимальный размер,
+максимальные counts, пустые arrays, нулевые варианты и редкие branches.
+
+Property tests генерируют случайные корректные NRes/RsLi/WEAR records,
+выполняют encode -> decode и сравнивают семантику. Fuzz tests изменяют длины,
+offsets, counts и termination bytes и требуют контролируемой ошибки без crash и
+чрезмерного выделения памяти.
+
+Критические алгоритмы имеют отдельные vectors: ASCII casefold, NRes permutation
+search, RsLi byte transform, LZSS backreferences, quaternion shortest path,
+matrix composition и terrain mask remap.
+
+### Corpus validation
+
+Каждый файл оригинального каталога проходит parser своего семейства. Отчёт
+содержит hash, variant, counts, warnings, errors и точный offset сбоя. Baseline
+демоверсии:
+
+```text
+MSH 435
+MAT0 905
+Texm 518
+FXID 923
+WEAR 457
+Land.msh 6
+Land.map 6
+TMA 6
+unit DAT 425
+errors 0
+```
+
+Изменение parser-а принимается только если baseline остаётся стабильной либо
+новый variant зарегистрирован с образцом и объяснением. Warnings должны быть
+именованными: «неизвестное opaque поле» не равно «выход ссылки за диапазон».
+
+### Cross-resource integration
+
+Интеграционный тест начинается с миссии и проходит весь dependency graph:
+object -> prototype -> MSH -> WEAR -> MAT0 -> Texm/lightmap/FXID. Он не
+ограничивается тем, что файлы существуют: material slot должен указывать на
+допустимый MAT0, phase -- на допустимую texture, model batch -- на существующий
+WEAR index.
+
+Demo mission total: 201 objects -> 501 prototypes -> 501 object MSH/WEAR.
+Чистый object graph даёт 3 873 material slots и 5 049 texture requests; после
+включения environment WEAR итог равен 3 879 material slots, 5 067 textures и
+18 lightmaps, failures 0. Такой тест ловит ошибки casefold, suffix, fallback и
+путей, которые отдельный parser не замечает.
+
+Для каждого отсутствующего узла отчёт хранит полный parent chain, чтобы
+различать broken global archive и реально достижимый mission failure.
+
+### Deterministic simulation replay
+
+Записывается начальная миссия, seed, input events, network messages и значения
+внешних часов. На контрольных ticks сохраняется canonical state hash:
+
+```text
+sorted ObjectId list
+transforms and velocities
+critical properties and owners
+AI/behavior state IDs
+active effect state
+game clock and RNG states
+```
+
+Pointer addresses, allocator order и GPU handles в hash не входят. Два запуска с
+одинаковым log должны давать одинаковый state hash на каждом checkpoint. Первое
+расхождение гораздо информативнее финального разного результата миссии.
+
+### Render command parity
+
+До pixel comparison сравнивается command list:
+
+```text
+camera matrices and viewport
+visible ObjectIds
+render phase and stable order
+model/node/slot/batch IDs
+material phase and texture handles
+legacy pipeline states
+index ranges and transforms
+```
+
+Если command lists совпадают, но pixels различаются, проблема находится в
+shader/backend, sampling или численной точности. Если command lists уже
+различаются, pixel diff лишь скрывает более раннюю ошибку.
+
+Golden captures следует хранить отдельно для статической модели, анимации,
+terrain, transparent FX, shadows, lightmap и atmosphere.
+
+### Pixel, audio и network tests
+
+Pixel tests используют фиксированное разрешение, camera, device profile, seed и
+timeline. Сравниваются exact pixels для CPU/reference path и tolerance metrics
+для GPU path, но tolerance не должна скрывать переставленные прозрачные
+primitives.
+
+Audio tests сравнивают список sound events, sample IDs, positions, loop flags и
+gains; waveform зависит от mixer/device и является вторичным уровнем. Network
+tests воспроизводят captured message sequences, проверяют mirrors, ownership и
+disconnect. Для native DirectPlay compatibility дополнительно нужен packet-level
+corpus.
+
+## Regression baselines
+
+Corpus validation формирует три независимых отчёта: демоверсия, Часть 1 и
+Часть 2. Каждый сохраняет manifest файлов, hashes executable/DLL, variants,
+warnings, global archive health и mission reachability.
+
+Ключевые corpus gates:
+
+```text
+NRes: 120 файлов / 6 804 entries и 134 / 8 171 для Частей 1/2
+TMA: 29 миссий / 864 objects / 28 extras и 31 / 885 / 41
+MSH: 435 и 511 моделей
+MAT0: 905 и 1 127 материалов
+Texm: 518 и 631 текстура
+FXID: 923 и 1 065 эффектов
+full reachability: 4 701 и 5 845 prototype requests, failures 0
+```
+
+Расширенные mission-reachability totals:
+
+```text
+Часть 1: 29 TMA, 864 objects, 4 701 prototypes,
+ 36 954 materials, 48 806 textures, 139 lightmaps, failures 0
+Часть 2: 31 TMA, 885 objects, 5 845 prototypes,
+ 50 888 materials, 68 603 textures, 214 lightmaps, failures 0
+```
+
+Обязательные regression cases:
+
+- NRes с ненулевым unindexed region;
+- prototype inheritance через `objects.rlb`;
+- unit DAT `description[32]` без NUL;
+- TMA epilogue и `extra_count` 0--4;
+- empty SWAV entry;
+- stale save-slot metadata без payload;
+- build-scoped RVA lookup.
+
+Byte-identical asset comparison выполняется только внутри одного корпуса. Между
+Частями 1 и 2 сравниваются semantic invariants и decoded representation,
+поскольку многие assets пересобраны.
+
+## Точность, скорость и повторяемость
+
+Совместимый движок должен быть корректным, повторяемым и достаточно быстрым.
+Эти свойства нельзя получать одним и тем же приёмом. Сначала создаётся простой
+эталонный путь, затем он измеряется и оптимизируется без изменения результата.
+
+Главные источники расхождений: x87 extended precision, преобразование float в
+integer, порядок операций, старые SIMD implementations, нестабильная сортировка,
+RNG и использование разных часов.
+
+### x87 и округление
+
+Оригинальный x86-код мог хранить промежуточные значения в 80-битных регистрах
+x87, а в память записывать 32-битный float. Современный compiler чаще использует
+SSE с округлением после каждой операции. Различие заметно на границах animation
+frame, culling plane и collision threshold.
+
+Для критических формул нужен reference mode:
+
+- фиксированный порядок операций без reassociation;
+- запрещённый fast-math;
+- явные преобразования и проверенный режим округления;
+- тесты возле half-integer и epsilon boundaries;
+- при необходимости extended intermediate через `long double` на проверенной
+ платформе.
+
+Не требуется эмулировать x87 во всём движке. Нужно локализовать функции, где
+малое отличие меняет дискретное решение, и держать для них scalar reference path.
+
+### RNG как часть состояния
+
+FX, atmosphere и, вероятно, AI используют случайные значения. Один глобальный
+RNG легко расходится, если новая реализация запрашивает дополнительное число для
+визуальной оптимизации. Для трассировки полезны именованные streams:
+
+```text
+world/gameplay RNG
+AI/script RNG
+FX instance RNG
+atmosphere RNG
+non-deterministic cosmetic RNG
+```
+
+Для native parity может потребоваться один общий алгоритм и точная sequence. До
+подтверждения capture каждый stream хранит seed и счётчик вызовов в trace.
+Cosmetic stream не входит в simulation hash.
+
+### Стабильный порядок
+
+Коллекции не должны зависеть от адресов, unordered containers или порядка
+завершения worker threads. Для объектов, collision pairs, opaque/transparent
+draws и network messages задаются явные stable keys:
+
+- objects -- queue insertion sequence или OriginalObjectId;
+- collision pairs -- упорядоченная пара IDs;
+- opaque draws -- phase, pipeline key, material, stable insertion ID;
+- transparent draws -- layer, quantized distance, stable insertion ID;
+- network messages -- sequence и sender.
+
+Даже когда математический результат коммутативен, side effects, cache accesses и
+RNG делают порядок наблюдаемым.
+
+### Часы и fixed-step
+
+Monotonic platform clock хранится отдельно от game clock. Pause и time scaling
+применяются к game clock. Simulation работает с фиксированным или точно
+воспроизводимым шагом, а render может интерполировать presentation state, не
+изменяя authoritative world.
+
+Maintenance timers кэшей используют реальные часы или отдельную подтверждённую
+шкалу; их срабатывание не должно менять gameplay. При перегрузке лучше выполнить
+ограниченное число simulation steps и явно зафиксировать dropped presentation
+frames, чем передать огромный `dt` в AI/physics.
+
+### Оптимизация без потери эталона
+
+1. Сохранить scalar reference implementation.
+2. Добавить profiler counters на decoding, culling, sorting, animation, upload
+ и draw.
+3. Оптимизировать только измеренный bottleneck.
+4. Сравнить SIMD/parallel результат с reference на полном corpus.
+5. Оставить runtime switch для отключения оптимизации при диагностике.
+
+`g_FastProc` удобно моделировать как таблицу function objects: все slots сначала
+указывают на scalar path, затем безопасные slots заменяются SIMD-вариантами
+после self-test на старте.
+
+### Кэш и память
+
+Архивы, decoded blobs, CPU assets и GPU resources имеют отдельные budgets.
+Eviction разрешена только для объектов с нулевым external refcount и после
+безопасной frame fence. Original delayed cleanup порядка десятков секунд можно
+воспроизвести policy-параметрами, не сканируя все entries каждый кадр.
+
+Основные показатели: число открытых архивов, decoded bytes, resident
+textures/lightmaps, models, active FX, draw items и deferred-delete size. Любой
+неограниченно растущий счётчик является regression. Производительность считается
+достаточной только после корректности: стабильные 60 FPS с неверным LOD или
+пропущенными эффектами не являются успехом.
+
+## Release gates
+
+Версия не выпускается, если:
+
+- появился новый corpus error;
+- изменился byte roundtrip неизменённых ресурсов;
+- dependency graph получил failure в достижимом пути;
+- deterministic replay расходится;
+- command capture изменился без ожидаемого changelog;
+- parser допускает allocation по непроверенному count;
+- новая оптимизация не имеет scalar reference comparison.
+
+Каждое исправление регистрирует минимальный regression asset или synthetic
+vector. Если новый behavior намеренно отличается от предыдущего, изменение
+должно иметь compatibility profile, corpus sample и объяснение, почему старый
+baseline был неполным или неверным.
+
+## Уровни совместимости
+
+Слово «совместимый» используется только с уровнем:
+
+1. **Archive-compatible** -- открывает и сохраняет контейнеры.
+2. **Asset-compatible** -- декодирует модели, материалы, текстуры и эффекты.
+3. **Mission-compatible** -- загружает карту и создаёт все объекты.
+4. **Runtime-compatible** -- исполняет время, события, поведение и физику.
+5. **Presentation-compatible** -- воспроизводит рендер и звук.
+6. **Game-compatible** -- позволяет пройти миссии, сохраняться и продолжать.
+7. **Native-interoperable** -- взаимодействует с оригинальной сетью и внешним
+ ABI.
+
+Viewer с красивой моделью находится только на втором уровне.
+
+### Обязательные критерии запуска и данных
+
+- приложение запускается из неизменённого оригинального каталога;
+- относительные пути, регистр и legacy encodings разрешаются по исходным
+ правилам;
+- все требуемые NRes/RsLi открываются без предварительной конвертации;
+- parsers проверяют границы и не используют неопределённые bytes как указатели;
+- неизвестные поля сохраняются lossless;
+- все mission-reachable prototype, model, material, texture, lightmap и effect
+ references разрешаются;
+- отсутствие необязательного ресурса следует документированному fallback, а не
+ случайному default.
+
+### Обязательные критерии мира
+
+- TMA разбирается до точного EOF;
+- `Land.msh` и `Land.map` создают корректную поверхность и areal graph;
+- ObjectId, owner и mirror semantics устойчивы;
+- queue traversal и deferred deletion безопасны;
+- pause, game time и simulation steps повторяемы;
+- AI/Behavior/Wizard/Control взаимодействуют через заданные границы;
+- collision и navigation не подменяют друг друга;
+- script events используют logical IDs и переживают удаление объектов;
+- deterministic replay совпадает на контрольных ticks.
+
+### Обязательные критерии presentation
+
+- static и animated MSH используют правильные slots, batches и transforms;
+- WEAR/MAT0/Texm fallback и phase timing совпадают;
+- mip-skip, palettes, Page atlases и lightmaps работают;
+- render phases, depth/cull/blend state и transparent order подтверждены
+ captures;
+- FXID commands и RNG дают устойчивый результат;
+- camera и 3D sound listener синхронизированы;
+- atmosphere, тени, солнце и flares не являются декоративными заглушками;
+- UI и world rendering имеют правильную границу;
+- golden command captures стабильны, pixel parity измеряется на фиксированных
+ сценах.
+
+### Обязательные критерии полной игры
+
+- все доступные миссии стартуют, завершаются и корректно сообщают
+ success/failure;
+- campaign dispatcher сохраняет прогресс;
+- savegame восстанавливает world, script, AI, RNG и clocks, а не только
+ placement;
+- input remapping, pause, camera modes, sound и настройки работают из UI;
+- длительный прогон не накапливает objects, resources или audio sources;
+- ошибки данных показывают actionable chain;
+- производительность приемлема без отключения подсистем;
+- демоверсия, Часть 1 и Часть 2 проходят один и тот же тестовый контур с
+ раздельными manifests и эталонами.
+
+### Native interoperability
+
+Самый строгий уровень дополнительно требует совпадения x86 ABI экспортов, vtable
+slots и calling conventions для подключаемых оригинальных модулей, а также
+DirectPlay wire/framing и compression. Этот уровень независим от возможности
+играть в новом standalone runtime.
+
+Проект может честно заявлять game compatibility без native DLL/network
+interoperability, но это должно быть явно указано. Аналогично pixel-perfect режим
+может быть отдельным compatibility profile поверх функционально корректного
+renderer-а.
+
+### Совместимость нескольких наборов данных
+
+Критерий полной совместимости применяется отдельно к демоверсии, Части 1 и
+Части 2. Прохождение одного набора не позволяет заявлять поддержку остальных.
+
+Обязательное различие:
+
+- **format compatibility** -- один parser принимает все три набора;
+- **content compatibility** -- конкретная миссия разрешает весь reachable graph;
+- **behavior compatibility** -- runtime совпадает с соответствующей сборкой
+ изменённых DLL;
+- **cross-version support** -- один новый движок выбирает корректные данные и
+ defaults по fingerprint установки.
+
+Content fingerprint включает hashes executable/DLL и manifest ключевых архивов.
+Он не используется для запрета модификаций, но выбирает compatibility profile и
+делает отклонение диагностируемым.
+
+## Definition of done
+
+Полное документирование и реализация считаются завершёнными только когда каждый
+критерий связан с главой спецификации, executable test и хотя бы одним
+corpus/golden case. Утверждение без проверяемого критерия остаётся
+исследовательской заметкой, а не контрактом.