Original galaxy-map appearance evidence
All code evidence below belongs to the pinned 6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93 image at artifacts/ship-model-reference/client-copy/EliteDangerous64.exe. The installed Steam image changed on 2026-10-23; this document does not claim compatibility with that new image. All work was offline and read-only.
Original resource floats
research/Extract-OriginalGalaxyAppearance.py extracts the appearance configuration from original resource 86ec03fba621526059fc6812faca6f10adcb63cb, SHA256 29a90189d0bb238c88d09dcc0f15ff751ea29aa208b1a90894ef3b47f8942e5f. Its inflated frozen stream has SHA256 5135b3d55e5239b3d11f79a76adeda954eb78be5101b6a516fd25df257affa77.
The resolved original configuration is frozen pool 286, offset 6144, file offset 10612424. Multiple independent constructor/reference paths identify it: allegiance constructor 3AC56A0 reads +98, trade constructor 3AD86E0 reads +B8, exploration constructor 3AC4CF0 reads +A8, and security constructor 3AD0BF0 reads +D8. The Federation row at pool 411:6168 belongs to the allegiance table starting at 411:6144, referenced at configuration +98.
artifacts/galaxy-query-research/palette-resources/original-appearance.json contains the complete extracted floats, original string keys, pool positions and resource hashes:
| Offset | Meaning | Original layout |
|---|---|---|
| +28/+30 | Common palette | RGB float triples, 18 entries |
| +70/+74 | Population size endpoints | .3, 2.0 |
| +7C/+88 | Population RGB endpoints | (.07,.17,.26), (.53,.93,.26) |
| +98 | Allegiance | 5 named RGB entries, stride 24 |
| +A8 | Exploration data | 2 named RGB entries |
| +B8 | Trade data | 3 named RGB entries |
| +C8 | State | 27 named RGB entries |
| +D8 | Security | 4 named RGB entries |
| +E8 | Visited | 2 named RGB entries |
| +14C..184 | Colonisation | 5 inline RGB triples |
| +1E0 | Commodity direction | 5 entries, stride 32; name, ID, RGBA, integer |
| +1F0 | Civilisation | 4 named RGB entries |
Default map size is +1C=.7. Original HDR floats are preserved, including state stronghold R=100 and frontline G=2; SDR byte colours necessarily clamp them. There is no evidence supporting replacement by a cycling eight-colour palette.
Ordinary named entries are copied to map entry +20..2C; 3B134E0 and the government colour getter 3B26180 return these floats directly. Government constructor 3ACBCA0 increments palette offset by 12 and ID by one for IDs 0..17. Exact native names come from the static enumeration at 5E9E320. ID 18 Megaconstruction is outside that constructor's loop; wrapping it to palette zero is unsupported. Economy constructor 3AC41D0 copies RGB from actual definition rows +10..18; that separate source is now closed below.
Authored economy definition colours
Trace-OriginalGalaxyEconomyColours.py --verify verifies the original RootGalaxyMap type and all11 authored economy rows. Native1F47A0 supplies the RootGalaxyMap name at4DE07A0, its1C0-byte allocator and1AEA10 name registration. That helper installs factory vtable4DE0CA0; its+8 is1F1430, which uses the same allocator and invokes3AD0370. The lowercase type hash6E6841CD matches FRES recordD4648 [6E6841CD,10,647,590,3168]. Root647's component vector has309 entries; entry94 points to exactly that configuration.
Activation3B379A0 is the actual component+8 vtable552A410 slot60. Its configuration pointer is this+48 (=base50), and vector20/count28 holds11 named RGB rows of24 bytes. It converts the source name through3C42860, then copies RGB into the base198 runtime hash map. Economy interface552A5D0+20 returns that same table through978AF0; keyed getter3B136A0 reads row10/14/18. Finally3AC41D0 copies those values into the filter colour and explicitly writes alpha1. The source is not the common18-colour palette, and extra enum values do not wrap around it.
| Source name | Native ID | Raw RGB |
|---|---|---|
| None | 1 | (.4,.4,.4) |
| Extraction | 2 | (1,0,0) |
| Refinery | 7 | (1,.5,0) |
| Industrial | 4 | (1,1,0) |
| Agri | 3 | (.5,1,0) |
| Terraforming | 12 | (0,.6,0) |
| HighTech | 6 | (0,1,1) |
| Colony | 22 | (.2,.5,1) |
| Service | 5 | (0,.27,1) |
| Tourism | 20 | (.4,0,.9) |
| Military | 8 | (.9,0,.9) |
The extractor preserves exact float32 values/bytes and the original native IDs in palette-resources/original-economy-colours.json. The generator supplies these11 raw colours to both labels and the floating-point stellar path; the existing Agri→agriculture alias is explicit. Two tests exercise selected primary/secondary economy, source alpha and absent Repair/Rescue/Carrier/other rows. Missing authored rows remain unavailable. This recovers pinned configuration defaults, not a current live override snapshot.
Dual colour representation
3AC40B0 stores two RGB triples. With mode 1, the input is stored in the second triple (+0C), and 6CC950 transforms it into the first. Mode 0 performs the reverse using 6CCBE0. Constants returned by 6CC880 and 6CC890 are gamma=2.4 and offset=.055. This is a continuous sRGB-like transfer, with threshold a/(gamma-1) and the corresponding continuous linear slope, rather than an arbitrary RGB reorder. Power and colonisation use this representation. The final colonisation getter 3B26BD0 explicitly selects the second triple (+0C), i.e. the original resource RGB. Do not assume that every first triple or every output branch uses identical representation.
Exact star type colours and groups
research/galaxy_palette_code_tables.py reads the original static RGBA bytes at 5539360 and the 48 native type names at 5E9DBC0, selected by original name accessor 3C59A20. The output is palette-resources/code-tables.json.
Important native IDs are 9=TTS, 10=AeBe, 11=Y, 43=X, 44=Nebula, 45=RemnantNebula, 46=BigText, 47=NoSystem. A guess that places Y at 9 or supergiants at 43/44 disagrees with the original table.
The independent luminosity-name accessor 3C59990 selects table 5E9DAE0 by input index; complete entries are exported in code-tables.json.enumerations.luminosity. The original compact mask/shift is classification & 0x7C00, shifted right by 10. Native values are 0=O, 1=I, 2=Ia0, 3=Ia, 4=Ib, 5=Iab, 6=II, 7=IIa, 8=IIab, 9=IIb, 10=III, 11=IIIa, 12=IIIab, 13=IIIb, 14=IV, 15=IVa, 16=IVab, 17=IVb, 18=V, 19=Va, 20=Vab, 21=Vb, 22=Vz, 23=VI, 24=VII, 25=NoSystem, 26=ERROR. Thus I-family supergiants, II/III-family giants and IV-family subgiants can be distinguished from the independent spectral type; IDs 43/44 must not be repurposed for this.
Original star-class constructor 3AD2C70 builds these groups. Helper 3AE1220 chooses the group's actual RGBA from the native type palette, without assigning a new generated colour:
- IDs 0..8 individually; Y=11 individually.
- TTS/AeBe 9/10: palette type 9.
- Carbon family 17..24: palette type 18.
- Wolf-Rayet 12..16: palette type 12.
- White dwarfs 25..39: palette type 25.
- Non-sequence 40..43: palette type 40.
Realistic colour: read-only port
Physical vtable 552E718, slot +50, points to 3B26700. It obtains a live blend from its renderer handle and calls 3C415F0(compact,outRGBA,blend), then returns each packed byte multiplied by 1/255. 3C415F0 mixes the type palette with the original luminosity/subclass colour, quantising by truncation after the original float arithmetic.
3C3F5A0 reads compact classification ushort +40: type bits 0..5, subclass bits 6..9 (clamped to 9), luminosity bits 10..14. Prototype types TTS/AeBe use compact raw field +30 with two original temperature-bucket tables. 3C3F440 selects one of eight initialized global colour trees.
The original tree operator 3C284E0 inserts a zero-valued node on a miss. Calling it is therefore unsuitable for a read-only copy. Navigation.GalaxyAppearance.cs ports only the bounded exact-key traversal: root at tree+10, count+8, node type+1C, subclass byte+20, RGBA+2C, lower branch+8 and upper branch+0. Missing or malformed records yield nullable realistic colour and never insert a node.
Renderer type component ID is held at 5FA0A10. Constructor 3A06740 installs base vtable 551F2D8, base+8 551F308, main interface base+58 551F408, and type interface base+60 551F548. Registered component lookup returns the type interface. Main vtable +D8 is pure float getter 3A55CF0, which reads main+99C. Its default value is .11, but the adapter copies the current original value instead of assuming it is permanently static.
Realistic size
Physical vtable +48 points to 3B28090. It reads the original neutral raw uint field compact+34, multiplies it by 1/32768 and by configuration +38=1 for types below 40 and type 42, or +3C=1.4e-6 for type 40. Other types use epsilon 2^-23. It applies scalar natural logarithm 48B5BC0, clamps to configuration interval [-3,8], then normalises within that interval.
3B3E640 chooses output range [.3,1.2] or [.05,1.5]. It reads settings component 5F05DD4, vtable +158. Exact original implementation 552A9E8 uses getter 33D8280, movzx eax,byte[rcx+624];ret. Alternate vtable 552AE90 uses constant-true 201130. Both cases are supported without invoking them; an unknown implementation remains nullable.
Colonisation final colour
The category returned by 3B1A200 is not a palette index. Final 3B26BD0 selects:
- Group 0: source slot 0, grey.
- Group 1 (native status 5/6): source slot 3, red, alpha configuration +18C=.35.
- Groups 2/3/4 (native status 1..4): original CommanderID owner flag true selects slot 1 yellow, false selects slot 2 purple.
- An independently checked special candidate branch selects slot 4 green. Raw status 0 alone does not prove this branch.
An unknown owner must remain unknown; absence from a partial active-claim list does not by itself establish someone else's ownership.
Validation limits
The Core float path GalaxyMapFilter.GetOriginalRgba preserves the verified
raw table values, including Stronghold R=100, Frontline G=2 and actual Power
definition RGB above one. It never reconstructs those values from the SDR byte
label colour. Its nullable result distinguishes an unavailable source from an
explicitly transparent source. W is the actual source alpha multiplied once by
the independent filter opacity; territory geometry opacity is not a point alpha.
Packed original stellar colours retain their high-byte alpha. Unrecovered
extra-economy/tool palette entries and ambiguous colony ownership/special candidate
branches return null so the renderer can identify a fallback. Three focused
Core tests cover HDR, raw-versus-linear Power colours, packed alpha, unavailable
sources, selected service source and population/colony opacity. This API alone
does not certify the downstream GPU material or final image.
XFENavigationGalaxyAppearanceSelfTest expects mask 255. It covers original classification boundaries, exact type/subclass keys, no-write misses, cycle rejection, blend endpoints and quantisation, logarithmic size endpoints and special types, original luminosity group selection, and original temperature-bucket address expressions. The isolated production-source fixture passed all eight adapter groups at 255. These checks validate the port and its guard behaviour; they do not establish live original-game or visual equivalence. No game was running for this work.