Original selected-commodity balance cache
Pinned source SHA256:
6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93.
All functions are read from the saved image; no game setter, request, lookup or
reference-counting method is invoked by the adapter.
Source and current-version bindings
Original registration 1E2A720 exposes interface object+58 by dynamic type
5F7E844. Constructor 1DD2B60 finally installs main/secondary/interface tables
5241FB0/5241FF0/52420F0. Independent full-body and bound-slot comparison with
the current ED5A image gives 5241F80/5241FC0/52420C0; the type global remains
5F7E844. The sidecar commodity-tree/compatibility.json now includes twenty-four
complete functions, seventeen bound virtual slots and two name/category leaves.
This extends the commodity options source evidence; it does not relax the client
hash or runtime table/owner checks.
Exact cached inputs
All following offsets are relative to the registered interface, not the base.
| Field | Evidence | Meaning |
|---|---|---|
| +E8 pointer | selected-definition setter 1E4D5E0 |
Original actual definition instance |
| +F0 int | same setter, original enum lookup +28 | Zero clears the selected definition; a valid bound source has nonzero value |
| +F8 hash | getter +78 is EBDF50, lea rax,[rcx+F8] |
SystemAddress → signed float balance |
| +E0 bool, +2C0 count | ready getter +30 1DF3590 |
Ready only when bool is true and pending count is zero |
| +140 bool | setters 1E4D5E0/1E59760, original tick |
Cache dirty after selection/config changes |
| +144 uint | rebuilder 1E6BC80 |
Local cache revision, incremented before synchronous rebuild |
The selected definition is bound to a UID by exact instance identity in the
actual ready definition map (node+10 equals the selected pointer). Its real map
key supplies the UID. No Market ID, row number or fallback name hash supplies it.
The original 1B390F0 does compute an ASCII lowercase DJB2 name key for its own
lookup, but the read-only adapter still requires the actual definition entry.
1E6BC80 clears base+150/interface+F8, increments base+19C/interface+144 and
rebuilds the float map on the original owning thread. The copy publishes rows
only when the original ready predicate is true and dirty is false, preventing
an old selection's rows from being attached to a newly selected UID. Pending
sources retain the known UID/revision but return no publishable rows. Every
copied field, map bucket, node, name and source binding is rechecked for byte
stability. Current account registry, entity, owner, thread and 500ms snapshot
guards apply to the runtime entry point.
The system hash is the original 64-bit multiply/xor sequence used in
3B27B00. Each positive address, bucket assignment, uniqueness, count and chain
is checked. A stored float zero is real data; a missing row stays unknown.
Nonfinite values, malformed chains and counts are rejected. No absent address
is converted to zero balance or a negative availability fact.
Complete context-bound original classification
3B27B00 additionally requires the original filter's position/range, pending
flag and actual ready generic system descriptor. 3AF45E0 clears its pending
flag only after the source's +30 ready getter succeeds. The +58 method
1E31A90 forwards its caller's RDX address to the original neighbourhood
provider +38, then enumerates actual nearby rows and submits them through +18;
it is not a simple address field setter. These mutating routines are never
called by the tool. Navigation.GalaxyCommodityFilter.cs now independently binds
the real Main/filter context before classifying a requested original UID. The raw
cache reader remains separate and cannot by itself prove an original result.
Original registry type 5F05DB4 supplies Main interface base+80. The paired
current-version Main constructor proves filter instance base+3E0; its current
vtable is 552D9C8, its config+10 must equal Main base+50, selected UID+D0 must
equal both request and the actual balance definition UID, and pending+138 must
be zero. The filter's native centre floats are +78/+7C/+80 and its actual config
range +1D8 is40. Catalogue XYZ is relative to the galaxy origin; the classifier
adds GalaxyServices origin/32 before the original strict distance<40 test.
The original generic lookup returns hash-node+10; this predicate requires
returned+30, node+40, to be non-null. Trade's metadata status at node+30 is a
different field and is not reused as commodity readiness.
Verified classifier rules: positive balance → Import, negative → Export; PriceMode1 excludes Export, mode2 excludes Import, modes0/3 allow both signs. Stored zero selects ImportNothing, or ExportNothing for mode2. Actual config minimum/midpoint/maximum opacity is .25/.5/1, interpolated over absolute balance0..0.5..1 and clamped at the upper endpoint. Final RGBA multiplies the original row alpha by this opacity once. Inside a ready valid scope, a missing cache row takes original None with size .5; ordinary and Nothing size are1. Outside the strict range or with a known null descriptor, opacity and size are0. Missing/invalid metadata, unavailable source, mismatched UID and pending state remain unknown, not None. Exact original palette rows supply raw HDR RGBA and sprite12/11/12/11/13 for categories0..4.
The adapter uses the existing GalaxyServices and GalaxyFilterContext, checks
the original registry/account/entity, owner thread and500ms freshness, and rechecks
every source pointer, pending flag, selected UID and balance revision. It only
reads the existing original caches. It does not change CommodityIndex or call
the original neighbourhood subscriber to make another source available.
Read-only rebuild for another actual UID
Navigation.GalaxyCommodityRebuild.cs ports the actual 1E6BC80 synchronous
calculation over its copied all-commodity inputs. Original raw JSON parser
1E369C0 proves a systems→markets vector and each market's full commodities
dictionary, rather than a response containing only the currently selected item.
The ready enumeration row provides both float32 cost_mean at node+C and
integer JSON id at+10. Getter 1E102E0 returns MOVSS→XMM0; interpreting its
Ghidra undefined4 as uint would be incorrect. Getter+28 supplies the actual
market id. No Market.json ID, name hash or UID-as-index guess supplies either.
The existing registered source must have a valid selected definition, matching original filter selection, ready=true, pending count0, dirty=false, and a stable revision. For a different requested actual UID, the pure reader verifies its real enumeration/definition identity, then replays the original calculation:
- Raw source base+118 holds system nodes, whose actual32-byte market rows are at
node+48/count+40. Base+F8 holds market nodes with the original sparse commodity
table.
B1F390proves occupancy bitmap, aligned row base and linear probing. - The real enumeration
idaddresses16-byte quote records{id,buy,sell,flags}. Original surface, large-pad and maximum-distance conditions are retained. - Per-system best buy/min and sell/max, global min/max and float mean determine the original signed normalized balance. Each denominator is at least1, ties select buy/negative, and a selected nonzero branch has magnitude at least.01.
- The original creates a system temporary for an allowed actual market even if that commodity is missing or the quote is ignored/illegal. Such a temporary can produce actual zero/Nothing. A missing market or all stations excluded can instead leave no balance row. This rule applies only within the ready original cache, never to an absent public station report.
Source ready/dirty/pending/revision and enum/definition identity are rechecked; the private copied result does not change the game's selected UID or balance map. The original centre/40ly/descriptor/classification/style gates still apply. This removes the earlier requirement that the tool's chosen UID equal the game's current UID, while making no claim about uncached neighbourhoods or complete world market coverage. The runtime facts/wire/Core contract stays unchanged.
XFENavigationGalaxyCommodityRebuildSelfTest expects255 across eight independent
groups: per-system and global normalization, multiple markets, readonly copies,
surface/pad/distance gates, real collision+wrap probing, missing/illegal/zero
quotes, malformed bitmap/NaN/id, source identity changes and exact0/high-bit UID
bindings. Parent's isolated Native release passed480 unified invocations after
adding this adapter. The compatibility sidecar additionally binds full raw parser
and sparse lookup functions. Duplicate enum getters are tied to their already
proven vtable+20/+28, comparing both return branches through the first INT3,
rather than accepting an ambiguous global signature or truncating at first RET.
Core and application boundary
Capability galaxyCommodityFilterFacts gates the existing owning-thread facts
queue. Request fields are includeCommodity, numeric uint commodityUid, and
commodityPriceMode0..3. Every requested row echoes UID/mode even when unknown;
unknown revision/category/opacity/size/sprite/rgba are allnull. Core rejects wrong
UID/mode, partial styles, invalid values and mixed revisions across pages, then
releases the queue. The current PID/FID/origin/generation guards apply before VM
publication; the whole runtime source is excluded from disk persistence.
GalaxyMapFilter resolves one selected actual UID only through the live original
options. A matching native category0..3 is a target; category4 None is a known
non-target even when unknown display is enabled. Unknown original facts cannot be
replaced by public station presence or saved query proofs. Modes0 and3 retain
distinct requests and QueryKeys despite both allowing both directions. Original
commodity size is independently selectable through saved commodity selection.
Actual original RGBA preserves HDR and source alpha through GetOriginalRgba;
opacity is applied exactly once. Tool multi-selection/public supply-demand queries
remain separately identified and do not pretend to be the original regional filter.
An unresolved saved CommodityIndex is itself a pending original selection. It
does not run a previous public value or a different UID with the same displayed
name. Its pending UID/mode is part of QueryKey; it stays unknown until actual
definitions resolve it or a manual selection clears the pending original UID.
Actual published price choices
Original 3A3D910 publishes three, rather than four, radio rows. Its explicit
UID setters are0,1,2, paired respectively with the pinned-image strings at
5523748, 5523788, 55237C8:
| UID | Exact original key | Observed original Chinese text |
|---|---|---|
| 0 | GALAXY_MAP_COMMODITY_PRICE_MODE_IMPORT_EXPORT | 进口/出口价格 |
| 1 | GALAXY_MAP_COMMODITY_PRICE_MODE_IMPORT | 进口价格 |
| 2 | GALAXY_MAP_COMMODITY_PRICE_MODE_EXPORT | 出口价格 |
GMCommodityFiltersComponent.validate selects a matching published row, otherwise
the first. Saved mode3 is accepted by the original classifier as both directions
but is not a fourth published radio choice. The Panel follows the three actual
rows in their original order. Importing3 retains that raw mode/request and shows
the first row without mutating it; a later user selection supplies actual0/1/2.
No invented additional semantic label is exposed for3. Text provenance is the
previously recorded all-text-private.json localisation resource.
Tests and status
XFENavigationGalaxyCommodityBalanceSelfTest expects255 across eight independent
fixture groups: exact UID and >2^53 system address, positive/negative/zero values,
no writes, loaded/dirty/pending source transitions, mismatched definition/owner,
cycle and nonfinite rejection, UID0/high-bit identity, a real empty cache, and
immutable revision snapshots. Native unified compilation/check results are
reported by the parent integration task. XFENavigationGalaxyCommodityFilterSelfTest
also expects255: real context/UID binding, nonzero galaxy origin, all four modes,
Nothing/None, descriptor versus Trade status, exact40ly boundary, signed zero,
pending/dirty transitions, immutable revision and no-write checks. Parent unified
Native checks initially passed472 invocations with the corresponding wire fixture;
the read-only arbitrary-UID rebuild subsequently passed the480-invocation release.
Core named-pipe and filter regressions in NativeGalaxyCommodityFilterFactsTests
and GalaxyOriginalCommodityFilterTests cover exact0/high-bit UIDs, >2^53 addresses,
bound unknown, wrong echo/partial style cleanup, mixed revisions, strict matching,
HDR/alpha/sprite/independent-size, PID/FID/origin clearing, disk exclusion and reuse
of unchanged instances. Galaxy217/217 passed; the Test project compiled with zero
errors (nine existing warnings). The pending-UID regression subsequently brought
the Galaxy total to218/218; see commodity-pending-uid-build.txt and
commodity-pending-uid-tests.txt. Initial logs are
artifacts/galaxy-query-research/commodity-filter-core-build.txt and
commodity-filter-galaxy-tests.txt. These fixtures are not a live original-game
or final visual acceptance claim.