4.3 KiB
| id | title | priority | status | scope | owner | updated_at | evidence | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| p0-29 | GdTechWeb bridge — live game delegates research to mc-tech | p0 | done | game1 | shipwright | 2026-04-17 |
|
Summary
mc-tech exports TechWeb, PlayerTechState, ResearchResult, UnlockSignal. Previously consumed only by mc-turn/src/processor.rs::process_science (bench/optimizer path). The live game ran a parallel ~52-line _process_research in turn_processor.gd:156 duplicating cost accumulation, spell-vs-tech dispatch, and the FORCE_UNLIMITED_RESEARCH debug knob.
Resolved 2026-04-17 (bridge-tech-dev): GdTechWeb Rust wrapper + GDScript collapse landed. _process_research now delegates to Rust; parent p0-07-tech-research-costs re-promoted to ✅ done.
Acceptance
- ✓
api-gdext/src/lib.rs::GdTechWebexposesprocess_research(player_json: String, yield_json: String, sci_modifier: f32) -> Dictionaryreturning{completed_tech, completed_spell, new_progress, new_researching, unlock_signals[], error}. Seeapi-gdext/src/lib.rs:2800-3020for the class +GdTechPlayerInput/GdTechCityYieldmarshaling shims. - ✓
turn_processor.gd::_process_researchbody replaced by a singlebridge.process_research(...)call +_apply_research_result()helper that dispatchesEventBus.tech_researched/school_locked/resources_revealed. Inline cost loop, spell-vs-tech branch, and per-city yield sum deleted from GDScript. Seeturn_processor.gd:156-172. - ✓
FORCE_UNLIMITED_RESEARCHenv read moves to the Rust side:_build_research_player_jsonpasses"instant_complete": EnvConfig.get_bool("FORCE_UNLIMITED_RESEARCH")into the payload, and Rust saturatesgainedto999_999when the flag is set (api-gdext/src/lib.rs::process_research). One shared debug knob. - ✓ All 28/28
mc-techtests still pass —cargo test -p mc-tech(4 unit + 24 integration tests, exit 0, 2026-04-17 on macOS workspace). New GUT testtests/unit/management/test_research_bridge.gd(7 tests + pending sentinel) seeds a player mid-tech (researching="war", progress=10, spt=5, cost=15 in age-of-dwarves) and asserts completion with byte-exactnew_progress=0,new_researching="", andunlock_signalscontainingspearmen— the same outcome the deleted GDScript body produced. - ✓
turn_processor.gd::_process_researchbody is 12 LOC (lines 156–167, under the ≤15 budget). Three supporting helpers (_get_tech_bridge,_science_modifier_for,_apply_research_result,_build_research_player_json,_build_research_yield_json) live below in the same file. - ✓
p0-07-tech-research-costsre-promotedpartial→done(all 5 acceptance bullets now ✓, final bullet cited against the collapse diff).
Non-goals
- Arcane Lore / High Archon transformation branch (Game 3) — untouched per
scope-game1-vs-game2.md. The GDScript_form_high_archonstub stays in place; mc-tech'sPlayerTechState::add_sciencereturnsUnlockSignalfor any tech id includingarcane_lorewhen it eventually ships, but Age of Dwarves data has noarcane_loretech so the branch is dormant at runtime today.
Status
Closed 2026-04-17 by bridge-tech-dev. All 6 acceptance bullets ✓ with cited evidence. Rail-1 (Rust simulation source of truth) restored for tech research; GDScript path is presentation + EventBus dispatch only.
Deliverables:
api-gdext/Cargo.toml— addedmc-techdep.api-gdext/src/lib.rs—GdTechWebclass +GdTechPlayerInput/GdTechCityYieldshims +unlock_signal_to_dict/string_vec_to_packedhelpers (~220 LOC net).turn_processor.gd—_process_researchcollapsed 60 → 12 LOC body; 5 helpers added.tests/unit/management/test_research_bridge.gd— 8 tests, headless-safe (skip when GDExtension absent)..project/CHANGELOG.md— dated entry[ref: p0-29, p0-07].
Known caveat (unrelated): same commit batch bundled mc-ai features = ["gpu"] which breaks api-gdext/src/ai.rs::run_tactical signature — flagged to team-lead, not a p0-29 regression. GdTechWeb itself compiles clean against mc-ai stock features.