Master's catalog (2e2d927a, with missile-stats) plus the five smoke weapons the command authors; not a hand merge of the two branches' binaries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The five munition designs are written by the post-cut schema, so keys 29-31 and 24-26 are gone from the file. The catalog loads
through AetherDb (census) and every munition design carries its five parts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GT 3K, LRMM72, SRMM72, pswarm, scorched void policy. Acceleration, Lateral and MaxSpeed copy Thrust and MissileVelocity with
their thruster role; EvasionFrequency is DodgeFrequency; the rest are authored flat.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Output of `AetherDb smoke-hull apply` on this tree's base catalog, run on Yggdrasil: one HullData,
Smoke Test Hull, 17 hardpoints, no product.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The catalog is the output of `AetherDb smoke-hull apply` on this tree's catalog, run on Yggdrasil.
It adds one HullData, 17 hardpoints (the Longinus's 13 and four new ones), and nothing else.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master's catalog blob (f5645e0a, grammar global and seven verbs), then `consumables-first-set apply`.
Dry run on that tree, verbatim:
Vent radius Min 33.03 (Djinni 14x17 cells at 2 units: half diagonal 22.02, x1.5), Max 49.55
New designs:
Thruster Overdrive 1x1 mass 10 price 18000 stackable False duration 6 roles [propellant, regulator]
ThrottleLockData
Multiplier ThrusterData.Thrust 3-4.5 (propellant)
Multiplier VelocityLimitData.TopSpeed 2-3 (propellant)
Multiplier ThrusterData.Heat 5-3 (regulator)
Multiplier ThrusterData.Visibility 5-3 (regulator)
"Opens every drive wide and holds it there. The ship is thrown forward on a bright, hot plume while the pilot keeps the wheel."
Coolant Vent 1x1 mass 15 price 12000 stackable False duration 15 roles [nozzle, coolant]
VapourDump radius 33.03-49.55 (nozzle), opacity 0.9-0.98 (nozzle), lifetime 14-20 (coolant)
Multiplier RadiatorData.Emissivity 0.3-0.5 (coolant)
"Dumps the coolant loop into space as a spreading bank of vapour. Sensors lose whoever is inside it, and the radiators pay for the loss."
New products:
Thruster Overdrive -> "send it" by DME, every role mean 0.55 dev 0.2: no brakes/ no regrets/ one good burn
Thruster Overdrive -> "Updraft" by Finch, every role mean 0.65 dev 0.2: Light as a feather and, for six seconds, about as fast as one in a gale.
Coolant Vent -> "Smoke Machine" by NiteLife, every role mean 0.55 dev 0.12: Fills the room. Nobody can say who came in with you.
Coolant Vent -> "Morning Fog" by Lightsail, every role mean 0.55 dev 0.1: Rolls in thick, lifts slowly, and leaves the bills with the other fellow.
Dry run. Pass "apply" to author 2 designs and 4 products.
A second run answers "already authored; nothing to do". This commit builds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Catalog sha256 193a4d25... (origin/master) -> f5645e0a... Output of 'dotnet run --project tools/AetherDb -- verse-grammar' (the dry run, before this apply), CultLib git-45c2f40:
Grammar: new, revision 1.
Verbs a Ghostlight-simulated Aetheria world may use: ship actions the game films in-engine, and speech rendered as Aetheria conversation.
Starter verbs (7):
mine(site: Place, ore: Cargo) [ShipAction] new
The actor works an ore body at a place and takes the ore into its hold.
haul(cargo: Cargo, destination: Place) [ShipAction] new
The actor carries cargo to a destination place.
tow(target: Faction) [ShipAction] new
The actor tows a station or hull belonging to the target faction.
defend(protected: Faction, at: Place) [ShipAction] new
The actor guards a protected faction's ships and holdings at a place.
attack(target: Faction) [ShipAction] new
The actor attacks the target faction's ships and holdings.
explore(region: Place) [ShipAction] new
The actor surveys a region and charts what is there.
speak() [Conversation] new
The actor says something to whoever is in earshot. Shown as Aetheria dialogue: face to face when docked, by radio with the speaker's portrait over their ship when undocked.
Dry run. Pass "apply" to land the grammar global and 7 verb(s).
A second dry run printed 'Nothing to do.' Data only; does not itself pass the suite until the validation commit's tests are in (builds: yes, the code is unchanged by this commit).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AetherDb roles-backfill apply on master's blob 32a2e401: 12 designs and 6 products authored; a second apply is a no-op.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Master's catalog (LFS 5ecf375f: PD gear, Mine Launcher, retirements) differs from this
branch's base, so the branch's blob was not taken. AetherDb pirates-faction apply was rerun
on master's catalog (merged tool, Yggdrasil container): the Pirates faction and eight
emoji-named products authored; catalog 5ecf375f -> 32a2e401 (12712398 bytes); a second run
reports the faction already exists and the blob is byte-identical.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Master's catalog (LFS adba0389: Mine Launcher present, LonginusX and Traction retired)
differs from this branch's base, so the branch's catalog was not picked. AetherDb
pd-gear apply was rerun on master's catalog (merged tool): 3 designs and 11 products
authored, a second run reports it already authored, dangling reports 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master's catalog (LFS 9e75d9a4, carrying the Mine Launcher and the gear-without-presence
merge base) differed from this branch's base, so the branch's catalog was not picked.
AetherDb retire-longinusx apply was rerun on master's catalog (tool as of 8038b46a plus
origin/master): the dry run listed the same four records (HullData LonginusX, GearData
Traction, their two FactionProductData), a second apply is refused, dangling reports 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Authored by AetherDb mine-launcher apply from the 532be3a5 catalog; the new blob is 9e75d9a4 (LFS).
Fixes the zero performance at a hull's starting 280 K; ShippedWeaponOperabilityTests is green from here.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Supersedes the catalog blob of b60c695a (item without shape, curve or product, which broke six tests). The blob
is the file the verify job authored from the master catalog and ran 968 tests against.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
GameData/Aetheria.cc 70a7b0a9 -> 78fe2afe (12703072 bytes): one FieldKindData
record, Asteroid, cross-section 5, weight 1. Run on Yggdrasil from the merge
commit's tree, output pulled back byte-identical. Fixes
TheShippedCatalogHasAPickableFieldKind and makes master's strict Exact weapon
assertion hold on the rewritten catalog.
Builds: both commits build; the previous commit fails one test by design, this one passes 837/837.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Operator ruling, 2026-09-30: "removing the 11 self-entries was my intention".
IsAvailable, the one reach rule, now says a faction always reaches its own
manufacturer's gear, and a transient `AetherDb allegiance-self [apply]` drops
the self-entries from the eleven factions that had one (Rossum & Douglas never
did, which is why its stations could not carry its own gear).
Tests: in a main-sector galaxy every faction is offered all it makes and no
allegiance map names its own faction; and, through a fixture faction outside
the galaxy with no self-entry, its own product is on offer to it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Operator ruling, 2026-09-30: "Keep the variety, not every galaxy will have
Zhestokost in it." A transient `AetherDb station-reactors [apply]` gives each
manufacturer that makes reactors a design for Zenith's 16-cell Reactor
hardpoint, scaled by cells from its largest reactor with every other value,
stat term, role, temperature and sound bank its own, and a product by it:
Vulcan Station Reactor (AU, from Vulcan 12 cells x1.333) charge 66.7..266.7, mass 666.7, price 1,550,000
Notorious Station Reactor (Lucent, from Notorious 9 x1.778) charge 711.1..2133.3, mass 1333.3, price 1,800,000
MoveOnPro Station Reactor (NiteLife, from MoveOnPro 4 x4) charge 100..500, mass 1200, price 3,600,000
Core Power Station Reactor (R&D, from Core Power 4 x4) charge 400, mass 200, price 1,000,000
products: Vulcan Station, Notorious Station, MoveOnPro Station, Steadfast Station
The Manhattan-derived one is renamed "Manhattan Station Reactor" (product
"Manhattan Station").
Reach is read through the one rule, LoadoutGenerator.IsAvailable. Test: a
faction allied only to AU, Lightsail and NiteLife is offered none of
Zhestokost's products and AU's, its stations carry nothing it cannot reach and
nothing by Zhestokost, and they are powered.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Soul's F4: LRMM72, SRMM72, Autocannon, pswarm and plight had DamageCurve ==
null, and once they had products NPCs were generated with them and
CombatState.SampleDps threw at InstantWeapon.cs:64 / ChargedWeapon.cs:81.
A transient `AetherDb damage-curves [apply]` copies each one's curve from its
nearest comparable weapon, same class first, then closest range and damage:
Autocannon <- DeathCluster (auto-fire Ballistic, 4 cells, range reaching 1000)
LRMM72 <- GT 3K (the only other unguided launcher)
SRMM72 <- scorched void policy (guided; 750 range and 128 damage inside its 500-1250, 128-512)
pswarm <- scorched void policy (guided; identical damage, range, cooldown)
plight <- ChargeBlast+- (charged Energy; nearest range)
Every curve in the catalog is the same one, keys (0, 1, 0, 0) and
(1, 0, -1.7656243, -1.7656243): full damage at minimum range falling to none
at maximum. Test: every weapon a product sells has a damage curve.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Operator ruling, 2026-09-30: "Yep, we need a station reactor." Zenith's 16-cell
Reactor hardpoint had no design to fill it, so generated stations had no power.
A transient `AetherDb station-reactor [apply]` authored it from Manhattan, the
largest and most industrial reactor, scaled by cells (16/9):
Station Reactor (GearData, Reactor hardpoint, full 4x4)
mass 500 -> 888.9, price 750,000 -> 1,350,000 (to the nearest 50,000),
charge 500..1000 -> 888.9..1777.8; every other value, the efficiency,
overload and throttling stats and all stat terms, the roles (core,
regulator), temperatures, durability and sound bank are Manhattan's.
Product "Station Reactor" by Zhestokost (Manhattan's maker), default role
quality.
Station generation fills the slot through its ordinary hardpoint pass. Tests:
every generated station carries one heater and a reactor; an idle station (a
quiet arena, nothing else running) holds its heater's cells above freezing over
the second five of ten minutes (unpowered they fell to ~247 K); a station hull
with no room for a heater fails generation by name instead of skipping it
(Soul's S11 survived before).
The station's border cells still sit near 265 K with the heater and reactor
running (the reactor core reaches ~433 K); how warm the whole hull should run
is left as a tuning question.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Operator rulings, 2026-09-30 (docs/scenarios-cut.md, "the ten real designs with
no product"), landed through a transient `AetherDb product-gap [apply]`:
- Deleted, nothing referencing them: Assembly Line, Deep Ore Extractor, Surface
Ore Extractor, Refinery, Shipyard (RTS-era placeholders, price and durability
0, three with unreadable behaviour entries).
- Products, maker taken from the nearest analogue's product:
Autocannon -> Autocannon by Zhestokost (DeathCluster: Ballistic, 4 cells, AutoWeapon)
LRMM72 -> LRMM72 by Rossum & Douglas (GT 3K: the only other unguided launcher)
SRMM72 -> SRMM72 by Death Monkey Explosives (scorched void policy: guided, nearest size and price)
Tractor Beam -> Space Tractor by Ewan Hart Inc (no analogue; the wishlist's
"Space Tractor: It's a tractor. In space.", content-batch-one section 10)
Industrial Thermostatic Heater -> same name by Lightsail Express (Cockpit 2x2,
the same Thermotoggle/EnergyDraw/Heat group)
Each product carries its design's roles at the default quality (0.5 +- 0.15).
- The heater design kept (operator), with Price 0 -> 100,000 (between Cockpit
2x2 and Fire Control Array) and Durability 0 -> 100 (Cockpit 2x2's): at zero
price generation never offers it, at zero durability it never comes online.
The rewrite stores every weapon record at the current schema, so
FireControlCut124's shipped-catalog check now expects an Exact migration
report instead of drift with slot 32 defaulted. `AetherDb census` reports no
unsold design. Tractor Beam keeps price 0, durability 0 and no behaviour.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fire-control batches 1-8 with Soul passes, verified headless (Aetheria
Shared tests). Play smoke 2026-09-30: compile clean, steps 3-6 played
(pass/partial), steps 7-20 and fire-control checks A-F unplayed. The
operator preferred to merge now; Self ruled merge, with the unplayed
checks carried as open behaviours to verify through authored main-menu
scenarios (new Eureka cut). Report: docs/merge-to-master-checklist.md
section 8.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Landed via `dotnet run --project tools/AetherDb -- fix-loco1 apply`, then deleted the command in
the same batch (Cut 9/Cut 1 precedent). Fixes, each against the decoded 2021-04-14 legacy record
or a named catalog precedent:
- Djinni.Prefab was a fabricated/truncated GUID; corrected to Djinni.prefab.meta's own GUID.
- All five restored thrusters' ParticlesPrefab (null) -> Thruster 1.prefab's GUID, the same one
Large Drive uses (legacy record names the same prefab path for all of them).
- All five thrusters' invented OptimalTemperature/PlateauWidth (300/100) -> Large Drive's own
200-400 precedent, 251/24 (docs/stats-power-cut1-migration.md).
- ThermalResilience: Medium Drive/Small Drive -> 10, Victoire/Talaria/RevvITup 2.0 -> 15 (legacy
record). Victoire's Durability 100 -> 30 (legacy). Victoire and Medium Drive's legacy
descriptions restored (Talaria/RevvITup 2.0's legacy descriptions are the literal placeholder
"[TODO]" and are not).
- Djinni.Schematic (null) -> djinni_schematic_transparent.png's GUID, already in the tree, unused.
- Djinni's OptimalTemperature 250 -> 251, correcting a rounding slip in restore-hulls's own
"apply LonginusX's optimal-fraction to Djinni's band" derivation ((275.15-173.15)/400 = .255 of
band applied to Djinni's 200-unit band rounds to 251, not 250).
- All seven restored records (Longinus, Djinni, five thrusters) re-keyed from freshly minted GUIDs
to their own legacy GUIDs, decoded directly from GameData/Legacy/AetherDB.2021-04-14.msgpack,
matching the Cut 9 import precedent (tools/AetherDb/Import.cs, git history). Each record's own
FactionProductData.Design ref repointed at the new key.
Verified: dry run then apply, second apply refused (Longinus already carries its legacy key),
`dangling` reports 0, `census` still names both hulls, `loadout` generates every hull cleanly
across seeds 1-5.
Re-keying changed GetAll<GearData> enumeration order, which
RestoredHullMovesAndTurnsUnderMovementAndLookDirection's design-selection (thrusterDesigns.First())
depended on implicitly: it started landing every Djinni thruster hardpoint on Victoire, the one
restored thruster with a real EnergyUsage draw, and the fixture ship carries no reactor. Fixed by
equipping the fixture ship's own Reactor hardpoint, which every restored hull actually has, instead
of relying on incidental unpowered-item ordering.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Landed via `dotnet run --project tools/AetherDb -- restore-hulls apply`.
Longinus (13 hardpoints, Alakrita) and Djinni (22 hardpoints, Rossum &
Douglas), plus Medium Drive, Small Drive, Victoire, Talaria and RevvITup
2.0 (approved 2026-09-22), each with a FactionProductData. Verified:
census names both hulls with makers, dangling reports nothing new,
LoadoutGenerator/`loadout` generates every hull in the catalog cleanly
across seeds 1-5, second apply refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AetherDb targeting-catalog-6c apply, landed:
- Targeting Computer: Resolution .3 -> 2 (sensor-limited until info reaches
.55 under the new reciprocal reading)
- Fire Control Array: Resolution .75 -> 4 (until .325) -- now unambiguously
ahead of the 1-cell design at every info level, fixing the strictly-worse
regression Cut 6a's review found
- 4 new products: Panopticon / Panopticon Prime (Finch Cybernetics, passive
sensors) and ClapBack / ClapBack Ultra (Lucent Media, active sensors/lasers)
-- each design now has three sellers instead of one
Census: 53 designs (unchanged), 47 products (was 43). AetherDb dangling: 0.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Runs targeting-catalog apply: two new designs (Targeting Computer, Fire
Control Array) and six new products (LockOn / LockOn Pro by NiteLife Energy;
DragOnBreath by Lucent Media for plight; Leonid by Aeronautics Unlimited for
pswarm; Steadfast by Rossum & Douglas for Core Power; True North by Lightsail
Express for Large Drive).
Verified: census 53 designs/43 products (was 51/37); loadout over ten seeds
no longer throws for LonginusX and each gains exactly one interior targeting
system; dangling 0; a fresh census reopen carries 0 schema issues;
firing-arc-migrate dry run reports nothing left to migrate; dotnet test
tests/Aetheria.Shared.Tests is 197/197.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
tools/AetherDb firing-arc-migrate was written in Cut 2 and never run: the
Turret hull's two Ballistic hardpoints still carried a 0-degree arc, so a
turret only ever engaged within 60 degrees of its spawn facing. Applying it
sets both to 360, matching the operator ruling (fire-control-cut.md Q1) that a
turret's arc is authored data, not a new hardpoint type. A fresh dry run now
reports both hardpoints already authored.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
roles-migrate apply, run once: 32 of 51 designs now declare roles (183
stats pointed at the role that governs them; the other 19 designs' kinds
either carry no quality-bearing behaviour at all, or every candidate stat
is authored flat with no observable role-vs-workmanship difference). 28 of
37 products authored matching ProductRole quality; the rest sell an
unrolled design or a design no product sells (Core Power, Industrial
Thermostatic Heater, pswarm, plight -- all already flagged unsold in the
Cut 1 census).
docs/stats-power-cut7-roles.md is the legible review table the map's O7
calls for: every design's roles and which stat took each, grouped by item
kind, plus every product's authored mean/deviation and its basis (one real
brand identity -- Arctica/Alakrita on heat efficiency, from
item-provenance-target.md -- the rest generic placeholders flagged for
operator review).
Verified before/after: AetherDb dangling/station-fit/hardpoint-fit output
is byte-identical; `loadout 1` output is byte-identical (no generation
behaviour moved); census reports 0 designs with roles and no matching
product spread; 144 Aetheria.Shared.Tests pass (was 141); the six-mutation
harness in mutation_tests_stats_power_cut8.py all behave as declared.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cut 7's gate removal (previous commit) only has anything to curve if some
shipped stat actually declares a PowerSupply term. Checked: none did --
removing the gates would have made brownout invisible (still full
performance at any nonzero grant) instead of graceful.
Added tools/AetherDb's "brownout-migrate [apply]" command (ShieldMigrate's
own dry-run/apply/report shape) and ran it against GameData/Aetheria.cc,
authoring exponent-1 (linear, the gentle default) PowerSupply terms on:
design behaviour stat before after
Arctica RadiatorData pumpedHeat 3 -> 4
Iapyx RadiatorData pumpedHeat 1 -> 2
Large Drive ThrusterData thrust 2 -> 3
OK Disperser RadiatorData pumpedHeat 3 -> 4
Skiron RadiatorData pumpedHeat 1 -> 2
Traction AetherDriveData torque 3 -> 4
cold like my heart RadiatorData pumpedHeat 3 -> 4
deep space burnout ThrusterData thrust 3 -> 4
No shipped ConstantWeaponData record exists yet, so ConstantWeaponData.Damage
has nothing to author against; the tool still targets it for whenever one
ships. None of the four targeted fields is a power-request field
(StatValidation.PowerRequestFields), so this does not trip
ValidateNoPowerSupplyOnRequest.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
f4d5659d landed with StatValidation's OptimalTemperature-bounds check replaced by
`if (false)`: the mutation harness was running concurrently against this same file
and a `git add`/`git commit` caught it mid-mutation. Restores the real check. Caught
because the harness's own "not yet reached" scars in doctrine are what prompted a
by-hand recheck of the just-committed diff rather than trusting the terminal output
that said 80/80 green a moment earlier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Migrated by a two-phase scratch console (neither kept): phase A dumps the
four retired exponent fields plus a curve fit (peak, optimum, near-peak
band) from the pre-Cut-1 code; phase B applies them as declared StatTerms
and authored OptimalTemperature/PlateauWidth under the new schema, in one
Commit, refusing to write anything if a single record fails to resolve.
348/348 stats and 51/51 EquippableItemData records migrated; zero
failures. AetherDb's census/factions/dangling/station-fit/hardpoint-fit/
loadout-1 are byte-identical before and after (captured with the matching
pre/post binary against the matching pre/post catalog, since neither
binary can open the other's catalog shape -- the pre-migration catalog no
longer opens under the new code, confirmed and explained in the report).
37 items fitted from an authored curve; 14 had none and got a full-range
plateau (reproducing the old "always full performance" behavior exactly).
281 of 348 stats evaluate identically at quality .5/full durability/optimum;
67 diverge upward (toward Max), the intended balance change Cut 0 flagged --
max delta ~73 units on a 750000-1750000 stat. Full table:
docs/stats-power-cut1-migration.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cut 2 of docs/addressables-cut.md. The asset move (git mv
Resources/{Prefabs,Schematics,Sprites/Icons} -> Content/...) and the
UnityHelpers.cs deletion already landed in 1fdf8151, picked up by a
concurrent session sharing this working tree; this commit is the rest
of Cut 2 landing on top of that shared state, atomically:
- Bump CultLib to cultlib-unity-v1.0.60 / caching-unity-v1.4.0 (both
45c2f40) in Packages/manifest.json, packages-lock.json and
Directory.Build.props, together with the 8 ServerShared
[CultInspectorAssetPath] usages becoming [CultInspectorAssetGuid] -
the .NET and Unity sides move together or nothing compiles.
- Assets/Scripts/EngineAssets.cs replaces UnityHelpers: loads an
Addressables key (bare GUID or guid[subAsset]) synchronously,
loading the GameObject and taking the component for the four sites
that load a component. ActionBarSlot, EntityInstance, ShipInstance
and ZoneRenderer call it instead of Resources.Load/UnityHelpers; the
inline "Assets/Resources/" prefix strips are gone with them.
CultCacheDrawers' schematic preview goes through
AssetDatabase.GUIDToAssetPath first.
- Assets/Scripts/Editor/EngineAssetCheck.cs validates every stored
[CultInspectorAssetGuid] value: 32 lowercase hex, resolves to a file,
is addressable, and satisfies its member's consumer-type contract
(Texture2D for icons/logos/schematics, a GameObject with the right
component for prefabs) - table-driven, so an attributed member with
no row fails loudly instead of being skipped.
- GameData/Aetheria.cc: the scratch migration (Aetheria.Shared + the
pinned CultLib revision, a throwaway console app, never landed)
walked all 138 attributed field slots across 180 documents,
rewriting the 30 non-empty Resources paths to their .meta GUIDs -
108 stayed empty, 0 unresolved, matching the map's census exactly.
Verification: dotnet test tests/Aetheria.Shared.Tests 61/61 green
against CultLib 45c2f40; Unity 6000.3.24f1 batchmode compiles clean;
EngineAssetCheck.Run passes all 30 stored references; the map's
negative greps are clean; tests/mutation_tests.py's 5 mutations (wrong
type, non-addressable, random guid, an old path, and an untabled
attributed member) are all caught and named, the control case and the
post-revert recompile stay clean, and the catalog/source are restored
byte-identical afterward.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
codex/cultcache-cutover (modern CultCache from CultLib, lifecycle stores,
CultMath) and codex/item-provenance (lot provenance ledger, neutral
wanderers and IFF stance, capability presentation seam, settings and
content maps) stacked on it. Operator play smoke passed 2026-09-17: new
game, combat and grudges, stance toggle, loot, save and continue with lot
brand and quality intact, death clears the run across relaunch,
FieldShieldTest behaviour (materials broken by the dead Substance plugin,
not by this work).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Probe Q3's body: re-upsert every stored ItemData with its own key in one
commit, through a throwaway scratch console (not part of the repo). Every
record schema-migrated from key 3 (Manufacturer) as an ignored extra slot
after the field's deletion; the rewrite clears that, matching the probe.
115 ItemData records rewritten, 12,686,267 -> 12,683,061 bytes. Reopening
reports 0 ignored-extra-slot migrations across all 180 stored records.
AetherDb factions/dangling/station-fit/loadout-1/hardpoint-fit are byte
identical before and after; census is also identical, because every design's
old Manufacturer field already agreed with the product that sells it (probe
Q1: 0 designs with more than one maker, 0 unset-maker products).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The previous commit replaced the ignore line for GameData/PlayerSettings.msgpack
with run.cc and player.cc, and `git add -A` then picked up the operator's local
settings file. Q10-2 A discards that file; it was never tracked before. This
removes it from the index only, so `git ls-files GameData` matches Cut 9 again.
The working copy is left for the operator to delete.
Builds: headless. Unity does not build yet (see the previous commit).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The deletion line lands before RunSave, as the spec orders. Deleted, not
demoted:
- PlayerSettings.SavedRun (Key 1 stays unclaimed) and the SavedGame
constructor that upserted a fresh SavedZone per zone on every save.
- ActionGameManager: the PlayerSettings.msgpack getter, file path and
writer; the .loadout format (_loadoutPath, Loadouts, SaveLoadout and its
default-options serializer, the commented loader); OnApplicationQuit and
SaveState; SaveZone, which had no caller.
- MainMenu's SavedRun Continue branch and both `SavedRun = null` writes.
- InventoryPanel's Save Loadout and Restore Loadout bodies.
- InputDisplayLayout's KeyboardLayouts file reader, ParseJson,
AssociateInputKeys, SaveLayout and the usings they alone needed.
- AetherDb's Cut 9 importer (Import.cs, legacy-census, import).
- The three-gates note on loading writes; Cut 3 made loading non-writing.
- .gitignore ignores GameData/run.cc and GameData/player.cc instead of
PlayerSettings.msgpack.
DOES NOT BUILD in Unity: ActionGameManager, MainMenu and InputDisplayLayout
still reference the deleted members until the next commit wires RunSave,
the settings getter and the catalog layout read. Headless builds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AetherDb's one-off boss hull command becomes `dangling`: it walks every
catalog record's CultRecordRef members by reflection (plain refs, list and
array elements, ref-keyed dictionary keys, nested [MessagePackObject] and
[Union] values), prints each ref that resolves to nothing as
`<record> <DeclaringType.Member> -> <key>`, and with `clear <Member>` unsets
those refs or removes those dictionary keys. Dry run unless `apply`, which
alone opens the catalog writable and lands every changed record in one
Commit. Faction.BossHull stays clearable through it.
Ran `dangling clear CompoundCommodityData.DemandProfile apply` (operator
ruling, option B): 3 keys removed, 2 on Mouth Adapting Gummy Molars and 1 on
Neural Lace, pointing at the deleted Conscientiousness and Neuroticism
attributes. `dangling` now lists exactly the three WeaponData.AmmoType refs
(DeathCluster, FastBlast+-, pretty pretty bang bang), left for the operator's
Studio click-through. census, factions and hardpoint-fit are byte-identical
to the Cut 9 captures. The commit rewrote Aetheria.cc in 1.0.59's canonical
unset-ref form.
Builds: headless.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AetherDb gains legacy-census and a one-shot import (tools/AetherDb/Import.cs,
deleted by Cut 10). The import rewrites each legacy [tag, payload] record by
the target type's [Key] shape: slot 0 Guid becomes the record key and nil,
CultRecordRef members and DatabaseLink wrappers become D strings, the all-zero
Guid becomes nil, StatModifierData.RequireBehavior keeps the simple type name.
All 180 records land in one Commit; a second import refuses.
InputLayout moves to the catalog (Q9-1 A), with the test fixture seeding it
while the catalog is writable. GameData/*.cc is LFS, GameData/*.lock ignored.
The legacy msgpack and ansi104.json sources are removed.
Imported: SimpleCommodityData 13, CompoundCommodityData 51, GearData 25,
HullData 3, NameFile 12, Faction 12, PersonalityAttribute 3, CargoBayData 4,
DockingBayData 1, WeaponItemData 18, FactionProductData 37, InputLayout 1.
Six refs dangled already in the legacy data and are preserved as authored.
The Key(0) precondition checks only the Guid-slotted tagged types; InputLayout
is imported bare and keeps its Key(0).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deletes only the two candidate groups that survived independent re-verification
and had zero collision with the live codex/aetheria-state-rebuild branch:
- GameData/Narrative/HeroOrZero.json, GameData/Narrative/Locations/TestA.json,
GameData/Narrative/Quests/TestQuest.json: StoryProcessor.cs only ever calls
DirectoryInfo.EnumerateFiles("*.ink"/"*ink") against these directories; no
.cs, .csproj Content/None glob, or other file in the tree references these
basenames. Confirmed via rg across the whole tree and voidbot search_sources
(no hits either way).
- Vault/Aetheria/scratch.md: zero-byte Obsidian vault scratch file, no
references anywhere in the tree, no voidbot search_sources hits.
Kill-attempts that came up empty (recorded for the record, not evidence of
absence beyond what's stated):
- rg for basenames HeroOrZero.json/TestA.json/TestQuest.json/scratch.md
across the whole tree excluding Library/Temp/obj/bin/.git: no hits.
- Economy.Server.csproj and Economy.Shared.csproj inspected for wildcard
Content/None includes that might implicitly sweep in the JSON files: none
found (Economy.Shared only globs ServerShared/**/*.cs as Compile).
- mcp__voidbot__search_sources queried for both candidate groups: no
consumer hits, only unrelated fuzzy matches.
NOT deleted here despite being in REC-095's candidate list (see coordinator
report for full detail): StrategyGameManager.csbak, CultClient.cs,
CultCache.cs backing-store classes, Economy.Server/appsettings.json, and
Economy.Shared/bin+obj all collide with commits already on
origin/codex/aetheria-state-rebuild (which has independently already deleted
or heavily rewritten those exact paths) and are therefore BLOCKED per the
no-touch-live-branch-paths rule, not executed from this worktree.
REC-095.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
One product per design that carried a manufacturer, keeping its name,
description and maker. No design has roles yet, so every stat still reads
the item own workmanship and behavior is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The centered 4x4 reactor left no 4x4 interior block free, so the only
docking bay could never fit and every non-tutorial station threw
InvalidLoadoutException. Edited by the operator in the database tools.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>