@elite-dangerous-almanac/core 0.2.6 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/PROVENANCE/equipment/SOURCES.md +149 -27
  2. package/PROVENANCE/i18n/SOURCES.md +251 -40
  3. package/PROVENANCE/ships/SOURCES.md +232 -63
  4. package/README.md +21 -6
  5. package/THIRD_PARTY_NOTICES.md +4 -1
  6. package/dist/{chunk-AAU7OM47.js → chunk-2OBUSQA7.js} +1 -1
  7. package/dist/{chunk-AAU7OM47.js.map → chunk-2OBUSQA7.js.map} +1 -1
  8. package/dist/chunk-3GNYPM6J.js +1 -0
  9. package/dist/chunk-3GNYPM6J.js.map +1 -0
  10. package/dist/{chunk-A6OINYNP.js → chunk-3WGXGBW5.js} +1 -1
  11. package/dist/{chunk-ABSDZINM.js → chunk-5YEHJM6V.js} +1 -1
  12. package/dist/{chunk-ABSDZINM.js.map → chunk-5YEHJM6V.js.map} +1 -1
  13. package/dist/{chunk-7S7ZTZZY.js → chunk-7EWZGDWY.js} +1 -1
  14. package/dist/chunk-A7IVMYNF.js +1 -0
  15. package/dist/chunk-A7IVMYNF.js.map +1 -0
  16. package/dist/{chunk-KPJ77VPS.js → chunk-BJU27V6C.js} +1 -1
  17. package/dist/{chunk-KPJ77VPS.js.map → chunk-BJU27V6C.js.map} +1 -1
  18. package/dist/chunk-C3LLPLLD.js +1 -0
  19. package/dist/chunk-C3LLPLLD.js.map +1 -0
  20. package/dist/chunk-DAQ3PJ4R.js +1 -0
  21. package/dist/chunk-DAQ3PJ4R.js.map +1 -0
  22. package/dist/chunk-DHACRCLI.js +1 -0
  23. package/dist/chunk-DHACRCLI.js.map +1 -0
  24. package/dist/chunk-EHFHRQEP.js +1 -0
  25. package/dist/{chunk-LOWDDWDT.js.map → chunk-EHFHRQEP.js.map} +1 -1
  26. package/dist/{chunk-YCGISPDR.js → chunk-ETWMPMZP.js} +1 -1
  27. package/dist/chunk-FJIWJYKO.js +1 -0
  28. package/dist/chunk-FJIWJYKO.js.map +1 -0
  29. package/dist/chunk-GIGRBFIJ.js +1 -0
  30. package/dist/{chunk-MGRDB2BZ.js.map → chunk-GIGRBFIJ.js.map} +1 -1
  31. package/dist/{chunk-4CBMQULR.js → chunk-IMNOEFUE.js} +1 -1
  32. package/dist/{chunk-4CBMQULR.js.map → chunk-IMNOEFUE.js.map} +1 -1
  33. package/dist/chunk-IN36YSS4.js +1 -0
  34. package/dist/chunk-IN36YSS4.js.map +1 -0
  35. package/dist/chunk-IUSMAX5T.js +1 -0
  36. package/dist/{chunk-6GJHUWMO.js.map → chunk-IUSMAX5T.js.map} +1 -1
  37. package/dist/{chunk-XQJERZUS.js → chunk-JCYOE3C4.js} +1 -1
  38. package/dist/{chunk-XQJERZUS.js.map → chunk-JCYOE3C4.js.map} +1 -1
  39. package/dist/chunk-LWNBWRKL.js +1 -0
  40. package/dist/{chunk-B7EYTZRK.js.map → chunk-LWNBWRKL.js.map} +1 -1
  41. package/dist/chunk-M6J7KP7G.js +1 -0
  42. package/dist/chunk-M6J7KP7G.js.map +1 -0
  43. package/dist/chunk-MT5AHPNP.js +1 -0
  44. package/dist/{chunk-3CKWT2F3.js.map → chunk-MT5AHPNP.js.map} +1 -1
  45. package/dist/chunk-OLKOWR7S.js +1 -0
  46. package/dist/chunk-OLKOWR7S.js.map +1 -0
  47. package/dist/chunk-QJECDMQQ.js +1 -0
  48. package/dist/{chunk-LZYHBFJC.js.map → chunk-QJECDMQQ.js.map} +1 -1
  49. package/dist/chunk-SC4MEHVY.js +1 -0
  50. package/dist/chunk-SC4MEHVY.js.map +1 -0
  51. package/dist/chunk-T7IQHFQ2.js +1 -0
  52. package/dist/chunk-T7IQHFQ2.js.map +1 -0
  53. package/dist/chunk-W5ULI75F.js +1 -0
  54. package/dist/chunk-W5ULI75F.js.map +1 -0
  55. package/dist/chunk-WV7QCDL5.js +1 -0
  56. package/dist/chunk-WV7QCDL5.js.map +1 -0
  57. package/dist/{chunk-SDXUPP4P.js → chunk-XSLPWM5N.js} +1 -1
  58. package/dist/{chunk-S3MONE55.js → chunk-YJAH6DFY.js} +1 -1
  59. package/dist/chunk-YJAH6DFY.js.map +1 -0
  60. package/dist/chunk-ZZTDEDXJ.js +1 -0
  61. package/dist/{chunk-FA5JVXVG.js.map → chunk-ZZTDEDXJ.js.map} +1 -1
  62. package/dist/equipment/engineering.d.ts +53 -1
  63. package/dist/equipment/engineering.js +1 -1
  64. package/dist/equipment/index.d.ts +13 -2
  65. package/dist/equipment/index.js +1 -1
  66. package/dist/equipment/modification-journal.js +1 -1
  67. package/dist/equipment/modifications.d.ts +32 -9
  68. package/dist/equipment/modifications.js +1 -1
  69. package/dist/equipment/suits.d.ts +32 -2
  70. package/dist/equipment/suits.js +1 -1
  71. package/dist/equipment/upgrade-costs.js +1 -1
  72. package/dist/equipment/weapons.d.ts +16 -2
  73. package/dist/equipment/weapons.js +1 -1
  74. package/dist/i18n/index.d.ts +76 -0
  75. package/dist/i18n/index.js +1 -1
  76. package/dist/i18n/modules.d.ts +10 -7
  77. package/dist/i18n/modules.js +1 -1
  78. package/dist/i18n/personal-modifications.d.ts +68 -0
  79. package/dist/i18n/personal-modifications.js +1 -0
  80. package/dist/i18n/personal-modifications.js.map +1 -0
  81. package/dist/i18n/personal-weapons.d.ts +33 -0
  82. package/dist/i18n/personal-weapons.js +1 -0
  83. package/dist/i18n/personal-weapons.js.map +1 -0
  84. package/dist/i18n/pre-engineered.js +1 -1
  85. package/dist/i18n/suits.d.ts +59 -0
  86. package/dist/i18n/suits.js +1 -0
  87. package/dist/i18n/suits.js.map +1 -0
  88. package/dist/materials/index.js +1 -1
  89. package/dist/materials/micro-resources-all.js +1 -1
  90. package/dist/materials/micro-resources.js +1 -1
  91. package/dist/ships/blueprint-costs.js +1 -1
  92. package/dist/ships/blueprint-journal.js +1 -1
  93. package/dist/ships/build-metrics.js +1 -1
  94. package/dist/ships/engineering-options.d.ts +2 -2
  95. package/dist/ships/engineering-options.js +1 -1
  96. package/dist/ships/engineering.js +1 -1
  97. package/dist/ships/index.d.ts +5 -5
  98. package/dist/ships/index.js +1 -1
  99. package/dist/ships/loadout-calculations.d.ts +11 -2
  100. package/dist/ships/loadout-calculations.js +1 -1
  101. package/dist/ships/loadout-validation.d.ts +7 -2
  102. package/dist/ships/loadout-validation.js +1 -1
  103. package/dist/ships/modules-all.d.ts +2 -2
  104. package/dist/ships/modules-all.js +1 -1
  105. package/dist/ships/modules-core.d.ts +3 -3
  106. package/dist/ships/modules-core.js +1 -1
  107. package/dist/ships/modules-hardpoint.d.ts +1 -1
  108. package/dist/ships/modules-internal.d.ts +17 -6
  109. package/dist/ships/modules-internal.js +1 -1
  110. package/dist/ships/modules-utility.d.ts +1 -1
  111. package/dist/ships/modules.d.ts +14 -7
  112. package/dist/ships/modules.js +1 -1
  113. package/dist/ships/pre-engineered-stats.js +1 -1
  114. package/dist/ships/pre-engineered.js +1 -1
  115. package/dist/ships/shield-capacitor.js +1 -1
  116. package/dist/ships/ship-loadout.d.ts +71 -23
  117. package/dist/ships/ship-loadout.js +1 -1
  118. package/dist/ships/weapons.js +1 -1
  119. package/package.json +13 -1
  120. package/dist/chunk-3CKWT2F3.js +0 -1
  121. package/dist/chunk-3P455LF4.js +0 -1
  122. package/dist/chunk-3P455LF4.js.map +0 -1
  123. package/dist/chunk-5QSCLEEB.js +0 -1
  124. package/dist/chunk-5QSCLEEB.js.map +0 -1
  125. package/dist/chunk-6GJHUWMO.js +0 -1
  126. package/dist/chunk-B7EYTZRK.js +0 -1
  127. package/dist/chunk-C5HG4GJI.js +0 -1
  128. package/dist/chunk-C5HG4GJI.js.map +0 -1
  129. package/dist/chunk-DCB4COCL.js +0 -1
  130. package/dist/chunk-DCB4COCL.js.map +0 -1
  131. package/dist/chunk-E3AUKPSQ.js +0 -1
  132. package/dist/chunk-E3AUKPSQ.js.map +0 -1
  133. package/dist/chunk-FA5JVXVG.js +0 -1
  134. package/dist/chunk-GISL7YML.js +0 -1
  135. package/dist/chunk-GISL7YML.js.map +0 -1
  136. package/dist/chunk-KLC5XT6F.js +0 -1
  137. package/dist/chunk-KLC5XT6F.js.map +0 -1
  138. package/dist/chunk-LOWDDWDT.js +0 -1
  139. package/dist/chunk-LZYHBFJC.js +0 -1
  140. package/dist/chunk-MGRDB2BZ.js +0 -1
  141. package/dist/chunk-NBLLW7TH.js +0 -1
  142. package/dist/chunk-NBLLW7TH.js.map +0 -1
  143. package/dist/chunk-OJC6AUL7.js +0 -1
  144. package/dist/chunk-OJC6AUL7.js.map +0 -1
  145. package/dist/chunk-S3MONE55.js.map +0 -1
  146. /package/dist/{chunk-A6OINYNP.js.map → chunk-3WGXGBW5.js.map} +0 -0
  147. /package/dist/{chunk-7S7ZTZZY.js.map → chunk-7EWZGDWY.js.map} +0 -0
  148. /package/dist/{chunk-YCGISPDR.js.map → chunk-ETWMPMZP.js.map} +0 -0
  149. /package/dist/{chunk-SDXUPP4P.js.map → chunk-XSLPWM5N.js.map} +0 -0
@@ -1,33 +1,38 @@
1
1
  # Data sources — `data/equipment/`
2
2
 
3
+ ## Upstream snapshots this domain is pinned to
4
+
5
+ Referred to throughout by source name; the pin is here, once.
6
+
7
+ | Source | Pin | Acquired |
8
+ | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
9
+ | Odyssey Materials Helper | commit `2e6d4c3e767d2b714ffddc5c9386831d66812916` (2026-08-09), the last revision before the project extracted its core data into a separately distributed dependency | 2026-08-13 UTC |
10
+ | Frontier Elite Dangerous Gamestore | no immutable revision; the displayed weapon names were read on the acquisition date | 2026-08-13 UTC |
11
+ | Elite Dangerous in-game observation | no game version recorded; direct reading of the suit and weapon stats panels, the sight magnification they show, and the on-foot engineering options | 2026-08-31 UTC |
12
+
13
+ **Where a source and the game disagree, the in-game reading governs.** Odyssey Materials Helper
14
+ supplies the identities, the slot and grade structure, the engineer availability and
15
+ every material shopping list; the stat values are the ones the game itself shows.
16
+
3
17
  ## Personal suits, handheld weapons and engineering
4
18
 
5
19
  - **Files:** `suits.jsonc`, `weapons.jsonc`, `upgrade-costs.jsonc`,
6
20
  `modifications.jsonc`, `modification-costs.jsonc`,
7
21
  `modification-journal-names.jsonc`.
8
- - **Acquired:** 2026-08-13.
9
- - **Source:** Odyssey Materials Helper.
10
- - **Upstream revisions:**
11
- - Odyssey Materials Helper commit `2e6d4c3e767d2b714ffddc5c9386831d66812916`
12
- (2026-08-09), the last revision before the project extracted its core data into a
13
- separately distributed dependency.
14
- - Frontier Elite Dangerous Gamestore product pages have no immutable revision; their
15
- displayed weapon names were read on the acquisition date above.
16
22
  - **Derivation:**
17
23
  - `Suit.java` supplies the four suit families, journal symbols, weapon-slot counts and
18
- grade-dependent shield strength, shield regeneration, resistances and modification
19
- slots. English suit display names come from
24
+ the grade-dependent modification slots, shield strength and shield regeneration.
25
+ English suit display names come from
20
26
  `application/src/main/resources/locale/loadout/equipment.csv`. `family` removes
21
27
  `_class{grade}` from the grade-specific Frontier `symbol`; the exact symbol remains
22
28
  on every grade. Shield strength is in shield points, shield regeneration in shield
23
- points per second. The source's resistance percentage points are divided by 100 into
24
- fractions, matching the resistance convention used by the ships domain (`0.5` means
25
- 50% resisted).
29
+ points per second.
26
30
  - `Weapon.java` supplies the eleven handheld weapons, their exact journal symbols,
27
- class, slot, damage type, fire mode and combat stats. English weapon display names
28
- come from `application/src/main/resources/locale/loadout/equipment.csv`. Damage is
29
- per projectile or pellet, rate of fire is shots per second, effective range is
30
- metres, and the source's headshot percentages are divided by 100 into multipliers.
31
+ class, slot, damage type, fire mode, magazine size, headshot multiplier and effective
32
+ range. English weapon display names come from
33
+ `application/src/main/resources/locale/loadout/equipment.csv`. Damage is per
34
+ projectile or pellet, rate of fire is shots per second, effective range is metres,
35
+ and the source's headshot percentages are divided by 100 into multipliers.
31
36
  - `OdysseyBlueprintConstants.java` supplies each one-step suit and manufacturer-family
32
37
  weapon upgrade recipe, all engineer-applied modification recipes, and the engineers
33
38
  who offer them. Enum names are joined to the lower-case Frontier micro-resource
@@ -36,17 +41,134 @@
36
41
  the source's `karma`, `takada` and `manticore` identities; `engineeringType` separately
37
42
  records the `kinetic`, `laser` or `plasma` suffix used by modification recipes.
38
43
  - `SuitModification.java` and `WeaponModification.java` supply the journal symbols.
39
- English modification display names come from
40
- `application/src/main/resources/locale/loadout/modification.csv`; English engineer
41
- names come from `application/src/main/resources/locale/engineer/names.csv`. A recipe
42
- is keyed by its symbol rather than by a derived library id. Greater Range, Headshot
43
- Damage and Higher Accuracy retain their nine distinct Kinetic, Laser and Plasma
44
+ English engineer names come from
45
+ `application/src/main/resources/locale/engineer/names.csv`. A recipe is keyed by its
46
+ symbol rather than by a derived library id. Greater Range, Headshot Damage and
47
+ Improved Hip Fire Accuracy retain their nine distinct Kinetic, Laser and Plasma
44
48
  recipe symbols. The journal writes only three unsuffixed symbols, so
45
49
  `modification-journal-names.jsonc` records that collision once for resolution against
46
50
  the weapon. `modification-costs.jsonc` is split from recipe metadata so an identity
47
51
  lookup does not bundle every shopping list, matching the ships engineering boundary.
48
- - **Manual corrections:** Odyssey Materials Helper's English locale calls the four Karma
49
- weapons “Kinematic” and expands the three TK weapon names to “Takada”. The Frontier
50
- Elite Dangerous Gamestore confirms the in-game prefixes are `Karma` and `TK`, which are
51
- stored here. Frontier's misspelled `surveilleancelogs` symbol is kept verbatim so it
52
- joins to journal inventory data and the micro-resource catalogue.
52
+ - **In-game observation supplies every stat value** described in the three sections
53
+ below: the suit-wide component stats and the four resistances, the weapon combat
54
+ stats and damage, and the multipliers each modification applies.
55
+
56
+ - **Manual corrections:**
57
+ - Odyssey Materials Helper's English locale calls the four Karma weapons “Kinematic”
58
+ and expands the three TK weapon names to “Takada”. The Frontier Elite Dangerous
59
+ Gamestore confirms the in-game prefixes are `Karma` and `TK`, which are stored here.
60
+ - Frontier's misspelled `surveilleancelogs` symbol is kept verbatim so it joins to
61
+ journal inventory data and the micro-resource catalogue.
62
+ - Three modification display names are the in-game text rather than the source's:
63
+ `Faster Shield Regeneration`→`Faster Shield Regen`,
64
+ `Higher Accuracy`→`Improved Hip Fire Accuracy`, and `Stowed Reloading`→
65
+ `Stowed reloading`. The last keeps Frontier's own lower-case second word; it reads
66
+ like a typo and is not one, so do not "fix" it back.
67
+
68
+ ### Suit stats read in-game
69
+
70
+ The suit stats panel is read per suit family and per grade.
71
+
72
+ - **Suit-wide, identical at all five grades**, so they are stored once per family rather
73
+ than per grade: `health` (30 on every suit), `mass` (100 kg on every suit),
74
+ `batteryCapacity` in energy units, `oxygenTime` in seconds of emergency air,
75
+ `boostAcceleration` for the jump assist, the three backpack capacities
76
+ (`goodsCapacity`, `assetsCapacity`, `dataCapacity`), `footstepAudibleRange` as a
77
+ multiplier of the base audible range (1 on every suit), `losAnalysisRange` in metres
78
+ (50 on every suit) and `losAnalysisTime` in seconds (1 on every suit). The constant
79
+ ones are stored anyway: a suit-stats view reads them like any other field, and a value
80
+ that is the same everywhere is still the value.
81
+ - **Resistances are stored as fractions** (`0.5` means half the damage taken),
82
+ matching the ships domain. The panel's own figure is the same fraction as a
83
+ percentage, so a negative resistance is a weakness. Every resistance is now the
84
+ panel's, which corrects nine grade rows against Odyssey Materials Helper:
85
+
86
+ | Suit and grade | Field → stored value |
87
+ | ------------------- | ------------------------------------------------------------------------- |
88
+ | Artemis 1 | `thermalResistance` 0.39→0.4 |
89
+ | Artemis 2 | `kineticResistance` -0.42→-0.43; `plasmaResistance` 0→-0.01 |
90
+ | Artemis 3 | `plasmaResistance` 0.14→0.15 |
91
+ | Artemis 5 | `kineticResistance` 0.14→0.15; `plasmaResistance` 0.39→0.4 |
92
+ | Flight Suit | `thermalResistance` 0.39→0.4 |
93
+ | Dominator 4 | `kineticResistance` 0.19→0.11; `thermalResistance` 0.78→0.76; `plasmaResistance` 0.46→0.41; `explosiveResistance` 0.46→0.41 |
94
+ | Maverick 2 | `plasmaResistance` 0.07→0.08 |
95
+ | Maverick 3 | `kineticResistance` -0.13→-0.14 |
96
+ | Maverick 5 | `kineticResistance` 0.19→0.2 |
97
+
98
+ - **Shield strength and shield regeneration are unchanged.** Every stored value already
99
+ matches the panel, which is also why the resistance disagreements are read as source
100
+ rounding rather than as a different snapshot of the game.
101
+ - **A grade changes the armour, the shield generator, the modification slots and the
102
+ item symbol.** Nothing else on a suit moves with the grade, which is what makes the
103
+ suit-wide fields safe to store once per family.
104
+
105
+ ### Weapon stats read in-game
106
+
107
+ - **Rate of fire** is the panel's, correcting `Karma AR-50` 9.5→9.52,
108
+ `TK Aphelion` 5.7→5.71, `Manticore Oppressor` 6.7→6.67, `Manticore Intimidator`
109
+ 1.3→1.25, `Manticore Tormentor` 1.7→1.67, `Manticore Executioner` 0.8→0.833 and
110
+ `TK Zenith` 5.7→2.78. The Zenith is the one large disagreement and it is not a
111
+ rounding difference: it fires bursts, and 2.78 is the rate the panel shows.
112
+ - **Reserve ammunition** is the panel's, correcting `Karma P-15` 120→240,
113
+ `Karma AR-50` 200→250, `TK Eclipse` 280→315 and `TK Zenith` 90→180. It is the reserve
114
+ a stock suit carries, before the Extra Ammo Capacity modification.
115
+ - **Magazine size, effective range, class, slot, damage type and headshot multiplier**
116
+ are unchanged: every one already matches the panel.
117
+ - **Damage** is the grade-1 figure read in-game, times the grade multiplier the game
118
+ applies to it — `1`, `1.31`, `1.73`, `2.27`, `2.98` for grades 1 to 5. Each product is
119
+ taken in double-precision floating point and rounded to three decimals, as
120
+ `Number(x.toFixed(3))` does it; that reproduces all 55 stored figures exactly. The
121
+ rounding rule has to be stated rather than assumed, because twelve products land on a
122
+ half and are therefore broken in both directions, and because scaling before rounding
123
+ (`Math.round(x * 1000) / 1000`) re-introduces error and misses eight of the 55.
124
+ - **The multipliers are what Odyssey Materials Helper's own figures follow.** On the four
125
+ weapons whose grade-1 damage needed no correction — `Karma L-6`,
126
+ `Manticore Executioner`, `Manticore Tormentor` and `Manticore Oppressor` — its grades 2
127
+ to 5 sit within 0.05 of the same progression on 15 of those 16 rows, which is half of
128
+ one decimal — the most a figure rounded to one decimal can move. The exception is `Karma L-6` grade 4: 90.8 here, and
129
+ 90 in that source alone.
130
+ - **Every weapon's damage therefore changes**, and by more than rounding wherever the
131
+ grade-1 figure itself had been rounded: `Karma C-44` 0.6→0.65, `Karma AR-50` 1→0.95,
132
+ `TK Eclipse` 0.9→0.85, `Karma P-15` 1.4→1.38, `TK Aphelion` 1.6→1.572, `TK Zenith`
133
+ 1.7→1.668 and `Manticore Intimidator` 1.8→1.75. Damage is stored at the precision the
134
+ game reports it, which is why two of those grade-1 figures carry three decimals where
135
+ the panel shows one.
136
+ - **`scopeMagnification` is new**: the aim-down-sights magnification the panel shows with
137
+ the sight the weapon ships with, and with the sight the Scope modification fits, both
138
+ to two decimals. Scope stores no modifier of its own because its magnitude is this
139
+ pair, and it differs per weapon — `Manticore Executioner` gains 1.61x→3.75x where
140
+ `Manticore Intimidator` gains 1.08x→1.25x.
141
+
142
+ ### Modification magnitudes
143
+
144
+ Each recipe carries `modifiers`, the stat multipliers it applies. A modification is
145
+ applied in one step and has no grade or quality roll, so a modifier is a single factor
146
+ rather than the `[min, max]` band a ship blueprint feature carries, and `1` — a factor
147
+ that changes nothing — is never stored.
148
+
149
+ - **Enhanced Tracking effectively removes the analysis delay** rather than shortening
150
+ it proportionally: its factor on `losAnalysisTime` is `0.001`, which takes the 1 second
151
+ every suit needs down to a thousandth of one. It is recorded as the factor it applies,
152
+ like every other modifier.
153
+ - **A resistance factor multiplies the damage taken**, not the stored resistance
154
+ fraction. Damage Resistance is `×0.9` on damage taken, so a `0.5` resistance becomes
155
+ `0.55`. This is the same convention the ships domain uses for resistances.
156
+ - **`roundUp` marks the one result the game rounds up**: Magazine Size multiplies by 1.5
157
+ and rounds the magazine up to a whole number, so 45 rounds become 68 rather than 67.5.
158
+ - **Six recipes name a stat no catalogue field carries**, because the panel shows no
159
+ base for it: the melee damage, sprint duration and tool energy drain multipliers, the
160
+ reload speed, and the pressurised and unpressurised firing audible ranges. The factor
161
+ is recorded against the stat it moves; the base has to come from the panel.
162
+ - **Ten recipes carry an empty modifier list**, for two different reasons, and both are
163
+ a statement rather than a gap:
164
+ - Night Vision, Scope, Stowed reloading and Combat Movement Speed apply no factor to
165
+ any stat. Night Vision and Stowed reloading switch a capability on, Scope's whole
166
+ numeric effect is the weapon's own `scopeMagnification`, and Combat Movement Speed
167
+ changes how a suit moves while aiming without moving a displayed stat.
168
+ - Faster Handling, Improved Hip Fire Accuracy, Stability and Improved Jump Assist do
169
+ change stats, but ones the panel puts no number on — weapon handling, hip-fire
170
+ jitter and recoil, and the jump assist's boost drain and recharge. Improved Jump
171
+ Assist notably leaves the panel's Jump Assist Boost Acceleration exactly where it
172
+ was, so recording it against that field would be wrong.
173
+ - **Extra Ammo Capacity multiplies a weapon's `reserveAmmo`**, which is why the reserve
174
+ stored on a weapon is the stock figure and not an engineered one.
@@ -1,7 +1,9 @@
1
1
  # Localized game-name catalogues
2
2
 
3
- These catalogues keep the canonical English display names already published by the
4
- ships data domain and add only localized values carried explicitly by accepted sources.
3
+ These catalogues keep the canonical English display names already published by the ships
4
+ and equipment data domains and add only localized values carried explicitly by accepted
5
+ sources. Where a catalogue holds display prose rather than a name, the owning domain
6
+ publishes no English for it and all six values are the source's own.
5
7
  They are deliberately sparse: absence means that no accepted source carried a value, and
6
8
  the lookup API returns `null` for that locale rather than treating English as a
7
9
  translation.
@@ -23,24 +25,60 @@ tag follows the rule above, so `pt-PT` resolves to Brazilian Portuguese.
23
25
 
24
26
  ## `module-names.jsonc`
25
27
 
26
- - **Acquired:** 2026-08-14 UTC.
27
- - **EDDI revision:** commit `fdc1f47933bd930464610111fa11fc9dae264414`.
28
- - **EDSY revision:** commit `e446fbe6e4597dea7ab0bd3105b9a36642388040`;
29
- database version `424009901`, last-modified marker `20260810`.
30
- - **Derivation:** all 1,199 current module symbols and English names come from the four
31
- `data/ships/modules-*.jsonc` catalogues. EDDI's `ModuleDefinitions.cs` joins a symbol
32
- to a resource key; `Properties/Modules.resx` and its localized siblings supply names.
33
- An EDDI value is accepted only when its base English resource exactly equals the
34
- Almanac's canonical English name. This prevents broad EDDI families such as
35
- `CargoRack`, `MissileRack` and `PlanetaryApproachSuite` from erasing the distinct Mk II,
36
- seeker and advanced names the Almanac carries. EDSY's module `fdname` and effective
37
- `namekey` fill a missing `de`, `es`, `fr` or `ru` value only when EDSY's English
38
- module name also exactly equals the canonical name. Values shared by modules with one
39
- canonical name are retained only when they agree, then stored once under that name.
40
- - **Coverage:** English covers all 1,199 symbols. The explicit translations cover 1,120
41
- in German, 1,090 in Spanish, 1,088 in French, 1,155 in Brazilian Portuguese and 1,153
42
- in Russian. Portuguese comes from the same two joins, reading EDDI's
43
- `Modules.pt-BR.resx` and EDSY's `lang-pt.json`.
28
+ - **Acquired:** 2026-08-30 UTC.
29
+ - **In-game localisation revision:** none published; the game ships no immutable
30
+ identifier for its localisation tables. The acquired table is the evidence.
31
+ - **Derivation:** all 1,194 current module symbols and English names come from the four
32
+ `data/ships/modules-*.jsonc` catalogues, which stay authoritative for canonical
33
+ English. Each symbol joins case-insensitively to the in-game module localisation
34
+ identity, which carries a `name`, a `longname` and an `info` string per locale. The
35
+ join is exact and total: every one of the 1,194 resolves.
36
+ - **`longname` is the name taken.** It is the outfitting list's full name and equals
37
+ the canonical English on 1,041 of the symbols, where `name` the abbreviated panel
38
+ form equals it on 726. **Both totals were counted over the 1,199-symbol set that
39
+ preceded the removal of the five plain size-8 drives (§`data/ships/SOURCES.md`), and
40
+ are not re-derived here:** the in-game localisation table is not vendored, so whether
41
+ those five sat inside either total cannot be checked from this repository. Read them
42
+ as upper bounds over 1,194 symbols until the table is re-acquired. `name` is taken
43
+ only where a longname is a template rather than a name, which is the cargo racks,
44
+ fuel tanks and corrosion-resistant racks whose longname carries a capacity.
45
+ - **Aliasing is followed.** A localisation value may be a `$Other_Key;` pointer rather
46
+ than text; roughly three thousand of the keys are. Each is followed to the entry
47
+ holding real text before anything is stored, and a value still carrying a `$` token
48
+ after that is not a name and is rejected.
49
+ - **The `(Free)` vessel-hangar grants have no name of their own** — theirs is a
50
+ template wrapping the base hangar's. Their canonical English is already the base
51
+ module's, so they share its record.
52
+ - **The in-game table is authoritative over the EDDI and EDSY joins.** It carries 349
53
+ values absent from those registries and differs from them in 3,135 cells across 324
54
+ distinct record-and-locale pairs: 73 differ only in letter case, 10 only in punctuation
55
+ or accents, and 241 in wording. Many of the last are the game being specific where the
56
+ registries are general — Russian `Двигатели` is `Маневровые двигатели`, Brazilian
57
+ Portuguese `Propulsores` becomes `Propulsores de desempenho melhorado`.
58
+ - **The least abbreviated spelling is the one stored**, as it is in
59
+ `material-names.jsonc`. The outfitting panel shortens a label that will not fit, and
60
+ that is a rendering rather than a different translation, so where the panel abbreviates
61
+ the longest unabbreviated spelling available for that module and locale is taken
62
+ instead — the catalogue's own previous value where it had one, otherwise the source's
63
+ other field. French `Laser à impuls.` is stored as `Laser à impulsion`, Russian
64
+ `Разбрас-ль дип. отражателей` as `Разбрасыватель дипольных отражателей`. An
65
+ unabbreviated candidate is rejected when it is so much shorter that it is plainly a
66
+ different label rather than the same one spelled out: German `EGM` does not replace
67
+ `Elektr. Gegenmaßnahmen`. **Ten values remain abbreviated** because no source spells
68
+ them out — the Mk II gravity-optimised thrusters in four locales, the Advanced
69
+ Planetary Approach Suite in three, and three others — and there the alternative is a
70
+ bare `Schubdüsen` or `Propulseurs` that loses what distinguishes the module.
71
+ - **A rendered capacity or grant marker is not a name.** A longname may carry a module's
72
+ own capacity or a `(Free)` marker — `Anti-Korrosions-Frachtgestell (KAP.: 1)` — which
73
+ describes one module rather than naming the family, so it is rejected and the source's
74
+ other field is read instead.
75
+ - **One record per canonical English name.** Where the source distinguishes in another
76
+ locale what English spells the same way, the reading most symbols share is stored:
77
+ `Lightweight Alloy` and `Reinforced Alloy` are singular on 25 hulls and plural on the
78
+ rest, and the singular is kept, which is also the number the English carries.
79
+ `Hatch Breaker Limpet Controller` is specific on twenty symbols and generic on one, and
80
+ the specific is kept.
81
+ - **Coverage:** complete. All 1,194 symbols carry all six locales.
44
82
  - **Manual corrections:** none.
45
83
 
46
84
  ## `blueprint-names.jsonc`
@@ -84,10 +122,9 @@ tag follows the rule above, so `pt-PT` resolves to Brazilian Portuguese.
84
122
  - **Derivation:** each of the 86 current keys and its English name comes from
85
123
  `data/ships/experimental-effects.jsonc`, which stays authoritative for canonical
86
124
  English. The Frontier symbol joins to the in-game experimental-effect name table,
87
- which supplies every locale for all 86. The table replaces the EDSY join this
88
- catalogue previously used: where the two disagree the in-game value is kept, as
89
- everywhere else in this repository. It supplies six values EDSY did not carry — all
90
- five non-English `special_super_penetrator` names and the German
125
+ which supplies every locale for all 86. Where it and EDSY disagree, the in-game value
126
+ is kept, as everywhere else in this repository. It supplies six values EDSY does not
127
+ carry all five non-English `special_super_penetrator` names and the German
91
128
  `special_weapon_rateoffire` — and changes two EDSY already carried: German
92
129
  `special_regeneration_sequence` is "Regenerationssequenz" (EDSY
93
130
  "Regenerierungssequenz") and Brazilian Portuguese `special_lock_breaker` is "Quebra da
@@ -239,38 +276,212 @@ tag follows the rule above, so `pt-PT` resolves to Brazilian Portuguese.
239
276
  the in-game shop listing; no registry publishes them. The Brazilian Portuguese column
240
277
  was acquired 2026-08-30 UTC and agrees byte-for-byte with the five columns already
241
278
  stored, which it does not change.
242
- - **Coverage:** English covers every variant. Ordinary names inherit the explicit
243
- localized values available for their base module, which includes Brazilian Portuguese
244
- on 51 of the 76 variants; the Merc-shop names carry all six locales. Only the three
245
- `Decorative_*` fixed reward names have no accepted translation source, in any locale.
279
+ - **A tech-broker unlock may carry an unlock marker**, and 19 of them do — see
280
+ `data/ships/SOURCES.md`. Those names are not their base module's, so they do not reuse
281
+ its record. Where the marker is a manufacturer (`Sirius`, `Azimuth`) or a version
282
+ (`V1`) it is not a translatable word, so the localized value is that marker composed
283
+ with the base module's own localized name: German `Suchraketenrampe V1`, Spanish
284
+ `Sirius Lanzamisiles AX`. Composition can only reach as far as the base module does,
285
+ which is why `Frame Shift Drive (SCO) V1` has Brazilian Portuguese and Russian only and
286
+ `Azimuth Enhanced AX Multi-Cannon` lacks Spanish and French: those are the base
287
+ modules' own gaps, not new ones.
288
+ - **Six records carry a translation composed in this repository rather than taken from a
289
+ source, and are the only values in `data/i18n/` that are.** They are marked here
290
+ because the rest of this directory is explicit source values, and a reader is entitled
291
+ to know which is which. The game does not publish either phrase in a form this
292
+ repository can join to:
293
+ - The three `Modified` Guardian weapons. Unlike `Sirius`, `Azimuth` and `V1`, `Modified`
294
+ is a translatable word, so it cannot simply be composed with the base module's
295
+ localized name. Each locale's adjective agrees with the base noun it qualifies —
296
+ German `Modifizierter Guardian-Plasmalader` against `Modifizierte Guardian-Gausskanone`,
297
+ Russian `Модифицированная пушка Гаусса` against `Модифицированное осколочное орудие`.
298
+ - The three `Decorative_*` festive launchers. The game does not translate their names,
299
+ so `Festive` and the colour are rendered in each locale and qualify the base module's
300
+ own localized name.
301
+
302
+ Replace any of the twelve with a source-backed value the moment one is published.
303
+ - **Coverage:** English, Brazilian Portuguese and Russian cover every variant. Ordinary
304
+ names inherit the explicit localized values available for their base
305
+ module; the Merc-shop names carry all six locales. The German, Spanish and French gaps
306
+ that remain are their base modules' own — the SCO drive and the Enhanced AX
307
+ Multi-Cannon carry no value in those locales for composition to build on.
246
308
  - **Manual corrections:** none.
247
309
 
310
+ ## `suit-names.jsonc`
311
+
312
+ - **Acquired:** 2026-09-01 UTC.
313
+ - **In-game localisation revision:** none published; the game ships no immutable
314
+ identifier for its localisation tables. The acquired table is the evidence.
315
+ - **Derivation:** the four suit families and their canonical English names come from
316
+ `data/equipment/suits.jsonc`, which stays authoritative for canonical English. Each
317
+ family's grade symbols join case-insensitively to the in-game suit localisation
318
+ identity, which carries a `name`, a `longname` and an `info` string per locale. The
319
+ join is exact and total: all 16 grade symbols resolve.
320
+ - **`name` is the value taken.** It is the suit's own name and equals the canonical
321
+ English on all four families.
322
+ - **The manufacturer is not part of the name.** `longname` prefixes one —
323
+ `Remlok Maverick Suit`, `Supratech Artemis Suit`, `Manticore Dominator Suit` — which
324
+ names a Pioneer Supplies listing rather than the suit, so it is rejected the way a
325
+ rendered capacity is in `module-names.jsonc`. The brand is a proper noun the game
326
+ leaves in English in every locale, so composing it back on costs nothing but the
327
+ name it would displace.
328
+ - **A suit is named per family, not per grade.** Every grade of a family carries
329
+ byte-identical values in all six locales, so one record is stored per family and
330
+ `nameKeys` maps the family id and every grade symbol onto it. Both forms a consumer
331
+ holds therefore resolve: `Suit.family` and the `utilitysuit_class3` a journal line
332
+ writes. The flight suit has a single grade whose symbol *is* the family id, so the four
333
+ families and 16 grade symbols make 19 distinct identifiers rather than 20.
334
+ - **Coverage:** complete. All 19 identifiers carry all six locales.
335
+ - **Two suits are not stored**, because `data/equipment/suits.jsonc` does not carry them:
336
+ the five `specialistsuit_class{1..5}` grades, which the source does name
337
+ (`Specialist Suit`, listed as `Remlok Paragon Specialist Suit`), and `hyperspacesuit`,
338
+ which carries no text at all. Storing a name for equipment no catalogue owns would
339
+ leave a lookup answering for something the library cannot otherwise describe.
340
+ - **Manual corrections:** none.
341
+
342
+ ## `suit-descriptions.jsonc`
343
+
344
+ - **Acquired:** 2026-09-01 UTC.
345
+ - **In-game localisation revision:** none published; the game ships no immutable
346
+ identifier for its localisation tables. The acquired table is the evidence.
347
+ - **Derivation:** the same four families and the same identifier set as
348
+ `suit-names.jsonc`, joined to the `info` string of the in-game suit localisation
349
+ identity. All six values, English included, are the source's verbatim: the owning
350
+ catalogue publishes no description for a suit, so there is no canonical English here
351
+ to be authoritative for.
352
+ - **This is display prose, not the suit's stats.** `data/equipment/suits.jsonc` answers
353
+ what a suit does — shield strength, battery capacity, the four resistances — and the
354
+ description answers what it is for, naming no figure at all. Neither is projected onto
355
+ the other.
356
+ - **Coverage:** complete. All 19 identifiers carry all six locales, and every grade of a
357
+ family shares its record exactly as in `suit-names.jsonc`.
358
+ - **The Specialist Suit grades carry no description at all**, which is a second reason
359
+ they are absent here beyond the owning catalogue not carrying them.
360
+ - **Manual corrections:** none. The English keeps the source's own mixed apostrophes
361
+ (`Manticore's`, `a user’s`); they are the game's prose and are stored as published.
362
+
363
+ ## `personal-weapon-descriptions.jsonc`
364
+
365
+ - **Acquired:** 2026-09-01 UTC.
366
+ - **In-game localisation revision:** none published; the game ships no immutable
367
+ identifier for its localisation tables. The acquired table is the evidence.
368
+ - **Derivation:** all 11 current weapon symbols come from `data/equipment/weapons.jsonc`.
369
+ Each joins case-insensitively to the in-game weapon localisation identity and takes its
370
+ `info` string; the join is exact and total. All six values, English included, are the
371
+ source's verbatim, because the owning catalogue publishes no weapon description.
372
+ - **No sibling name catalogue exists**, and that is a decision rather than a gap — see
373
+ §Names this repository deliberately does not localize.
374
+ - **Coverage:** complete. All 11 weapons carry all six locales.
375
+ - **Two entries the source carries are not stored:** `wpn_h_launcher_rocket_sauto`
376
+ (`Karma HL-9`), the heavy rocket launcher no current catalogue owns, and
377
+ `wpn_m_submachinegun_kinetic_burst`, which the table lists with no text at all.
378
+ - **Manual corrections:** none.
379
+
380
+ ## `personal-modification-names.jsonc`
381
+
382
+ - **Acquired:** 2026-09-01 UTC.
383
+ - **In-game localisation revision:** none published; the game ships no immutable
384
+ identifier for its localisation tables. The acquired table is the evidence.
385
+ - **Derivation:** all 31 recipe symbols and their canonical English names come from
386
+ `data/equipment/modifications.jsonc`, which stays authoritative for canonical English.
387
+ A symbol joins case-insensitively to the in-game modification identity as
388
+ `humanoidmod_<symbol>`, which carries a `name` and a `description` per locale.
389
+ - **The nine technology-specific recipes share the entry the game publishes.** Greater
390
+ Range, Headshot Damage and Improved Hip Fire Accuracy are one engineering option each
391
+ in game; this repository keys the Kinetic, Laser and Plasma recipes separately because
392
+ their material costs differ (§`data/equipment/SOURCES.md`). The `_kinetic`, `_laser`
393
+ and `_plasma` suffix is dropped before the join, so each of the three takes its generic
394
+ entry's locales — exactly as a shadowing blueprint id takes its generic's in
395
+ `blueprint-names.jsonc`. 25 distinct source entries therefore cover all 31 recipes, and
396
+ the catalogue stores them once each: `nameKeys` maps a recipe symbol onto the entry the
397
+ game publishes, as `module-names.jsonc` maps a module symbol onto a shared name.
398
+ - **That shape is about visibility, not bytes.** Storing each shared entry three times
399
+ instead costs about the same, because the six duplicate name records weigh roughly what
400
+ the 31-entry `nameKeys` map does; the descriptions save about a fifteenth. What the
401
+ deduplicated form buys is that the sharing is stated in the data, rather than sitting in
402
+ six duplicate records a later edit could silently pull apart.
403
+ - **`Headshot Damage` is the one English value the game spells differently.** The in-game
404
+ menu reads `Headshot damage`; the owning catalogue's canonical `Headshot Damage` is
405
+ kept, as canonical English is kept everywhere in this directory. The lower-case
406
+ `Stowed reloading` the owning catalogue already carries *is* the game's own spelling
407
+ and agrees with it.
408
+ - **Coverage:** complete. All 31 recipes carry all six locales.
409
+ - **One in-game modification is not stored:** `humanoidmod_suit_headshotresistance`
410
+ (`Increased Helmet Protection`), which `data/equipment/modifications.jsonc` does not
411
+ carry as a recipe.
412
+ - **Manual corrections:** two German names are the engineering panel's own layout rather
413
+ than translations. `Kampf-Bewegungs-geschwindigkeit` and `Geräusch-unterdrückung` break
414
+ a compound word mid-noun, leaving a lower-case second half no German spelling has. The
415
+ whole word is kept in each, as it is for the wrapped consumables in
416
+ `micro-resource-names.jsonc`: `Kampfbewegungsgeschwindigkeit` and
417
+ `Geräuschunterdrückung`.
418
+
419
+ ## `personal-modification-descriptions.jsonc`
420
+
421
+ - **Acquired:** 2026-09-01 UTC.
422
+ - **In-game localisation revision:** none published; the game ships no immutable
423
+ identifier for its localisation tables. The acquired table is the evidence.
424
+ - **Derivation:** the same 31 recipe symbols as `personal-modification-names.jsonc`,
425
+ joined the same way and sharing the generic entry across the nine technology-specific
426
+ recipes for the same reason. Each takes the identity's `description` string. All six
427
+ values, English included, are the source's verbatim.
428
+ - **This is display prose, not the recipe's magnitudes.** The game says a modification
429
+ "allows more ammo to be carried for each weapon" and never how much more; the
430
+ `modifiers` list in `data/equipment/modifications.jsonc` is what states the multiplier,
431
+ and the two are deliberately different strings. It is also the only account of the ten
432
+ recipes whose `modifiers` list is empty — some switch a capability on, the rest move a
433
+ stat the panel puts no number on (§`data/equipment/SOURCES.md`).
434
+ - **Coverage:** complete. All 31 recipes carry all six locales.
435
+ - **Manual corrections:** none. The French
436
+ `weapon_backpackreloading` description keeps the non-breaking space the source sets
437
+ between a figure and its unit (`5 secondes`), which is French typography rather than
438
+ layout.
439
+
248
440
  ## Names this repository deliberately does not localize
249
441
 
250
- Three catalogues were removed rather than completed, because the game does not translate
251
- what they held and storing English under five more keys said otherwise.
442
+ No catalogues are stored for the following names, either because the game does not
443
+ translate them storing English under five more keys would say otherwise — or because no
444
+ record in this repository is keyed by them.
252
445
 
253
446
  - **Ship names and manufacturers.** Odyssey Materials Helper and EDSY each publish a
254
447
  per-locale ship column, and every value either one publishes is byte-for-byte the
255
448
  canonical English name: a hull name is a proper noun the game leaves alone, and so is
256
- a manufacturer's. No source publishes a localized manufacturer label at all. A lookup
257
- that can only ever answer in English is not a translation lookup, so `getShipName` and
258
- `getShipManufacturer` are gone; `data/ships/ships.jsonc` carries both strings and stays
259
- the one place to read them.
449
+ a manufacturer's. No source publishes a localized manufacturer label at all.
450
+ `data/ships/ships.jsonc` is the one place to read both strings.
260
451
  - **Engineering-group labels.** An engineering group is this repository's own partition
261
452
  of the modules that share one menu; the game heads that menu with the module's
262
- outfitting family and publishes no group label of its own. The EDSY `mtype-*` values
263
- previously stored here were outfitting labels reached by a name join, which is why they
264
- disagreed with `module-family-names.jsonc` in 22 places on wording. A group therefore
453
+ outfitting family and publishes no group label of its own. EDSY's `mtype-*` values are
454
+ outfitting labels reached by a name join and disagree with
455
+ `module-family-names.jsonc` in 22 places on wording. A group therefore
265
456
  carries no name at all — see the header of `data/ships/engineering-options.jsonc` — and
266
457
  a consumer names one by joining a module's `familyId` to `module-family-names.jsonc`.
458
+ - **Handheld personal-weapon names.** The in-game weapon localisation table publishes all
459
+ six locales for every one of the eleven weapons, and each of the 55 non-English values
460
+ is byte-for-byte the English: `Karma P-15`, `TK Aphelion` and `Manticore Executioner`
461
+ are product names the game leaves alone, exactly as it does a hull's. `PersonalWeapon`
462
+ in `data/equipment/weapons.jsonc` is the one place to read the name; the weapons'
463
+ *descriptions* are prose and are localized, in `personal-weapon-descriptions.jsonc`.
464
+ - **Personal-equipment manufacturers.** `Supratech`, `Remlok`, `Manticore` and
465
+ `Kinematic Armaments` are byte-for-byte identical in all six locales wherever the game
466
+ names them, which is why `suit-names.jsonc` stores a suit's own name and not the
467
+ outfitting list's manufacturer-prefixed listing.
468
+ - **Suit and weapon stat labels, the on-foot loadout panel's row labels, and engineer
469
+ dialogue.** These are the second reason rather than the first: the game does publish all
470
+ six locales for each, and none of them names a record in any catalogue here. A stat
471
+ label names a field of `Suit` or `PersonalWeapon`, a row label names a line of the
472
+ on-foot loadout panel, and an engineer's line is spoken flavour attached to an offer.
473
+ Storing them would mean inventing keys this repository does not otherwise own, so a
474
+ consumer that needs a field label supplies its own. **This is not the ship slot and
475
+ restriction gap of [#320](https://github.com/DarkSession/Elite-Dangerous-Almanac/issues/320)**,
476
+ which is about labels no source translates at all.
267
477
 
268
478
  ## Known gaps
269
479
 
270
480
  Localized coverage follows the accepted sources and is not complete for every catalogue or
271
- stored locale. A language absent from all eight catalogues is the locale decision
481
+ stored locale. A language absent from all thirteen catalogues is the locale decision
272
482
  recorded above rather than a gap. The accepted sources carry only canonical English for
273
483
  19 of the 77 outfitting-family labels, slot and restriction labels, fixed reward names,
274
- and structured loadout, calculation, SLEF and edit messages. Missing source-backed
275
- translations remain tracked by
484
+ and structured loadout, calculation, SLEF and edit messages. Personal equipment carries
485
+ no gap: every suit, handheld weapon and modification the owning catalogues hold is
486
+ complete in all six locales. Missing source-backed translations remain tracked by
276
487
  [#320](https://github.com/DarkSession/Elite-Dangerous-Almanac/issues/320).