aboutsummaryrefslogtreecommitdiff
path: root/docs/appendices
diff options
context:
space:
mode:
Diffstat (limited to 'docs/appendices')
-rw-r--r--docs/appendices/knowledge-boundaries.md39
-rw-r--r--docs/appendices/script-vm.md77
2 files changed, 26 insertions, 90 deletions
diff --git a/docs/appendices/knowledge-boundaries.md b/docs/appendices/knowledge-boundaries.md
index 6f9553e..661069a 100644
--- a/docs/appendices/knowledge-boundaries.md
+++ b/docs/appendices/knowledge-boundaries.md
@@ -98,42 +98,3 @@ typed schema свойств по consumers, а не по одному имени
Такие ветки реализуются по бинарному коду и synthetic tests, а статус
corpus-verified получают только после реального файла или runtime trace.
-
-## Dynamic-stage requirements
-
-Оставшиеся вопросы нельзя закрыть только статическими архивами. Нужна
-изолированная 32-bit Windows-среда, неизменённые игровые каталоги, manifest
-SHA-256, debugger, API/vtable hooks, controlled clocks/input и автоматический
-launcher, который восстанавливает snapshot, запускает один test case, собирает
-логи и завершает процесс без ручного вмешательства.
-
-Для каждого capture сохраняются build profile, module hashes, mission/resource
-key, configuration, device profile, initial state, input/time script и версии
-инструментов.
-
-## Local evidence requests
-
-Поддерживаемая desktop-платформа — только Windows/Vulkan. Локальный smoke
-`fparkan-vulkan-smoke` уже подтверждает настоящий Win32 surface/swapchain,
-300 кадров, controlled resize и отсутствие validation warnings/errors.
-Это закрывает фундамент Stage 0, но не доказывает визуальный паритет игры.
-
-Следующие доказательства всё ещё нужны именно для Iron3D-compatible рендера:
-
-- capability-gated capture из оригинального GOG процесса с camera/matrix,
- draw/state и frame-boundary provenance;
-- фиксированные Windows Vulkan captures статической модели, lightmapped модели
- и terrain после совпадения backend-neutral command capture;
-- затем controlled captures анимации, FX, прозрачности, теней и атмосферы.
-
-Linux/macOS, GLES2, RG40XX и удалённые portability runners не являются
-acceptance-гейтами этого проекта. Они не должны появляться в списке блокеров
-или подменять Windows evidence.
-
-## Closure criteria
-
-Вопрос считается закрытым только при наличии build fingerprint, raw trace,
-parser trace-а, минимального воспроизводимого input/resource/save/message,
-формального контракта или явно ограниченной гипотезы, differential test для
-изменённых DLL, обновления тематической главы и regression case, запускаемого
-без ручного анализа.
diff --git a/docs/appendices/script-vm.md b/docs/appendices/script-vm.md
index afc63e5..64dc4fc 100644
--- a/docs/appendices/script-vm.md
+++ b/docs/appendices/script-vm.md
@@ -10,7 +10,7 @@ messages, teleports, задачи, research и campaign transitions. Точки
и `briefing.cfg`.
`.scr` — binary package с version checks, symbol/event sections и offsets;
-полная opcode grammar не доказана. Его внешний framing теперь читает
+полная opcode grammar не доказана. Его внешний framing читает
`fparkan-script`: первый little-endian `u32` является числом required opcode
handlers, второй — числом event records. Каждый event хранит `name_len`,
`name_len + 1` raw bytes с обязательным NUL, opaque event word и count вложенных
@@ -52,18 +52,11 @@ number, size, operands, control flow, effects, errors и минимальный
GOG `ai.dll` доказывает этот framing двумя consumer-ами: loader по
`0x10001000` открывает `<bundle>.scr`, `varset.var`, `<bundle>.fml`, затем
собирает ровно 73 pointers handlers; `0x10011b20` читает описанную count-driven
-структуру. Команда
+структуру. В GOG `c1m2p.scr` reader находит 73 handler slots,
+9 events, 17 nested records и 20 references, заканчивая на EOF.
+Это подтверждает разбор пакета, но не смысл всех opcodes.
-```powershell
-cargo run -p fparkan-cli -- script inspect `
- 'C:\GOG Games\Parkan - Iron Strategy\MISSIONS\SCRIPTS\c1m2p.scr' --format json
-```
-
-на исходном пакете возвращает `opcode_handler_count=73`, 9 events, 17 nested
-records, 20 references и 0 trailing bytes. Это corpus evidence для reader-а,
-но не разрешение на исполнение неизвестных 73 opcodes.
-
-Теперь установлен selector: loader `0x10001000` создаёт 73 pointers в
+Selector устроен следующим образом: loader `0x10001000` создаёт 73 pointers в
фиксированном порядке, а `0x10011e70` копирует их без перестановки в runtime
array. Во всех 58 GOG `.scr` первый header word каждого nested record равен
`0..72` либо `0xffff_ffff`: соответственно 2095 handler selectors и 3992
@@ -115,24 +108,21 @@ unsupported result, а не «примерный» game command.
записи `0x100059f0` вызывает `0x1000f920`, а Ghidra 12.1.2 декомпилирует эту
функцию как пустой `return`. Следовательно, найденные `<base>_Start` и
`<base>_Continue` только кэшируются в scheduler state; их фактический consumer
-находится в отдельном позднем update path. Воспроизводимый read-only extractor:
-`tools/ghidra/ExportAiVmHandler2Dispatch.java`.
-
-Corpus priority теперь измерен, а не предполагается: во всех 58 GOG `.scr`
-имеются 6 087 instruction records, из них 3 992 sentinel; самый частый
-non-sentinel selector — `Handler(30)`, 246 records. Его VA `0x1000c266`
-читает первые два reference words активной instruction, разрешает каждый
-через varset (`0x10002d30` и `0x10013570`) и вызывает внешний callback с
-тремя `u32`: `(0, first, second)`. Callback не принадлежит `ai.dll`: его
+находится в отдельном позднем update path.
+
+Во всех 58 GOG `.scr` имеются 6 087 instruction records, включая 3 992
+sentinel. Самый частый non-sentinel selector — `Handler(30)`, 246 records.
+Его VA `0x1000c266` читает первые два reference words активной instruction,
+разрешает каждый через varset (`0x10002d30` и `0x10013570`) и вызывает внешний
+callback с тремя `u32`: `(0, first, second)`. Callback не принадлежит `ai.dll`: его
кладёт десятый argument экспортного `CreateSuperAI`. Тот же callback встречен
у `Handler(57)` с первым word `2` и у отдельного lifecycle path с первым word
`1`; предметная семантика этих modes ещё не доказана. В частности, это пока
не основание назвать Handler(30) сообщением, приказом или UI opcode. Точный
text-to-varset resolver расположен за wrapper `0x10011ea0` в
-`0x100174a0`. Воспроизводимые exports: `ExportAiVmHandler30.java`,
-`FindAiVmHandler30Callback.java`, `ExportAiVarSetLoader.java`.
+`0x100174a0`.
-Следующий pass восстанавливает эту индексацию. `0x100174a0` добавляет каждый
+`0x100174a0` добавляет каждый
recognized source declaration в encounter order как 48-byte record; GOG shared
`varset.var` не содержит `STRING(...)`, поэтому его 231 numeric `VAR` entries
образуют точно это index space. `0x10013570` возвращает `DWORD` record kind
@@ -141,10 +131,9 @@ capture. Полный GOG scan всех 246 Handler(30) instructions показÑ
operand references: все 492 in-range и указывают на `DWORD`. Поэтому
`VarSet::resolve_handler30` уже materializes точный opaque callback command
`(mode=0, first, second)` для данного corpus path, но явно отклоняет float,
-out-of-range и incomplete instructions вместо silent coercion. Extractors:
-`ExportAiVarSetParser.java`, `ExportAiVarSetU32Resolver.java`.
+out-of-range и incomplete instructions вместо silent coercion.
-Следующий static pass закрывает equality/update policy. Identity ровно равна
+Identity ровно равна
`(slot0 word, slot4 IEEE-754 bits, slot5 IEEE-754 bits)`, поэтому `-0.0` и
`+0.0` различаются. Новый 100-byte record получает slot1 в поле `+0x14`,
slot2 одновременно в `+0x24/+0x28`, slot3 в `+0x2c` и slot6 в `+0x0c`. При
@@ -154,12 +143,11 @@ slot2 одновременно в `+0x24/+0x28`, slot3 в `+0x2c` и slot6 в `+
изолированную часть как `Handler2RecordScheduler`; он не выполняет bytecode,
не назначает игровых имён и не делает event lookup за original VM.
-На границе mission runtime выбранный TMA clan `first_resource` теперь
+На границе mission runtime выбранный TMA clan `first_resource`
материализуется как отдельный `MissionScriptBundle`: loader нормализует
`<base>.scr`, декодирует его тем же bounded reader-ом и публикует immutable
-package вместе с clan provenance. Headless report выводит число таких packages
-и их named events. Это именно wiring входных данных, не VM execution: Init и
-остальные events пока не dispatch-ятся, а ошибка чтения сохраняет
+package вместе с clan provenance. Это именно wiring входных данных, не VM
+execution: Init и остальные events пока не dispatch-ятся, а ошибка чтения сохраняет
transactional rollback mission loader-а.
TMA properties остаются four raw `u32` words плюс имя, пока consumer/schema не
@@ -214,9 +202,9 @@ contains two initialized SuperAI entries `(500, 752, 0)` and `(728, 449, 1)`;
the Rust loader reports `script_init_states=2` and `script_varset_states=2`.
`GetSuperAI` returns element `n` of the 64-pointer global table at preferred
-`ai.dll + 0x55398` for `n <= 63`. The read-only
-`tools/capture-ai-init.ps1` probe observed the running GOG AutoDemo values
-`(500, 752, 0)` for entry 0 and `(728, 449, 1)` for entry 1 at fields
+`ai.dll + 0x55398` for `n <= 63`. A read-only capture of the running GOG
+AutoDemo process observed `(500, 752, 0)` for entry 0 and `(728, 449, 1)` for
+entry 1 at fields
`(+0x80, +0x84, +0x7c)`. These values are integral samples, not a rounding
profile.
@@ -224,12 +212,7 @@ The Rust reader exposes `VarSet::resolve_handler19`. It accepts the already
converted first two words and the third raw word, produces three typed writes,
and rejects missing, out-of-range, or non-`DWORD` targets. The runtime only
binds it to the proven creation/anchor path above; it does not guess the
-remaining script event semantics. The associated Ghidra scripts are
-`ExportAiVmHandler19.java`, `ExportAiVmHandler19Setter.java`,
-`ExportAiVmHandler19SetterCallee.java`, and `ExportAiGetSuperAi.java`.
-The creation and conversion boundaries are reproducible with
-`ExportAiCreateSuperAi.java`, `ExportAiSuperAiConstructor.java`, and
-`ExportAiFtol.java`.
+remaining script event semantics.
### Runtime Handler(30) operand binding
@@ -264,12 +247,7 @@ proves the lookup and one-shot/repeat split, not the UI/message subject or the
semantics of either resource ID; Rust therefore retains command `1` as
`Unhandled`.
-Reproduce the callback and the command-one consumers with
-`capture-ai-init.ps1`, `ExportIron3dAiCallback.java`,
-`ExportIron3dAiCallbackCommand1.java`, and
-`ExportIron3dAiCallbackCommand1Dispatch.java`.
-
-Runtime now applies only this recovered branch as
+Runtime applies only this branch as
`apply_loaded_script_host_callback`: `(0, 0, 0)` transitions a loaded mission
to `Failed`, `(0, 0, 1)` transitions it to `Completed`, and a repeated target
state is a no-op just as the Iron3D guards require. The effect is deliberately
@@ -292,9 +270,7 @@ opaque callback slots; state `3` does the same except word `3` is preserved.
Both then write `+0x18`. Every other state simply writes the state word.
`VarSet::resolve_handler8` emits a `Handler8StateChange` with the caller-owned
live record index, resolved state, and explicit reset kind. It does not invent
-the table owner, the pre-reset helper, or callback semantics. Reproduce the
-evidence with `ExportAiVmHandler8.java`, `ExportAiVmHandler8Callees.java`, and
-`ExportAiVmHandler8Transitions.java`.
+the table owner, the pre-reset helper, or callback semantics.
### Handler(15): typed target-call boundary
@@ -322,8 +298,7 @@ with that record and the third word. Its zero/non-zero result becomes
return value remain unproven. Accordingly `VarSet::resolve_handler15` only
materializes a type-checked `Handler15Invocation` and `Handler15TargetPayload`;
it never executes the opaque target call. Missing, out-of-range, wrong-type,
-and unobserved-mode inputs are explicit errors. Reproduce the static evidence
-with `tools/ghidra/ExportAiVmHandler15.java`.
+and unobserved-mode inputs are explicit errors.
## Готовность