Files
Syplheed-Reborn/docs/re/BACKLOG.md
Claude (auto-RE) a7905d0f6b re: kill the duplicate-resource-name hypothesis for the viewer bug, and reconcile 22 vs 16 stages
build_ship_model resolves each placement with find(|m| m.name == p.resource) --
first match wins -- so a repeated resource name inside a container would draw
the wrong geometry. It cannot happen: decoding every XBG7 resource in all 22
stage containers gives 4603 resources and ZERO repeated names. Per ship it is
tighter still: e106 wants 9 distinct names and decodes exactly 9 models for 11
placements, e105 9 for 9, f105 5 for 6.

Two of the three remaining candidates for the user-reported viewer bug are now
gone (this and include_external), leaving mirror handling and the exhaust cones,
plus the untried visual comparison.

The container sweep also reconciles a number I flagged earlier: the disc has 22
stage CONTAINERS -- Stage_S01..S16 plus Stage_S24..S29 -- i.e. 16 story stages
plus 6 extra. The save screen's 16 STAGE sprites and the notes' "22 stages" are
both right and count different things; neither gets edited to match the other.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 21:31:18 +00:00

6.2 KiB
Raw Blame History

RE backlog

Open items that are not being worked right now. Each entry says what is wrong or unknown, what evidence exists, and what the first step would be. Move an item into INDEX.md (with a structures/…md or a parser + test) once it is actually settled.


Capital ships assemble wrong in the viewer

Reported: 2026-07-30, by the user. Status: 🔎 diagnosed 2026-08-10 — the format layer is exonerated. Runtime captures of three classes (f105, e105, e106) at controlled range reproduce assemble_ship to ≤0.43 units in translation and to 0.000 in rotation for every part that does not move; see ship-placement-capture-generalisation.md §4. So look at the viewer: first that it passes include_external = true (iso_loader.rs:4012 — with false an e106 loses its bridge and both nacelles, 5 parts instead of 11), then its own transform stack.

One real format-side bug was found on the way and is fixed: index-less parts (e105_brg) never matched their GN_Bridge_01 hardpoint, so 34 (stage, ship) entries — e102, e104, e105 across Stages 0229 — assembled without a bridge. The other apparent exception (e105_eng_01 rotation) was an aggregation artefact and is 0.000.

The original report and its reasoning follow.

The reborn viewer builds capital ships from the split XBG7 parts via sylpheed-formats::ship::assemble_ship, and they come out wrong — parts in the wrong place / wrong orientation.

Why this is a real finding and not a known limitation: the RE write-up ship-placement-runtime-capture.md declares static assembly exact as of 2026-07-26 — 9-channel joint tables [TX TY TZ RY RX RZ SX SY SZ], Euler Ry·Rx·Rz, with ship::tests::static_assembly_matches_runtime_capture asserting static == runtime capture (T < 1.0, R < 0.02). So either the viewer is not using that path, or the claim generalises worse than the test suggests.

The likely gap: that test is one ship — the e106 destroyer, 8 parts plus two nacelles, two turrets and the hull mirror. Nothing pins the other classes. Rules that were derived from e106 and could easily be e106-specific:

  • the engine cluster rig mounted at GN_Engine_01 (two mirrored nacelles + centre);
  • "X-reflect the shared-geometry twin whose lateral offset opposes the geometry's dominant side" — a heuristic, not a decoded flag;
  • cross-id turret instancing (×2).

First step (the oracle already exists): re-run the runtime capture on a different capital ship and diff static vs captured, exactly as e106 was done — F10 in the capture-ship-placement build of xenia-canary-native dumps the ship shader's c0..c2 WorldViewProjection rows per part; WV_ref⁻¹ · WV_p is the ship-space rigid transform, which is ground truth. Pick a class whose rig differs from e106 (different engine count, a ship with no sld, a carrier). Then extend static_assembly_matches_runtime_capture into a per-ship table so a regression in one class cannot hide behind e106 passing.

Also worth ruling out first, cheaply: that the viewer's own transform stack (scale, handedness, node-instance recursion) is not re-breaking a correct assembly — compare the viewer's placement against assemble_ship's output directly before blaming the format layer.


Viewer: include_external is already on — that hypothesis is dead

Checked 2026-08-11. The item above names "first that it passes include_external = true (iso_loader.rs:4012)" as the cheap first step. It does: ShipBrowser::show_external defaults to true (iso_loader.rs:643), the checkbox reads it (ui.rs:1593) and it is threaded through RequestShipRenderbuild_ship_modelassemble_ship unchanged (ui.rs:1689, iso_loader.rs:4012). So a ship rendered by the viewer is the full external assembly, not the bare hull.

The viewer also does not have a transform stack of its own to blame: it bakes ScenePart::apply straight into the vertices and rotates normals by the same p.m (iso_loader.rs:4030-4062), so its placement is assemble_ship's output by construction. What remains unexcluded, in order of cheapness: the mirror handling (det < 0 reverses triangle winding only — a reflected part keeps its reflected geometry), Xbg7Model::models_named resolving the wrong sub-model when a resource name repeats, and the exhaust cones. Next step is a visual: the diagnosis has run out of things it can settle by reading, so the viewer needs to be run against a known-good class (e106) and its render compared with ship_render's.


Viewer: the duplicate-resource-name hypothesis is dead too

Checked 2026-08-11. The diagnosis above left three candidates for why capital ships assemble wrong in the viewer: mirror handling, Xbg7Model::models_named resolving the wrong sub-model when a resource name repeats, and the exhaust cones. The second is now refuted, and comprehensively.

build_ship_model resolves each placement with base.iter().find(|m| m.name == p.resource) (iso_loader.rs:4041) — first match wins — so a repeated resource name inside a container would silently draw the wrong geometry. It cannot happen: decoding every XBG7 resource in all 22 stage containers gives 4 603 resources and zero repeated names.

Stage_S01  62/62      Stage_S07 323/323     Stage_S13 290/290     Stage_S25 351/351
Stage_S02 304/304     Stage_S08 388/388     Stage_S14  22/22      Stage_S26 318/318
Stage_S03 214/214     Stage_S09 316/316     Stage_S15 386/386     Stage_S27 321/321
Stage_S04 179/179     Stage_S10   7/7       Stage_S16  65/65      Stage_S28 118/118
Stage_S05  92/92      Stage_S11 157/157     Stage_S24 162/162     Stage_S29 386/386
Stage_S06 266/266     Stage_S12 376/376

Per-ship it is tighter still: e106 wants 9 distinct names and decodes exactly 9 models for 11 placements; e105 9 for 9; f105 5 for 6. Every placement resolves to the one model it names.

So two of the three candidates are gone (this one and include_external), leaving mirror handling and the exhaust cones — and the still-untried visual comparison, which remains the right next step.