Investigating "make the engine play all the .dat types". Answer: the container
parses for all three tables, but playability is a per-table reverse-engineering
project, not a loader fix. Evidence recorded in CLAUDE.md so it isn't re-derived.
- tools/datdump.py: parse and diff PARTOUT(4.0) DATs — groups, component type
ids, float attribute ids. Asserts its own entry walk stayed in sync, since a
desync silently turns every later field into garbage.
- loader: add query_float_attribute_opt for genuinely optional attributes.
Dragon/Pirate ramps omit wall0 (1303), which Cadet always carries; treat a
missing wall as no wall instead of a fatal load error.
Cadet and Full Tilt Cadet verified unchanged after this.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>