CW must support the complete native gameplay loop, not just entering a battle.
Completion remains unproven until the current Client demonstrates all of:
- Entry through Cosmic Strife with a valid season, activity state and reward track.
- Tutorial, normal and Overcharge selection supported by the current Client tables.
- New runs, reconnect/resume, abandon and restart without resetting unrelated saves.
- Gold, interest, player EXP/levels, HP, shops, buying/selling and role upgrades.
- Board/front/back/bench placement, equipment, crafting, tracking and trait effects.
- Native routes, enemies, battle parameters and results for the selected node.
- Supplies, selections, augments, portals, bonuses, bonfires and other node actions.
- Chapter progression through the final boss, defeat and completion settlement.
- Persistent records, reward claims, weekly progression and talents.
- Client confirmation of the above and preservation of the established ordinary Battle paths.
## Entry update (2026-10-20)
- Current StartGamePlay request: division tag 2, season `LJNGPCKPJLF` tag 4, Overclock tag 9. Tag 3 remains semantically unresolved; it was observed as 1 on the tutorial path. Do not interpret it as season or remap division 0 to a regular division.
- Start now saves a complete initial run before replying, then GetData restores it. Resume validates run identity; QuitLeave preserves it. Pending portal actions, shop commands and battles remain incomplete.
-`resources/CurrencyWarsInitialRuns.json` contains captured initial runs for division 20101 in both modes, bound to the current Client assembly. Other divisions are rejected. Captured choices/modifiers are fixed samples; procedural generation remains unfinished.
- Reference source: https://github.com/Mar7thLover/March7thHoney-OpenSource/tree/fe00bdbda3c28ca33d01f171566aa35b5ab95083 . Native reference requests were replayed against an isolated loopback copy and disposable account.
- Error 6908 occurred with division 0 and tag 3 = 1. Named current-Client predicates confirmed `ShouldStartCurrentSeasonTutorial=true`, `IsFinishedTutorialThisSeason=false`, and `LastTutorialFinishedSeasonID=0`. Fresh bootstrap omitted tutorial state and selected the tutorial path.
- The entry resource declares `freeplay_unlocked` explicitly using reference GetData tutorial metadata (seasonal completion tag 15, permanent latest tutorial season tag 11, and permanent per-season history map tag 6). Sending only the two scalar values did not resolve 6908: the Client continued requesting season 1 with division 0. The history map has now also been restored from the reference capture. This bypasses scripted tutorials for freeplay entry; it does not implement their missions or grant rewards. Client confirmation of corrected entry is pending.
- Only builds were run for this change; a successful build does not prove Client entry or battle completion.
### Initial pending choices and recovery
The user confirmed entry to Investment Environment after the tutorial-history change. The first Confirm sent request 8485 and previously had no handler. Controlled native replay establishes the current table's `GridFightHandleBonfireHealHpCsReq` as the pending-action request, with `MFFCPLBNHCF.JCAPCNLJGFC` carrying the portal and a `GridFightHandlePendingActionScRsp` response (8466). The reference sends ordered `GridFightSyncUpdateResultScNotify` (8683) before that response. All handlers resolve names through the current table; no numeric aliases were added.
`CurrencyWarsEntryTransitions.json` now contains six initial outcomes for the already captured Standard/Overclock offers. The handler checks offer membership, pending queue, revision, resource identity/digests and next-phase structure before saving and syncing the result. This extends the fixed entry prototype only: starter outcomes are captured, not procedurally generated; later pending actions, shops, battle and settlement remain incomplete. Client confirmation of Confirm is pending.
`tools/export_cw_reference_tables.py` reads the native reference MemoryPack cache without loading its unrelated mismatched schemas. It extracted 493 node templates, 116 portals, 966 basic bonuses and 372 combination bonuses. All current captured route template IDs are covered. These reference tables remain diagnostic data. Current Client portal capture yielded 73 handbook rows and found 26 field/coverage differences, including decimal parameters on portal 121 that the reference represents as zero. Do not replace current effect formulas with these older integer parameters.
Unstuck is a separate explicit UI recovery operation. A queued nonce reaches the connected game through the existing heartbeat Lua transport and calls the observed `UIManager.ClearWaitNetPacketFullScreenBlock()`. Client acknowledgement is required before the web UI reports completion. It preserves saved runs and does not fabricate gameplay success or reset phase/loading flags. UI recovery still requires Client confirmation.
## Authoritative inputs captured on 2026-10-18
- Command table: PearlSR revision `005d2c12db4781071f4b5b68e8f364587886a710`, recorded in `protocol/proto/upstream_cmdids.go`.
- Current GameAssembly SHA-256: `c5e02e6e984f7e5577c78b995a8efeee2d06ee22e67d484ad5e859c8bf21e144`.
-`tools/inventory_cw.py` found 78 `GridFight*` commands and 491 reachable local protobuf declarations. This is a dependency inventory, not Client compatibility verification. Pending actions also use commands with obfuscated/non-GridFight names.
- Initially no CW handler was registered. `dangerFamilies` suppressed empty replies because the native module dereferences missing state. Keep that guard for unsupported requests.
- The current PearlSR gameserver checkout contains no CW gameplay implementation to port.
- Native common/client constant tables provided 197 CW constants. Active season is 2, subseason 1. First season is 1; it is not the active-season default.
- Captured division catalogs: 97 rows for season 1, 71 for season 2, each with a completed native enumeration marker. `resources/CurrencyWarsCatalog.json` records capture and assembly hashes.
- Active `GridFightSeasonModuleConfigRow`: OfferingID 16, ActivityQuestConfigID 71101, ActivityModuleID 7110101, MaxRewardExp 48000. ActivityConfig maps that module to parent activity 71101. Runtime schedule dates are operator policy, not claimed official dates.
## Client entry evidence
The user's Cosmic Strife screenshot is the intended CW entry. Player.log contained:
-`GridFightModule.get_ExpLineRewardData` NullReferenceException through `HandbookRogueGridFightTabItem._setup_level`.
CW failed before the gameplay loop. These errors do not establish that ordinary battle conversion is the cause.
## Protocol mapping evidence
Probes inspect named CW types, never all assembly types/methods. They remain outside `scripts/` when not being captured.
`tools/cw_scalar_wire_probe.lua` creates isolated protobuf objects, assigns one UInt32 backing field through boxed reflection and serializes it. No object is synced into a game module or sent as a response. This maps backing fields to wire tags and property getter tokens.
The native token-check correlation was anchored by the stack RVA for `get_ExpLineRewardData`, adjacent `GetSeason`/`_SyncSeason` implementations and named runtime MetadataToken values. `tools/cw_native_token_sites.py` reports candidate check sites only. Proto method tokens can also match unrelated metadata-initialization constants; a candidate does not prove a function address.
Native `_SyncSeason` at RVA `0xdb6efa0` reads offsets `0x40`, `0x30`, `0x34` into module SeasonID, SubSeasonID and keep-win count. Matching protobuf field order/encoding gives:
| Meaning | AMEEHIIPMFP Go field | Wire tag |
| --- | --- | --- |
| SeasonID | ADFEKPNIFOJ | 4 |
| SubSeasonID | GEGMHOMNBDG | 11 |
| DivisionID | DivisionId | 2 |
| Keep-win count | GDAKCOICIDA | 15 |
The bootstrap populates the nested metadata, reward EXP and handbook containers dereferenced by `_OnGridFightGetDataScRsp`. The optional active gameplay session remains absent because no CW run has started.
Limitations: `Marshal.OffsetOf` is stripped, native field offset reflection returns -1, and the existing `.pdata` helper produced unusable boundaries. These are not successful layout verification. The season mapping still requires checking the bootstrap response in the Client. No method pointer is dereferenced or memory layout patched by retained probes.
## Current boundary and next work
- Version-checked catalog loader and source-based activity mapping; missing gameplay rules return errors, without guessed defaults.
-`GridFightGetData` bootstrap for a fresh profile; CW progression/resume are not yet implemented.
- Active CW activity in the schedule response. Timestamps moved from the handler to shared runtime config, retaining the previous interval as explicit configuration.
- Other CW commands remain guarded; no successful empty gameplay replies added.
- Initial code compiled. Client bootstrap verification and full gameplay remain pending.
Next: verify bootstrap/activity state, capture initialized CW role/route/level tables, implement persistent run state and the complete node/action/battle loop, then verify gameplay and settlement in the Client.
## First bootstrap result
The current Client confirmed Season=2, Subseason=1, Division=20101, no active game, and a non-null ExpLineRewardData object. This verifies the initial season field mapping; it does not verify the full guide or gameplay.
The user then reported an empty Cosmic Strife tab. The initial schedule entry used a parent ActivityID where the protocol expects an ActivityModuleID. PearlSR `services/events.zig` explicitly assigns module IDs to `ActivityScheduleData.activity_id` and parent ActivityID to `panel_id`. The active-season module alone also omits the whole-season CW module from `GridFight_WholeSeason_ActivityModuleID` in the native constants. The corrected CW schedule therefore derives both whole-season and current-season module/parent pairs from the captured constants, season metadata and ActivityConfig; it does not generate IDs arithmetically or expose unsupported unrelated activities. Ordinary Endgame schedule identities remain as before.
The timestamp config checks covered normal JSON, local override, environment override, an invalid interval and a missing interval in both Go and launcher. They do not prove Client entry, combat or settlement.
## Corrected schedule result and lobby investigation
After the schedule correction, the user confirmed that Go returns to a world scene, but does not open the CW event UI. The server received EnterScene for the native `GridFight_EntranceID`, then an InteractProp request. There was no subsequent CW gameplay-start request. The interacted entity resolves to a SandBoardGate, not evidence of a CW entrance interaction. The native module still has `_NeedShowEntrancePage=false` and LastTutorialFinishedSeasonID=0; neither value was changed by a probe.
The ordinary `loadScene` no-teleport path currently selects the first checkpoint instead of the MapEntrance start anchor. This can place a mission entrance in the outer hall. The matching MapEntrance row specifies a start group absent from the old res scene group list. Both placement and current RuntimeGroup data are being checked before updating the CW entrance. This is not yet a verified UI-entry fix.
The catalog now also retains 71 active-season stage wrapper rows and 60 default handbook role rows, with a completed capture and its SHA-256. Stage wrapper values were observed on a fresh profile without talents. Handbook defaults do not establish the full hidden/variant shop pool. `tools/export_cw_catalog.py --gameplay-log` rejects incomplete final batches and checks stage identities against the active division catalog and role season/identity/star values.
The native start anchor was captured and matches the existing Anchor table. The CW no-checkpoint path now uses that captured anchor; the user confirmed arrival inside the CW room. This fixes placement only. They still report that UI closes, and the console/hologram is absent and cannot be used.
Targeted RuntimeGroup captures identify the CW Console and Emblem in an activity-tagged Client-managed group. Both props have `IsClientOnly=false`, `LoadOnInitial=true`, state 1, and exact captured world transforms. The loaded MapPropDef enumeration contained neither prop (0 matches). The group's saved-value condition is `FSV_370GridFight >= 1`; native `RPG.GameCore.CompareType` enum capture confirms operation 2 means GreaterEqual.
The first prop-binding attempt produced no `CW_ROOM_BIND` log and the user still saw an empty table. Further inspection corrected an earlier mistaken inference: the supplementary table has MaxValue=2, but inline `res.json` has `FSV_370GridFight=0`, which wins during merging. The room condition was never satisfied; absence of the props did not prove that Client-managed entities needed server binding. The supplied video confirms the guide transition returns to a room with an empty table.
The replacement implementation removes forced prop binding. On the native CW entrance only, it clones saved values and applies a resource-defined freeplay profile for the condition's referenced name, using the current native RuntimeDimension MaxValue (the existing PearlSR freeplay policy). Native MinValue/MaxValue/AllowedValues and activation threshold are validated, and unrelated keys are rejected. It does not mutate shared scene data, other entrances, or Client graphs. Room visibility, UI entry and gameplay remain pending Client verification.
The user subsequently confirmed the hologram/props appeared. The actual packet path logged `CW_ROOM_ACTIVATION ... previous=0 selected=2`. Both the table interaction and Guide Go still opened the entrance briefly and closed it.
Temporary observers on seven named CW Lua lifecycle methods, automatically restored after two minutes, identified `MonoRemainTimer._UpdateTime -> UITransitionManager.SwitchBack` as the close path. A second bounded observation captured two CW timers: `LeftPanel/TitlePanel/RemainTime` targeted 2031, while `LeftPanel/PtRewardPanel/RemainTime` targeted 1970-01-01. This distinguishes the missing points-reward period from the correctly populated season schedule. No timer value or callback was suppressed.
The server receives `CycleScoreRewardGetDataCsReq` on login but previously left it unanswered under the CycleScore safety guard. The next typed handler supplies the non-null period object and its `end_time` using the explicit shared activity window; other CycleScore commands remain guarded. This is a fresh-profile/freeplay bootstrap, not implemented weekly rollover or reward-claim persistence, and needs Client confirmation. The separate CW EXP counters are not dates and remain zero.
Client verification after this build: the user confirmed the CW UI stays open. The server logged `CYCLE_SCORE_REWARD_DATA end_time=1924992000 score=0 bootstrap=true policy=activity_window` and sent the typed `CycleScoreRewardGetDataScRsp`. Room placement, hologram visibility and stable entrance UI are now user-confirmed; starting a run, shops, battles, settlement and persistence remain unfinished. All temporary lifecycle observers were restored and their active scripts removed.
## Native route catalog and battle configuration boundary
The complete `GridFightStageRouteConfigExcelTable.dataDict` capture contains 493 rows. Its owner is `RPG.GameCore.Config`, reached from the known `GridFightRoleConfigRow` assembly, rather than the Client module assembly. The producer now requires `--route-log`, rejects incomplete batches and duplicate `(ID, ChapterID, SectionID)` coordinates, and preserves the capture hash. The Go catalog indexes sorted copies of each route and checks that the native `GridFight_FirstPlay_StageRouteID` is present. NodeTemplateID is retained as a configuration identity, never substituted for battle StageID.
Targeted loader/type metadata identifies `GridFightStageTemplateConfig.GridFightWaveList` as `(WaveIndex, StageId)` entries, and a separate BattleTemplateList carrying monster waves, formation, level/hard level, elite group, monster stars and affixes. These schemas are captured in `cw-template-schema.log`; no graph or battle-template loader was invoked. The named NodeDisplay Excel table was absent in the inspected assemblies. Tutorial wrappers also do not expose the raw row through the field/getter paths used by the first bounded probe; those failed attempts are not captured gameplay data.
The route reader compiled into `.runtime/cw-route-catalog-gameserver.exe`. This binary has not replaced the running server, and compilation does not verify CW run entry. Starting a run still requires a complete native node, player and shop state mapping. The original full CW scope remains open.
The tutorial wrapper is flattened rather than retaining a raw Row. After inspecting that one named type, a bounded scalar exporter captured both initialized `TutorialStageConfigs` entries completely. The producer now also requires `--tutorial-log`; it preserves trial-avatar, portal/reveal/supply flags, sale restrictions, tutorial division/reward identities and native shop restriction objects. Obfuscated shop coordinate keys remain opaque; their numeric order has not been guessed. The Go loader validates identities, provenance and restriction shapes. These configuration captures do not create a run or bypass tutorial progression. All CW probes installed during this capture were removed from `scripts/` after completion; the unrelated scene metadata probe was left untouched.
## Run player scalar mapping
The next bounded capture encodes isolated `NIHNGPKHEPC`, `BEEFLEJAOCN`, `BCCIJHPLJOJ` and `OHMDHKGAEMM` UInt32 backing fields individually, without syncing objects or sending packets. `cw-gameplay-scalar-wire.log` completed all four types. Getter-token matches against metadata initialization calls are **not** treated as getter function addresses.
Native `GridFightPlayer.SetData` starts at RVA `0xdb9d670`. It reads player protobuf offsets and updates named setters identified by their MethodDef checks. `cw-player-proto-fields.log` supplies the declaration order: nine reference fields precede thirteen UInt32 fields. The offset-to-wire association below uses the sequential IL2CPP field-layout inference; it is corroborated by the already named HP/EXP/gold wire fields, but is not yet a Client gameplay verification. Native getter offsets were not independently obtained.
| Native offset | Wire tag / Go field | Player meaning |
| --- | --- | --- |
| 0x58 | 1 / PPKKHHNEOHB | MaxHP |
| 0x5c | 10 / GridFightLineupHp | HP |
| 0x60 | 3 / NDAINFLOLPJ | PlayerLevelLimit |
| 0x64 | 11 / AFFCFLFIFPH | RoleMaxNum |
| 0x68 | 2 / KNFOCCPOJEA | MaxInterestNum |
| 0x6c | 9 / GridFightCurLevelExp | Exp |
| 0x70 | 4 / JLOCMDIDPCI | MaxBackRoleNum |
| 0x74 | 15 / CPKLHPJMMDO | BuyExpHpCost |
| 0x78 | 7 / EHNJDIDABHD | Level |
| 0x7c | 12 / BEPMODICONA | BuyExpCost |
| 0x80 | 5 / GDAKCOICIDA | KeepWinCnt |
| 0x84 | 8 / Gold | Gold, passed to UpdateGold |
| 0x88 | 6 / MICEOJBAKGN | MaxBenchRoleNum |
`currency_wars_player.go` implements this isolated scalar conversion and basic health/level validation, preserving destination restriction/tracker containers. It supplies no invented initial stats and is deliberately not wired to StartGamePlay before the full context and initial configuration are available. Native SetData also dereferences the active session, so it was not invoked on an isolated player merely to test these mappings. Ordinary Battle converters are untouched.
Native `GridFightStage.Sync` (0xdc05680) copies the BEEFLEJAOCN scalars at 0x60/0x64/0x68. `_SyncRouteInfo` (0xdc05740) passes 0x68 and its route-node list to `SyncRouteNodes` (0xdc07090), which stores the scalar in `GridFightStageRoute._StageRouteID`. Thus the first parameter of SyncRouteNodes is route ID, not chapter ID. Together with scalar encoding this maps tag 7 / EMOHLJHPOPC to route ID, tag 5 / DCAHJELNJNP to chapter and tag 8 / SectionId to section. `currency_wars_route.go` builds that component from captured route coordinates and caller-provided display configurations, rejects missing/extra nodes and an invalid current coordinate, clones display objects, and commits only after validation. It does not invent display values from NodeTemplateID or replace battle-node state.
A metadata-only search on the known GameCoreConfigLoader found `LoadJsonConfig(string)`. Reading only the native FirstPlay path with this plain JSON reader returned nil; no tutorial JSON was captured and no graph loader was invoked. Row metadata attributes also supplied no table accessor. These attempts do not establish that the native binary configuration is missing. The completed captures are retained outside scripts and all probes from this turn are removed after completion.
## Standard Gambit and Overclock start request
Both modes use the same `GridFightStartGamePlayCsReq` command (8579); the current protocol schema distinguishes Overclock with `is_overlock` (field 9) and carries `division_id` (field 2). A command-ID-only packet trace cannot reveal that flag, so the user's identification of the 23:05 request as Overclock is retained as the context for that capture.
That trace has no `GridFightStartGamePlayScRsp` (8511). It only shows `GridFightGetDataCsReq` (8541) answered by `GridFightGetDataScRsp` (8503). A source-level diagnostic now logs the start mode, but deliberately sends no start response: the active-run object and its initialized state are not yet verified. This explains why this trace does not demonstrate a successful Overclock entry; it also must not be used as evidence about Standard Gambit. Do not return an empty start success or fabricate a run object to hide the missing state.
## CW snapshot persistence foundation
`currency_wars_store.go` adds a separate `currency_wars` object inside the existing persistent file, keyed by UID. Each envelope records its own save format, configured Client version, captured assembly SHA-256, a monotonic revision and serialized GridFightGetDataScRsp bytes. Reads do not create files, rewrite defaults or migrate data. Writes use the existing process mutex, shared OS file lock and atomic file replacement; unrelated JSON values are retained as RawMessage to avoid float conversion. A stale expected revision is rejected rather than overwriting a later run. Account/Client/schema mismatches preserve the existing save and return an error.
GridFightGetData now reads a matching snapshot when one exists, decodes it, checks the known permanent/season/handbook prerequisites and restores its response. With no saved snapshot, it retains the existing fresh-profile bootstrap and does not write during GetData. A session helper prepares future commits after validated gameplay transitions. No gameplay handler writes a run yet, and full active-run/action validation must accompany the upcoming state machine; envelope persistence alone does not implement run resume or playable CW. The save build compiles into `.runtime/cw-save-gameserver.exe`, has not replaced the live server, and was not tested with a completed CW run.
The known `_SessionPreloadProvider` field declares an obfuscated interface describing stage preparation. Its live value is nil before CW starts, so no concrete provider metadata or template paths were captured. Native `GridFightPlayer.set_Level` is a local scalar setter at 0xdba2110; the 0xdba2280 call in SetData is the Gold update path, not the level setter. No player/session instances were created or synced during this research.
## Captured roles and economy
The Go catalog now reads and indexes the 60 captured default roles and 71 fresh-profile stage wrappers, verifies source hash and active-season identities, rejects duplicate/missing division wrappers, and returns copies of mutable role/stage lists. This retains the original capture scope: handbook defaults are not the complete shop pool, and fresh-profile wrapper rewards are not the final totals after run modifiers.
Native sale arrays exist for star ranks 1–3. Their rarity-indexed default-star values match all 60 captured `DefaultSellPrice` getters. The catalog checks this relation at load time. `BaseSalePrice` reads those arrays and rejects unsupported stars/rarities rather than fabricating a price. It is a base quote, not implemented sale processing, special-role handling or stolen-card refunds.
Native `GridFightPlayer.GetWillGainInterest` (0xdba1aa0) divides the provided gold by a constant-table value and caps it with the player's resolved MaxInterestNum (0x50). The missing-native-rule fallback is not copied. `BaseInterest` uses captured `GridFight_DepositPerInterest` and an explicit run cap; zero caps remain zero. These helpers do not apply node rewards or mutate a run. The native string argument of the constant lookup was not independently decoded, so identifying the captured rule by its semantic name remains an inference pending Client confirmation.
The upstream repository was rechecked at `https://git.xeondev.com/HonkaiSlopRail/pearl-sr`; its master page still identifies revision 005d2c12db from 2026-10-16, matching the recorded reference. No newer master implementation was established. During the user's AA round, no CW probe is installed and the live server is not replaced.
`tools/cw_handbook_variants_export.lua` is prepared outside scripts for the next idle capture. It enumerates initialized DefaultRole and OtherRoles wrappers in bounded batches, recording role/star sale getters and native role rows without creating roles or changing stars. This will distinguish actual variants/higher-star wrappers from an assumed full pool. It has not run. No result from this planned capture is claimed in the current catalog.
The bounded capture now completed all 64 initialized wrappers: 60 default entries plus four OtherRoles entries. These are captured at star 1, not all stars or the complete hidden shop pool. The catalog producer retains native role/star/optional servant-star rows and the observed price/sale getters, with the completed capture SHA-256. The Go reader validates season, role/star identity, duplicate keys, and agreement with the earlier 60 default-role capture. Returned rows and slices are copied. Raw native star JSON preserves FixPoint strings and 64-bit text hashes without float conversion.
The OtherRoles entries are 151112, 151122, 151132 and 141402. In particular role 151132 has rarity 5 but native buy/sale getters of 7; it must not be priced by blindly indexing the ordinary rarity array. `CapturedSalePrice` returns the actually captured star quote and rejects stars that were not captured. Run effects, stolen refunds and transactions are still separate unfinished work. The catalog and reader compile into `.runtime/cw-variants-gameserver.exe`; this staged build has not replaced the live server.
Exact-name table lookup completed all 143 loaded assemblies without finding either `RPG.GameCore.GridFightPlayerLevelConfigExcelTable` or `RPG.GameCore.GridFightRoleConfigExcelTable`. This proves absence of those names, not absence of the native tables. A separate named-type metadata capture confirms `GridFightPlayer._ConfigRow` is a `GridFightPlayerLevelConfigRow`, and that the guessed PlayerLevelConfig/StageNodeTemplateConfig wrapper names are absent in the two relevant assemblies. All completed Lua probes from these captures were removed from `scripts/`.
The user's 00:49:57 Standard Gambit and 00:50:18 Overclock traces both show StartGamePlay (8579), then GetData (8541/8503), without a StartGamePlayScRsp. This corroborates the unfinished start path; neither run mode is playable yet. Role/price capture and a successful build are not evidence of run entry.
## Native player-level scalar capture
The AMD64 PE exception table identifies the handbook getter entry at RVA 0xdb5f860 and the player-level table getter at 0x1e3a7880. `disassemble_pe_range.py --containing-function` records exact exception-table bounds and assembly digest. Native `GetLevelUpNeedExp` at 0xdba1b90 calls the latter getter and reads row offset 0x20 when no run modifier is present; named Row field metadata corroborates the other scalar offsets.
A temporary Frida hook ran two table queries per read-only handbook call on managed Client thread 37460. The default level limit came from the captured constant rather than a probe default. An initial read-only check found that the table was not loaded. After inspecting its native Excel loader, the bounded capture used the normal getter's lazy initialization of that one Excel table; it did not invoke a level graph. Ten identity-checked rows completed, retaining EXP costs, front capacity and five shop rarity weights. The capture and REA Evidence are in `battle_diagnostics/cw-native-player-levels*`; the catalog producer hashes the scalar log and rejects missing/duplicate/out-of-range levels. `GeneralPropertyList` is explicitly outside this scalar capture. No run state, player object or saved progression was modified. The hook was detached and its Lua pulse removed.
The catalog now retains these scalar columns and `CurrencyWarsCatalog.PlayerLevel` returns a copied value. Run EXP modifiers, actual purchases, level transitions and shop draws are not implemented by this lookup. The stage build `.runtime/cw-levels-gameserver.exe` compiles; it has not replaced the live server or demonstrated CW entry.
A subsequent capture completed the full ten player-level rows, including `GeneralPropertyList`. The named Newtonsoft `SerializeObject(Object)` method exposes `RuntimeMethodHandle.Value` as Lua light userdata; reading that specific handle shows its executable method pointer at +8 (RVA 0x1d3efb60). PE function inspection confirms a static serialization overload forwarding path. This replaces an incorrect *candidate* produced by matching that method's MetadataToken to an unrelated native metadata-initialization check; that candidate was never invoked. Metadata-token pattern matches must not be generalized across assemblies as function addresses.
The existing bounded handbook-thread hook queried each native level row and serialized it through that verified method. Every serialized scalar was cross-checked against the earlier raw layout. The raw JSON preserves FixPoint property values as strings; levels 4–10 include nonzero property modifiers, so omitting these columns would lose gameplay data. Complete capture/Evidence are retained in `cw-native-player-levels-full*`. The resource now uses `captured_player_levels` and validates/copies the property rows. Both temporary hooks were detached, and all Lua probes from this work were removed from scripts. This capture still does not define initial run gold/level/context, shop pool depletion, stage generation or StartGamePlay behavior.
An additional metadata inspection of initialized DivisionStageConfigs (one selected stage in this Client session) and DivisionLevelConfigs (nine entries) found flattened wrapper fields rather than retained raw Row references. Its complete log is `cw-division-run-rows.log`. No raw division/server run configuration is claimed from that inspection.
## Route-node fields and chapter rules (2026-10-20)
The prior goal turn made concrete progress by capturing full player-level rows and role variants; CW start remains unfinished. This continuation resolves exact runtime handles for the named node/player protobuf getters and native node properties. `RuntimeMethodHandle.Value + 8` supplies their executable pointers. `cw-property-handle-rvas.json` and `cw-property-native-layout.json` retain the explicit targets and direct baseline return loads. The mapper accepts exact exception-table entries or short, branch-free leaf getters; computed getters remain unmapped. It tracks overwritten `this` aliases so a load through `_NodeParam` is not mistaken for an offset on the node itself. No all-type/assembly scan or getter invocation is used for that map.
The native node's `_RefreshCachedFields` (runtime-resolved RVA 0xdc09fa0) establishes these associations with previously captured wire tags:
| OHMDHKGAEMM offset | Wire tag / Go field | Native meaning |
| --- | --- | --- |
| 0x30 | 2 / StageId | CW node StageID |
| 0x3c | 14 / CJCCMAACJDB | RawNodeType |
| 0x50 | 12 / PICMDONCKCO | BasicReward |
| 0x40 | 8 / PFEMDGNFHNH | compared with 1 for IsAugmentNode |
| 0x4c | 11 / FCNNBODJNIK | base HasExpert flag, later affected by run modifiers |
| 0x4d | 4 / HPNNLMBHOPF | base HasSpotLight flag |
The route-node protobuf's native offsets 0x20 and 0x24 are SectionId (tag 1) and ChapterId (tag 5), respectively. The player protobuf getter offsets independently corroborate the earlier thirteen scalar layout associations. `currency_wars_node.go` applies the mapped node subset while retaining other parameters; it rejects node types absent from the captured enum. The native enum capture contains GridFightNodeNone, Monster, CampMonster, EliteBranch, Boss and Supply. NodeTemplateID remains distinct from node StageID and must not be passed as battle StageID.
The same native node refresh calls a table getter at 0x1de40ce0 with ChapterID, then reads HealNum into RestHealNum. A bounded managed-thread capture serialized the three chapter rows referenced by the complete route catalog, checking each identity; all completed with HealNum=20. These values are captured resource data, not a code fallback. The catalog validates complete chapter coverage and source digests and returns copied values. Applying actual HP recovery still belongs to the node action; this lookup does not decide whether a later modifier changes the amount.
## Captured monster camps
`GetAllMonsterCampData` yielded 21 initialized active-season handbook configurations. A bounded exporter captured each native GridFightCampConfigRow and GridFightCampSeasonConfigRow, including season-specific monster IDs, normal battle areas and boss battle area. The producer verifies the common/season/wrapper identities, positive monster IDs, duplicate keys and complete capture markers. Text hashes retain integer precision in the resource and raw JSON in the Go reader. The catalog reader returns copied arrays and text metadata.
This is the observed handbook camp set, not proof of the full hidden pool. Camp MonsterList is not a complete node wave recipe: monster stars, levels, waves, battle templates and runtime enemy modifiers are still required for battle construction. No arbitrary camp list is substituted for an actual battle stage. The staged `.runtime/cw-node-state-gameserver.exe` includes the node/chapter/camp readers and compiles; the live server was not replaced during this capture, and neither Standard Gambit nor Overclock has been verified entering a run. All temporary probes/hooks from this continuation were removed or detached after their captures completed.
## Shop pool and transaction plans (2026-10-20)
The previous continuation progressed through the captured pool algorithm and bounded shop metadata capture. This continuation resolves 84 explicit method handles while the same Client process is live, then compares the native consumers and getters from the source assembly. Abstract GoodType has no executable pointer and is excluded from static getter analysis. Evidence is retained in `cw-shop-handle-rvas.json`, `cw-shop-getter-layout.json`, and the native shop disassemblies. The process subsequently closed; no handles from it may be reused after restart.
Important correction to the provisional shop interpretation: `RoleShop.Sync` RVA 0xdbc9fd0 reads POC +0x28 as MONJNCPINKN, then enumerates its pair list into **RarityWeights** at this+0x28. It is not the goods list or a card-pool count snapshot. The POC goods list is +0x18 / tag 3, passed to 0xdbca1a0, which fills shop slots. DLDJEOPKNMB at +0x10 / tag 15 has not been assigned a semantic meaning. Pair-column meaning still needs its exact selector resolved. POC +0x30 / tag 13 is the refresh price; +0x34 / tag 6 is free refresh count; +0x38 / tag 5 is lock state. Do not encode rarity weights into tag 15 based on its repeated-uint shape.
`GridFightShopGood.Cost` RVA 0xdbf2860 reads HDE +0x28 / tag 13. `Sold` RVA 0xdbf26f0 reads +0x24 / tag 7. The factory at 0xdbf2340 receives the slot index separately and selects the role constructor for oneof 1403, whose payload is NJBGFHDPFNO. The factory also recognizes native case 291, absent from the current generated Go oneof; that special goods variant is unsupported, not silently substituted. The source enum's normal/special meaning remains unassigned.
`currency_wars_pool.go` reserves offers against the captured eligible pool, reads native per-rarity capacities/exclusions, and returns unsold copies before a new draw. Within-rarity weighting is explicit server policy (`remaining_copies` or `uniform_role_ids`), not asserted to reproduce the original server. Depleted rarity buckets are excluded and errors discard the proposed draw. This is still the captured handbook pool, not every hidden role.
`currency_wars_shop.go` now produces detached transaction plans for manual refresh, node-entry refresh and purchase. Free refreshes, debit checks, repeated-purchase rejection and reserved-copy bookkeeping are included. Resolved slot count, refresh cost, rarity weights, quote and RNG are supplied explicitly; base rules come from the catalog. Upgraded offers require a separate copy-consumption rule. Board placement/merges and the run revision must be committed together with these plans by the upcoming action processor. No shop handler writes a run yet. The role-offer wire converter covers the supported role oneof and observed price/sold fields only.
`go build -o .runtime/cw-shop-transactions-gameserver.exe ./cmd/gameserver` succeeded. No tests were added or run. This staged binary has not replaced the root executable or running server, and it does not implement StartGamePlay. Both Standard Gambit and Overclock remain unverified at run entry. All temporary shop Lua probes were removed from `scripts/`; unrelated scripts were preserved. Remaining work includes complete initial run state, route/node generation rules, board actions, modifiers, battle construction, progression, rewards and Client verification.
## Offline continuation: references and EXP transitions
The preceding turn made progress through transaction plans and explicit shop field mapping. The Client process is now absent, so no runtime handles were reused and no new probe was deployed. Offline source reads and compilation remain available.
An adjacent older server installation contains GridFightRuntime, GridFightRewardRules and GridFightBasicOrbRewards JSON files. Their section inventory and source hashes are retained in `cw-offline-reference-inventory.json`. Reward rules contain nine combat profiles, three boss profiles, five node reward profiles and four talent triggers. These profile keys are not established as the same namespace as native NodeTemplateID, and the files carry no Client revision/provenance. They have not been imported or treated as current native node recipes. The SQLite file in that installation is player persistence, not a substitute for the missing native CW tables. The adjacent gameserver executable has no CLI directory, so managed reflection/CIL inspection cannot recover its implementation. No adjacent files or databases were modified or executed.
`CurrencyWarsCatalog.PlanBaseExperience` now resolves multiple crossed levels from captured thresholds, validates the current counter and run limit, preserves each crossed level's copied property/capacity/rarity configuration, and rejects a protocol counter overflow. It is a detached calculation, not a BuyExp handler. Initial run values, run modifiers, gold/HP payment and the native treatment of residual EXP at the cap still need to be established and applied together by the action processor. No cap-reset behavior is invented here. The staged `.runtime/cw-experience-gameserver.exe` compiles; no tests were added/run and the root executable was not replaced. This does not prove CW entry or progression in the Client.
## Preparation and position blockers (2026-10-20, continuation)
Client logs now confirm RoundBegin queue 2 -> ReturnPreparation queue 10 -> no pending, followed by successful UpdatePos saves. The previous 6900 was an unsupported RoundBegin; 8795 had no handler. Current implementation uses revision-bound pending recipe `CurrencyWarsPreparation.json`, generates a current catalog shop and saves before notifying. UpdatePos validates the entire final board, ownership, duplicate request IDs, collisions, capacity and duplicate active avatar IDs. GDAKCOICIDA is keep-win count, not bench overflow; overflow bounds now read the captured constant.
A controlled native commerce replay confirms `GridFightBuyGoodsCsReq` -> `BuyGoodRsp`, zero-based indices and add-role/shop sync. Buy, refresh and lock handlers are implemented. Purchases require shared entry property scales, use a fresh entity ID across the run and save the gold debit, sold offers and new bench role in one revision. This is the entry prototype: merges, role switches, trait recalculation and full modifier-dependent quotes remain incomplete.
The SDK `/cw` command path queues run-bound absolute gold/HP commands in a separate persistent field, without writing adventure data or changing the CW snapshot revision. The game applies them under the session lock only while CW is open, preparing and outside Battle. It saves before notifying and acknowledges afterwards; retrying an absolute assignment is idempotent.
Native replay also captures a first-node battle response. `tools/export_cw_battle_template.go` retains its exact enemy recipe. Runtime validates its route, node, division, mode, stage and penalty, replaces party/NPC equipment/portal/player identities, and rejects unsupported nodes. The captured party's traits/buffs/events are removed, not inherited. This describes the entry prototype at that point; subsequent Client evidence and settlement work are recorded below.
## Client-confirmed first settlement and preparation continuation (2026-10-21)
The user confirms first-node combat works. The actual game server trace records `CW_SETTLEMENT` for battle 21, followed by RoundBegin queue 12, Investment queue 13 and ReturnPreparation queue 14. The run reaches chapter 1, section 2 with its existing team, purchases and GM gold retained. This supersedes earlier statements in this investigation that run entry or all settlement is unimplemented. It does not establish a complete run or Overclock gameplay.
First-node settlement now checks uploaded battle identity, percentage bounds and the saved revision. Gold, HP, EXP, next-node enemy layer and pending action are saved together before notification. Interest and victory ranges use captured data. Three captured Investment outcomes update only owned augment/gold state; these are not a general augment effect engine. Loss/terminal settlement, all node transitions, orb collection, merging and full traits/equipment effects remain unfinished.
Native sale replay establishes request `GridFightRecycleRoleCsReq`, response `GridFightRecycleRoleScRsp`, the `HFCBOIOAECK` remove-role arm and observed sale source enum. The handler saves the role removal and captured sale quote atomically. Equipped roles are rejected until the equipment-return ownership notification is implemented; sale must not orphan gear.
Native EXP replay establishes `GridFightBuyExpCsReq` / `GridFightBuyExpScRsp`, source `JJDFGMMMCMI_IHEKGIGCGEC`, gold, capacity (`BPCFDPNHIEL`), shop weights and player-level sync. Repeated purchases reach level 10 with residual EXP 2; further purchases return failure without spending gold. Before/after native team property maps remain identical. The implemented base purchase uses the run's gold quote and current captured EXP rule, saves before notifying, and updates capacity and rarity weights together. Modifier-dependent EXP gains and additional capacity bonuses still need their own resolution; this is not a claim of complete modifier support.
The user's current Client exposes node 1-2 penalty row 92013, including TotalTurn 15, base HP penalty 5 and progress coefficient 10. This exact row and its capture digest are retained in `CurrencyWarsSettlementRules.json`. Named stage/monster metadata reads are bounded and do not load scene graphs. The isolated reference returns retcode 1 with no BattleInfo for node 1-2, even after re-entering that node and refreshing positions. The cause inside that binary is not established. Its first-node BattleInfo must not be copied onto another node to hide this failure. The current server still rejects an uncaptured enemy recipe explicitly; second-node combat and subsequent settlement remain work in progress.
### Second-node recipe recovered from the reference save
The isolated reference's `GridFight.RunInstance` holds a serialized native BattlePlan even though its second EnterBattle response fails. A unique bounded MemoryPack record at snapshot offsets 158:309 decodes as camp, elite group, penalty, difficulty and two waves; wave/monster record field counts match the public native schemas. `tools/export_cw_enemy_plan.py` rejects ambiguous matches, oversized arrays and nonempty drop payloads. It exports only the wave parameters and provenance hashes, not the account or party. The current target's flat `StageExcelTable` row independently supplies Level 90 and HardLevelGroup 1; no level graph loader was invoked. Its active stage reports zero additional difficulty.
`CurrencyWarsEnemyPlans.json` binds this recipe to the captured route/division/node/mode/stage/penalty. Runtime builds enemies from the saved layer's monster identities and stars, checks them against the current target season's camp, validates wave IDs/counts and rejects unresolved difficulty modifiers. The proven first-node path is retained. The second-node parameter reconstruction and resulting combat are still awaiting Client verification.
An isolated native administrative move to the next route node followed by RoundBegin captures the Supply layer/action. This is explicitly not a native second-battle settlement capture. Only next-node layer/pending definitions are imported; runtime settlement computes the player's own rewards and preserves their team. The queued action identifiers are opaque server-issued cursors following the preceding consumed action. The user confirms sale and EXP purchases work, including reaching the level cap. A staged and deployed second-node build now links its settlement to the Supply screen; Supply selection and later nodes remain unfinished.
### Current Client correction: node 1-2 is Plot Armor
The user reports that this node presents the Protagonist button, not ordinary Battle. Requests include `GridFightSpotLightEnterCsReq` and `GridFightUpdateSpotLightTrackCsReq`, both previously unhandled. The old reference lacks this current Spotlight implementation. The reconstructed normal second-battle path above is not verified as the appropriate current route. Moreover, the imported old layer's camp must not be treated as a generated member of the current run's active camps. Selection, actual effects and the appropriate enemy layer remain unfinished.
Bounded current Client captures now contain 84 initialized Spotlight rows, exported by `tools/export_cw_spotlights.py` to `resources/CurrencyWarsSpotlights.json`. These are real configurations and suitable-role lists, not evidence of original-server selection weights, offer count, costs or grant policy. `CurrencyWarsSpotlightPolicy.json` explicitly defines the current server's uniform compatible selection policy (three options, no rerolls); it must not be described as captured original weighting. No success-only response replaces selection state.
Named MethodHandle +8 reads and bounded PE disassembly establish `GridFightSpotLightSelectAction._SyncFromProto` at RVA `0xdc00cd0`. Isolated protobuf setters encoded to bytes establish the field tags independently. Assembly SHA256 is `c5e02e6e984f7e5577c78b995a8efeee2d06ee22e67d484ad5e859c8bf21e144`. Evidence is retained in `battle_diagnostics/cw-spotlight-selection.asm`, `cw-getter-native.json`, `cw-spotlight-wire.log` and `cw-spotlight-getters.log` (ignored diagnostics).
| Pending BDLBHJGNCFM field | Current Client meaning |
| --- | --- |
| GFGJOKJGGCO (2) | TargetSpotLightUniqueId |
| BKOGIFHEKHH (4) | IsGrant |
| HPKFKBKOADP (5) | Candidate Spotlight IDs |
| IAJCPLMAACH (7) | IsUnlimitedTier |
| GFJDGNKAOFK (8) | NextRefreshCost |
| DLIANLGFMBG (9) | TargetRoleId |
| DOAHJPPPMGM (12) | RemainingRefreshCnt |
| ACKOKJBBPKH (14) | IsAbandonForbidden |
ActionID comes from the enclosing pending QueuePosition. The protobuf arm is EEKMIAMGHFL (1817), not the ordinary Battle arm. `SelectCandidate` dispatches role and selected Spotlight ID through `Select`; this still needs a server-owned offered-choice/role validation path. FMBACDOFCAL mappings independently encoded: IHHNLLAJAGB (1) SpotlightID, UniqueId (2), MDNAGANGNKK (9), ELBPNDIENDL (11), RoleId (13). Meanings of fields 9/11 and special effects are not inferred merely from their types.
Further named native inspection resolves fields 9/11: AddOrUpdate at RVA `0xdbfb3f0` shuffles the proto scalars into its ACNDKIFJLJC record. GetActiveSpotLightBindingByRoleId at `0xdbfb9a0` and binding constructor at `0xdbf6380` place that record into RoleUniqueID/RoleID/SpotLightID/UniqueID/IsLoss. Thus MDNAGANGNKK is RoleUniqueID and ELBPNDIENDL is IsLoss. New grants bind an owned role UID and use IsLoss=false; merges move the UID binding when the selected card is consumed. See `cw-spotlight-add.asm`, `cw-spotlight-binding-get.asm`, `cw-spotlight-binding-ctor.asm` in ignored diagnostics.
The implemented Enter handler validates preparation and the current node flag, persists an offered pending choice, then sends pending sync before the typed response. Selection validates the saved offer, suitability, ownership and duplicate binding; it saves a run-owned Spotlight, updates the route node, finishes the pending action and unlocks preparation. Start/entry transitions preserve an empty Spotlight component, and explicit Resume migrates old runs so Client Sync marks the manager valid. Snapshot reads remain read-only. The build compiles; UI selection/resume is still awaiting current Client proof. Battle projection/effect execution and subsequent route fidelity are unfinished; do not claim the complete mode works yet.
`CurrencyWarsCatalog.json` now contains 219 actual native star rows, identity checked against the requested role/star (no clamped rows accepted). `tools/import_cw_role_stars.py` preserves earlier configurations and imports only observed rows. Ordinary sale quotes use the current rarity table only when the captured default quote agrees with that table; unestablished special quotes are rejected.
`tools/export_cw_merge_rule.go` derives the required copy count from an isolated native merge sync. The captured merge group removes three UIDs, adds one new UID at star 2, and uses source `JJDFGMMMCMI_NJBMBFFLNGM`. Runtime basic merges cascade for identical role IDs up to the resource-defined ordinary limit, prefer active/equipped roles for the retained position, preserve the retained role's equipment attachments and leave other equipment in the bag. It rejects unresolved divergent role modifiers. Physical pool accounting uses the merged card's underlying copy count; ordinary full-star cards are excluded from new offers. A full bench can accept a third copy only when merging consumes it. Resume reconciles old triplets in a saved transition; its following GetData returns the changed roster, avoiding notifications before the Client session exists. Switch groups, Spotlight star locks, special higher-star upgrades and merge-triggered trait effects remain incomplete.
Current tracking handlers bind names from the current command table: GridFightUpdateEquipTrack and GridFightUpdateEquipTrackPriority. Tracks persist in the player component MIIDIMOCPEB; KFNCAIHIHCM.BMGFDIKDOBE carries the complete updated list. Native `CreateServerTrackUpdateInfo` at RVA `0xda5afa0`, `RemoveEquipTrack` at `0xda63a30` and `_AddTrackToLastAndSend` at `0xda628d0` prove BJDOINAHDLN is **enabled**: add passes true, removal false. It is not a deletion flag. Priority is NALMBOOCCIN; the source protocol comparison also names it priority, but old source tags/opcodes are not used. Equipment IDs are checked against the 142 current initialized handbook equipment rows. This implements tracking persistence/display, not equipping, crafting or combat item effects.
The merge/tracking build compiles; no automated tests were added or run. Client confirmation of these new changes remains pending. Finished research scripts have been removed from scripts/; their source remains under tools/.
### Protagonist selection confirmed; CW trial blocker found
The user confirms selection works. Current logs prove Enter offered three choices at queue 215/revision 215 and DKDFDGJGIHM selection finished at revision 216 with preparation restored. An initial validation error was our incorrect requirement that every native Spotlight row contain JsonPath; fifteen real rows have an empty path and must be retained, not replaced with guessed paths. The validator now accepts their native shape.
The subsequent EnterBattle failure is distinct: `CW role avatar 6042 not owned; trial resolver required`. The captured role row marks this as a fake CW avatar and supplies SpecialAvatarID. The current native flat SpecialAvatar table supplies its identity, world level, level, promotion, rank, enhancement and equipment values. `CurrencyWarsTrialAvatars.json` retains this complete native row and capture hash; `cwTrialBattleAvatar` builds an isolated trial battle avatar with the special ID and Trial enum. It never adds the fake avatar or trial gear to Adventure/persistent inventory. The native reference's ResolveBattleAvatar / SpecialAvatarInfo.ToBattleProto corroborate this special-ID serialization and do not create relics for this fake avatar. Only captured trial profiles/world levels are supported; others still fail explicitly.
Native `BattleGridFightAvatarData.get_SpotLightID` at RVA `0xefae920` reads BattleExtInfo +0x18 then that object's +0x18. Isolated ABJGLPCOMMK setters encode tag 2 as `10-01`, whose accessor at `0x1eea9f00` reads +0x18; tag 1 reads +0x1c. The old captured role envelope independently has tag 1 Mode=2. Runtime retains that mode and injects only the selected run binding's SpotlightID at tag 2. It does not inherit the reference avatar's Spotlight. Server-side economic/difficulty/trait-specific Spotlight effects remain unfinished; the presence of this projection is not proof of all effects.
Current trial/Spotlight projection build compiles and is deployed at root. Actual node-1-2 combat after the trial fix is awaiting Client confirmation. No automated tests were added or run. Research captures are outside scripts/ after completion. Future probes should wrap their whole body in a local function: a top-level return in one concatenated script can skip later scripts in the same heartbeat.
### Supply selection and second-node Client confirmation (2026-10-21)
The user now confirms node 1-2 Battle works after the fake-avatar resolver. The server records battle 247, a completed settlement with progress 100, followed by Supply queue 16 at revision 248. This supersedes earlier pending-verification statements for this particular fight only.
The Supply 6900 was a missing FIKAGBAEOAP request branch. The new handler validates the saved queue, exact selection count, one-based indices, offered role/star and item identities against current resources. It grants the selected equipment and role with fresh run-owned UIDs, merges eligible triplets, and saves once before sending equipment/role/merge groups and the pending acknowledgement. A rejected transaction sends no grants and writes no partial changes. Paid selections and rerolls remain unimplemented rather than inventing prices. The acquisition Source=9 discriminator is corroborated by the native Supply selection captures and the reference SupplyEquipmentSource definition.
The captured Standard Supply transition advances the existing party to section 1-4. It imports only the next level/pending recipe from march-cw-supply-next stage 17/18/19, never another account's balances or inventory. The later EliteBranch action and current-camp procedural encounter generation are unfinished; the captured branch layer is a reference recipe, not proof of correctly generated encounters for every selected camp. Do not claim a complete CW run or use it as proof of later Battle fidelity. Current Supply selection still awaits Client confirmation. Build only; no automated tests added or run.
### CW flow audit and staged Encounter work (2026-10-21)
The current Client/server trace confirms Supply queue 16 succeeds, advances to RoundBegin 20 and Encounter 21 (revision 250). The next 6900 is the unimplemented BAKAKODKECM arm, not a Supply failure. The user explicitly requests completing connected CW flows in batches instead of repeatedly requesting one-button Client checks.
`tools/inventory_cw.py --reference-root <source-checkout> --markdown <output>` now compares all current command names, Go registrations and reference source handlers, plus every pending-action arm. `docs/currency-wars-coverage.md` is the current static audit. Registration is deliberately not labeled gameplay success, and old reference names are not registered as aliases. Missing equipment, consumable, progression and pending actions remain visible.
A staged Encounter implementation validates the offered one-based branch, saves SelectedEliteBranchId, emits the mapped FGODNPLCECH selection sync, and queues ReturnPreparation; it also implements changing the selected branch during preparation. It compiles but has not replaced the root Supply build. It must not be presented as a complete Encounter combat/settlement implementation: wave recipes, difficulty, penalties, rewards and the following transition still require the connected work.
Native Create(UInt32,...) method handles identify RVA 0xdb7d780. Its bounded PE disassembly calls the monster row getter at 0x1dee0820 before constructing MonsterData; the capture invokes only that flat getter and the previously established serializer at 0x1d3efb60, on the initialized handbook getter thread, four rows per call. Current assembly hash matches the catalog. REA observations ev_6de4d1e2da5ceaf24244fb3effc43b0a9ed5122a6edc252a912fd7397b051311, ev_a5ea1ccc45442bcd8550983f294080ecb6cca0ea2d39f28828f17094433fe8ce and ev_2e7d90ac354eaf31406ddb077b68e18b2dccc0b1dbefb3d5f764136de324219d plus the retained getter disassembly establish 42 identity-checked monster rows covering this run's camps and the imported branch camp. No monster/scene/level-graph constructor executes. Finished probes are outside scripts/.
`CurrencyWarsMonsters.json` retains native tiers and all four star elite-group fields, with a complete plan/capture digest. Its coverage is partial, not the complete game table. The staged compatibility sampler selects a compatible active camp uniformly and replaces imported branch monsters with current native monsters of the same tier while preserving stars, wave layout, penalties and rewards. This is an explicit server compatibility policy, not a claim about original-server random weights. Explicit Resume reconciles an old pending Encounter once and saves before GetData; readers remain read-only. No Adventure inventory or party is changed. The root build is still cw-supply-gameserver; do not request another Client retry until the connected Encounter flow is ready.
### Quit/abandon active run request (2026-10-21)
The first handler only cleared the saved run and returned `GridFightQuitSettleScRsp`. The screenshot's “Currently unable to manually end and finalize” showed that was insufficient: the Client also expects `GridFightSyncKeepWinCntNotify` followed by `GridFightSettleNotify` before the success response. The handler now builds those notifications from the active run and current catalog, commits only the removal of `DHFOFLFCLAH`, sends the notifications in that order, then lets the dispatcher send the typed response. It does not award victory rewards or change Adventure inventory.
The packet names and wire layout come from the checked-in current protocol; the older reference is used only to confirm the required packet order and Quit reason, not its old CmdIDs or field tags. Settlement rank and completed-battle count are not present in the saved run/catalog mapping yet, so their protobuf defaults remain unset. The UI flow still needs confirmation in a connected Client after rebuilding/restarting the server.
### Encounter battle returns 6900 (2026-10-22)
`RET_GRID_FIGHT_CONF_MISS` is protocol retcode 6900. The current log attributes the Encounter failure to a missing enemy plan. The saved run is Standard, route 2801, chapter 1, section 4, stage 70000006. The Encounter layer offers two branches, with branch 1 selected; its saved enemy payload has one wave containing 12 monsters and penalty 91113. The second offer has penalty 91114. These live saved values do not include the battle's level, hard-level group, elite group, formation wave or complete difficulty modifiers.
`CurrencyWarsEnemyPlans.json` has a captured recipe only for stage 70000003 / penalty 92013, so it cannot construct either current Encounter branch. The builder previously also rejected every multi-branch layer and looked up a recipe using the node's penalty instead of the chosen branch's penalty. It now resolves the saved one-based selected branch, looks up that branch's penalty and logs the route/section/stage/selection when no recipe exists. Unit tests verify first/second branch selection and reject absent, empty or out-of-range choices. This avoids starting the wrong branch once its exact recipe is available.
The connected Client 4.6.53 capture confirms stage level 90, HardLevelGroup 1 and zero difficulty deltas. It records both one-wave branches, their 12 monster IDs and stars, and penalties 91113/91114. StageExcel's EliteGroup is 0; a separate monster row reports EliteGroup 1, but the current capture does not establish which value belongs in `SceneMonsterWaveParam.EliteGroup`. The saved branch message has no formation-wave ID, and the expected formation/elite table classes were not resolved through the direct Lua API. Do not fill these fields from the older reference or infer them from monster identities. The Encounter still fails closed until the current Client's exact formation and elite configuration values are captured. `tools/cw_active_encounter_capture.lua` is the bounded read-only probe; it uses reflected fields from this current Client, so it is not a general decoder. The full retcode audit is in `docs/currency-wars-6900-audit.md`.
Current 6900 paths elsewhere include missing gameplay catalog/snapshot, unsupported pending-action arms or failed action validation, missing EXP/Spotlight config, unavailable sale/role variants, mismatched party property scales on purchase, battle settlement validation, and save failure during quit. These are reported in their handlers; they do not justify returning success without state changes. CW equipment/forge, many pending-action arms, talents and later route recipes remain incomplete as listed in `docs/currency-wars-coverage.md`.
### Beta scan source correction (2026-10-22)
The user clarified that the target is the Beta 4.6.53 OS installation. The previous static lookup using the D: main-game assets was invalid and must not inform this Encounter. The retained runtime capture has the Beta `GameAssembly.dll` SHA-256 `c5e02e6e984f7e5577c78b995a8efeee2d06ee22e67d484ad5e859c8bf21e144` and records the current run as route 2801 / section 4 / stage 70000006. The live process path was independently verified with `QueryFullProcessImageName` and resolves to the user's Beta installation. `GridFightStageRouteConfigExcelTable.GetData` returned an empty row for the attempted key, while `GridFightEnemyDifficultyLvConfigExcelTable.GetData` failed to resolve that exact type; these are incomplete lookups, not proof that the data is missing. Continue only against this Beta runtime and its matching assets.