One reader, LoadoutGenerator.IsOffered, read by IsAvailable (ahead of the no-faction
shortcut), the AvailableProducts candidates (so the any-maker fallback cannot reach one)
and SoldHulls. A Loadout that pins the product still builds it. Rulings
off-market-is-unoffered-product and boss-hulls-exclusive.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ItemManager(uint seed, ...) refuses seed 0 and seeds Random from it.
- RunStart.ItemSeed(galaxy, step) is public (formula unchanged), refuses a
zero result; named steps ArenaStep, StageStep, ContinueStep and NoRunSeed.
- Continue seeds the item stream from the saved run's seed (ContinueStep);
a scene with no galaxy uses NoRunSeed.
- Zone's unpack scatter draws SimulationDice.For(CombatSeed, ScatterStream,
1-based pack ordinal), never the item stream.
- Loadout's scratch manager and AetherDb's catalog command take fixed seeds;
every test and Editor construction gains 1u (mechanical rewrite).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ItemManager no longer seeds itself from DateTime.Now, and Zone's unpack no
longer scatters ships with _itemManager.Random. Deletes before adds: this
commit does not build (the scatter and every ItemManager seed return in the
next commit).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Materialize now settles what the catalog alone decides, tries the cells on a
throwaway ItemManager (own ledger and stream, designs built unbranded), and only
then asks the chooser and mints lots. ZoneGenerator's copy-and-restore of
itemManager.Random is deleted, and the boss faction's LoadoutGenerator is created
on the first choice instead of as an argument. Resolve keeps its signature and is
Settle then Build.
Tests: an unbuildable boss zone equals the no-boss zone (serialized pack, ledger,
roster and gear, next item draw) for one failure, several failures and design-only
slots, across every faction as boss faction.
Not yet built or run when committed.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
BossOf refuses typed (BossRefusal Unset or Missing, Describe names the field and echoes no input).
ZoneGenerator builds the boss from the Loadout with ChooseProduct as the chooser; a refused or
unbuildable boss logs and spawns none. Galaxy picks boss factions through BossOf; AetherDb factions
prints the boss Loadout. Loadout vocabulary: no preset, no variant. Production builds; the tests
project does not until the next commit (RunGoalTests still sets BossHull).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A boss is a Loadout the faction references, never drawn (rulings faction-boss-is-a-loadout-reference,
boss-gear-is-a-loadout, demo-boss-hull-invented). This commit does not build: ZoneGenerator, Galaxy,
AetherDb and the tests still read the deleted members; the next commit replaces them.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The runtime no longer trusts the authoring tool for a bin: a NaN Floor weighed NaN and nulled every
draw of its design. AetheriaStores.Open names the field and echoes no value.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The all-weights-zero branch of ChooseProduct and the required-item fallback of RandomProducts weighed
every product 1, so a bin doubled its maker's presence there. Both now weigh by Share alone (the
preference drops out, the bins' shares do not). The sum of a line's bins' pass fractions is computed
once per weighting pass instead of scanning the product table per candidate.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
FactionProductData slot 7 Bin (schema id unchanged, additive as slot 6). Mint derives a bin's
distributions from its line on every lot, truncated by NextGaussianAbove (64 tries, then the cutoff).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
DropSeed = CombatSeed ^ Mix(Galaxy.Seed), derived at construction. A zone with
no galaxy, or a restored seed of 0, keeps its dice bit for bit; CombatSeed
still roots shot, patrol and range-sample dice. RunSeedFixture builds a test
zone's galaxy through RunSave.Commit and the Continue constructor.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Galaxy.Seed on a continued run is the saved seed instead of zero. A save
written before run-seed decodes Seed 0.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
GalaxyStage.SeedFrom is the one minter of a run's seed; both generation
constructors now take progressCallback and seed without defaults and throw
ArgumentOutOfRangeException on zero instead of reading the clock.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Rulings trojans-first, trojans-ride-host-period-with-stations. AsteroidBeltData
key 11 RidesRail; AsteroidBelt.Extent is the one belt extent rule (replaces
Zone's inline farthest-rock loop and the Math.Max at the well node); a swarm's
Periods are its rail's period. The generator draws swarms from a stream of its
own (TrojanStream), so no other draw in the zone moves. Tuning defaults are the
spec's proposals; the code default TrojanProbability 0 draws none. Existing
annulus tests skip swarm rails. Builds.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Price, tier, equipped thermal and durability exponents, wear and the unequipped durability exponent now read the one effective quality; no reader keeps a path to the assembly alone. Tests pin each reader against a lot whose part sits below its assembly. Unverified until the Yggdrasil run.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Code from eureka/aetheria-release-faction-curated-place-names. Conflicts kept both sides: Faction holds Assembly (key 19) and Places (key 21); AetherDb dispatches assembly-from-maker, place-names and doctrine-catalog, and its usage names both; FlightTests counts the Faction wire at 22 slots (19 is Assembly, 21 is Places).
The two LFS files are the merge's resolution, replayed on the post-assembly bytes, never merged as text or by side.
GameData/Aetheria.cc, per h1's two-step replay: (1) AetherDb place-names apply built at the branch's commit 1 (740e1ee7, merged onto the assembly merge so key 19 survives), run on the post-assembly catalog: purges the Markov NameFile records while their type exists and authors 15 place lists; (2) place-names apply built at this merged tree, run on step 1's output: authors Miss Terri's list (1 list). Each step's second apply said nothing to do and left the bytes identical; the whole chain run twice from the assembly catalog gave bytes equal except the record write timestamps (masked, both hash alike). Decoded independently with cultcache-py: 16 factions, key 19 Assembly filled on the 15 makers (Ewan Hart has none), key 21 Places 20 names on all 16, key 9 nil on all, no namefile type among the 321 records.
Assets/Resources/Settings.asset: the post-assembly file (Rarity values removed) with the four NameGeneratorSettings lines removed (NameGeneratorSettings, MinLength 5, MaxLength 10, Order 3).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Code from eureka/aetheria-release-assembly-from-maker-r2. The two LFS files are not merged as text or by side; they are the merge's resolution, made as follows.
GameData/Aetheria.cc: master's catalog (0f5def17's, sha256 a4ff0eff...ebee9) is unchanged by master since, so the branch's blob was checked against the replay. AetherDb assembly-from-maker apply, built from this merged tree, run on master's catalog twice from fresh copies and once more on its own output: 15 factions written; the second pass said No changes and left the bytes identical. The replayed bytes equal the branch's blob (sha256 2b18ff7f...90e... ) except for the 333 record write timestamps, each of which a fresh write restamps (masked to a constant, both hash alike). The branch's blob, which h5's full suite tested, is taken.
Assets/Resources/Settings.asset: master's file (b004d902..., which dropped AsteroidVerticalOffset) with the branch's Rarity cleanup replayed: the five Rarity values (1, 0.5, 0.15, 0.05, 0.01) removed, nothing else touched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ScenarioStage.Approach(entity, target) states a piloted entity's task as a follow task on the target, passed through Zone.Admit to the flight as the member's baseline task; it replaces Patrol(entity, orbit) and the orbit index, and RunStart's post-admit circuit overwrite. LockOn stages at .6, the quality Crossing and the other RunStart scenarios use (its brief states none), not .8 picked by outcome.
The bearing check keeps well-law r4's intent (measure against the hostile's actual pose, not the staged line) but reads the poses of the tick before the paint was first seen, which is the tick it was stamped in, with a .05 deg limit for float error; the live-pose check at .5 deg spent its budget on the paint inbox's deliberate one-tick delay. LockOnHoldsUnderOnePercentOfEachStagedInput moves hostile x, y and quality by 1% each way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The unseeded Random.Range prune leaves ZoneRenderer: the kept set is a function of the candidates, the kept count and the belt key.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces RockMeshing/AssignRockMeshes and the renderer's slot bucketing (findings scale-lookup-unpinned,
renderer-index-wiring-unpinned). The build gate message names the mesh and the field, not the radii.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Roche-margin check on a rosette's ring read heavy.Mass before any member had
settled; each member's own Settle later folds its overflowing children into it,
so a ring could stand with a member inside its Roche margin. Settle now places
and settles the ring's members first and judges the ring on ring.Max(Mass); the
queue skips members already settled.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ScenarioStage.Patrol(entity, near) states a piloted entity's patrol order (the orbit nearest a point) and RunStart applies it over the drawn circuit. LockOn stages its fit at .6 and the hostile on the orbit by the player. Tests: every SimulationDice stream draws independently of every other (they already did: the stream is mixed into the hash), the pilot's sample offset is on its own stream's grid, a patrol circuit does not move with items minted first, Crossing.ProjectorRange is read against the live range.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Combat.SampleDps and Zone.CreateAgent's patrol circuit drew from the item stream, so minting items moved
how a pilot fights and where it patrols. Both now draw SimulationDice.For(CombatSeed, stream, Agent.Id);
Agent.Id is the zone-scoped ordinal Zone.NextAgentId gives a pilot at admission (ruling
ai-sample-offset-off-item-stream).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DrawAhead.AssignRockMeshes ranks rocks by unworn size onto meshes in ascending radius; RockScale divides the
gameplay radius by the mesh's measured radius; ChunkAt is the one rock position for the renderer and the reticle
(ChunkHeight folded into it). InstancedMesh.Radius is filled and verified by RockMeshRadius. Tests pin the
assignment, the scale and that the renderer and reticle call DrawAhead (finding owner-not-pinned).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FusedRounds.StagedQuality (.6) states the shooter's quality so the Cluster Cannon's damage in TheDirectWeaponKillsTheFragileHullWhileASmokeRoundIsStillInTheAir does not ride the item stream. The Faction wire now has 20 slots (Assembly at 19); the Doctrine-at-17 rule is unchanged. LockOn is not staged here: see the question raised on the spec.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The NameFile records went with commit 2's apply, so the type, Faction key 9
(left as a retired-key comment), NameGeneratorSettings and its parameter on
Galaxy and GalaxyStage, the Settings.asset block, the Name Tools editor
window, the Geonames resources, the purge leg of place-names and the
minor-power and Pirates commands' name-file lookups all go. The Pirates
missing-name-file test pins a retired rule and goes with it. Factions shows a
places count where the geonames column was. Unity compile owed at merge.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each faction names the zones it owns from its own curated list (ruling
faction-curated-place-names): the home zone takes Places[0], the rest follow
in distance order, a spent or absent list falls back to unique catalogue
designations. Galaxy.NamePlaces replaces the Markov GenerateNames body. The
place-names command authors the 15-row table and, until commit 3, purges the
NameFile records and GeonameFile links while their type still exists.
The shipped catalog carries no Places yet (commit 2), so the tests that read
shipped lists fail at this commit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>