diff options
| author | Valentin Popov <valentin@popov.link> | 2026-10-22 10:45:23 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-10-22 10:45:23 +0300 |
| commit | dcc64598916dba92de74c6e27a2359fa08b72e84 (patch) | |
| tree | 51b9d767e1650ebfff3d0fa7ddb378e37f5bcd6b /docs | |
| parent | 374db10daf5db88a52596edebc6cf5f2d560065f (diff) | |
| download | fparkan-dcc64598916dba92de74c6e27a2359fa08b72e84.tar.xz fparkan-dcc64598916dba92de74c6e27a2359fa08b72e84.zip | |
feat(runtime): initialize mission ore properties
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/appendices/knowledge-boundaries.md | 36 | ||||
| -rw-r--r-- | docs/reference/tma.md | 12 | ||||
| -rw-r--r-- | docs/tomes/06-behavior.md | 50 |
3 files changed, 98 insertions, 0 deletions
diff --git a/docs/appendices/knowledge-boundaries.md b/docs/appendices/knowledge-boundaries.md index 873497c..c1993ca 100644 --- a/docs/appendices/knowledge-boundaries.md +++ b/docs/appendices/knowledge-boundaries.md @@ -169,6 +169,42 @@ Behavior (`Behavior.dll`, RVA `0x3600`) вызывает `World3D!stdGetGameMode с реальными интерфейсами ArealMap, нужными `FUN_10019e80`; полный Behavior tick flow и общий dispatcher событий также остаются открытыми. +Начальные свойства `CurrentOre`/`MaximumOre` восстановлены отдельно от +регулярного обмена. В проверенных `Behavior.dll` (SHA-256 +`ddfbdbde07832358fe6e35e01c8dba9b58e7313789498b6049ed51d4ed9baf99`) RVA +`0x8790` выбирает начальные значения по class word, `0xb110` регистрирует +дескрипторы кодов 4/5, `0xb470` пишет только код 5, а `0xb5b0` читает код 4 +как дополнительное слово и код 5 как основное. `MisLoad.dll` (SHA-256 +`c607762bb67db14ca530927c8e1347339b62b0a163ac90c708ee83142292e2bf`) RVA +`0x40b0` выбирает первое свойство TMA с точным именем `CurrentOre` и передаёт +его `raw_value[1]`; setter сохраняет биты напрямую. В AutoDemo snapshot на этих +входах было восемь объектов Unit DAT, у всех raw `CurrentOre` равен нулю; +четыре объекта класса `0x01008000` не вошли в distributor, но остались среди +инициализированных Rust-состояний. Поэтому путь нулевого значения наблюдался +наживую, но ненулевое TMA-значение в живой миссии пока не проверено. + +Синтетический x86 oracle вызвал `Behavior.dll!FUN_10008790` напрямую для классов +`0x80000004`, `0x80000008`, `0x01002000`, `0x01004000` и `0x01008000`; перед +вызовом в записи были значения `CurrentOre=123` и `MaximumOre=-1`, так что +проверено их перезаписывание. Тест выставляет `a64=1`, чтобы отключить отложенный +side effect обёртки setter-а. Это подтверждает ветви initializer-а, но не весь +путь его запуска и связи с остальными фазами объекта. Другой изолированный x86 +oracle проверяет ненулевое raw-слово `CurrentOre`, только чтение `MaximumOre` и +перестановку строк дескрипторов на синтетических записях свойств. + +Не проверен селектор 4 для внешнего config-like ресурса: в наблюдавшемся +AutoDemo его вызова нет, а установленный `Behavior.ini` не содержит +`Mine_MaxOre`, `Storage_MaxOre` или `Transport_MaxOre`. Поэтому Rust пока +воспроизводит доказанные class defaults (500, 4000 и 2000) и не заявляет +поддержку конфигурационного переопределения. Отдельно не доказано, что каждый +Unit DAT создаёт тот же Behavior-компонент во всех host factory paths. Rust +ограничивает новую запись полными TMA-объектами с Unit DAT; preview, прямые +prototype roots без Unit DAT и отложенные spawn после исходной загрузки вне +этой модели. Путь в `ArealMap.dll` (SHA-256 +`a25f9254ebb339d70e2e07c8121950191e9584ca0858d8e9c2e2b6c671edf6ea`) к +`CreateObject` по RVA `0x14fd0`/`0x15290` показывает выбор World3D class 3 или 4 +по старшему биту, но не всю цепочку их Behavior attachment. + Для `Handler(30)` отдельно подтверждены обратный вызов `iron3d.dll` RVA `0x611d0` (SHA-256 `d1dc4ea8535e2069b0a05c9e8be2724dd438ba44cca7a83007d8b2e50f9e35fa`), начальные поля IGame и проверки режима/состояния. Обработчик выбора миссии diff --git a/docs/reference/tma.md b/docs/reference/tma.md index 2a84d6d..8eb6f66 100644 --- a/docs/reference/tma.md +++ b/docs/reference/tma.md @@ -92,3 +92,15 @@ slot `+0x40` в путь выбора AI в Behavior. Поэтому Rust сох `Property` состоит из четырёх raw `u32` и имени. Typed views разрешены только для доказанных property names и consumers. + +Для свойств объекта `MisLoad.dll!FUN_10003ab0` (RVA `0x3ab0`) переставляет +дисковые слова в runtime-запись, а `FUN_100040b0` (RVA `0x40b0`) проходит её +таблицу в порядке runtime-дескрипторов. Поиск имени учитывает длину и байты с +точным регистром и использует первое совпадение. В подтверждённом пути +дисковое `raw_value[1]` становится первым DWORD аргумента setter-а, поэтому +значение передаётся как биты, без промежуточного float-преобразования. +Например, Behavior регистрирует `CurrentOre` под кодом `5`; его setter кладёт +полученные биты в основное слово свойства `0x02000100`. `MaximumOre` с кодом +`4` читает дополнительное слово той же записи, а setter этого дескриптора +ничего не меняет. Подтверждение классов и native getter/setter находится в +[главе о Behavior](../tomes/06-behavior.md#начальные-свойства-запасов-руды). diff --git a/docs/tomes/06-behavior.md b/docs/tomes/06-behavior.md index c00705b..16ea21a 100644 --- a/docs/tomes/06-behavior.md +++ b/docs/tomes/06-behavior.md @@ -255,6 +255,56 @@ Rust хранит этот небольшой начальный список с опирается на уже созданный `ObjectHandle`. Регулярный обмен ресурсами пока остаётся отдельным этапом, потому что для него нужны интерфейсы игровых объектов. +### Начальные свойства запасов руды + +Behavior хранит `CurrentOre` и `MaximumOre` в одной записи свойства с ключом +`0x02000100`: текущее количество лежит в основном float-слове, предел — в +дополнительном DWORD. В TMA это не означает, что оба значения свободно задаются +файлом. При загрузке `MisLoad.dll` ищет первое свойство с точным, чувствительным +к регистру совпадением имени и передаёт его второе raw-слово в setter. В +Behavior дескриптор `CurrentOre` записывает это слово в основное значение; +дескриптор `MaximumOre` читает дополнительное слово, но его setter ничего не +меняет. + +Оба дескриптора регистрируются как коды `4` и `5`. Это коды обработчика, а не +позиции в таблице дескрипторов: исходная DLL корректно работает и после +перестановки строк, потому что callback выбирает обработчик по коду строки. +Поэтому начальное состояние можно описать так, сохраняя биты без пересчёта +через `float`: + +```text +current = first_exact("CurrentOre").raw_value[1] ?? class_default_current +maximum = class_default_maximum +``` + +Класс задаёт значения по умолчанию в Behavior RVA `0x8790`: + +| Слово класса | `CurrentOre` | `MaximumOre` | +| --- | ---: | ---: | +| `0x80000004` | 0 | 500 | +| `0x80000008` | 0 | 4000 | +| `0x01002000` | 0 | 2000 | +| `0x01004000` | 2000 | 2000 | +| прочие слова в этой ветви | 0 | 0 | + +Вызов RVA `0x8790` на синтетической структуре подтвердил эти значения для +классов таблицы, включая `0x01008000`; он проверяет тело native initializer-а, +но не его полный жизненный цикл в игре. + +В полной загрузке Rust сохраняет эти два raw-значения рядом с исходным TMA ID +и `ObjectHandle` каждого объекта с Unit DAT; список участников распределителя +для этого не требуется. Это важно для объектов, у которых есть компонент +Behavior, но нет членства в ресурсном distributor. Preview намеренно не создаёт +начальное состояние. Лицензированная AutoDemo показывает восемь объектов с +Unit DAT, включая объекты класса `0x01008000` вне списков distributor; в этом +снимке TMA `CurrentOre` равен нулю у всех восьми. Нативный x86 oracle отдельно +проверяет ненулевое raw-слово, чтение предела, отсутствие записи в `MaximumOre` +и переставленные строки дескрипторов. + +Эта модель покрывает именно начальную загрузку полных TMA-объектов. Она не +утверждает, что уже восстановлены все пути создания Behavior, отложенное +создание объектов или внешняя подмена class defaults конфигурацией. + ### Регулярная передача ресурсов Resource Distributor работает со списком зарегистрированных объектов. За один |
