Commit graph Aetheria/tests
Author SHA1 Message Date
Meta Vens
db19ecfeb7 EvasionTrackingTests: the entity overload's offset is checked with the shooter away from the origin
Stryker survivor at FireControl.cs:211 (target.Position + source.Position) was invisible while the shooter sat at 0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 17:43:21 +02:00
Meta Vens
7d80af6dfe EvasionTrackingTests: both guns on the one shooter, at the origin at rest
A ship's targeting gear carries its own item quality, so Tracking(shooter) differs between two ships fitted alike:
the gun-times-ship comparison needs two designs on one ship. The gunner now carries FastBlast+- and ColdFire, and
the mount fixture puts it back at the origin so the sweep is the geometry the test states.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 17:02:52 +02:00
Meta Vens
2b7cf309d2 EvasionTermTests: EvLonginus carries the Targeting Computer at the generated Longinus's cell; the stop-jinking probe reads at a half-period of 0.5 s
Tool gear fits only interior hull cells and the Fire Control Array has no free one on a Longinus. The jink that
stops at t=3 s has been quiet longer than the 0.75 s window by t=4 s, so the Djinni reads 0 there: the jink is the
0.5 s half-period that was already used in the speed-demon rows.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 16:55:54 +02:00
Meta Vens
e5232ad9d3 EvasionTrackingTests: take the targeting gear offline through its durability, as the gear tests do
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 16:45:54 +02:00
Meta Vens
286a610b17 EvasionTrackingTests: the mount term's rules, with EvCross taking a velocity
AngularVelocityIsTransverseOverRange, TheMountHitsHalfAtItsRate, TrackingRateIsGunTimesShip,
LightAndHeavyGunsSplitOnAFastCloseCrosser, ABigGunHitsABigShipAtRange, TheJinkIsStillForgivenPerShip,
AShotFreezesItsMount, AnUnauthoredWeaponHasNoMountLimit. Rates are set on the loaded designs in code.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 16:43:32 +02:00
Meta Vens
e360ceeb27 Evasion r6: drop the aether drive from the envelope; the gemini fixtures fly thruster hulls
Ruling retire-longinusx. AetherDrive.Manoeuvre and the drive line in Ship.RecalculateEnvelope go: the envelope
sums thrusters only. TheDrivesReportReadsItsStateAndTheShipsSpeed, the EvGemini fixture and the drive-only asserts
are deleted. Sideways jinks and the shooters' target move to the generated Djinni; the gun platforms (FastBlast+-,
ColdFire) are EvLonginus, the Duel's guns on a Longinus. TheThreeShipsOrder becomes TheShipsOrder.

Not built or run on its own: verified together with the mount term at the head.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 16:39:45 +02:00
Meta Vens
593958ec2d EvasionTermTests: one-way ships are probed at 160 degrees, not the knife-edge at 180 where the two turn directions tie
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 16:21:41 +02:00
Meta Vens
ee5f5cbb49 EvasionTermTests: reach for ships that can thrust one way only, over windows long enough that the long way round is best
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 16:19:49 +02:00
Meta Vens
78daa12db5 EvasionTermTests: reach all the way round and for a ship that cannot turn, the face form past a right angle, the degenerate guards of the term and the track
Stryker on the batch's ranges left the corner faces, the wrap, the no-turn box support, the time before a face may thrust,
the zero line of sight and heading, the Observe guards and thresholds, and a step of no time alive; each is pinned here.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 14:40:41 +02:00
Meta Vens
e494454941 EvasionTermTests: the diagonal jink fixture asks for a spread of 3 m, not 5 (it reads 4.997)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 12:47:31 +02:00
Meta Vens
0ca7a7c98e EvasionTermTests: the forgetting probe jinks inside the window; the aggregate tolerance reads a negative torque
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 12:39:58 +02:00
Meta Vens
5f404d5094 EvasionTermTests: pin reach geometry, the oblique line of sight, the track window and forgetting, the drive's inputs and the live-thrust readers
Reach against a brute-force turn search (M26) on five envelopes, two windows, an oblique heading; a line of sight at
30/45/120/200 degrees rotated not reflected; evasion from the heading, not the velocity; the entity's track at the
solution window; the drive's offline gate and speed efficiency; the forget time as a function of the window, coasting
and burning; every Ship thrust aggregate and the strafe compensation against live thrust. TheSpeedDemonNumbers now
states what the code gives, to 0.5 percent.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 12:32:58 +02:00
Meta Vens
46b2850165 ASpeedAboveTheLimitIsNotEvasion reads every tick after the clamp: the track forgets within a window
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 06:02:34 +02:00
Meta Vens
522b5af0b4 ManoeuvreTrack forgets a whole window after the last change of vector; tests stop resetting it, and pin the three fixes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 05:39:41 +02:00
Meta Vens
2910a35dff EvasionTermTests: reach and evasion read each side of the envelope
An asymmetric forward-only envelope pins the clockwise and counter-clockwise sides, the
mirrored direction, the two-sided average capped by the observed spread, and the track's
cross term.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 03:37:31 +02:00
Meta Vens
f8065a4d2b EvasionTermTests: which thrusters are left decides the envelope
Destroy the Djinni's right-pushing thrusters and the envelope loses its right push and
the turn they gave one way; reverse push and the Traction drive's turn rate are checked
against the ship's own flight.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 03:12:47 +02:00
Meta Vens
da2957b81c Evasion term: reachable spread from the thrust and turn envelope, realised by changes of vector
Every hit price gains one factor, PDeviation(Evasion, Tracking): how far the target can
and does move off the line of fire within SolutionWindow (0.75 s). Capability is Reach, an
eight-face closed form over the ship's ManoeuvreEnvelope (summed from what each live
thruster and aether drive reports with its own Execute arithmetic, read live: a thruster's
Thrust property is stale until it fires, which is why the Djinni moved 1.6 times its stats,
M25). Behaviour is ManoeuvreTrack, observed once per Entity.Update from the measured
acceleration; a steady burn, coasting and a dither much faster than the window do not
evade, and sideways speed alone does not (ruling evasion-speed). The commit price adds the
term at any flight time, so an instant weapon feels a jinking target. Forecast owns the
term for HitProbability and Inspect, which gain Evasion and PEvasion.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 00:48:27 +02:00
Meta Vens
d9f85dc639 Merge origin/master into mining: resolve five conflicts by owner, delete the belt-task machine
Mining owns belts, chunks and target picking; scenarios owns admission and run
staging; master owns ships and fire control (rule scenarios-cut.md S4).

- AetheriaStores.CatalogTypes: nine-type union, master's list plus FieldKindData, no Scenario.
- tools/AetherDb/Program.cs: both cases (ship-authoring, field-kinds), one usage string.
- Zone.cs: master's MineAsteroid dropped (mining deleted its inputs); scenarios' SettleBelts and its three calls deleted.
- RunStartTests: the two belt-task tests deleted (they read belt.Transforms and MineAsteroid).
- FireControlCut124Tests: master's strict Exact assertions; mining's CompatibleDrift allowance and its comment dropped.
- GameData/Aetheria.cc: master's pointer 70a7b0a9. This commit lacks the Asteroid field kind in the catalog, so
  TheShippedCatalogHasAPickableFieldKind fails here by design; the next commit rebuilds it.

Builds: this commit builds (verified at the end with commit 2); the catalog pin test fails at this commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 15:29:29 +02:00
Meta Vens
561a21f3b2 Mining target queries tests: the blind ship needs no tick; it has no equipment to bring online
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:20:37 +02:00
Meta Vens
9e10166c76 Mining target queries tests: press pruning pinned by per-press examined ceilings near the measured costs
A second density-equal belt size and reach, held-target presses and the reticle at three headings,
each ceiling within about 10% of the measured count; the shared ceiling drops from 1500 to 700.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:19:23 +02:00
Meta Vens
c57466a398 Mining target queries tests: tie-break across belts by field key, and nearest-first pruning from no target
Pins two Stryker survivors: Entity.Order's field comparison and DistanceKey.Bound's forward bound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:06:30 +02:00
Meta Vens
7a01e608ba Mining target queries tests: a launcher-only ship may see a ship but picks no rock; name the press ceiling
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:49:55 +02:00
Meta Vens
793fdc8789 Mining target queries tests: pick the sensor that sees a share of the rocks in reach; report every press cost together
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:44:38 +02:00
Meta Vens
60383cf00e Mining target queries tests: brute-force order, farthest, smallest angle, cost, reach, enemies
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:38:21 +02:00
Meta Vens
8cd68f4e65 Pin that a failed start's own writes are removed: the failed starts write a record the saved run does not hold, and the open store must not keep it
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 22:36:04 +02:00
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
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
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
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
16f7bdbfab Mining index pins: a belt region's bounds stay tight and a rock exactly at reach is found
Three tests in MiningIndexTests, no production change. RegionsStayNearTheSearchArc bounds the share
of a small search's regions that lie past reach on both sides (window widened, nearest loosened);
VisibilityBoundPrunesADimBelt bounds rocks examined against rocks in reach in a half-lit belt of
largest rocks; ARockExactlyAtReachIsFound searches from 1-300 units with reach set to a rock's exact
distance, a third of them radially outward from a belt's outermost rock. Each threshold's unmutated
and mutant values are in its comment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 16:48:05 +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
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
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
a4e8e14718 Mining index: the index alone decides reach; tests pin what Stryker found loose
BeltTargets drops its own reach skip (TargetRegion.CanHold owns it) and an
empty-belt guard AsteroidBelt already makes unreachable. Tests add an
off-centre sun, whole-belt searches across the antipode, cost after time
passes, a late short step that re-keys nothing, and an entity search off the
origin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:25:32 +02:00
Meta Vens
944baa02a7 Mining index tests: fit the observer before it activates; break distinct rocks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:08:48 +02:00
Meta Vens
6a79f87a64 Mining index tests: brute-force equality, bounds, pruning and cost
The two chunk-query tests compare sets through Zone.Targets.Within.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 15:02:52 +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
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
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
83d8371e9c Mining Cut 3 tests: commit Soul's probes and the shipped field kind check
- AFirstLoadKindIsSavedFromACleanStore: FieldKinds.Ensure's kind is saved
  when the store was clean at load (ZoneData.cs:162).
- SetTargetRefusesALitChunkBeyondSight: a lit rock too far to see is
  refused (Entity.cs:345).
- TheChunkQueryMatchesBruteForce: 3000 random queries, off-origin, two
  belts, across the outer skip edge (Soul F7).
- ThePingArmIsUnchangedByTheGainExtraction: Soul's ping sweep, golden
  recorded at cb4a1dbd; kills the Sensor.cs:168 and :189 mutants.
- TheShippedCatalogHasAPickableFieldKind (Soul F2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 13:02:27 +02:00
Meta Vens
f88d1fc1b3 Mining Cut 3 fix: launchers do not count toward rock reach (Q12 A)
Weapon.CanMine is the one mining predicate; LockWeapon overrides it to
false. Entity.VisibleChunksInReach counts only weapons that can mine.

Tests: LaunchersDoNotCountTowardChunkReach (a launcher-only ship is offered
no rock; a gun of 200 beside a launcher of 400 is offered the near rock
only) and AnOfflineWeaponAddsNoReach (Soul F8: reach reads Active, not
Enabled).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 13:02:26 +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