diff options
Diffstat (limited to 'docs/tomes/08-evidence.md')
| -rw-r--r-- | docs/tomes/08-evidence.md | 779 |
1 files changed, 38 insertions, 741 deletions
diff --git a/docs/tomes/08-evidence.md b/docs/tomes/08-evidence.md index 98f6f13..35bee99 100644 --- a/docs/tomes/08-evidence.md +++ b/docs/tomes/08-evidence.md @@ -1,33 +1,9 @@ -# VIII. Справочник и доказательная база +# VIII. Устройство оригинальной программы -Восьмой том фиксирует, на чём держится книга: ABI, exports/imports, файловая -поверхность, статистика корпусов, открытые вопросы, критерии доказанности и -словарь терминов. Это самостоятельная справочная глава: она не заменяет -профильные статьи о форматах, но задаёт общий контракт, по которому проверяются -реализация, parser-ы, compatibility layer и будущие динамические эксперименты. - -## Как читать доказательства - -Доказательством считается наблюдение, которое можно повторить на конкретном -файле, сборке или трассе. Вывод может объединять несколько наблюдений, но он -должен сохранять происхождение данных: демоверсия, полная Часть 1 и полная -Часть 2 не смешиваются в один безымянный corpus. - -Для каждого утверждения полезно различать четыре уровня: - -- `layout-confirmed`: известны offset, size, count, bounds и правила безопасного - чтения; -- `corpus-verified`: branch или вариант реально встречается в доступных игровых - данных; -- `code-confirmed`: branch виден в бинарном коде, но отсутствует в доступном - corpus; -- `behavior-confirmed`: поведение подтверждено исполнением оригинальной - программы, трассой API/vtable или controlled differential test. - -Если поле не имеет доказанного предметного смысла, документация хранит его как -opaque field. Это не мешает lossless read/write, но запрещает строить writer, -который очищает, переименовывает или пересчитывает такое поле на основании -правдоподобной догадки. +Здесь собраны детали, полезные при чтении оригинальных DLL: экспортируемые +функции, соглашения вызова, адреса и конфигурационные файлы. Адрес относится +к конкретной сборке; сравнить её можно по +[хэшам модулей](../reference/original-binaries.md). ## ABI и границы модулей @@ -215,12 +191,10 @@ RVA используются только для сопоставления и Ñ implementation не должна встраивать их как постоянные игровые идентификаторы. Таблица внутренних RVA хранится по SHA-256 конкретного модуля. -Операционные evidence-артефакты, которые должны оставаться синхронизированными -с кодом и acceptance, вынесены в отдельные страницы: - -- [Hashes и import/export summary оригинального движка](../evidence/original_engine_hashes.md) -- [Stage 4 capture schema](../evidence/stage4_capture_schema.md) -- [Renderer truth table](../rendering/renderer_truth_table.md) +Сводка hashes и import/export оригинального движка вынесена в отдельную +[страницу](../reference/original-binaries.md). Текущее состояние +реализации и границы live Vulkan path описаны в [справочнике render frame](../reference/render-frame.md) +и в исходном коде адаптера. Подтверждённые hashes неизменённых DLL: @@ -229,11 +203,10 @@ World3D.dll 17e4a3089b2583a8cf2356c9db0390b1aba138356a09130d79b4e7e4791da61e Ngi32.dll bab9840d94f4e4e74ffc26677724fa896cf4823845504d09a9e025f80016edf5 ``` -Повторный headless IDA/Hex-Rays review GOG `World3D.dll` с этим hash уточнил -RVA export-ов: `stdCalculateGame=0x139A0`, `stdRenderGame=0x13BD0`, +Для GOG `World3D.dll` с этим hash RVA export-ов такие: `stdCalculateGame=0x139A0`, +`stdRenderGame=0x13BD0`, `sendEndOfRender=0x13D90`, `stdSetCurrentCamera=0x13E60` и -`stdGetCurrentCamera=0x13E80`. Предыдущая таблица была сдвинута и не должна -использоваться для hooks или differential capture. +`stdGetCurrentCamera=0x13E80`. `stdRenderGame(camera)` сначала вызывает экспорт Terrain `stdSetCurrentCamera2(camera)`, затем сохраняет текущий camera pointer в @@ -254,7 +227,7 @@ Terrain object. Следовательно, selector `18`, slot `+12` и global должны оставаться именованными evidence boundary до dynamic capture; считать `stdGetCurrentCamera2` getter-ом переданной camera было бы ошибкой. -Повторный headless-IDA review той же GOG базы уточняет рабочий static contract +Статический анализ той же GOG базы уточняет рабочий контракт `CBufferingCamera`. Метод Terrain RVA `0x4D740` копирует ровно 64 байта (16 dword) в component offset `+0x10`. Frame-preparation метод RVA `0x4D9C0` получает viewport rectangle через virtual slot `+0x3C`, выводит width, height, @@ -268,45 +241,20 @@ near/far mapping, handedness или initial camera selection. Важно, что `ICamera::GetTransformMatrix` (RVA `0x4F850`) ведут только в obsolete-call stubs и не дают usable ABI. -Live elevated read-only probe впервые подтвердил relocation-aware runtime связь: -`Terrain.dll` был загружен по `0x02510000`, global `base + 0x7355C` содержал -non-null `0x0B37DF08`, а первый dword этого объекта был `0x025765B4` — ровно -relocated `off_100665B4` из `LoadCamera` construction path. Это доказывает -live camera object с outer vtable, но одновременно исправляет прежнее слишком -сильное сопоставление offsets: raw read `global + 0x10` не дал finite 4x4 matrix, -а `+0x234` был zero в данном sample. Receiver static procedures `0x4D740`/ -`0x4D9C0` и exported global ещё не доказаны как один layout без interface -adjustment; их offsets остаются unassigned до recovery selector relationship. - -Локальная IDA-база уточняет адреса этой связи: `stdGetCurrentCamera2` — это -шестибайтный getter по RVA `0x4FD80`, который возвращает `dword` по RVA -`0x7355C`. Единственный найденный **direct static** initializer этого global — функция Terrain -по RVA `0x4D4D0`: она запрашивает selector `8` у своего `this` и сохраняет -полученный interface pointer. Это доказывает адрес хранения и путь заполнения, -но не разрешает трактовать pointer как конкретный layout камеры либо читать его -как runtime evidence без доступа к процессу на том же уровне привилегий. - -Elevated live sampling теперь доказывает, что direct static xref не исчерпывает -runtime writers: за 25 секунд autoplay global переключился между тремя heap -pointer, все с relocated outer vtables `0x025765B4`/`0x02576558`. У двух объектов -paired blocks `+0x2C/+0x3C/+0x4C` и `+0x6C/+0x7C/+0x8C` синхронно несли -world-like translation, например `(491.562, 761.551, 7.361)`; третий давал -normalized-looking `(0.098, 0.018, 0.856)` и не совпадал с paired block. -Наблюдение согласуется с автоматическими camera switches, но не маркирует mode; -оно запрещает называть `0x4D4D0` единственным runtime writer и требует recovery -indirect/unanalyzed write path. - -Outer vtable `off_100665B4` теперь даёт exact transform adjustment для -world-like sample. Slot `+0x54` вызывает у subobject `outer + 4` slot `+0x20` -с selector `0`, затем копирует returned `+0x0C/+0x1C/+0x2C`. В live объекте -selector field `outer + 0x10` был `0xFFFFFFFF`; реализация selector `0` при -этом возвращает `outer + 0x20`. Значит observed triple -`outer + 0x2C/+0x3C/+0x4C` — доказанная translation часть active affine -transform, а не корреляция. Selector `2` возвращает paired block `outer + 0x60`; -outer slot `+0x70` применяет `atan2` к его axis values, что доказывает -orientation-angle path. Названия полей, angle order и handedness пока не -установлены, но raw affine transform и translation можно сохранять как -backend-neutral camera pose без догадок. +Глобальная camera boundary имеет более точное статическое описание. +`stdGetCurrentCamera2` — короткий getter Terrain по RVA `0x4FD80`, который +читает указатель из global RVA `0x7355C`; initializer по RVA `0x4D4D0` +запрашивает selector `8` у своего `this` и сохраняет полученный interface +pointer. Запрос selector `18` у landscape object проходит через RVA `0x106D0` +и `0x107E0`, возвращает subobject по `base + 0x138`. + +Внешняя camera vtable по RVA `0x665B4` имеет slot `+0x54`, который вызывает у +subobject `outer + 0x4` slot `+0x20` с selector `0` и копирует возвращённые +компоненты `+0x0C`, `+0x1C` и `+0x2C`. При значении selector field +`outer + 0x10 = -1` selector `0` возвращает `outer + 0x20`; selector `2` +возвращает `outer + 0x60`, а slot `+0x70` выводит углы через `atan2`. +Это фиксирует пути чтения положения и ориентации, но не назначает имена полям, +порядок углов или handedness. ### Vtable и interface negotiation @@ -315,6 +263,11 @@ backend-neutral camera pose без догадок. world traversal; camera и viewport получаются через selector-based interface calls; shared objects используют ранний slot как AddRef-подобную операцию. +Запрос selector `18` у landscape object проходит через RVA `0x106D0` и +`0x107E0`, возвращает subobject по `base + 0x138`, а его vtable slot `+0x18` +ведёт через RVA `0x14230` к обработчику `0x127D0`. Это geometry-interface +boundary, отдельная от хранения активной camera. + Правила реконструкции: 1. Зафиксировать byte offset slot и число аргументов. @@ -326,45 +279,6 @@ calls; shared objects используют ранний slot как AddRef-поÐ Нельзя добавлять virtual destructor в начало reconstructed interface: это сдвинет все slots. -### ABI-матрица Частей 1 и 2 - -Во всех пятнадцати DLL совпадают export names, ordinals и import sets. Общее -число exports остаётся 313. Обе полные части содержат 1 134 imported function -slots; значение 1 126 относится к демоверсии и хранится отдельно. - -Побайтно идентичны девять DLL: - -```text -ai.dll -Behavior.dll -Joystick.dll -MisLoad.dll -Net.dll -Ngi32.dll -Terrain.dll -Wizard.dll -World3D.dll -``` - -Пересобраны `AniMesh.dll`, `ArealMap.dll`, `Control.dll`, `Effect.dll`, -`iron3d.dll`, `services.dll`. - -Изменение export RVA: - -```text -AniMesh 2 / 2 -Control 5 / 5 -iron3d 8 / 8 -services 6 / 6 -ArealMap 0 / 9 -Effect 0 / 2 -``` - -Нулевое изменение export RVA не доказывает идентичность тела функции: -`ArealMap.dll` и `Effect.dll` имеют изменённый `.text` при прежних адресах -exports. Compatibility headers фиксируют внешний ABI один раз, но внутренняя -таблица адресов, тестов и semantic deltas выбирается по build fingerprint. - ## Файловая поверхность ### Каталог как внешний API @@ -546,628 +460,11 @@ provenance: parser хранит не только effective value, но и прÐ identifier и path normalization должны оставаться разными слоями: локализация текста не меняет ASCII-casefold policy имён entries. -## Результаты проверки корпусов - -### Demo baseline - -Демоверсия содержит `iron_3d.exe`, те же 15 DLL и сокращённый набор -миссий/ресурсов. Все 15 DLL совпали с первоначально исследованными файлами по -SHA-256. Поэтому executable, бинарный код DLL и demo-assets относятся к одной -совместимой технологической сборке. - -```text -modules: 16, из них DLL: 15 -DLL exports: 313 -DLL imports: 1126 -DLL identity: 15/15 -``` - -`iron_3d.exe`: 36 864 байта, PE32/x86, image base `0x400000`, entry RVA -`0x141E`, timestamp 28 июня 2001 года, SHA-256 -`b0a8b0db1c3a8698c4d4604d89c655496bd91ac1f8859a455e8a45838aebfbd6`. - -### Миссии и сквозные ссылки - -Шесть TMA разобраны до точного EOF: суммарно 20 paths, 15 clans, 201 placed -objects и 1 extra record. 48 объектов ссылаются на unit DAT, 153 -- на прямые -prototype keys. Unit-файлы раскрыли 348 компонентов. - -Сквозной результат: - -```text -501 prototype requests 501 resolved -501 MSH requests 501 resolved -501 WEAR requests 501 resolved -3879 material slots 3879 resolved -5067 texture requests 5067 resolved -18 lightmap requests 18 resolved -failures 0 -``` - -Это самое сильное интеграционное подтверждение текущего корпуса: имена, -архивы, ASCII casefold и fallback согласуются между реальными форматами. - -### Реестр и unit DAT - -`objects.rlb` содержит 590 prototype entries: - -```text -554 имеют прямую MSH-ссылку -549 прямых MSH разрешаются в demo-каталоге -34 раскрываются через родительский prototype и локальный BASE -7 не дают доступной геометрии -41 ссылка общего реестра указывает на отсутствующий demo-content -``` - -Негеометрические или неразрешённые глобальные entries: - -```text -sun_01 -sun_02 -ws_al_01 -ws_al_02 -ws_fl_01 -ws_hm_01 -ws_hm_02 -``` - -Они не входят в фактически требуемую цепочку проверенных миссий. - -Проверено 425 unit DAT, 5 219 records, errors 0. Все records имеют kind 1 и -archive `objects.rlb`; в 5 205 name fields есть ненулевые хвостовые байты после -string terminator. Такой tail является данными, а не мусором, если цель -- -lossless roundtrip. - -### Модели - -Проверено 435 MSH без errors/warnings; 157 анимированных. Диапазоны: 1-38 -nodes, 1-112 slots, 12-9 686 vertices, 1-439 batches. - -```text -414 моделей: types [1,2,3,4,5,15,13,6,7,8,19,9,10,17] -21 модель: [1,2,3,4,5,18,15,13,6,7,8,19,9,10,17,20] -``` - -Type 17 непуст у 29 моделей; type 20 встречается у 21. Редкий variant type 1 -найден в `system.rlb::MTCHECK.MSH`. - -Повторная проверка terrain исправила layout face: vertex indices находятся с -`+0x08`, neighbor indices с `+0x0E`. Эта локальная проверка имеет приоритет над -ранними черновыми описаниями. - -### Материалы и текстуры - -Проверено 457 WEAR, 905 MAT0 и 518 Texm без ошибок. У всех MAT0 `attr2 = 6`. -531 материал содержит одну phase; максимальное число phases -- 29. У 860 -материалов один animation block, у 43 -- два, у 2 -- восемь. - -Распределение Texm по форматам: - -```text -indexed 15 -565 155 -4444 59 -888 52 -8888 237 -``` - -Форматы 556 и 88 присутствуют в loader-е, но не встречаются в demo-assets. -65 текстур содержат `Page`; размеры лежат от `8x8` до `256x256`. Все 385 -уникальных texture references из MAT0 разрешаются. - -### Эффекты - -Проверено 923 FXID без ошибок. Наиболее часты команды 3, 7, 1 и 2. Команда 6 в -данных демоверсии не встречается. Наблюдаются режимы времени 0, 1, 2, 4, 5, -14, 15, 16 и 17. - -### Карты - -Шесть `Land.msh` и шесть `Land.map` проходят проверку без ошибок. Всего 3 811 -ареалов; grid всегда `128x128`, максимальное число candidates в ячейке -- 10, -`poly_count` во всех записях равен нулю. - -```text -AutoMAP 3051 vertices, 3174 faces, 343 areas -PROL 11125 vertices, 9234 faces, 731 area -Tut_1 8827 vertices, 8290 faces, 378 areas -Tut_2 9456 vertices, 8996 faces, 900 areas -Tut_3 9833 vertices, 8560 faces, 722 areas -Tut_4 9022 vertices, 8612 faces, 737 areas -``` - -Максимальное отклонение длины areal normal от единицы около `1.05e-7`. - -### Вспомогательные форматы - -```text -CTPT 284 resources, 3599 points, errors 0 -NDPR 494 resources, 1915 records, errors 0 -BASE 30 resources, errors 0 -EXPL 144 resources, versions 1/2/3, errors 0 -reference arrays 585 resources, 2956 records, errors 0 -SUND 2 resources, 12 keys, errors 0 -CTLD 531 payloads, errors 0 -TRF 5 files, errors 0 -preload 38 entries -ANI 8 resources -SKE 6 resources -``` - -CTPT names подтверждают attachment semantics: `TurretCenter`, `TurretDirect`, -`CameraCenter`, `TargetDirect`, `Root`, `Sfx`, `Width`, `Height`, `Dir` и -другие. - -### Как читать статистику - -Нулевое число parser errors подтверждает layout и диапазонные инварианты на -имеющихся variants, но не автоматически раскрывает предметный смысл каждого -opaque field. Отсутствие opcode или poly branch в corpus означает, что эту -ветку нельзя считать corpus-verified. - -Особенно важно различать весь архив и достижимый runtime path. В `objects.rlb` -есть ссылки на вырезанный demo-content, однако шесть миссий не требуют их. -Поэтому quality gate имеет два отчёта: global archive health и mission -reachability. - -### Полные каталоги Частей 1 и 2 - -Статистика демоверсии остаётся неизменной. Полные Части 1 и 2 образуют два -самостоятельных профиля с отдельными manifests, hashes и golden data. - -Часть 1: - -```text -files 1 017, bytes 197 056 957 -NRes 120 / 6 804 entries -TMA 29 / 864 objects / 28 extras -unit DAT 425 / 5 219 records -objects.rlb 590 prototypes -MSH 435, MAT0 905, Texm 518, FXID 923 -Land maps 33 / 34 662 areals -reachable prototypes 4 701 -materials 36 954, textures 48 806, lightmaps 139 -reachability failures 0 -``` - -Часть 2: - -```text -files 1 302, bytes 358 004 931 -NRes 134 / 8 171 entries -TMA 31 / 885 objects / 41 extras -unit DAT 676 / 8 145 records -objects.rlb 683 prototypes -MSH 511, MAT0 1 127, Texm 631, FXID 1 065 -Land maps 32 / 18 984 areals -reachable prototypes 5 845 -materials 50 888, textures 68 603, lightmaps 214 -reachability failures 0 -``` - -Bootstrap Частей 1 и 2 идентичен. Девять DLL идентичны, шесть пересобраны при -сохранённом ABI. Активные NRes entries сравниваются так: 3 733 идентичны, 2 503 -имеют изменённый payload, 1 934 добавлены в Части 2, 567 удалены. Это -показывает стабильность форматов при существенной переработке content, -особенно MSH, CTLD и FXID. - -## Границы знания - -### Закрытые или практически закрытые области - -- Startup bootstrap и восемь exports `iron3d.dll`. -- Карта 15 DLL, exports/imports и основные interface boundaries. -- NRes layout, поиск и writer rules. -- RsLi header, table transform, lookup, mapping и используемые decode paths. -- TMA всех 60 проверенных миссий, unit DAT и `objects.rlb` resolution. -- MSH core/animation range contracts. -- WEAR, MAT0, Texm и FXID framing. -- `Land.msh`/`Land.map` и areal grid. -- World3D calculation/render order и deferred deletion. -- Сквозная mission-to-texture цепочка. - -Полная проверка доступных каталогов усилила NRes active ranges, recursive -prototype inheritance через `objects.rlb`, bounded non-NUL unit descriptions, -полный TMA epilogue, extra records и Clan mode 0, MSH/MAT0/Texm/FXID variant -matrix Частей 1 и 2, 65 `Land.msh`/`Land.map`, полный reachable graph 60 -миссий, stability matrix пятнадцати DLL, empty SWAV и stale save-slot metadata. - -### Render-state и pixel parity - -Доказан порядок frame boundaries, world traversal, material resolve и крупных -проходов. Не доказаны символами точные названия renderer vtable slots -`+0x28/+0x30/+0x34`, полный набор state transitions CShade и окончательный -взаимный порядок некоторых transparent/FX/shadow subpasses. - -Pixel parity требует эталонных кадров оригинала с фиксированными camera, -timing, seed, разрешением и capability profile. Вместе с изображением -необходимо сохранять command/state trace; иначе pixel difference не позволяет -отличить ошибку формата от ошибки backend-а. - -Минимальный capture должен фиксировать resolution, bit depth, selected driver, -device capabilities, camera matrices, mission, game time, seed, input log, -scene boundaries, transforms, render states, texture-stage states, texture -binds, viewport, clear, draw calls и `Blt/Flip`. Сначала сравниваются command -lists; pixel diff имеет смысл только после совпадения geometry/state sequence. - -### FXID field-level semantics - -Размеры команд, resource references, lifecycle, flags families и используемые -time modes известны. Не закрыто значение каждого поля body opcodes 1-10, -отсутствующий во всех проверенных каталогах opcode 6 и точные формулы редких -time modes. - -Закрывающий эксперимент: создать инструмент, который изменяет по одному полю -копии эффекта, воспроизводить его в контролируемой сцене и логировать runtime -command object, emitted primitives и sound events. Одновременно reads в -`Effect.dll` сопоставляются с offsets body. - -### Script VM - -Сценарные packages, symbol names, event sections, variable declarations и -version check доступны. Полная instruction grammar `.scr`, semantics всех -opcodes и serialization состояния VM ещё не восстановлены. - -План реконструкции: - -1. Найти loader `.scr`, version check, границы bytecode, таблицы - strings/symbols/events. -2. Найти dispatcher loop по повторяющемуся чтению opcode и indirect branch или - jump table. -3. Для каждого handler определить instruction size, operands, чтения/записи VM - state, stack effect, branch target и world side effects. -4. Hook-нуть dispatcher и писать запись `package,event,ip,opcode,raw - operands,state before,state after,next ip`. -5. Построить disassembler и CFG; branch target обязан попадать на - подтверждённую границу инструкции. -6. Закрывать opcode после статического handler contract, одного динамического - trace и одного regression script. - -После opcode table отдельно восстанавливаются serialization IP, call/event -frames, variables, timers и RNG. - -### Physical/control formats - -CTLD и связанные resources структурно читаются, count patterns и variants -известны. Не названы все секции, shape types, coefficients и точный contact -solver. То же относится к редким MSH types 17/20 и части CTPT/NDPR flags. - -Закрывающий эксперимент: трассировать `LoadControlSystem`, -`LoadPhysicalModel` и создание collision objects на нескольких прототипах; -записать offsets, созданные shape instances и реакции на контролируемое -движение. Изменение одного resource field должно связываться с одним -наблюдаемым параметром. - -### Сеть - -DirectPlay lifecycle и имена игровых сообщений известны. Точные framing, -payload schema, reliability flags и алгоритм `netZipData` пока не подтверждены -записью сетевого обмена. Поэтому совместимость с оригинальным сетевым клиентом -ещё не доказана. - -Для закрытия нужны два оригинальных клиента в изолированной среде и логирование -`netZipData`, `netUnZipData`, DirectPlay Send/Receive и World3D message -enqueue/dequeue. Native interoperability подтверждается только успешным -обменом original client <-> compatibility implementation в обе стороны. - -### Редкие или отсутствующие corpus-ветки - -- `Land.map poly_count > 0`: layout читается из loader-а, но ни одна из 65 - проверенных карт не содержит живой записи. -- RsLi adaptive methods `0x080`/`0x0A0`: decoder path известен, однако - демоверсия и обе полные части их не используют. -- Texm formats 556 и 88: loader поддерживает их, но ни один проверенный Texm не - использует эти значения. -- FX opcode 6: размер известен, однако живой command отсутствует во всём - доступном corpus. -- Некоторые material flags и MSH auxiliary streams встречаются слишком редко - для полного authoring contract. - -Такие ветки реализуются строго по бинарному коду и synthetic tests, а статус -corpus-verified получают только после появления реального файла. - -### Сохранения и campaign state - -`saveslots.cfg` и `missions/dispatcher.ini` найдены, но полный бинарный -savegame payload, serialization World3D/AI/script/RNG и правила миграции версии -не восстановлены. Без этого нельзя честно заявлять полную campaign -compatibility. - -Минимальный набор сохранений для каждой части: - -```text -S0 сразу после старта миссии -S1 тот же state без simulation step -S2 изменена только позиция одного объекта -S3 изменено только здоровье/свойство -S4 активен один Behavior order/path -S5 активен один FX и timer -S6 изменена одна script variable -S7 изменён research/economy state -S8 перед/после mission completion -S9 pause и non-default game time -``` - -Без самих binary save payload возможно описать обязательный state и найти код -сериализации, но невозможно доказать disk layout и roundtrip. - -### Shell, HUD, шрифты и локализация - -Граница shell подтверждена экспортами `createShell`/`getIShell`, `IGUIServer`, -верхнеуровневым UI-pass и файлами `ui/*.cfg`, `DATA/TextRes.cfg`, -`gamefont.rlb` и `sprites.lib`. RsLi framing двух библиотек закрыт, но widget -tree, layout rules, font glyph metrics, sprite command semantics, -focus/navigation и полный HUD state machine пока не восстановлены до -field-level спецификации. - -До закрытия новая реализация может построить функционально эквивалентный UI -поверх известных ресурсов, но не заявлять native layout/behavior parity. - -### Исследования, экономика и игровые свойства - -Экспорты `LoadResearch`, `CalcFullResearchCost`, TRF/preload resources и TMA -properties доказывают отдельный слой исследований, стоимости, добычи и -производственных параметров. Сквозные имена (`MaximumOre`, `CurrentOre`, -`FreeResearchTime`, `FreeConstructionTime` и другие) доступны, однако формулы -стоимости, dependency graph технологий, inventory/economy transitions и точная -типизация всех 16-byte property values не закрыты. - -Закрывающий эксперимент: сопоставить `LoadResearch`/`CalcFullResearchCost` с -ресурсами и UI, снять изменения state на контролируемых покупках/исследованиях -и построить typed schema свойств по consumers, не по одному имени. - -### Условия динамического этапа - -Полное закрытие оставшихся вопросов технически возможно, но не только по -статическим архивам. Нужна среда, способная запускать оригинальный 32-битный -код, и набор эталонных наблюдений: - -1. Изолированная 32-битная Windows VM или отдельная машина с исходными - DirectDraw/Direct3D/DirectSound/DirectPlay interfaces. -2. Два неизменённых игровых каталога и manifest SHA-256 для executable, DLL, - конфигураций и ключевых архивов. -3. Отладчик с hardware/software breakpoints, просмотром x87/SSE state и - сохранением memory dumps. -4. API/vtable hooking для Win32 file I/O, DirectDraw/Direct3D, DirectSound и - DirectPlay; hooks должны писать binary trace, не изменяя порядок вызовов. -5. Управляемые clocks, input log и RNG seed либо trace всех вызовов источника - случайности. -6. Автоматический launcher, который восстанавливает snapshot VM, запускает один - test case, собирает логи и завершает процесс без ручного вмешательства. - -Для каждого capture сохраняются profile сборки, hash модулей, -mission/resource key, конфигурация, device profile, начальное состояние, -input/time script и версии инструментов. - -### Критерий закрытия открытого вопроса - -Для каждого открытого вопроса должны существовать: - -- build fingerprint и адреса наблюдаемых функций; -- raw trace и автоматический parser trace-а; -- минимальный воспроизводимый input/resource/save/message; -- формальный контракт или явно ограниченная гипотеза; -- differential test для Частей 1 и 2, если модуль изменён; -- обновление тематической статьи; -- regression case, запускаемый без ручного анализа. - -До выполнения этих условий статический контракт пригоден для реализации, но -утверждение о полном поведенческом или native-паритете не публикуется. - -## Глоссарий - -### Бинарные файлы и reverse engineering - -**PE (Portable Executable)** -- формат исполняемых файлов Windows: EXE и DLL. -Он содержит заголовки, секции, таблицы импортов и экспортов, relocations и -адрес точки входа. - -**Image base** -- предпочтительный адрес начала загруженного PE-образа. -**VA** -- виртуальный адрес в процессе. **RVA** -- адрес относительно image -base. Адрес функции в памяти обычно равен `image_base + RVA`. - -**Import** -- внешняя функция или переменная, которую модуль получает из другой -DLL. **Export** -- символ, предоставляемый другим модулям. Имя, ordinal и -calling convention вместе образуют часть бинарного контракта. - -**ABI** -- соглашение о двоичном взаимодействии: размещение аргументов, возврат -значений, очистка stack, layout структур, порядок virtual methods и правила -владения. - -**Calling convention** -- часть ABI, определяющая передачу аргументов и очистку -stack. Для исследованного 32-битного кода важны `__cdecl`, `__stdcall` и -`__thiscall`. - -**Vtable** -- массив указателей на virtual methods C++-объекта. Запись -`vtable +0x34` означает вызов указателя по байтовому смещению `0x34` от начала -таблицы. - -**Static analysis** исследует файл без его исполнения: disassembly, strings, -imports, call graph и data flow. **Dynamic analysis** наблюдает работающую -программу: breakpoints, traces, API hooks, memory state и packet/frame captures. - -**Evidence** -- наблюдение, которое можно повторить. **Inference** -- вывод, -объединяющий несколько наблюдений. **Hypothesis** -- рабочее предположение, ещё -не подтверждённое достаточным экспериментом. - -### Форматы данных и ресурсы - -**Archive** -- контейнер, объединяющий множество ресурсов. **Entry** -- запись -его каталога. **Payload** -- полезные bytes конкретной записи. - -**Magic** -- короткая сигнатура формата, например `NRes` или `Texm`. -**Version** -- номер варианта layout. Проверка одной magic без проверки version -и размеров недостаточна. - -**Offset** -- положение данных относительно начала файла или структуры. -**Size** -- число занимаемых bytes. **Stride** -- размер одного элемента -массива. **Alignment** -- требование начинать данные на address или offset, -кратном заданному числу. - -**Little-endian** -- порядок, в котором младший byte многобайтного числа -расположен первым. Все основные числовые поля исследованных форматов Iron3D -используют этот порядок. - -**Fixed-size string** -- поле заранее известной длины. Полезная строка -заканчивается первым NUL, но оставшиеся bytes поля могут содержать служебный -хвост и должны сохраняться. - -**Opaque field** -- поле с доказанными offset и размером, но не установленным -предметным смыслом. Его безопасно читать и копировать, но нельзя очищать или -переосмысливать без эксперимента. - -**Invariant** -- условие, которое обязано выполняться: диапазон находится -внутри payload, индекс указывает на существующий элемент, число записей -соответствует размеру секции. - -**Strict reader** отклоняет любое нарушение контракта. **Compatibility reader** -дополнительно воспроизводит только известные особенности оригинала, например -именованный fallback. Compatibility mode не означает игнорирование произвольной -порчи. - -**Roundtrip** -- последовательность decode -> encode. **Byte-identical -roundtrip** создаёт файл, полностью совпадающий с исходным. **Lossless editor** -может изменить известное поле, сохранив все остальные bytes и порядок записей. - -**Fallback** -- явно предписанный запасной путь, например материал `DEFAULT`, -затем entry 0. **Heuristic** -- догадка по похожим данным; она не должна -незаметно заменять доказанный fallback. - -### Игровой runtime - -**Engine** -- программная среда, которая загружает данные, ведёт время, -исполняет мир и формирует изображение/звук. **Game** -- конкретные правила, -миссии и содержимое, работающие поверх engine services. - -**World** -- долгоживущее состояние миссии: objects, terrain, время, кланы и -managers. **Scene** -- представление части мира для конкретной обработки, чаще -всего текущей камеры. - -**Game object** -- сущность с идентичностью, transform, properties и lifecycle. -**Component/controller** -- специализированная часть поведения: animation, -physics, AI или rendering representation. - -**Simulation** отвечает за изменение мира. **Tick** -- один расчётный шаг -simulation. **Frame** -- одно подготовленное изображение. Число ticks и frames -за единицу времени не обязано совпадать. - -**Game loop** -- повторяющийся порядок ввода, расчёта, рендера и обслуживания. -**Scheduler phase** -- явно ограниченный участок loop, где разрешены -определённые операции. -**Event/message** -- типизированное сообщение между objects или subsystems. -**Queue traversal** -- стабильный обход зарегистрированных объектов. -**Deferred deletion** -- перенос фактического удаления до безопасной границы -после traversal. +## Дальнейшее чтение -**Determinism** -- одинаковый результат при одинаковом initial state, input, -времени и порядке событий. **Replay** -- повторное исполнение записанной -последовательности входов/сообщений для проверки determinism. - -**Authority** -- subsystem или network peer, которому разрешено окончательно -менять состояние объекта. **Mirror object** -- локальное представление объекта, -authority которого находится у другого player. - -### Геометрия, анимация и рендеринг - -**Mesh** -- набор vertex/index streams и draw-групп, описывающий форму. -**Node** -- элемент hierarchy модели со своим local transform. **Slot** в MSH --- выбранная геометрическая группа для комбинации node, LOD и group; он также -хранит bounds и диапазоны batches. - -**Batch** -- непрерывный индексный диапазон с одним material slot и общим -render state. **Transform** переводит данные между local, world, view и clip -spaces. Порядок умножения matrices является частью контракта. - -**Quaternion** -- четырёхкомпонентное представление вращения. **Keyframe** -- -pose в определённое время. **Sampling** выбирает pose для времени, а -**blending** смешивает animation states. - -**Bounds** -- упрощённый объём для быстрых тестов. **AABB** -- пара -minimum/maximum по осям. **Bounding sphere** -- center и radius. - -**Renderer** -- subsystem, преобразующая подготовленную сцену в изображение. -**Backend** -- реализация renderer поверх конкретного API или устройства. - -**Draw call** -- команда нарисовать диапазон primitives с текущими resources и -states. **Material** -- правила отображения поверхности: texture, коэффициенты, -прозрачность и режимы pipeline. **Material phase** -- одно временное состояние -анимированного материала. - -**Texture** -- двумерный массив texels. **UV coordinates** -- координаты -выборки. **Mip chain** -- последовательность уменьшенных уровней texture. -**Lightmap** -- texture с заранее рассчитанным вкладом освещения. - -**Fixed-function pipeline** -- старый графический pipeline, где приложение -выбирает predefined transform, lighting, texture-stage и blend states вместо -пользовательских shaders. - -**Depth buffer** хранит глубину уже принятой поверхности. **Alpha test** -полностью принимает или отвергает fragment. **Blending** смешивает новый цвет с -framebuffer. - -**Back buffer** -- скрытый framebuffer. **Present/flip** делает завершённый -кадр видимым. **Pixel parity** -- совпадение конечного изображения при -фиксированных условиях. - -### Навигация, физика, звук и сеть - -**Areal** -- логическая область карты с границей, class/flags и связями с -соседями. **Areal graph** -- граф, вершинами которого служат области, а рёбрами --- допустимые переходы. **Cell grid** -- пространственный индекс для candidate -areas или objects. - -**Pathfinding** -- поиск маршрута по графу. **A\*** использует стоимость уже -пройденного пути и оценку расстояния до цели. Навигационная проходимость, -отсутствие collision и видимость -- разные свойства. - -**Collision proxy** -- упрощённое представление объекта для столкновений. -**Broad phase** быстро находит потенциальные пары; **narrow phase** выполняет -точную проверку и вычисляет contact. - -**Sample** -- декодированные звуковые данные. **Source** -- экземпляр -воспроизведения с position, gain, loop state и временем. **Listener** -- позиция -и ориентация слушателя для 3D spatialization. - -**Transport** -- механизм доставки bytes между peers. **Protocol** -- framing, -message types, порядок и правила подтверждения. **Serialization** -- -преобразование typed state в byte sequence. - -**Reliable delivery** гарантирует доставку/порядок в пределах выбранной модели; -**unreliable delivery** допускает потери ради задержки. **Wire compatibility** --- способность обмениваться данными с оригинальным клиентом, а не только -воспроизводить ту же игровую семантику в новом протоколе. - -## Связанные локальные справки - -- [NRes](../reference/nres.md) -- [RsLi](../reference/rsli.md) -- [TMA](../reference/tma.md) -- [MSH](../reference/msh.md) -- [Texm](../reference/texm.md) -- [Materials](../reference/materials.md) -- [Render frame](../reference/render-frame.md) -- [Границы знания](../appendices/knowledge-boundaries.md) -- [Глоссарий](../appendices/glossary.md) - -## Дополнительное чтение - -Эти материалы помогают понять PE, ABI, сжатие, graphics pipeline, game loop и -навигацию. Они не являются доказательством поведения Iron3D: детали движка -принимаются только после проверки его бинарного кода и игровых ресурсов. - -- [Microsoft PE/COFF specification](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format) -- [Microsoft x86 calling conventions](https://learn.microsoft.com/en-us/cpp/build/x86-calling-conventions) -- [Intel Software Developer Manuals](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html) -- [Ghidra documentation](https://ghidra-sre.org/) -- [RFC 1951: DEFLATE](https://www.rfc-editor.org/rfc/rfc1951) -- [zlib manual](https://zlib.net/manual.html) -- [Kaitai Struct user guide](https://doc.kaitai.io/user_guide.html) -- [Microsoft Direct3D documentation](https://learn.microsoft.com/en-us/windows/win32/direct3d) -- [Vulkan specification](https://registry.khronos.org/vulkan/specs/1.4-extensions/html/vkspec.html) -- [Real-Time Rendering resources](https://www.realtimerendering.com/) -- [LearnOpenGL](https://learnopengl.com/) -- [Scratchapixel](https://www.scratchapixel.com/) -- [Game Programming Patterns](https://gameprogrammingpatterns.com/) -- [Fix Your Timestep](https://gafferongames.com/post/fix_your_timestep/) -- [Red Blob Games: A*](https://www.redblobgames.com/pathfinding/a-star/introduction.html) +[Глоссарий](../appendices/glossary.md), +[открытые вопросы](../appendices/knowledge-boundaries.md), +[сценарная VM](../appendices/script-vm.md), +[сохранения и кампания](../appendices/saves-campaign.md), +[интерфейс игры](../appendices/ui-shell.md). |
