2 Commits

Author SHA1 Message Date
sim
e909c7c133 chore: retire the last dead paths and names from the consolidation
Nothing here changes what a tool computes; it changes where tools look.

- tools/re-capture: 33 censuses globbed /work/sylph_extract, a path that has
  existed nowhere since /work became a clone, so they matched nothing and
  printed empty results. They now resolve the disc through a new disc.py
  from $SYLPHEED_DISC and exit loudly without it (the #44 fix, generalised).
  Nine scripts that imported siblings from the retired Reborn checkout or an
  old session scratchpad now import from their own directory. unitgroup.py
  only needs the variable when --pak is not given.
- sylpheed-xex: the loader only ever uses the XEX2 retail key. The dead
  devkit key and a doc comment claiming a devkit fallback that does not
  exist are gone; Project Sylpheed is a retail XEX2, so no XEX1 key either.
- sylpheed-viewer: real_font_rasterizes looked for /tmp/sylph_extract and so
  always skipped. It reads $SYLPHEED_DISC now, and passes against the disc.
- Comments and docs that named xenia-rs, the Reborn repository or /work/*.pe
  as places to look now name sylpheed.db, Canary's ppc_context.h and the
  flat .pe; docs/re/README.md no longer says the native Canary build does not
  run.

Historical records keep their original paths: findings that were measured
against /work/xenia-rs/sylpheed.db still say so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 22:30:28 +02:00
eec42bdef0 re: solve the runtime Unit (craft/vessel) struct from live guest memory
Craft stats were the last parked Route-B target: the Hangar exposes only a
weight class, and in menus the flight-model object is not instantiated at all.
It is instantiated in-mission, so this reads it there.

The definition class is discovered rather than assumed (unit_discover.py):
scanning for pointers to the disc ID strings and tallying the word behind each
pointer site picks out vtable 0x820af844 -- one object per unit ID, name-record
pointer at +0x04, string at +0x10, exactly the Weapon shape. The neighbouring
class 0x820af030 is the spawned entity, not the definition; the two are told
apart by one-object-per-ID and by 14/14 objects being byte-identical across two
snapshots 12 minutes and one firefight apart.

22 fields bind with zero contradictions on >=3 distinct values. Beyond that,
the Maneuver sub-record turns out to be laid out in schema declaration order,
4 bytes per field, base 0x9c with a two-slot gap after AA_Roll_Min -- 29
independently solved anchors fit two exact bases with no conflicts. That rule
pins five fields NO unit table ever values (PitchDragFactor, RollDragFactor,
DragFactorThreshold, ArterBurner_Acc, DecPitchFactor); PitchDrag == RollDrag ==
the disc's YawDrag on 18/18 units corroborates the interpolation.

Angles are float32 radians at runtime and degrees on disc.

Coverage is 18 of 110 units: unlike weapons, unit definitions are instantiated
per stage, so it grows by visiting missions. The AI-behaviour tail of Maneuver
is explicitly NOT resolved and marked tentative in the CSV.

Captured from Xenia Canary (BASIC CONTROLS tutorial + Stage 02 from save 01).
2026-07-29 17:27:53 +00:00