Scenario selected-root pattern review
scenario-selected-root-vm-pattern-grounded-producer-pending
The web-runtime observation is consistent with the EXE. A common VM runner, selected-root writers, and selected-root executor are statically grounded. The remaining missing evidence is the upstream producer that chooses those streams from concrete field/NPC/region conditions.
JSON: out/scenario_selected_root_pattern_review.json
확정
- The VM dispatcher at 0x00402321 executes bytecode streams from object+0x40.
- selected_root at 0x0059de30 is a real global consumed by the selected-root executor.
- 0x0040ad9b writes selected_root by table index; 0x0040ae0e writes it directly or as an inline continuation.
- 0x0040adc9 pushes the current stream to object+0x44/object+0x5c and jumps object+0x40 to selected_root.
- 0x00406dbb writes selector bytes and jumps to fixed roots, so selector bytes and selected roots are part of the same VM family.
- Existing selector-root reports already expose dozens of roots and command blocks that fit this mechanism.
후보
- field/NPC/region triggers likely enter this VM through active descriptors or inline stream pointers, but the exact live producer is not promoted here.
- object+0xa8 appears repeatedly in VM handlers as a context/base pointer family; object+0xb0 remains a script-pointer candidate, not a confirmed stream slot in this review.
- selectedRoot indexed tables and direct inline roots are good static enumeration targets, but each entry still needs owner/trigger binding.
차단점
- No static proof yet maps a specific field entrance, talk target, or region descriptor to one selected_root write in normal gameplay.
- scene/event command streams are found, but route-linked command block count remains zero in the current command-stream candidate report.
- automatic map transition and scenario branch producer remain separate problems from the selected-root executor mechanism.
전역/오프셋
| name | value |
|---|---|
| selectedRootVaHex | 0x0059de30 |
| rootObjectVaHex | 0x0055be00 |
| currentStreamOffsetHex | 0x40 |
| returnStackOffsetHex | 0x44 |
| returnDepthOffsetHex | 0x5c |
| vmContextOffsetCandidateHex | 0xa8 |
| scriptPointerOffsetCandidateHex | 0xb0 |
디스패치 엔트리
| name | handler VA | opcode index | dispatch entry |
|---|---|---|---|
| vmDispatcher | 0x00402321 | - | - |
| selectorByteWriter | 0x00406dbb | 0x4f | 0x00440674 |
| selectedRootIndexedWriter | 0x0040ad9b | 0x81 | 0x0044073c |
| selectedRootExecutor | 0x0040adc9 | 0x82 | 0x00440740 |
| selectedRootDirectWriter | 0x0040ae0e | 0x83 | 0x00440744 |
바이트 근거
| label | VA | status | decoded semantics |
|---|---|---|---|
| generic VM dispatcher | 0x00402321 | confirmed | reads object+0x40 as current stream, reads opcode byte, dispatches through table 0x00440538. |
| nested VM stream runner | 0x00402360 | confirmed | temporarily replaces object+0x40 with an argument stream, runs the dispatcher, then restores the old stream. |
| selector byte writer | 0x00406dbb | confirmed | mode 1 writes selector bytes from stream operands and jumps to a fixed root pointer; modes 2/3 delegate save/load restore. |
| selected root indexed writer | 0x0040ad9b | confirmed | selected_root = dword[streamTable + stream[1] * 4], where streamTable is dword at stream+4; advances stream by 8. |
| selected root executor | 0x0040adc9 | confirmed | if selected_root is nonzero, pushes current continuation to object+0x44 return stack, increments object+0x5c, and writes selected_root to object+0x40. |
| selected root direct writer | 0x0040ae0e | confirmed | mode 0 stores inline stream+4 as selected_root; mode 1 stores dword at stream+4 as selected_root. |
| root object pool initializer | 0x004359d6 | confirmed-base | initializes the object pool/list around 0x0055be00, matching the VM object base seen in selected-root handlers. |
관련 산출물 요약
| metric | value |
|---|---|
| selectorRootCount | 93 |
| selectorRows | 94 |
| rootsWithSceneSeqCount | 37 |
| rootsWithResourceRefCount | 66 |
| sequenceRootWithResourceStructureCount | 37 |
| unclassifiedSelectorRootCount | 27 |
| rootsWithSelectedRootOpcodeCount | 57 |
| opcode4fMode1WriterCount | 27 |
| opcode4fSelfWriterCount | 23 |
| opcode4fSlotAliasCount | 4 |
| selectedRootDirectRefCount | 10 |
| selectedRootExecutorFound | True |
| liveWriterStatus | selected-root-writer-primitives-grounded-route-producer-pending |
| opcodeMatrixStatus | opcode-matrix-grounded-no-upstream-route-producer |
| selectorStructureStatus | selector-root-structure-decomposed-candidate |
| routeReviewStatus | partial-execution-route-blocked-direct-root-missing |
| directExecutionRootFound | False |
| commandBlockCount | 47 |
| dialogueLikeBlockCount | 43 |
| routeLinkedCommandBlockCount | 0 |
| mapLinkedCommandBlockCount | 7 |
다음 정적 분석
- Enumerate opcode 0x81 indexed-writer command rows and group them by owner root.
- Enumerate opcode 0x83 direct-writer inline roots and split mode 0 inline continuation from mode 1 dword-root writes.
- Cross-link selected-root writer rows to prompt/text groups and resource records, but keep them below route-proof until a producer is found.
- Use future runtime traces to tag which writer row fired before a known talk/region/event interaction.