The backfilled Large Drives differ in quality, so a held forward thrust is a net torque and TurnRate never settled to zero. Release the movement demand with the turn demand.
Co-Authored-By: Claude Sonnet 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>
AetherDrive.cs: master deleted the behaviour (2cfdc728); the branch only added a
TurnRate line to it. Deletion kept. Thruster remains the one rotation actuator
and feeds Entity.TurnRate. No sim stepping outside the clock on master
(mines presenter, Pirates AI, lot-product all step through Zone.Update).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Large Drive and Small Drive shipped with unnamed Quality terms on their flat stats; the command keeps those exponents. The reset stripped them, so the new exponent check read the Thruster precedent instead.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A non-flat stat must carry exactly one Quality term, named, declared, with a positive exponent; a flat stat may not name a role. The check is one function with its own synthetic-stat test.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ExponentFor drew its pool from items.Except(targets), so growing the targets from six to twelve changed the exponents a rerun on master's catalog writes. The pool is now snapshotted once, from every design that declares roles and names a Quality term, before the loop mutates anything. Describe prints each named term's exponent, one test pins Autocannon's and LRMM72's exponents against the shipped blob, and one clears a single role of a two-role seller and expects only that role re-authored.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ShippedCatalogRolesAreLive checks every design of every kind: each non-flat stat reads one declared role,
declared roles are read, sellers author each once, role-mapped designs are not all flat (the tool answers
which, via Program.HasRoleMap). RolesBackfillIsAuthored pins ratios and roles, with the Autocannon
Penetration, Mine Range and LRMM72 LockAngle asserts. RolesBackfillCommandTests resets the backfilled designs
on a scratch catalog, applies, and expects the shipped catalog back, then replays as a no-op.
EveryShippedProductHasAMaker. TheEnvelopeComesFromTheGear bounds each drive by the catalog's Large Drive
Thrust range; ShippedWeaponOperabilityTests reads the catalog's DefaultEntitySettings.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
RoleMapFor answers for the Mine Launcher (MineLayerRoles) so roles-migrate and roles-backfill no longer
disagree on it; BackfillMapFor is deleted. Count, MinRange, DamageSpread and the reactor Modifier join their
kind maps, and the backfill points a varying stat's unnamed Quality term at its role without touching its
range. DeathCluster, Flak Gun, GT 3K, plight and both MoveOnPros join the backfill set (CB-R1 forces them).
RolesBackfill(apply, root) mirrors PiratesFaction so tests can replay it on a scratch catalog.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
DrawAhead leaves a ship in a wormhole animation where the step put it. The clock is
one static instance; a zone entered inside a step ends that frame's stepping and the
clock resets between frames (SimClock.Reset throws inside Advance). DrawAhead.Time had
no consumer.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
EmojiFont.Build leaves TMP's emoji fallback list empty. EmojiCheck fails when that list is non-empty,
when the global fallback lacks Emoji.asset, or when a glyph is served by a font other than Emoji.asset
or the body font; reads the Pirates product names from the shipped catalog; renders the
emoji-test.txt corpus and reports what Twemoji lacks; counts only used atlas pages (TMP doubles the
array capacity, so trailing slots are null by design).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1400 single code points (the 2 and 3 digit ones included), Twemoji lacks none; font sha256
unchanged (reproduced in python:3.13-slim on Yggdrasil).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Each fitted Talaria has its own lot's thrust, so Left and Right are the two flanks'
accelerations, not both the larger one.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ShippedCatalogRolesAreLive skips gear with no PerformanceStat at all (Tractor Beam is a
thruster kind with none). TheEnvelopeComesFromTheGear fits the Longinus by name: the
generator's picks follow the item stream and every authored ProductRole draws from it, so
the generated hull stopped carrying Large Drives (Medium Drive and RevvITup instead). Its
forward bound is the drives' own thrust, since a Large Drive now rolls 0.8x to 1.2x.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Probes B1-B9, the owner answer (published AetherDb), the r5 authority map
and rationale from the imagination-addon-frame pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Output of `AetherDb roles-backfill apply` on origin/master 325ef4bc's catalog, run on
Yggdrasil at 54999a64. Dry run: Autocannon, LRMM72, SRMM72, Mine Launcher, Large Drive
and Small Drive gain roles and quality ranges; Autocannon (Zhestokost, Pirates),
LRMM72 (R&D), SRMM72 (DME), Mine Launcher (DME) and True North (Lightsail) author their
ProductRoles. A replay prints "already authored". At merge, take master's catalog and
rerun `AetherDb roles-backfill apply`.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
AetherDb roles-backfill gives Autocannon, LRMM72, SRMM72, Mine Launcher, Large Drive
(and Small Drive, which declared roles no stat read) live roles: each mapped flat
stat becomes a 0.8x..1.2x range read through a Quality term naming its role, and
every seller authors a ProductRole per role from its maker profile. MineLayerRoles
is new; the maker profile table is hoisted so pd-gear and this command share it.
ShippedCatalogRolesAreLive and RolesBackfillIsAuthored read the shipped catalog.
The catalog blob lands in its own commit.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Body facts CC1-CC12, rules CS-R1..CS-R4 and rationale from the
imagination-consumables pass; specs and questions are in the mind.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The corpus now derives from emoji-test.txt (sha256 pinned), keeps single code points of any digit
count, and lists the emoji Twemoji lacks. The script runs only on linux, Python 3.13, image
python:3.13-slim and records those in the lock; identical pins with a different font exit 1 and
leave the committed font and lock untouched.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A StatReference naming WeaponData.Damage validated and attached to nothing,
because TargetsOf compared exact types. All three filters now use
targetType.IsAssignableFrom; no exact-match path remains.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Body facts CB1-CB12, rules CB-R1..CB-R5 and rationale from the
imagination-catalog-breadth pass; specs and questions are in the mind.
Co-Authored-By: Claude Opus 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>
AetherDb Program.cs: both sides appended a command (pd-gear/mine-launcher, pirates-faction);
kept all, one usage line. GameData/Aetheria.cc: master's blob kept here, pirates-faction
apply replayed on it in the next commit (follow-up catalog-blob-merge-order).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
DrawAhead.Rotation delegates to Turned(pose, angle) so the turn is testable on a tilted pose, where the flat Duel poses make the quaternion product's off-axis terms vanish. Unverified at this commit.
Co-Authored-By: Claude Opus 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>
The catalog is regenerated from master's catalog with pd-gear apply (next commit).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
# GameData/Aetheria.cc
# tools/AetherDb/Program.cs
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>
Assets/Fonts/Emoji/Twemoji.ttf is fetch_emoji_font.py's output for jdecked/twemoji
v17.0.3 (nanoemoji 0.16.0, glyf_colr_0), reproduced bit-identically by two
independent runs on Yggdrasil; the lock pins source and font sha256. EmojiFont.Build
wrote Emoji.asset (dynamic, COLOR, multi-atlas) and TMP Settings' emoji fallback list,
global fallback entry and empty default sprite asset. EmojiCheck.Run: 1425 single
code points and the eight Pirates names render with no missing code point. CC BY 4.0
attribution ships in Assets/Fonts/Emoji/LICENSE.txt. Builds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stryker's one survivor in the first sweep was the guard's `true ?` mutant: the
cache's Get(ref) extension already returns null for an unset reference, so the
guard was a second path. Adds the removed-product fact the spec names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lands retire-longinusx on master after gear-without-presence. The catalog
is regenerated from master's catalog with retire-longinusx apply (next commit).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
# GameData/Aetheria.cc