2026-09-12 01:27:18 +02:00
/ * This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at https : //mozilla.org/MPL/2.0/. */
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
2026-09-14 17:39:12 +02:00
using CultMath ;
using Random = CultMath . Random ;
2026-09-12 01:27:18 +02:00
// Commands over the game database, run with: dotnet run --project tools/AetherDb -- <command>
public static class Program
{
public static int Main ( string [ ] args )
{
var command = args . FirstOrDefault ( ) ? ? "help" ;
switch ( command )
{
case "census" : return Census ( ) ;
case "station-fit" : return StationFit ( ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
case "hardpoint-fit" : return HardpointFit ( ) ;
case "loadout" : return Loadout ( args . Skip ( 1 ) . FirstOrDefault ( ) ) ;
case "save" : return Save ( ) ;
case "factions" : return Factions ( ) ;
case "clear-boss-hulls" : return ClearBossHulls ( args . Contains ( "apply" ) ) ;
2026-09-12 02:09:34 +02:00
case "settings" : return Settings ( ) ;
case "settings-dump" : return SettingsDump ( ) ;
2026-09-12 01:27:18 +02:00
default :
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
Console . WriteLine ( "commands: census, factions, station-fit, hardpoint-fit, loadout [seed], save, settings, settings-dump, clear-boss-hulls [apply]" ) ;
2026-09-12 01:27:18 +02:00
return 1 ;
}
}
// Designs by kind and manufacturer, designs no product sells, and products with authored role quality.
private static int Census ( )
{
var db = AetherDb . Open ( ) ;
var items = db . Cache . GetAll < EquippableItemData > ( ) . ToArray ( ) ;
var products = db . Cache . GetAll < FactionProductData > ( ) . ToArray ( ) ;
var kinds = new Dictionary < string , List < string > > ( ) ;
foreach ( var item in items )
{
var kind = item is HullData hull ? $"Hull/{hull.HullType}"
: item is DockingBayData ? "DockingBay"
: item is CargoBayData ? "CargoBay"
: item is WeaponItemData weapon ? $"Weapon/{weapon.HardpointType}"
: item . HardpointType . ToString ( ) ;
if ( ! kinds . TryGetValue ( kind , out var makers ) ) kinds [ kind ] = makers = new List < string > ( ) ;
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
makers . Add ( db . Cache . Get ( item . Manufacturer ) ? . ShortName ? ? "(none)" ) ;
2026-09-12 01:27:18 +02:00
}
Console . WriteLine ( $"{items.Length} designs, {products.Length} products\n" ) ;
foreach ( var kind in kinds . OrderBy ( k = > k . Key ) )
Console . WriteLine ( $"{kind.Key,-22} {kind.Value.Count,3} " + string . Join ( ", " ,
kind . Value . GroupBy ( m = > m ) . OrderByDescending ( g = > g . Count ( ) ) . Select ( g = > $"{g.Key}:{g.Count()}" ) ) ) ;
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var sold = SoldDesigns ( products ) ;
var orphans = items . Where ( i = > ! sold . Contains ( db . Cache . RefOf ( i ) . Key ) ) . ToArray ( ) ;
2026-09-12 01:27:18 +02:00
Console . WriteLine ( $"\n{orphans.Length} designs no product sells, so they cannot spawn:" ) ;
foreach ( var item in orphans ) Console . WriteLine ( $" {item.Name}" ) ;
var authored = products . Where ( p = > p . Roles ! = null & & p . Roles . Count > 0 ) . ToArray ( ) ;
Console . WriteLine ( $"\n{authored.Length} products carry role quality:" ) ;
foreach ( var product in authored )
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
Console . WriteLine ( $" {product.Name,-28} by {db.Cache.Get(product.Manufacturer)?.ShortName ?? " ( none ) ",-12} " +
2026-09-12 01:27:18 +02:00
string . Join ( ", " , product . Roles . Select ( r = > $"{r.Role} {r.Mean:0.00}±{r.StandardDeviation:0.00}" ) ) ) ;
if ( authored . Length = = 0 ) Console . WriteLine ( " none yet: add roles to a design, then set each product's means" ) ;
return 0 ;
}
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
private static HashSet < GameCult . Caching . CultRecordKey > SoldDesigns ( IEnumerable < FactionProductData > products ) = >
new HashSet < GameCult . Caching . CultRecordKey > ( products . Select ( p = > p . Design . Key ) ) ;
2026-09-12 01:27:18 +02:00
// Some docking bay fits every station hull, which LoadoutGenerator.GenerateStationLoadout requires.
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
// Models the rule the game applies: an interior cell is usable when no gear occupies it, empty hardpoint
// cells included. Reports both the empty hull and the case where every hardpoint is already filled, because
// generation equips hardpoint gear first and only the first of those is guaranteed.
2026-09-12 01:27:18 +02:00
private static int StationFit ( )
{
var db = AetherDb . Open ( ) ;
var bays = db . Cache . GetAll < DockingBayData > ( ) . ToArray ( ) ;
var failures = 0 ;
foreach ( var hull in db . Cache . GetAll < HullData > ( ) . Where ( h = > h . HullType = = HullType . Station ) )
{
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
var empty = new Shape ( hull . Shape . Width , hull . Shape . Height ) ;
foreach ( var v in hull . InteriorCells . Coordinates ) empty [ v ] = true ;
var hardpointsFilled = new Shape ( hull . Shape . Width , hull . Shape . Height ) ;
foreach ( var v in hull . InteriorCells . Coordinates ) hardpointsFilled [ v ] = true ;
2026-09-12 01:27:18 +02:00
foreach ( var hardpoint in hull . Hardpoints )
foreach ( var v in hardpoint . Shape . Coordinates )
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
hardpointsFilled [ hardpoint . Position + v ] = false ;
var onEmpty = bays . Where ( b = > b . Shape . FitsWithin ( empty , out _ , out _ ) ) . Select ( b = > b . Name ) . ToArray ( ) ;
var onFilled = bays . Where ( b = > b . Shape . FitsWithin ( hardpointsFilled , out _ , out _ ) ) . Select ( b = > b . Name ) . ToArray ( ) ;
if ( onEmpty . Length = = 0 ) failures + + ;
Console . WriteLine ( $"{hull.Name}: empty hull fits [{string.Join(" , ", onEmpty)}], every hardpoint filled fits [{string.Join(" , ", onFilled)}]" ) ;
if ( onEmpty . Length > 0 & & onFilled . Length = = 0 )
Console . WriteLine ( " depends on hardpoint gear leaving cells free; generation can still fail here" ) ;
}
return failures ;
}
// Every hardpoint on every hull, and which designs can fill it: LoadoutGenerator requires a matching
// HardpointType, a shape that fits the hardpoint, and exactly as many cells as the hardpoint has. A
// hardpoint no product can fill is gear the game cannot place.
private static int HardpointFit ( )
{
var db = AetherDb . Open ( ) ;
var gear = db . Cache . GetAll < GearData > ( ) . ToArray ( ) ;
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var sold = SoldDesigns ( db . Cache . GetAll < FactionProductData > ( ) ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
var unfillable = 0 ;
foreach ( var hull in db . Cache . GetAll < HullData > ( ) . OrderBy ( h = > h . HullType ) . ThenBy ( h = > h . Name ) )
{
Console . WriteLine ( $"\n{hull.Name} ({hull.HullType}):" ) ;
foreach ( var hardpoint in hull . Hardpoints . OrderByDescending ( h = > h . Shape . Coordinates . Length ) )
{
var cells = hardpoint . Shape . Coordinates . Length ;
var matches = gear . Where ( g = >
g . HardpointType = = hardpoint . Type & &
g . Shape . FitsWithin ( hardpoint . Shape , hardpoint . Rotation , out _ ) & &
g . Shape . Coordinates . Length = = cells ) . ToArray ( ) ;
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var soldMatches = matches . Where ( m = > sold . Contains ( db . Cache . RefOf ( m ) . Key ) ) . ToArray ( ) ;
if ( soldMatches . Length = = 0 ) unfillable + + ;
Console . WriteLine ( $" {hardpoint.Type,-14} {cells,2} cells: {matches.Length} designs match, {soldMatches.Length} sold" +
( matches . Length = = 0 ? " <- no design of that size" : soldMatches . Length = = 0 ? " <- designs exist but no product sells them" : "" ) ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
foreach ( var match in matches )
Console . WriteLine ( $" {match.Name,-28} {match.Shape.Coordinates.Length} cells" +
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
( sold . Contains ( db . Cache . RefOf ( match ) . Key ) ? "" : " (unsold)" ) ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
}
}
Console . WriteLine ( $"\n{unfillable} hardpoints no product can fill" ) ;
return unfillable ;
}
2026-09-12 02:09:34 +02:00
// The parsed shape of the settings asset, for checking where sequence items actually landed.
private static int SettingsDump ( )
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var authored = AuthoredSettings . Load ( AetherDb . FindRoot ( ) ) ;
2026-09-12 02:09:34 +02:00
authored . Dump ( "TutorialGenerationSettings" , 2 ) ;
Console . WriteLine ( ) ;
authored . Dump ( "GameplaySettings" , 2 ) ;
return 0 ;
}
// What the authored settings asset actually yields, so a fixture using it can be trusted before it reports
// anything about galaxies. Prints the values that matter to generation and every field it could not place.
private static int Settings ( )
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var authored = AuthoredSettings . Load ( AetherDb . FindRoot ( ) ) ;
2026-09-12 02:09:34 +02:00
var tutorial = authored . Read < TutorialGenerationSettings > ( "TutorialGenerationSettings" ) ;
var background = authored . Read < SectorBackgroundSettings > ( "TutorialBackgroundSettings" ) ;
var names = authored . Read < NameGeneratorSettings > ( "NameGeneratorSettings" ) ;
var zones = authored . Read < ZoneGenerationSettings > ( "ZoneSettings" ) ;
var gameplay = authored . Read < GameplaySettings > ( "GameplaySettings" ) ;
Console . WriteLine ( $"tutorial: protagonist {tutorial.ProtagonistFaction}, antagonist {tutorial.AntagonistFaction}, " +
$"buffer {tutorial.BufferFaction}, quest {tutorial.QuestFaction}, " +
$"neutrals [{string.Join(" , ", tutorial.NeutralFactions ?? new string[0])}], " +
$"{tutorial.ZoneCount} zones, link density {tutorial.LinkDensity}" ) ;
Console . WriteLine ( $"background: frequency {background.NoiseFrequency}, amplitude {background.NoiseAmplitude}, " +
$"cloud exponent {background.CloudExponent}, density at centre {background.CloudDensity(new float2(.5f)):0.000}" ) ;
Console . WriteLine ( $"names: order {names.NameGeneratorOrder}, length {names.NameGeneratorMinLength}-{names.NameGeneratorMaxLength}" ) ;
Console . WriteLine ( $"zones: sun mass {zones.SunMass}, planet mass {zones.PlanetMass}, satellite passes {zones.SatellitePasses}, " +
$"belt probability {zones.BeltProbability}" ) ;
Console . WriteLine ( $" zone radius curve {zones.ZoneRadius?.Minimum}-{zones.ZoneRadius?.Maximum} exponent {zones.ZoneRadius?.Exponent}" ) ;
Console . WriteLine ( $" sub zone count {zones.SubZoneCount?.Minimum}-{zones.SubZoneCount?.Maximum} exponent {zones.SubZoneCount?.Exponent}" ) ;
Console . WriteLine ( $"gameplay: weapon groups {gameplay.WeaponGroupCount}, shutdown performance {gameplay.DefaultEntitySettings?.ShutdownPerformance}" ) ;
Console . WriteLine ( $" tiers: {string.Join(" , ", (gameplay.Tiers ?? new RarityTier[0]).Select(t => $" { t . Name } q { t . Quality } r { t . Rarity } "))}" ) ;
Console . WriteLine ( $" price modifier {gameplay.QualityPriceModifier?.Minimum}-{gameplay.QualityPriceModifier?.Maximum} exponent {gameplay.QualityPriceModifier?.Exponent}" ) ;
// Assert counts, not non-null: an empty array reads as populated and would make every number a fixture
// reports downstream a fiction. These are the authored values as of the asset read above.
var missing = new List < string > ( ) ;
if ( zones . ZoneRadius = = null | | zones . ZoneRadius . Maximum < = 0 ) missing . Add ( "ZoneSettings.ZoneRadius" ) ;
if ( zones . SubZoneCount = = null | | zones . SubZoneCount . Maximum < = 0 ) missing . Add ( "ZoneSettings.SubZoneCount" ) ;
if ( zones . PlanetSafetyRadius = = null | | zones . PlanetSafetyRadius . Multiplier < = 0 ) missing . Add ( "ZoneSettings.PlanetSafetyRadius" ) ;
if ( gameplay . Tiers = = null | | gameplay . Tiers . Length ! = 5 ) missing . Add ( $"GameplaySettings.Tiers (expected 5, got {gameplay.Tiers?.Length ?? 0})" ) ;
else if ( gameplay . Tiers . Any ( t = > string . IsNullOrEmpty ( t . Name ) | | t . Quality < = 0 ) ) missing . Add ( "GameplaySettings.Tiers (a tier parsed without a name or quality)" ) ;
if ( gameplay . DefaultEntitySettings = = null ) missing . Add ( "GameplaySettings.DefaultEntitySettings" ) ;
if ( gameplay . QualityPriceModifier = = null | | gameplay . QualityPriceModifier . Maximum < = 0 ) missing . Add ( "GameplaySettings.QualityPriceModifier" ) ;
if ( tutorial . NeutralFactions = = null | | tutorial . NeutralFactions . Length ! = 2 ) missing . Add ( $"TutorialGenerationSettings.NeutralFactions (expected 2, got {tutorial.NeutralFactions?.Length ?? 0})" ) ;
if ( string . IsNullOrEmpty ( tutorial . ProtagonistFaction ) ) missing . Add ( "TutorialGenerationSettings.ProtagonistFaction" ) ;
Console . WriteLine ( $"\n{authored.Unplaced.Count} fields in the asset had nowhere to go" ) ;
foreach ( var field in authored . Unplaced . Take ( 20 ) ) Console . WriteLine ( $" {field}" ) ;
Console . WriteLine ( $"{missing.Count} settings generation needs came back unset" ) ;
foreach ( var field in missing ) Console . WriteLine ( $" {field}" ) ;
return missing . Count ;
}
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
// Clears boss hull links that resolve to nothing. Galaxy.PlaceFactionsMain gives a boss zone to every faction
// carrying a BossHull, so a dangling link claims a chokepoint that can never spawn a boss. Dry run unless
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
// passed "apply", which alone opens the catalog writable and lands every cleared faction in one commit.
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
private static int ClearBossHulls ( bool apply )
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var db = AetherDb . Open ( catalogWritable : apply ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
var dangling = db . Cache . GetAll < Faction > ( )
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
. Where ( f = > f . BossHull . IsSet ( ) & & db . Cache . Get ( f . BossHull ) = = null )
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
. OrderBy ( f = > f . Name )
. ToArray ( ) ;
Console . WriteLine ( $"{dangling.Length} factions point at a boss hull that does not exist:" ) ;
foreach ( var faction in dangling )
Console . WriteLine ( $" {faction.Name,-26} {faction.BossHull}" ) ;
if ( apply & & dangling . Length > 0 )
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
db . Cache . Commit ( batch = >
{
foreach ( var faction in dangling )
{
faction . BossHull = default ;
batch . Upsert ( faction ) ;
}
} ) ;
Console . WriteLine ( $"\nCleared {dangling.Length} boss hull links in Aetheria.cc" ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
}
else if ( ! apply & & dangling . Length > 0 ) Console . WriteLine ( "\nDry run. Pass \"apply\" to clear them." ) ;
return 0 ;
}
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
// Each faction's generation-critical links. Galaxy.GenerateNames dereferences the geoname file without a
// guard, so an unset link there stops galaxy generation outright.
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
private static int Factions ( )
{
var db = AetherDb . Open ( ) ;
var products = db . Cache . GetAll < FactionProductData > ( ) . ToArray ( ) ;
Console . WriteLine ( $"{" faction ",-26} {" short ",-13} {" geonames ",-22} {" boss hull ",-14} {" influence ",-9} products" ) ;
var broken = 0 ;
foreach ( var faction in db . Cache . GetAll < Faction > ( ) . OrderBy ( f = > f . Name ) )
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var key = db . Cache . RefOf ( faction ) . Key ;
var geonames = faction . GeonameFile . IsSet ( ) ? "set" : "UNSET" ;
var boss = ! faction . BossHull . IsSet ( )
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
? "none"
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
: db . Cache . Get ( faction . BossHull ) ? . Name ? ? "DANGLING" ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
if ( geonames = = "UNSET" | | boss = = "DANGLING" ) broken + + ;
Console . WriteLine ( $"{faction.Name,-26} {faction.ShortName,-13} {geonames,-22} {boss,-14} {faction.InfluenceDistance,-9} " +
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
products . Count ( p = > p . Manufacturer . Key . Equals ( key ) ) ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
}
Console . WriteLine ( $"\n{broken} factions carry a link that would break generation" ) ;
return broken ;
}
// What the saved run actually holds per zone. A zone carrying orbits but no orbital entities was packed by a
// generation run that failed partway, and is reused on revisit rather than regenerated, so a fixed generator
// does not repopulate it.
private static int Save ( )
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var path = Path . Combine ( AetherDb . FindRoot ( ) , "GameData" , "run.cc" ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
if ( ! File . Exists ( path ) )
{
Console . WriteLine ( $"no save at {path}" ) ;
return 0 ;
}
2026-09-12 01:27:18 +02:00
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
AetherDb db ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
try
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
db = AetherDb . Open ( withRun : true ) ;
2026-09-12 01:27:18 +02:00
}
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
catch ( Exception e )
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
Console . WriteLine ( $"save does not open: {e.GetType().Name}: {e.Message}" ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
return 1 ;
}
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var run = db . Cache . GetGlobal < SavedGame > ( ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
if ( run ? . Zones = = null )
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
Console . WriteLine ( "run store holds no SavedGame" ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
return 0 ;
}
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
Console . WriteLine ( $"{run.Zones.Length} zones, current zone {run.CurrentZone}\n" ) ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
var suspect = 0 ;
for ( var i = 0 ; i < run . Zones . Length ; i + + )
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
var zone = db . Cache . Get ( run . Zones [ i ] ) ;
if ( zone ? . Contents = = null ) continue ;
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
var stations = zone . Contents . Entities . Count ( e = > e is OrbitalEntityPack ) ;
var ships = zone . Contents . Entities . Count ( e = > e is ShipPack ) ;
var owner = zone . Owner > = 0 & & zone . Owner < run . Factions . Length
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
? db . Cache . Get ( run . Factions [ zone . Owner ] ) ? . ShortName ? ? "(unknown)"
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
: "(none)" ;
var packedEmpty = zone . Contents . Orbits . Count > 0 & & stations = = 0 ;
if ( packedEmpty ) suspect + + ;
Console . WriteLine ( $" [{i,3}] {zone.Name,-18} owner {owner,-12} orbits {zone.Contents.Orbits.Count,3} " +
$"stations {stations,2} ships {ships,2}{(packedEmpty ? " < - packed with orbits but no stations " : " ")}" ) ;
}
Console . WriteLine ( $"\n{suspect} visited zones packed with orbits but no stations" ) ;
return 0 ;
}
// Runs the real LoadoutGenerator against every hull, so a generation failure reproduces here instead of on a
// flight to a populated sector. No galaxy, so this covers placement, roles and products but NOT availability
// filtering or distance weighting, which need a real galaxy. Seeded: a failure repeats.
private static int Loadout ( string seedArgument )
{
var db = AetherDb . Open ( ) ;
var seed = uint . TryParse ( seedArgument , out var parsed ) ? parsed : 1 u ;
var settings = new GameplaySettings
{
DefaultEntitySettings = new EntitySettings ( ) ,
Tiers = new [ ] { new RarityTier { Name = "Common" , Quality = . 5f , Rarity = 0 , Color = new float3 ( 1 , 1 , 1 ) } } ,
QualityPriceModifier = new ExponentialLerp ( )
} ;
var log = new List < string > ( ) ;
var itemManager = new ItemManager ( db . Cache , settings , log . Add ) ;
var failures = 0 ;
foreach ( var hull in db . Cache . GetAll < HullData > ( ) . OrderBy ( h = > h . HullType ) . ThenBy ( h = > h . Name ) )
{
var random = new Random ( seed ) ;
var generator = new LoadoutGenerator ( ref random , itemManager , null , null , null , . 5f ) ;
log . Clear ( ) ;
string outcome ;
try
{
var pack = hull . HullType switch
{
Rewrite AetherDb over AetheriaStores and CultRecordRef
Cut 8b. AetherDb.Open composes GameData/Aetheria.cc through
AetheriaStores.Open, read-only unless clear-boss-hulls runs with apply;
save attaches GameData/run.cc when present and reads the SavedGame global.
- census, factions, station-fit, hardpoint-fit, loadout, settings,
settings-dump and clear-boss-hulls read references through the null-safe
Get(ref) and compare identity by record key (RefOf, from TryGetHandle).
Their output formats are unchanged so Cut 9 can compare them with the
Cut 0 captures.
- clear-boss-hulls lands every cleared faction in one Commit.
- The help line lists every command.
- Deleted: doctor, migrate-products, AetherDb.Save(), and
OpenWithNameFiles. The last was Cut 9's delete, but it needs the removed
multi-file store, and NameFile now routes to the catalog.
- FindRoot looks for Aetheria.Shared.csproj; AetherDB.msgpack leaves in
Cut 9.
It compiles. It cannot run until Cut 9 writes Aetheria.cc, so the pre-cut
captures do not apply to this cut.
Builds: Aetheria.Shared, AetherDb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:05:14 +02:00
HullType . Ship = > generator . GenerateShipLoadout ( candidate = > candidate = = hull ) ,
Clear dangling boss hull links, and stop the tool writing on read
Eight factions pointed at one boss hull GUID that no longer resolves,
shared wreckage from the database loss. PlaceFactionsMain gives a boss zone
to every faction carrying a BossHull, so each dangling link claimed a
chokepoint that could never spawn a boss.
AetherDb.Open no longer registers the name file store. CultCache subscribes
Add to a store EntryAdded, MultiFileBackingStore.PullAll re-emits what it
loads, and Add pushes to that type store, whose Push writes a file: opening
the cache rewrote all twelve name files, 4.4 MB, on every command. They were
byte identical, and it only surfaced as an error because Unity had one of
them memory mapped. Name files now load only on request, and the scope doc
records the underlying smell.
Adds commands: factions, clear-boss-hulls, save, loadout (runs the real
LoadoutGenerator against every hull), hardpoint-fit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 02:05:33 +02:00
HullType . Turret = > generator . GenerateTurretLoadout ( ) ,
_ = > generator . GenerateStationLoadout ( )
} ;
outcome = pack = = null ? "NO LOADOUT (nothing suitable found)" : "ok" ;
if ( pack = = null ) failures + + ;
}
catch ( Exception e )
{
outcome = $"THREW {e.GetType().Name}: {e.Message}" ;
failures + + ;
}
Console . WriteLine ( $"{hull.Name,-12} ({hull.HullType,-7}) {outcome}" ) ;
foreach ( var line in log . Distinct ( ) ) Console . WriteLine ( $" {line}" ) ;
}
Console . WriteLine ( $"\n{failures} hulls failed to generate a loadout (seed {seed})" ) ;
2026-09-12 01:27:18 +02:00
return failures ;
}
}