Original Fleet and Mission list selection sources
Offline pinned 6891 executable and current map AS were inspected. Current ED5A addresses below are established by complete function/constructor matches and original vtable slots in fleet-mission-sources/compatibility.json. No client function, account request or game input was invoked.
Fleet: published original data, implemented
GMYourFleetComponent.as passes the row's numeric id to OnGMYourFleetSelected. Original callback registration 468D240 binds that name to 46C33F0, which calls main MapUI vfunc+1F0, 3A6BB50. YourFleetButton.as also uses the same ID for OnStoredShipQuickPlot; this is a list-selection identity, not a ship ID or system address.
3A6BB50 resolves original component ID global 5F59D94 through the current player context. Its vfunc+20 is pure getter B27050: lea rax,[rcx+C8];ret. Original constructor 25BB9B0 puts this interface at base+58, so the published header is base+120, count+130, vector+138. Each row is 0x68 bytes. 26110E0 independently registers the same interface/global. Current ED5A guards are main 529CBF8, secondary 529CC28, interface 529CD28; original counterparts were 529CC28/529CC58/529CD58.
The actual left panel producer is 3A6F3B0. It and 3A6BB50 both exclude the current ship ID, require row+1C true, and count the remaining rows from one. The AS row ID is that filtered ordinal. Ship ID is row+18 (uint32); row+10 is the original location/body address, masked to the lower 55 bits for system lookup. These three values must remain separate. Original order and duplicate ship IDs/addresses are retained. 3A956F0 is a different selected-system RHS producer with extra same-system/transfer conditions; it is not used to reconstruct the all-Fleet left list.
The current-ship exclusion is a pure port of the original chain:
- Original current actor interface is
5F05BA4, current vtable5294CD8(old5294D08).25613D0(kind3)picks an eligible actor row: immediate kind2, otherwise last kind0, otherwise last kind3; rows with +1B8=-1 are skipped. Rows are stride1C0 at manager+978/count970. - Original
255A140compares its selected weak life (copied by25614F0from row+1A8) against the owner's existing IEntity reference. Original IEntity vfunc+20/8C5400is purelea rax,[rcx-228];ret, with the old/current vtable512AA10. No weak life is created or initialised. - If equal and weak life is active (
636A80: first pointer nonzero and life+C0>4), original2564BA0resolves component5F2F24C. Its pure vfunc+78/2DCCFE0reads uint32 at iface+2B0; current profile vtable is532DE38(old532DE68). - For an inactive weak life, the original fallback is descriptor(row+178)+E0, or row+F0 when no descriptor exists. None of these operations issues a request.
- Original unavailable sentinel FFFFFFFF is exported as
currentShipId:null. It is never a real zero ID or a fabricated 64-bit ID.
Navigation.GalaxyAccountFleet.cs reads only this owner-bound cache on the game owning thread, checks registry/source/row bytes before and after, caps the entire source at 4096 rows and rejects over-cap/malformed sources rather than truncating them. Its wire model is GalaxyAccountFleet(tick,entity,uint? currentShipId,items) and each item (int id,uint shipId,ulong systemAddress). No private ship names or identifiers are copied to public artifacts. complete=false deliberately describes published-cache scope, not an exhaustive current account/server response.
The independent NativeAOT fixture passed sixteen groups in eight successive calls, mask65535. It covers >2^53 addresses, exact body-to-system mask, original ordinal/current exclusion, duplicate preservation, capacity/owner/VT guards, loaded/unloaded current-ID branches, exact actor priority and no native writes. Report: artifacts/galaxy-fleet-native-tests/fleet-selftest.json. The test library is private and was never installed or started.
The unified runtime-neutral ledger imports/rechecks Fleet's ten complete function bodies, leaf slots, constructor references, actor dual-method table binding and four dynamic globals. At the Fleet stable point it accounted for266 source RVAs in333 mappings, with zero unresolved entries; the additional Mission bindings below extend that ledger. This does not approve a live hook or prove runtime cache freshness.
Mission: published original source, implemented
GMMissionListComponent.as and MissionButton.as use uidHigh/uidLow to form the true uint64 mission identity. Selection callback name OnGMMissionSelected is bound to 46C2410, which dispatches main MapUI+2E8 to 3A69D00. The original callback reconstructs (uint64(high)<<32)|low and searches both original manager sources; a row ordinal or a system address cannot replace this ID.
Original 5F53244 interface+70 returns the live mission-pointer vector. The callback reads each mission's +38 ID and +78 address list, then selects the final address. Its alternate +78 manager source is an open hash map of 0x88 summary records keyed by the actual mission ID. 20D1A00 extracts type22 structured-text values from those summaries, splits by the key's first character (default ':'), parses the first token as uint64 and returns addresses in source order. It must not parse unrelated mission text or use a mission ID as a location.
The original manager is ExternalPanelMissionList, registered at base+58 by 20E9C00, constructed by 208CD90. Its current guards are 525EE18/525EE48/525EF48 (original 525EE48/525EE78/525EF78). The pure interface+70 getter 1F28D0 returns iface+40, hence base98/countA8/vectorB0. Interface+78 returns baseC0: countC8/capacityD0/allocationD8. The allocation contains its original occupancy bitmap, then aligned 0x88 slots. Each occupied slot is [u64 MissionID,0x80 summary]; the summary's structured text is at slot+28, not a guessed address member.
Two original derived entries have been closed by their entire constructor/getter bodies and their actual vtable slots:
208E800installsMissionExternalPanelEntrymain52609F8 and interface5260A48 at object+1A8; current tables are 52609C8/5260A18. Original+38/20E1DC0 reads uint64 ID at iface-C0. Original+78/20D1C40 first extracts the structured text at iface-B0, then appends the address vector at iface-90. Full order and duplicate addresses matter.208EED0installsMissionFailedExternalPanelEntrymain5260BA8 and interface5260BF8 at object+118; current tables are 5260B78/5260BC8. Original+38/20E1DD0 reads ID at iface-40. Original+78/20D1E10 copies the existing vector at iface+E0. Failed does not mean the item must be hidden.
The real left list producer 3A8A190 traverses live entries backwards, obtains +B0 summary/+78 addresses and calls 3A3FFD0. This path does not apply the marker D8/E0 exclusion. 3A3FFD0 requires a nonempty first summary title field, then writes the original mission ID. Normal/failed +B0 use the original +10 getters with parameter1; these produce a nonempty $... resource string even when its optional raw key is empty. The adapter does not need to translate or publish that private title. Summary-only rows retain the original nonempty-title gate by inspecting only the existing string length. The second list passed to 3A8A190 is already materialized separately; the adapter therefore reports only the current published manager source and never asserts whole-account list completeness or the game's final locale-dependent sort.
The world marker path is separate: 3AFF080 emits marker45 for live rows whose +D8 is true or +E0 equals1. 20E0E60 emits ordinary marker4 for the complementary live rows and for summary rows. On a normal interface these getters read bytes at iface-27 and iface-20. The failed interface getters return false and2, so its world marker remains4. The adapter retains this original integer markerType; it does not infer a mission category from a name.
20D1A00 uses the identity getter233A70 and a 24-byte structured-text entry array at header+18/count+10. Only type22 entries are considered. Their key/value are original FGDK string references (length+0, UTF8 bytes+14). The first token is split at the key's first byte, default :. Original52D8F0 skips C whitespace and reads the leading decimal digits; later description/station text is not another address. The safe port rejects invalid, overflowing or non-system values rather than exporting a fabricated location or changing the final target. Typed-text addresses precede the normal entry's explicit address vector. The fallback summary uses typed text only. No vfunc, allocation, lazy initialization, mission acceptance, plot action or account request is invoked.
Navigation.GalaxyAccountMissions.cs returns GalaxyAccountMissions(tick,entity,items) and (ulong missionId,ulong[] systemAddresses,ulong? selectedSystemAddress) plus original markerType. Original callback has no proved zero/all-ones mission-ID sentinel: every u64 ID is retained. It searches reverse live IDs first, then the summary map, so the reader gives that live result precedence. It preserves full address arrays, duplicates and the true final address; empty arrays have null selected target. It rejects unknown entry tables, malformed occupancy/counts, more than4096 source/items/addresses, a per-string bound4096 bytes or copy budget8MiB instead of truncating. Final copied bytes, current owner/registry/type and entity are rechecked on the game owning thread. No private title, description or mission text enters its output. Source is original-external-panel-mission-list; complete=false remains explicit for empty or partial published caches.
The isolated NativeAOT test ran sixteen groups eight times: all65535, no game/network access. It covers >2^53 addresses, u64 IDs including0/FFFFFFFFFFFFFFFF, exact type22 extraction and delimiter/whitespace rules, ordered address appending, failed entries, marker4/45, live-over-summary precedence, nonempty summary title gate, empty/null target, owner/old-table/unknown/bounds rejection, malformed addresses, copy immutability and final byte stability. Report artifacts/galaxy-missions-native-tests/missions-selftest.json. Runtime freshness and exact visible translated list are not established by this fixture.
research/galaxy_missions_compatibility.py regenerates fleet-mission-sources/missions-compatibility.json from both actual PE files: nine whole matched bodies, seven constructor-bound tables, nine actual interface slots and the paired operand for unchanged dynamic ID5F53244. The unified mapping validator now includes and rechecks these original bindings. This remains runtime-neutral evidence, never a reason to loosen the client hash guard or to install hooks without separate live verification.