Commit graph

2,498 commits

Author SHA1 Message Date
Meta Vens
d44df96fb0 SeedRules scrambles the item random between the arena and staging, so the staging step's own seed is pinned
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:04:17 +02:00
Meta Vens
8a1e205cf0 A new run replaces the saved run only once it has staged; a failed start says why and leaves the saved run
Launch cleared the run store before generating, and a generation or staging failure only reached the log: the
Generating Galaxy dialog stayed up, StartGame threw, and the saved run was already gone.

RunSave.Replace runs a start with the saved run still stored: when it returns a staged run the saved run's records go,
and when it returns null or throws, only the records it wrote (the arena's orbits and bodies) go. StartGame's
new-run branch is StartScenario, chosen by PendingScenario rather than by the absence of a SavedGame; it mints into an
empty ledger, and a failed start clears CurrentGalaxy (so quitting saves nothing) and refuses on the main menu with
every failure. Launch no longer clears; a galaxy that throws is refused on the title menu. The menu offers Continue
whenever no run is live, which replaces MainMenu.InGame (cut, with its prefab value and scene override), so a
failed start can resume the saved run in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:03:50 +02:00
Meta Vens
02e7fd4b7e A fixed seed fixes every fit: RunStart seeds the run's item draws from the galaxy's seed
ScenarioStage.Generated picked from ItemManager.Random, which is clock-seeded per process and advances in play, so a
relaunch of Djinni Shakedown or Long Haul in one session gave the player a different fit; every branded lot's
workmanship and role fills came from the same clock stream, so arena gear and explicit fits varied in quality too.
Galaxy now keeps the seed it was generated at, and RunStart.GenerateArena and Stage each reseed the item manager's
random from it, one stream per step, so what runs between them cannot shift either.

SeedRules relaunches every fixed-seed scenario around a clock-free Main Galaxy launch and a scrambled item random,
and compares the galaxy (links, factions, homes, exit too), the arena down to each item's maker and workmanship, and
the staged fits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:01:17 +02:00
Meta Vens
4d1334e044 Arcs runs at seed 103 again, as the spec sets it: its prelude galaxy generates now that every zone is linked
Reverts 0854d91d.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 21:59:18 +02:00
Meta Vens
e56af28892 Galaxy links zones along a double-precision Delaunay triangulation: the vendored float MIConvexHull dropped zones, so ~2% of galaxies threw
The vendored MIConvexHull (NIH, ported from double to float) returned triangulations that left whole sets of
interior zones with no cell at all (prelude seed 103: 22 of 64 zones; main seed 4247651650: 182 of 196). Those
zones had no link, Distance lacked them, and the constructor threw KeyNotFoundException placing the antagonist
home (prelude) or the entrance (main). Galaxy was its only consumer; Delaunay.Edges (Bowyer-Watson, double) replaces
it, and the 3,896 vendored lines go.

The three RestoredHullsTests loops that skipped seeds whose galaxy threw now require every seed to build, and the
stale comment that Galaxy mutates Faction.InfluenceDistance goes with them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 21:59:09 +02:00
Meta Vens
494d795550 Pin that generating a galaxy leaves the catalog's faction influence as authored
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 20:55:02 +02:00
Meta Vens
0854d91d77 Arcs runs at seed 107: seed 103's prelude galaxy fails generation (a pre-existing KeyNotFound in Galaxy's home-zone placement)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 20:45:31 +02:00
Meta Vens
c0be2843ea A galaxy's zone names are unique within the galaxy, not across the process
MarkovNameGenerator kept every name it ever gave in a static list, so each later galaxy in a session drew different
zone names at the same seed, and ZoneGenerator seeds a zone from its name: a fixed-seed scenario relaunched in one
session got a different arena. Galaxy now passes one used-name set to its factions' generators. The unused Reset goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 20:45:26 +02:00
Meta Vens
d0782a7d14 Every new run is a scenario: the script harness, the tutorial and main galaxies as scenarios, the New Game submenu and six test arenas
A Scenario is an abstract C# class compiled with the game: Generate picks the galaxy through GalaxyStage (Main or
Prelude, at the scenario's seed, the background noise drawn from the same seed), Stage places the run's first
entities through ScenarioStage (Fit, Bare, Generated, Preset, Player, Place, Cargo), which collects named failures
and admits nothing. RunStart generates the galaxy, the arena under Ambient and admits everything through Zone.Admit,
all or nothing. The aetheria.scenario record, ScenarioShip, ScenarioEntity, RunStart.Check and the null-scenario
branch are cut.

New Game opens a submenu: Tutorial Galaxy and Main Galaxy, then (editor and development builds) Djinni Shakedown,
Starved Reactor, Arcs, Duel, Launcher Angles and Long Haul, each with its brief. MainMenu.Launch is the one way into a
new run; ActionGameManager.PendingScenario carries the scenario to StartGame once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 20:33:55 +02:00
Meta Vens
8a0a29e0de Galaxy.IsPrelude is the one owner of whether a run is the prelude: ActionGameManager.IsTutorial and PlayerSettings.TutorialPassed are cut
IsTutorial duplicated Galaxy.IsPrelude; its readers read CurrentGalaxy.IsPrelude, and RunSave.Capture writes
SavedGame.IsTutorial from galaxy.IsPrelude with no isTutorial argument. TutorialPassed was never written and its only
reader was New Game's unreachable main-galaxy branch, which goes with it (S2 brings the main galaxy back as a
scenario). spawnturret's two identical generator branches collapse to one. Old player.cc files still load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 20:26:30 +02:00
Meta Vens
c37d6adfa8 Galaxy derives a prelude's halved faction influence instead of writing it into the catalog's Faction
A prelude halved every faction's InfluenceDistance on the shared catalog object, so each later generation in the same
session, prelude or main, started from an already-halved value, and a continued prelude read the unhalved one. A
fixed-seed scenario relaunched in one session therefore could not reproduce its galaxy. Galaxy.InfluenceOf derives
the reach from IsPrelude; Galaxy and ZoneGenerator read it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 20:25:26 +02:00
Meta Vens
4895c75236 Bind Ship Collection: compute the stored .cc path before binding, absolute when relative cannot hold
The bind called bpy.path.relpath after setting aetheria.asset_kind and aetheria.id, so a .cc on another drive than the
.blend raised and left the collection half-bound, and an unsaved .blend stored a path relative to the working
directory. The stored path is now computed first: absolute for an unsaved .blend, '//'-relative when relpath succeeds,
absolute when it raises ValueError. Every reader already resolves both through bpy.path.abspath.

smoke_package.py gains the bind cases: unsaved stores absolute and survives two Save As moves, a failing bind leaves
no aetheria.* property, same-drive stores '//'-relative, and with SMOKE_OTHER_DRIVE the final bind crosses drives
before the package passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 17:37:21 +02:00
Meta Vens
7d649d5c31 Package Ship: headless Blender smoke, and the authoring doc says how Package and create --like are used
smoke_package.py builds a primitive ship from role-tagged objects, creates it --like Djinni, saves a layout with an
internal reactor, packages it and requires validate to pass; then swaps the thruster disc for an empty and requires the
refusal naming the anchor; then restores and packages again so the left-behind package is good. Proof gate 2's
outstanding authoring action is now Package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 17:13:44 +02:00
Meta Vens
82ca9e9be1 aetheria_ships: Package Ship derives anchors and ship.glb from the bound collection and runs AetherDb validate
Every object tagged aetheria.role becomes a ShipAnchor whose Id and ModelNodeId are its aetheria.id (a muzzle's ParentId
is its parent's). The collection, Grease Pencil excluded, exports to ship.glb with custom properties as node extras;
replace_visual writes the anchors, a lone Grease Pencil object's lines are captured, and AetherDb's verdict shows in the
panel. The add-on preference 'Aetheria repo' names the checkout; by default it is the nearest folder above the .cc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 17:13:42 +02:00
Meta Vens
aca1d53e6f ship_cc: replace_visual writes ShipAuthoring's model asset and anchors, pinned to the C# keys
MODEL_ASSET_SLOT, ANCHORS_SLOT and ANCHOR_MEMBERS sit beside the other slot constants and ShipSchemaPinTests binds them
to ShipAuthoring's and ShipAnchor's [Key]s. replace_visual carries an anchor's slots past Order by Id, refuses a blank
or duplicate id, a wrong-length row and a changed ship id, and leaves the hull record and the lines alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 17:07:10 +02:00
Meta Vens
f98be434f0 AetherDb ship-authoring: create --like a shipped hull, and validate reads the GLB when present
ShipAuthoringStore.HullLike copies a reference hull through its MessagePack round trip and resets Name, Shape,
Hardpoints, Prefab, Schematic and Visual. 'create ... --like <name>' opens the shipped catalog read-only and refuses an
unknown or non-ship hull. 'validate' runs ReadPackage when ModelAsset names an existing file and says which it judged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 17:07:09 +02:00
Meta Vens
f5743cbad2 Ship packages: a thruster or radiator anchor on a mesh-less GLB node is refused at bind
ReadNodeIds is the one GLB parse and now records, per aetheria.id node, whether it carries a mesh. Bind refuses a
thruster-emitter or radiator-mesh anchor whose node has none, naming the ship and anchor (ruling
thrusters-radiators-are-meshes), so Compose and validate refuse such a package before the catalog sees it. AetherDb
'ship-authoring validate' judges the GLB when it exists (next commit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 17:07:08 +02:00
Meta Vens
ed15d34b35 Tests: generated loadouts give every reader its hardpoint (Soul's headless probe)
Soul's scenarios-adopt probe S4 as a committed test: on generated ships,
stations and turrets every weapon, thruster and radiator holds a non-null
Hardpoint containing all its cells, and Tool gear and the hull hold none.
It pins the input the muzzle, arc, thruster-emitter and radiator readers
dereference (finding headless-reader-input).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 16:14:10 +02:00
Meta Vens
4b002b50bc Merge master 239f3599 into eureka/aetheria-release-scenarios: ship render fixes
The one conflict, ShipInstance.cs's thruster emitter lookup, keeps the
branch's thruster.Item.Hardpoint.Transform and master's new
ThrusterHardpoint.WireExhaust(particles, thrusterHardpoint). Master's side
as written would have brought back the origin-cell hardpoint lookup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 16:09:55 +02:00
Meta Vens
cfd9884a33 Merge master into eureka/aetheria-release-scenarios: take the ship-mounts lane
The one conflict is EntityInstance's SoundBank block, which this branch had
moved onto item.Hardpoint and ship-mounts deleted: it stays deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:41:54 +02:00
Meta Vens
239f359990 Ship exhaust: wiring an exhaust to an emitter turns Use Mesh Colors off
The emitter carries the invisible material, whose alpha is 0, so an exhaust
prefab left at Unity's default (Use Mesh Colors on) emitted nothing. The
shipped thruster prefabs only worked because theirs is off. ThrusterHardpoint
.WireExhaust now owns the wiring and turns it off; ShipInstance calls it. The
preview smoke wires a default particle system to each emitter on the clone and
requires every particle emitted and none transparent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:39:14 +02:00
Meta Vens
6709b06e2e Ship preload: a mod ship that fails to load or assemble is skipped, not fatal
PreloadAsync rethrew on the first failing hull, so one bad package faulted
Loading and no mod ship could spawn. Each hull now loads in its own try: a
failure destroys its partial visual, is logged with the hull's name, and the
rest still preload, as Compose skips a bad package. The play smoke installs the
package beside a broken sibling that composes but cannot assemble (its map icon
moved onto a meshless muzzle node) and proves the sibling has no prototype while
the good ship spawns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:38:35 +02:00
Meta Vens
fc73d7abcd Ship render: the hull collider carries the invisible material, so clones draw nothing
forceRenderingOff is not serialized, so Instantiate and SaveAsPrefabAsset dropped
it and every cloned mod ship (and every FBX-built prefab) drew its collision hull.
The collider renderer now takes the template's invisible material, as the thruster
emitter does. The preview smoke checks the collider on the clone and the prefab
smoke checks it on the configured prefab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:37:33 +02:00
Meta Vens
9787df6f4b Tests: a full hardpoint offers no space (Stryker survivor at TryFindSpace's last return)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:35:51 +02:00
Meta Vens
bba169cac5 Tests: an equipped item knows its hardpoint (Soul's P30 fixtures)
Soul's scenarios batch-4 probe P30 lived only in a session scratchpad. Its
fixtures are now tests: an L gun in an L hardpoint whose origin lies outside
it, an edge gun whose origin lies in a neighbouring radiator hardpoint,
TryFindSpace finding what ItemFits accepts (unrotated and turned), reload into
the same hardpoint, and Tool gear holding none. Three batch-4 minors are
pinned too: IsFilledBy against a cell oracle written in the test, the last-row
placement search, and billing independent of heater equip order.

The file is a part of RunStartTests, so it shares that fixture's scratch-hull
and catalog helpers instead of a second copy of them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:00:00 +02:00
Meta Vens
5ea59ac6b5 Entity: an equipped item keeps the hardpoint it occupies
The placement rule (HardpointAt) already finds the one hardpoint an item lies
in at equip; TryEquip threw that answer away and eighteen readers recomputed it
from the item's origin cell, which need not lie in the hardpoint (Soul's
scenarios batch-4 P30). EquippedItem.Hardpoint now carries the answer, null for
Tool gear and the hull, and every origin-cell lookup reads it instead:
FireControl.ArcFor, the eleven weapon managers, EntityInstance, ShipInstance
and ActionGameManager's articulation grouping. Entity.Hardpoints[,] stays the
per-cell map for armour and display.

TryFindSpace's hardpoint search tries every origin the fit rule can accept,
including ones up and left of the hardpoint, so a design whose shape lacks its
origin cell is found wherever ItemFits would place it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:57:27 +02:00
Meta Vens
80de88f267 Ship mounts: each weapon needs a muzzle of its own
Kills the Stryker survivor that armed every weapon with any muzzle on the ship
(the && in the per-weapon muzzle check turned into ||): a second weapon mount
with no muzzle is refused even when the first has one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:54:03 +02:00
Meta Vens
2d39c83504 Merge master into eureka/aetheria-release-scenarios: adopt the scenarios lane onto master's base
The one conflict is AetheriaStores.CatalogTypes: keep ShipAuthoring from the
ships lane and Scenario from the scenarios lane.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:53:29 +02:00
Meta Vens
da2a299baa Ship mounts: hide the thruster emitter with the invisible material
forceRenderingOff is not serialized, so the prototype's clone drew the
emitter again; the preview smoke's clone check caught it. The emitter's
materials become the template's invisible material, which survives
Instantiate and which EntityInstance keeps as the renderer's own material.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:48:51 +02:00
Meta Vens
95c0fa621b Ship mounts: a thruster's mesh is an unrendered emission surface
Ruling thrusters-radiators-are-meshes: thruster and radiator mounts are meshes;
the thruster's is not drawn and is the surface its exhaust emits from, the
radiator's is drawn. The assembler already required a mesh for both; it now
turns rendering off on the thruster emitter, and the preview smoke checks it.
The authoring doc states the mount rules and the mesh rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:39:09 +02:00
Meta Vens
976b711905 Ship mounts: anchors only for visible hardpoints, every role rule in Validate
ShipAuthoringStore.Validate now alone decides which hardpoints carry anchors
and which role each plays. A thruster, radiator, energy, ballistic or launcher
hardpoint needs an anchor of its mount id with role thruster-emitter,
radiator-mesh or the new weapon-mount; every other hardpoint is internal and
no anchor may take its id. A mount-role anchor must be a hardpoint's mount, a
muzzle must hang off a weapon mount, and each weapon needs a muzzle; these
checks move out of ShipModPlan.Build, which now only maps a validated pair to
slots and throws nothing itself. 'articulation' stays in the vocabulary for
pivots and is never a mount.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:39:08 +02:00
Meta Vens
23976aada7 Ship mounts: delete EquipmentHardpoints and the plan's Equipment list
The array's only reader was the dead SoundBank block in EntityInstance, which
looked up a hardpoint transform and did nothing with it. ShipModPlan.Equipment,
ShipModShips' assignment, the preview check, the FBX builder's HP.Equipment
case and its smoke assertion all fed that one dead reader. An HP.Equipment node
is now refused by the builder as an unknown hardpoint kind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:34:05 +02:00
Meta Vens
7d1b74fca6 Merge master into eureka/aetheria-release-ships: adopt the moddable-ships lane onto master's base
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:18:39 +02:00
Meta Vens
f1dee18409 Scenarios map: belt-freeze rulings (general targeting index; fix Previous off-by-one)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:04:00 +02:00
Meta Vens
1cc08e20c0 Scenarios map: mining fix batch landed on codex/mining; belt freeze stopped at structure fork
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 13:37:50 +02:00
Meta Vens
22e9741984 Scenarios map: operator rules mining F1 fixed before merge; launchers excluded from rock reach
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 12:45:55 +02:00
Meta Vens
d00a16480d Scenarios map: mining Cut 3 Soul (hold for one fix batch); merge rule corrected
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 01:48:47 +02:00
Meta Vens
5dd03cab00 Scenarios map: Soul on batch 4 (origin-outside-hardpoint blocker); queued under drain
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:15:09 +02:00
Meta Vens
4809b0663f Scenarios map: F1 ruled a separate thermal balance campaign; Cut 1 merges with the freeze as a known defect
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:56:45 +02:00
Meta Vens
aa3baf12e4 AetherDb: retire the station-reactors and allegiance-self one-shots
Both landed their content; git history keeps them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:13:40 +02:00
Meta Vens
2d30403ab2 Tests: pin generation's fill preference, lot reuse and thermostat billing
Soul's S6. Generation always gives Zenith's 16-cell Reactor hardpoint a reactor
that fills it though smaller ones fit; a generated Djinni's eight thrusters
share one lot; across 5 K either side of a heater's target the bus bills it
exactly when its thermostat is open; and a thermostat gates only its own
behaviour group (a two-group fixture: the closed group's 10 is not billed, the
other group's 7 is).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:13:38 +02:00
Meta Vens
ff2be8e26f One placement rule for hardpoint gear
Soul's S3 and the S2 ruling ("B is the design intent, saving slots in a
hardpoint can be a valid tradeoff for crowded ships if you really need to fit
an extra tool"). Entity.HardpointAt is the one placement rule: at an origin,
the item lies within a hardpoint of its type at that hardpoint's rotation
(HardpointData.TakesAt), its own cells are free, and that hardpoint holds no
other hardpoint item. The origin no longer has to be a hardpoint cell, and
TryFindSpace tries every offset inside a hardpoint, the offsets the fit rule
tries, so an L-shaped hardpoint takes its L design instead of generation
throwing. Leftover hardpoint cells may hold general gear, and a hardpoint still
holds one hardpoint item.

Tests: an L hardpoint takes its L design by hand and in generation (Soul's
P11); a turret's gun goes back beside the tool gear in its leftover cells
(P21); a second gun in a roomy hardpoint is refused; a saved entity reloads to
the same loadout with its items in reverse order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:13:37 +02:00
Meta Vens
d50fd1b973 A faction reaches its own gear; allegiance names only other factions
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>
2026-09-30 23:13:34 +02:00
Meta Vens
f458206c76 Content: a station reactor for every reactor maker
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>
2026-09-30 23:13:31 +02:00
Meta Vens
09050ae920 Tests: drop the flaky failed-belt-task test
AFailedBeltTaskSurfacesOnce swapped a belt's asteroids while that belt's task
could still be running, so it failed in 5 of 8 runs including unmutated ones
(Soul S1). It tests belt-task machinery that codex/mining deletes (Cut 1,
22a54ccb), so it goes rather than being reworked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:13:27 +02:00
Meta Vens
ad42ff5554 Scenarios map: S2 ruled B (leftover hardpoint cells may hold tool gear)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:23:28 +02:00
Meta Vens
8863f05ebb Scenarios map: belt code superseded by mining; merge rule for Zone.cs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:22:36 +02:00
Meta Vens
b2f74f0565 Scenarios map: Soul on batch 3 (flaky test, occupancy question, L-hardpoint crash, respawn timers)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:20:48 +02:00
Meta Vens
b3b550dbaf Scenarios map: self-allegiance ruled (own-faction reach implicit; 11 self-entries removed)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 21:37:20 +02:00
Meta Vens
d19b7251ac Scenarios map: stations get radiators; per-manufacturer reactors kept; self-allegiance question
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 21:33:52 +02:00