The headless trade pipeline was unit-proven but inert in real runs: nothing called
set_resource_categories_json, so process_trade_phase saw empty categories and sourced
nothing. Wire it in.
- scenes/headless/player_api_main.gd::_apply_resource_categories builds the resource
id→category map from DataLoader.get_all_resources() and stamps it onto GdPlayerApi via
set_resource_categories_json, AFTER load_state_json (same #[serde(skip)] re-stamp
pattern as units_runtime_catalog + tech_web). Now a real headless game classifies
owned-tile collectibles → sources luxury/strategic surpluses → forms trades → view_json
carries them. End-to-end LIVE.
Verified: unit+integration GUT 750 (737 pass / 13 pending / 0 fail); the headless
projection-roundtrip boot path (which exercises _apply_resource_categories) is green.
GDScript-only change calling an existing FFI — no dylib rebuild needed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>