Skip to content
This repository was archived by the owner on Aug 31, 2026. It is now read-only.

Commit 329ece8

Browse files
committed
fix: a partially specified galaxy type inherits the stock spiral
- the galaxyType reader's defaults were a stale copy of it - a pack writing one attribute got a 900 ly "spiral" - defaults now read off GalaxyGenConfig.stockSpiral() - weight stays 1: an unweighted type is the rarest
1 parent cd6a84b commit 329ece8

3 files changed

Lines changed: 58 additions & 9 deletions

File tree

‎src/main/java/zmaster587/advancedRocketry/universe/GalaxyGenConfig.java‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,24 @@ private static List<StarType> defaultStarTypes() {
256256
* The stock galaxy table. Weights are the real abundance ordering — dwarfs outnumber giants by two
257257
* orders — so a spiral is something a player FINDS rather than the default sky.
258258
*/
259+
/**
260+
* The stock SPIRAL archetype — the type every partially-specified {@code <galaxyType>} inherits
261+
* its unwritten attributes from.
262+
*
263+
* <p>It exists so those defaults are not a second copy of the numbers below. They were, and the
264+
* copy went stale the moment the galaxy scale moved: a pack writing
265+
* {@code <galaxyType thickness="0.05"/>} got a "spiral" 900&ndash;2 200 ly across, an order and a
266+
* half under every real one, silently and only in the authored path.</p>
267+
*/
268+
public static GalaxyType stockSpiral() {
269+
for (GalaxyType t : defaultGalaxyTypes()) {
270+
if ("Spiral".equals(t.name)) {
271+
return t;
272+
}
273+
}
274+
throw new IllegalStateException("the stock galaxy table must contain a Spiral");
275+
}
276+
259277
private static List<GalaxyType> defaultGalaxyTypes() {
260278
// The bands are REAL radii, read off a catalogue and stated in light years so they can be
261279
// checked against one — never a multiple of UniverseScale.REFERENCE_GALAXY_RADIUS_LY. They

‎src/main/java/zmaster587/advancedRocketry/util/XMLPlanetLoader.java‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,16 @@ private GalaxyGenConfig readGalaxyGen(Node node) {
329329
* Parse one {@code <galaxyType>} element into a galaxy archetype.
330330
*
331331
* <pre>{@code
332-
* <galaxyType name="Spiral" profile="DISC" minRadius="900" maxRadius="2200"
332+
* <galaxyType name="Spiral" profile="DISC" minRadius="15000" maxRadius="60000"
333333
* thickness="0.02" arms="2" rotationSpeed="220" coreFraction="0.08" weight="7"/>
334334
* }</pre>
335335
*
336-
* <p>Every attribute defaults to the stock spiral's value, so a pack that wants to change only
337-
* how flat a disc is writes only {@code thickness}.</p>
336+
* <p>Every SHAPE attribute defaults to the stock spiral's value, so a pack that wants to change
337+
* only how flat a disc is writes only {@code thickness}. Those defaults are READ OFF
338+
* {@link GalaxyGenConfig#stockSpiral()} rather than written here: they were literals once, and the
339+
* copy went stale the moment the galaxy scale moved. {@code weight} is the deliberate exception —
340+
* it defaults to {@code 1}, the rarest, because a type a pack did not weight should not silently
341+
* inherit a spiral's abundance.</p>
338342
*/
339343
private static GalaxyGenConfig.GalaxyType readGalaxyType(Node node) {
340344
String profileName = attr(node, ATTR_PROFILE);
@@ -348,15 +352,16 @@ private static GalaxyGenConfig.GalaxyType readGalaxyType(Node node) {
348352
}
349353
}
350354
String name = attr(node, ATTR_NAME);
355+
GalaxyGenConfig.GalaxyType stock = GalaxyGenConfig.stockSpiral();
351356
return new GalaxyGenConfig.GalaxyType(
352357
(name == null || name.trim().isEmpty()) ? "Galaxy" : name.trim(),
353358
profile,
354-
attrDouble(node, ATTR_MINRADIUS, 900d),
355-
attrDouble(node, ATTR_MAXRADIUS, 2200d),
356-
attrDouble(node, ATTR_THICKNESS, 0.02d),
357-
attrInt(node, ATTR_ARMS, 2),
358-
attrDouble(node, ATTR_ROTATIONSPEED, 220d),
359-
attrDouble(node, ATTR_COREFRACTION, 0.08d),
359+
attrDouble(node, ATTR_MINRADIUS, stock.minRadiusLy),
360+
attrDouble(node, ATTR_MAXRADIUS, stock.maxRadiusLy),
361+
attrDouble(node, ATTR_THICKNESS, stock.scaleHeightRatio),
362+
attrInt(node, ATTR_ARMS, stock.armCount),
363+
attrDouble(node, ATTR_ROTATIONSPEED, stock.rotationSpeedKmS),
364+
attrDouble(node, ATTR_COREFRACTION, stock.coreRadiusFraction),
360365
attrInt(node, ATTR_WEIGHT, 1));
361366
}
362367

‎src/test/java/zmaster587/advancedRocketry/test/integration/XMLPlanetLoaderTest.java‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,32 @@ public void galaxyTypeChildrenReplaceTheStockTable() throws Exception {
558558
assertEquals(5, t.weight);
559559
}
560560

561+
@Test
562+
public void aPartiallySpecifiedGalaxyTypeInheritsTheSTOCKspiralNotAFrozenCopyOfIt()
563+
throws Exception {
564+
// The reason this test exists: the reader's defaults used to be literals — 900 / 2200 ly — and
565+
// they went stale the moment the galaxy scale moved, so a pack that wrote only `thickness` got
566+
// a "spiral" an order and a half under every real one, silently and only in the authored path.
567+
// A pack writing one attribute must get the SHIPPED spiral for the rest.
568+
GalaxyGenConfig.GalaxyType stock = GalaxyGenConfig.stockSpiral();
569+
DimensionPropertyCoupling c = parse(galaxy(
570+
"<galaxyGen>\n"
571+
+ " <galaxyType name=\"Fat Disc\" thickness=\"0.25\"/>\n"
572+
+ "</galaxyGen>\n"));
573+
assertNotNull(c.galaxyGenConfig);
574+
GalaxyGenConfig.GalaxyType t = c.galaxyGenConfig.galaxyTypes.get(0);
575+
576+
assertEquals("thickness is what the pack asked for", 0.25d, t.scaleHeightRatio, 1e-9);
577+
assertEquals("and the radius band is the SHIPPED spiral's", stock.minRadiusLy,
578+
t.minRadiusLy, 1e-9);
579+
assertEquals(stock.maxRadiusLy, t.maxRadiusLy, 1e-9);
580+
assertEquals(stock.armCount, t.armCount);
581+
assertEquals(stock.rotationSpeedKmS, t.rotationSpeedKmS, 1e-9);
582+
assertEquals(stock.coreRadiusFraction, t.coreRadiusFraction, 1e-9);
583+
assertEquals("weight is the deliberate exception: an unweighted type is the rarest", 1,
584+
t.weight);
585+
}
586+
561587
@Test
562588
public void galaxyTypesRoundTripThroughWriteXml() throws IOException {
563589
// This file is REWRITTEN on every world save, so a table the writer does not emit is a table a

0 commit comments

Comments
 (0)