(null);
+
+ const classes = useMemo(() => {
+ let list = data.classes;
+ if (search) list = list.filter(c => c.name.toLowerCase().includes(search.toLowerCase()));
+ if (filter === "used") list = list.filter(c => c.callerFiles.length > 0);
+ if (filter === "unused") list = list.filter(c => c.callerFiles.length === 0);
+ return sortClasses(list, sortKey, sortAsc);
+ }, [search, filter, sortKey, sortAsc]);
+
+ const selectedClass = selected ? data.classes.find(c => c.name === selected) ?? null : null;
+
+ function toggleSort(key: SortKey) {
+ if (sortKey === key) setSortAsc(a => !a);
+ else { setSortKey(key); setSortAsc(false); }
+ }
+
+ function sortArrow(key: SortKey) {
+ if (sortKey !== key) return "";
+ return sortAsc ? " ↑" : " ↓";
+ }
+
+ return (
+ <>
+
+ setSearch(e.target.value)}
+ />
+
+
+
+
+
+
+ | toggleSort("name")}>Godot class{sortArrow("name")} |
+ base |
+ toggleSort("funcCount")}>#[func]{sortArrow("funcCount")} |
+ toggleSort("callerFiles")}>GD files{sortArrow("callerFiles")} |
+ Rust source |
+
+
+
+ {classes.map(c => (
+ setSelected(selected === c.name ? null : c.name)}
+ >
+
+ {c.name}
+ {c.callerFiles.length === 0 && (
+ <> unused>
+ )}
+ |
+ {c.base ?? "—"} |
+ {c.funcCount} |
+
+ {c.callerFiles.length}
+ |
+
+ {c.file}:{c.line}
+ |
+
+ ))}
+
+
+
+ {selectedClass && (
+
+ {selectedClass.name}
+
+ Rust struct {selectedClass.rustStruct} · base {selectedClass.base ?? "—"}
+ {" · "}{selectedClass.funcCount} #[func] · defined at {selectedClass.file}:{selectedClass.line}
+
+ {selectedClass.callerFiles.length === 0 ? (
+ No GDScript references found.
+ ) : (
+
+ {selectedClass.callerFiles.map(file => {
+ const lines = selectedClass.callerLines
+ .filter(cl => cl.file === file)
+ .map(cl => cl.line)
+ .slice(0, 10);
+ return (
+
+ {file}
+ L{lines.join(", L")}
+
+ );
+ })}
+
+ )}
+
+ )}
+ >
+ );
+}
+
+function CallersTab() {
+ const [search, setSearch] = useState("");
+ const sorted = useMemo(() => {
+ const list = data.classes.filter(c => c.callerFiles.length > 0);
+ if (search) return list.filter(c =>
+ c.name.toLowerCase().includes(search.toLowerCase()) ||
+ c.callerFiles.some(f => f.toLowerCase().includes(search.toLowerCase()))
+ );
+ return list;
+ }, [search]);
+
+ return (
+ <>
+
+ setSearch(e.target.value)}
+ />
+ {sorted.length} classes
+
+ {sorted.map(c => (
+
+
+ {c.name}
+
+ {c.callerFiles.length} file{c.callerFiles.length !== 1 ? "s" : ""}
+
+
+
+ {c.callerFiles.map(file => {
+ const lines = c.callerLines.filter(cl => cl.file === file).map(cl => cl.line).slice(0, 12);
+ return (
+
+ {file}
+ L{lines.join(", L")}{c.callerLines.filter(cl => cl.file === file).length > 12 ? "…" : ""}
+
+ );
+ })}
+
+
+ ))}
+ >
+ );
+}
+
+function DepsTab() {
+ const BRIDGES = new Set(["api-gdext", "api-wasm"]);
+ const entries = Object.entries(data.crateDeps).sort((a, b) => {
+ const ab = BRIDGES.has(a[0]), bb = BRIDGES.has(b[0]);
+ if (ab && !bb) return -1;
+ if (!ab && bb) return 1;
+ return b[1].length - a[1].length;
+ });
+
+ return (
+ <>
+
+ {Object.keys(data.crateDeps).length} workspace crates.
+ Bridge crates (api-gdext, api-wasm) highlighted.
+
+
+ {entries.map(([crate, deps]) => (
+
+ {crate}
+ {deps.length === 0 ? (
+ no internal deps
+ ) : (
+
+ {deps.map(d => {d})}
+
+ )}
+
+ ))}
+
+ >
+ );
+}
+
+function GdClassesTab() {
+ const [search, setSearch] = useState("");
+ const collisionSet = new Set(data.collisions);
+ const entries = useMemo(() => {
+ const all = Object.entries(data.gdClassNames);
+ return search
+ ? all.filter(([n, f]) => n.toLowerCase().includes(search.toLowerCase()) || f.toLowerCase().includes(search.toLowerCase()))
+ : all;
+ }, [search]);
+
+ return (
+ <>
+
+ setSearch(e.target.value)}
+ />
+ {data.collisions.length > 0 && (
+ ⚠ {data.collisions.length} name collision{data.collisions.length !== 1 ? "s" : ""}
+ )}
+ {entries.length} classes
+
+
+ {entries.map(([name, file]) => (
+
+ {name}
+ {file}
+ {collisionSet.has(name) && collision}
+
+ ))}
+
+ >
+ );
+}
+
+// ── page ──────────────────────────────────────────────────────────────────
+
+const TAB_LABELS: Record = {
+ surface: "Binding surface",
+ callers: "Per-class callers",
+ deps: "Crate deps",
+ "gd-classes": "GD class_names",
+};
+
+export function GdRustBridgePage(): React.ReactElement {
+ const [tab, setTab] = useState("surface");
+ const ts = new Date(data.generatedAt).toLocaleString();
+ const usedCount = data.classes.filter(c => c.callerFiles.length > 0).length;
+ const totalGdRefs = data.classes.reduce((s, c) => s + c.callerFiles.length, 0);
+
+ return (
+
+ ← back
+
+
+
+ {data.classes.length}exported classes
+ {usedCount}referenced from GD
+ {totalGdRefs}total GD–file links
+ {Object.keys(data.crateDeps).length}workspace crates
+ {Object.keys(data.gdClassNames).length}GD class_names
+
+
+
+ {(Object.keys(TAB_LABELS) as TabId[]).map(id => (
+ setTab(id)}>
+ {TAB_LABELS[id]}
+
+ ))}
+
+
+ {tab === "surface" && }
+ {tab === "callers" && }
+ {tab === "deps" && }
+ {tab === "gd-classes" && }
+
+ );
+}
diff --git a/.project/designs/app/src/pages/Index.tsx b/.project/designs/app/src/pages/Index.tsx
index da9ae45a..9d4d9f09 100644
--- a/.project/designs/app/src/pages/Index.tsx
+++ b/.project/designs/app/src/pages/Index.tsx
@@ -64,8 +64,9 @@ const routes = [
{ path: "/promotion", label: "★ Promotion Picker — grid, lock states, prereqs" },
{ path: "/stats", label: "📊 Statistics — Demographics, Graphs, Rankings, Histories" },
{ path: "/end-game", label: "🏆 End-of-Game Summary — outcome, standings, awards, score graph" },
- { path: "/past-games",label: "📚 Past Games — archived game cards, filters, sorts" },
- { path: "/replay", label: "⏯ Replay Viewer — scrubber, event ticker, stats overlay" },
+ { path: "/past-games", label: "📚 Past Games — archived game cards, filters, sorts" },
+ { path: "/replay", label: "⏯ Replay Viewer — scrubber, event ticker, stats overlay" },
+ { path: "/gd-rust", label: "🦀 GD ↔ Rust Bridge — binding surface, callers, crate deps" },
];
export function IndexPage(): React.ReactElement {
diff --git a/.project/designs/app/tsconfig.json b/.project/designs/app/tsconfig.json
index 5b49ce81..05e07d97 100644
--- a/.project/designs/app/tsconfig.json
+++ b/.project/designs/app/tsconfig.json
@@ -18,11 +18,13 @@
"@game-data/*": ["../../../public/games/age-of-dwarves/data/*"],
"@game-assets/*": ["../../../public/games/age-of-dwarves/assets/*"],
"@resources/*": ["../../../public/resources/*"],
- "@audio-alts/*": ["../../../.local/audio-alternatives/*"]
+ "@audio-alts/*": ["../../../.local/audio-alternatives/*"],
+ "@reports/*": ["../../reports/*"]
}
},
"include": [
"src",
+ "../../reports/gd-rust-relationships.json",
"../../../public/resources/audio/library.json",
"../../../public/games/age-of-dwarves/data/audio/manifest.json",
"../../../public/games/age-of-dwarves/data/audio/pools.json"
diff --git a/.project/designs/app/vite.config.ts b/.project/designs/app/vite.config.ts
index 3c86e51c..82766c5d 100644
--- a/.project/designs/app/vite.config.ts
+++ b/.project/designs/app/vite.config.ts
@@ -12,6 +12,7 @@ export default defineConfig({
"@resources": path.resolve(__dirname, "../../../public/resources"),
"@audio-alts": path.resolve(__dirname, "../../../.local/audio-alternatives"),
"@audio-staging": path.resolve(__dirname, "../../../.local/audio-staging"),
+ "@reports": path.resolve(__dirname, "../../reports"),
},
},
server: {
@@ -24,6 +25,7 @@ export default defineConfig({
path.resolve(__dirname, "../../../public"),
path.resolve(__dirname, "../../../.local/audio-alternatives"),
path.resolve(__dirname, "../../../.local/audio-staging"),
+ path.resolve(__dirname, "../../reports"),
],
},
watch: {
diff --git a/.project/objectives/p2-45-elimination-reconciliation.md b/.project/objectives/p2-45-elimination-reconciliation.md
index a6014f5e..adcf1abe 100644
--- a/.project/objectives/p2-45-elimination-reconciliation.md
+++ b/.project/objectives/p2-45-elimination-reconciliation.md
@@ -2,10 +2,16 @@
id: p2-45
title: "Player elimination reconciliation — emit `player_eliminated` on every transition"
priority: p2
-status: missing
+status: done
scope: game1
updated_at: 2026-04-30
assigned_by: shipwright
+evidence:
+ - "src/game/engine/src/entities/player.gd:36 — `is_eliminated: bool` flag added (default false), latches forever once set"
+ - "src/game/engine/src/modules/victory/victory_manager.gd:54 — `_reconcile_eliminations()` called on every check_all() at turn-end; sweeps all players, sets is_eliminated + emits EventBus.player_eliminated for any newly-eliminated player exactly once"
+ - "src/game/engine/src/modules/combat/combat_utils.gd:139 + src/game/engine/src/entities/combat_utils.gd:138 — both city-capture paths now check the latch before emitting and set it themselves; dedupes against the reconciliation sweep"
+ - "src/game/engine/tests/unit/test_victory_manager.gd — 5/5 GUT tests passing on apricot (rehydrated from stub): test_reconciliation_emits_for_eliminated_player, test_reconciliation_latches_is_eliminated_flag, test_second_sweep_is_silent, test_survivor_does_not_trigger, test_already_eliminated_flag_skips_emit"
+ - "Regression-clean: test_audio_manager.gd 18/18 + test_chronicle_coverage.gd all-pass after the change (apricot headless, 2026-04-30)"
---
## Summary
diff --git a/.project/reports/gd-rust-relationships.json b/.project/reports/gd-rust-relationships.json
new file mode 100644
index 00000000..fd938b3c
--- /dev/null
+++ b/.project/reports/gd-rust-relationships.json
@@ -0,0 +1,3563 @@
+{
+ "generatedAt": "2026-04-30T14:29:32.516762Z",
+ "classes": [
+ {
+ "name": "GdAiController",
+ "rustStruct": "GdAiController",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/ai.rs",
+ "line": 577,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/auto_play.gd",
+ "src/game/engine/src/autoloads/game_state.gd",
+ "src/game/engine/src/entities/auto_play.gd",
+ "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "src/game/engine/src/modules/ai/ai_turn_bridge_state.gd",
+ "src/game/engine/tests/integration/test_ai_simulation.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/auto_play.gd",
+ "line": 1195
+ },
+ {
+ "file": "src/game/engine/src/autoloads/game_state.gd",
+ "line": 143
+ },
+ {
+ "file": "src/game/engine/src/autoloads/game_state.gd",
+ "line": 145
+ },
+ {
+ "file": "src/game/engine/src/autoloads/game_state.gd",
+ "line": 151
+ },
+ {
+ "file": "src/game/engine/src/autoloads/game_state.gd",
+ "line": 156
+ },
+ {
+ "file": "src/game/engine/src/autoloads/game_state.gd",
+ "line": 158
+ },
+ {
+ "file": "src/game/engine/src/entities/auto_play.gd",
+ "line": 1203
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "line": 7
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "line": 126
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "line": 127
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge_state.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge_state.gd",
+ "line": 84
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge_state.gd",
+ "line": 103
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge_state.gd",
+ "line": 118
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_ai_simulation.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 26
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 104
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 145
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 348
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 352
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 353
+ }
+ ]
+ },
+ {
+ "name": "GdAtmosphericChemistry",
+ "rustStruct": "GdAtmosphericChemistry",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 381,
+ "funcCount": 2,
+ "callerFiles": [
+ "src/game/engine/tests/integration/test_gdextension_contract.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 20
+ }
+ ]
+ },
+ {
+ "name": "GdCity",
+ "rustStruct": "GdCity",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 976,
+ "funcCount": 5,
+ "callerFiles": [
+ "src/game/engine/scenes/city/city_buildable_helper.gd",
+ "src/game/engine/scenes/hud/crafting_complete_modal.gd",
+ "src/game/engine/scenes/tests/city_proof.gd",
+ "src/game/engine/scenes/tests/city_screen_proof.gd",
+ "src/game/engine/src/autoloads/event_bus.gd",
+ "src/game/engine/src/entities/city.gd",
+ "src/game/engine/src/entities/city_rust_bridge.gd",
+ "src/game/engine/src/modules/management/turn_processor_helpers.gd",
+ "src/game/engine/tests/integration/test_1000_turns.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/entities/test_city.gd",
+ "src/game/engine/tests/unit/test_city_bridge.gd",
+ "src/game/engine/tests/unit/test_city_screen_p09.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/city/city_buildable_helper.gd",
+ "line": 178
+ },
+ {
+ "file": "src/game/engine/scenes/city/city_buildable_helper.gd",
+ "line": 262
+ },
+ {
+ "file": "src/game/engine/scenes/hud/crafting_complete_modal.gd",
+ "line": 142
+ },
+ {
+ "file": "src/game/engine/scenes/tests/city_proof.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/scenes/tests/city_proof.gd",
+ "line": 82
+ },
+ {
+ "file": "src/game/engine/scenes/tests/city_proof.gd",
+ "line": 178
+ },
+ {
+ "file": "src/game/engine/scenes/tests/city_screen_proof.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/src/autoloads/event_bus.gd",
+ "line": 75
+ },
+ {
+ "file": "src/game/engine/src/entities/city.gd",
+ "line": 1
+ },
+ {
+ "file": "src/game/engine/src/entities/city.gd",
+ "line": 6
+ },
+ {
+ "file": "src/game/engine/src/entities/city.gd",
+ "line": 8
+ },
+ {
+ "file": "src/game/engine/src/entities/city.gd",
+ "line": 88
+ },
+ {
+ "file": "src/game/engine/src/entities/city.gd",
+ "line": 96
+ },
+ {
+ "file": "src/game/engine/src/entities/city.gd",
+ "line": 97
+ },
+ {
+ "file": "src/game/engine/src/entities/city.gd",
+ "line": 424
+ },
+ {
+ "file": "src/game/engine/src/entities/city_rust_bridge.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/src/entities/city_rust_bridge.gd",
+ "line": 215
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor_helpers.gd",
+ "line": 95
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_1000_turns.gd",
+ "line": 15
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 56
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 245
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 245
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 249
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 250
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 251
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_city.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 53
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 55
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 66
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 67
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 121
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 122
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_screen_p09.gd",
+ "line": 15
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_screen_p09.gd",
+ "line": 16
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_screen_p09.gd",
+ "line": 37
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_screen_p09.gd",
+ "line": 38
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_screen_p09.gd",
+ "line": 57
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_screen_p09.gd",
+ "line": 58
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_screen_p09.gd",
+ "line": 79
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_screen_p09.gd",
+ "line": 80
+ }
+ ]
+ },
+ {
+ "name": "GdCityActions",
+ "rustStruct": "GdCityActions",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 4859,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/placement_mode_proof.gd",
+ "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "src/game/engine/scenes/world_map/tile_info_panel.gd",
+ "src/game/engine/scenes/world_map/world_map.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/placement_mode_proof.gd",
+ "line": 6
+ },
+ {
+ "file": "src/game/engine/scenes/tests/placement_mode_proof.gd",
+ "line": 62
+ },
+ {
+ "file": "src/game/engine/scenes/tests/placement_mode_proof.gd",
+ "line": 63
+ },
+ {
+ "file": "src/game/engine/scenes/tests/placement_mode_proof.gd",
+ "line": 66
+ },
+ {
+ "file": "src/game/engine/scenes/tests/placement_mode_proof.gd",
+ "line": 90
+ },
+ {
+ "file": "src/game/engine/scenes/tests/placement_mode_proof.gd",
+ "line": 93
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 64
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 68
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 70
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 73
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 75
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/tile_info_panel.gd",
+ "line": 166
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 93
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 1537
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 1554
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 1556
+ }
+ ]
+ },
+ {
+ "name": "GdClimateEffectsPhysics",
+ "rustStruct": "GdClimateEffectsPhysics",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 4413,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/src/entities/turn_processor.gd",
+ "src/game/engine/src/modules/climate/climate_effects.gd",
+ "src/game/engine/src/modules/management/turn_processor.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/entities/turn_processor.gd",
+ "line": 481
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_effects.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_effects.gd",
+ "line": 18
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_effects.gd",
+ "line": 26
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_effects.gd",
+ "line": 27
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor.gd",
+ "line": 466
+ }
+ ]
+ },
+ {
+ "name": "GdClimatePhysics",
+ "rustStruct": "GdClimatePhysics",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 160,
+ "funcCount": 2,
+ "callerFiles": [
+ "src/game/engine/src/entities/turn_processor.gd",
+ "src/game/engine/src/modules/climate/climate.gd",
+ "src/game/engine/src/modules/management/prologue_driver.gd",
+ "src/game/engine/src/modules/management/turn_processor.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/test_smoke.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/entities/turn_processor.gd",
+ "line": 476
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 26
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 72
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 95
+ },
+ {
+ "file": "src/game/engine/src/modules/management/prologue_driver.gd",
+ "line": 43
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor.gd",
+ "line": 461
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 50
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 177
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 178
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 183
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 184
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 185
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_smoke.gd",
+ "line": 47
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_smoke.gd",
+ "line": 50
+ }
+ ]
+ },
+ {
+ "name": "GdClimateSpecEval",
+ "rustStruct": "GdClimateSpecEval",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 466,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/src/modules/climate/climate_spec_eval.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/modules/climate/climate_spec_eval.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_spec_eval.gd",
+ "line": 17
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_spec_eval.gd",
+ "line": 24
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_spec_eval.gd",
+ "line": 34
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 52
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 203
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 204
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 209
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 210
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 211
+ }
+ ]
+ },
+ {
+ "name": "GdCombatResolver",
+ "rustStruct": "GdCombatResolver",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 2637,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/scenes/combat/combat_preview.gd",
+ "src/game/engine/scenes/combat/combat_result.gd",
+ "src/game/engine/scenes/tests/auto_play.gd",
+ "src/game/engine/scenes/world_map/world_map_combat.gd",
+ "src/game/engine/src/entities/auto_play.gd",
+ "src/game/engine/src/entities/combat_utils.gd",
+ "src/game/engine/src/modules/combat/combat_resolver.gd",
+ "src/game/engine/src/modules/combat/combat_utils.gd",
+ "src/game/engine/src/modules/combat/keyword_handler.gd",
+ "src/game/engine/tests/ffi/test_golden_combat.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/combat/test_combat_bridge.gd",
+ "src/game/engine/tests/unit/test_combat_resolver.gd",
+ "src/game/engine/tests/unit/test_keyword_handler.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/combat/combat_preview.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/scenes/combat/combat_preview.gd",
+ "line": 14
+ },
+ {
+ "file": "src/game/engine/scenes/combat/combat_preview.gd",
+ "line": 46
+ },
+ {
+ "file": "src/game/engine/scenes/combat/combat_preview.gd",
+ "line": 79
+ },
+ {
+ "file": "src/game/engine/scenes/combat/combat_preview.gd",
+ "line": 188
+ },
+ {
+ "file": "src/game/engine/scenes/combat/combat_result.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/scenes/combat/combat_result.gd",
+ "line": 54
+ },
+ {
+ "file": "src/game/engine/scenes/tests/auto_play.gd",
+ "line": 2060
+ },
+ {
+ "file": "src/game/engine/scenes/tests/auto_play.gd",
+ "line": 2085
+ },
+ {
+ "file": "src/game/engine/scenes/tests/auto_play.gd",
+ "line": 2086
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map_combat.gd",
+ "line": 103
+ },
+ {
+ "file": "src/game/engine/src/entities/auto_play.gd",
+ "line": 2074
+ },
+ {
+ "file": "src/game/engine/src/entities/auto_play.gd",
+ "line": 2099
+ },
+ {
+ "file": "src/game/engine/src/entities/auto_play.gd",
+ "line": 2100
+ },
+ {
+ "file": "src/game/engine/src/entities/combat_utils.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/src/modules/combat/combat_resolver.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/combat/combat_resolver.gd",
+ "line": 49
+ },
+ {
+ "file": "src/game/engine/src/modules/combat/combat_resolver.gd",
+ "line": 50
+ },
+ {
+ "file": "src/game/engine/src/modules/combat/combat_resolver.gd",
+ "line": 52
+ },
+ {
+ "file": "src/game/engine/src/modules/combat/combat_resolver.gd",
+ "line": 140
+ },
+ {
+ "file": "src/game/engine/src/modules/combat/combat_utils.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/src/modules/combat/keyword_handler.gd",
+ "line": 5
+ },
+ {
+ "file": "src/game/engine/src/modules/combat/keyword_handler.gd",
+ "line": 37
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_combat.gd",
+ "line": 5
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_combat.gd",
+ "line": 31
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_combat.gd",
+ "line": 139
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_combat.gd",
+ "line": 147
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 96
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 308
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 309
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 314
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 315
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 316
+ },
+ {
+ "file": "src/game/engine/tests/unit/combat/test_combat_bridge.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_combat_resolver.gd",
+ "line": 10
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_combat_resolver.gd",
+ "line": 11
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_combat_resolver.gd",
+ "line": 28
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_combat_resolver.gd",
+ "line": 38
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_keyword_handler.gd",
+ "line": 5
+ }
+ ]
+ },
+ {
+ "name": "GdCourierMapView",
+ "rustStruct": "GdCourierMapView",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 3416,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "src/game/engine/tests/unit/test_courier_lifecycle.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 44
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 45
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 106
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 108
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 32
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 33
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 37
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 42
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 43
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 104
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 106
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 9
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 34
+ }
+ ]
+ },
+ {
+ "name": "GdCourierRoute",
+ "rustStruct": "GdCourierRoute",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 3108,
+ "funcCount": 9,
+ "callerFiles": [
+ "src/game/engine/tests/unit/test_courier_lifecycle.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 8
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 11
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 148
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 242
+ }
+ ]
+ },
+ {
+ "name": "GdCulture",
+ "rustStruct": "GdCulture",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 3458,
+ "funcCount": 7,
+ "callerFiles": [
+ "src/game/engine/src/modules/empire/culture.gd",
+ "src/game/engine/tests/unit/empire/test_culture_bridge.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/modules/empire/culture.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/culture.gd",
+ "line": 7
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/culture.gd",
+ "line": 11
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/culture.gd",
+ "line": 15
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 21
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 48
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 49
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 51
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 64
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 65
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 92
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 93
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_culture_bridge.gd",
+ "line": 111
+ }
+ ]
+ },
+ {
+ "name": "GdCultureWeb",
+ "rustStruct": "GdCultureWeb",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 4050,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/src/modules/empire/culture_web.gd",
+ "src/game/engine/src/modules/tech/knowledge_web.gd",
+ "src/game/engine/tests/unit/test_culture_web.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/modules/empire/culture_web.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/culture_web.gd",
+ "line": 14
+ },
+ {
+ "file": "src/game/engine/src/modules/tech/knowledge_web.gd",
+ "line": 12
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_culture_web.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_culture_web.gd",
+ "line": 47
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_culture_web.gd",
+ "line": 48
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_culture_web.gd",
+ "line": 50
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_culture_web.gd",
+ "line": 52
+ }
+ ]
+ },
+ {
+ "name": "GdEcologyPhysics",
+ "rustStruct": "GdEcologyPhysics",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 202,
+ "funcCount": 2,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/auto_play.gd",
+ "src/game/engine/src/entities/auto_play.gd",
+ "src/game/engine/src/entities/turn_processor.gd",
+ "src/game/engine/src/modules/climate/climate.gd",
+ "src/game/engine/src/modules/management/prologue_driver.gd",
+ "src/game/engine/src/modules/management/turn_processor.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/auto_play.gd",
+ "line": 2676
+ },
+ {
+ "file": "src/game/engine/src/entities/auto_play.gd",
+ "line": 2690
+ },
+ {
+ "file": "src/game/engine/src/entities/turn_processor.gd",
+ "line": 476
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 29
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 98
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 99
+ },
+ {
+ "file": "src/game/engine/src/modules/management/prologue_driver.gd",
+ "line": 43
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor.gd",
+ "line": 461
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 21
+ }
+ ]
+ },
+ {
+ "name": "GdEconomy",
+ "rustStruct": "GdEconomy",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 3618,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/src/entities/turn_processor.gd",
+ "src/game/engine/src/modules/empire/economy.gd",
+ "src/game/engine/src/modules/management/turn_processor.gd",
+ "src/game/engine/tests/unit/empire/test_economy_bridge.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/entities/turn_processor.gd",
+ "line": 359
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/economy.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/economy.gd",
+ "line": 8
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/economy.gd",
+ "line": 36
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/economy.gd",
+ "line": 44
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/economy.gd",
+ "line": 47
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor.gd",
+ "line": 355
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 7
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 44
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 45
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 48
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 62
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 63
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 84
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 99
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 100
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 116
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 126
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 127
+ },
+ {
+ "file": "src/game/engine/tests/unit/empire/test_economy_bridge.gd",
+ "line": 141
+ }
+ ]
+ },
+ {
+ "name": "GdFaunaEcology",
+ "rustStruct": "GdFaunaEcology",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 282,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/proof_biome_economy_coupling.gd",
+ "src/game/engine/src/modules/empire/happiness.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/proof_biome_economy_coupling.gd",
+ "line": 5
+ },
+ {
+ "file": "src/game/engine/scenes/tests/proof_biome_economy_coupling.gd",
+ "line": 98
+ },
+ {
+ "file": "src/game/engine/scenes/tests/proof_biome_economy_coupling.gd",
+ "line": 99
+ },
+ {
+ "file": "src/game/engine/scenes/tests/proof_biome_economy_coupling.gd",
+ "line": 101
+ },
+ {
+ "file": "src/game/engine/scenes/tests/proof_biome_economy_coupling.gd",
+ "line": 103
+ },
+ {
+ "file": "src/game/engine/scenes/tests/proof_biome_economy_coupling.gd",
+ "line": 125
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/happiness.gd",
+ "line": 186
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/happiness.gd",
+ "line": 192
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/happiness.gd",
+ "line": 213
+ }
+ ]
+ },
+ {
+ "name": "GdFormationActions",
+ "rustStruct": "GdFormationActions",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 4982,
+ "funcCount": 2,
+ "callerFiles": [],
+ "callerLines": []
+ },
+ {
+ "name": "GdFormationState",
+ "rustStruct": "GdFormationState",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 5076,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/scenes/world_map/formation_bridge.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 2
+ }
+ ]
+ },
+ {
+ "name": "GdGameState",
+ "rustStruct": "GdGameState",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 1963,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "src/game/engine/scenes/tests/iter_7k_turn_processor_gated_proof.gd",
+ "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "src/game/engine/src/entities/player.gd",
+ "src/game/engine/src/entities/unit.gd",
+ "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "src/game/engine/tests/integration/test_1000_turns.gd",
+ "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/test_courier_lifecycle.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 14
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 37
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 38
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 99
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 100
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 24
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 25
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 11
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 35
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 36
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 97
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 98
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 5
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 38
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 83
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 89
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 91
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 168
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 13
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 114
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 116
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 211
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "line": 57
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "line": 104
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "line": 106
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "line": 253
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "line": 15
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "line": 107
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "line": 111
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "line": 164
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7k_turn_processor_gated_proof.gd",
+ "line": 14
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7k_turn_processor_gated_proof.gd",
+ "line": 194
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 9
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 12
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 18
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 22
+ },
+ {
+ "file": "src/game/engine/src/entities/player.gd",
+ "line": 183
+ },
+ {
+ "file": "src/game/engine/src/entities/unit.gd",
+ "line": 332
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 8
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 10
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 26
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 29
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 46
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 48
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_1000_turns.gd",
+ "line": 21
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 37
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 40
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 48
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 174
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 175
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 176
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 74
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 282
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 283
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 288
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 289
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 290
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 30
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 33
+ }
+ ]
+ },
+ {
+ "name": "GdGridState",
+ "rustStruct": "GdGridState",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 37,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/scenes/city/city_buildable_helper.gd",
+ "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "src/game/engine/scenes/world_map/tile_info_panel.gd",
+ "src/game/engine/scenes/world_map/world_map.gd",
+ "src/game/engine/src/entities/turn_processor.gd",
+ "src/game/engine/src/modules/climate/climate.gd",
+ "src/game/engine/src/modules/climate/climate_effects.gd",
+ "src/game/engine/src/modules/climate/weather.gd",
+ "src/game/engine/src/modules/management/prologue_driver.gd",
+ "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "src/game/engine/src/modules/management/turn_processor.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/test_climate_tile_sync.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/city/city_buildable_helper.gd",
+ "line": 103
+ },
+ {
+ "file": "src/game/engine/scenes/city/city_buildable_helper.gd",
+ "line": 104
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 13
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 211
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/tile_info_panel.gd",
+ "line": 124
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 371
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 388
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 390
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 392
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 434
+ },
+ {
+ "file": "src/game/engine/src/entities/turn_processor.gd",
+ "line": 477
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 33
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 82
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 86
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate.gd",
+ "line": 133
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_effects.gd",
+ "line": 8
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_effects.gd",
+ "line": 40
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/climate_effects.gd",
+ "line": 40
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 6
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 47
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 57
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 57
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 106
+ },
+ {
+ "file": "src/game/engine/src/modules/management/prologue_driver.gd",
+ "line": 42
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 27
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 37
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor.gd",
+ "line": 462
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 49
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 166
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 166
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 170
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 171
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 172
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_climate_tile_sync.gd",
+ "line": 6
+ }
+ ]
+ },
+ {
+ "name": "GdHappiness",
+ "rustStruct": "GdHappiness",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 719,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/src/entities/turn_processor.gd",
+ "src/game/engine/src/modules/empire/happiness.gd",
+ "src/game/engine/src/modules/management/turn_processor.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/integration/test_happiness_turn.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/entities/turn_processor.gd",
+ "line": 417
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/happiness.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/happiness.gd",
+ "line": 46
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/happiness.gd",
+ "line": 47
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/happiness.gd",
+ "line": 49
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/happiness.gd",
+ "line": 51
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor.gd",
+ "line": 402
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 55
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 235
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 235
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 239
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 240
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 241
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 61
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 62
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 126
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 128
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 129
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 324
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 326
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 327
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_happiness_turn.gd",
+ "line": 329
+ }
+ ]
+ },
+ {
+ "name": "GdItemSystem",
+ "rustStruct": "GdItemSystem",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 1769,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/src/entities/unit.gd",
+ "src/game/engine/src/modules/management/item_system.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/entities/unit.gd",
+ "line": 94
+ },
+ {
+ "file": "src/game/engine/src/modules/management/item_system.gd",
+ "line": 5
+ },
+ {
+ "file": "src/game/engine/src/modules/management/item_system.gd",
+ "line": 32
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 65
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 269
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 270
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 275
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 276
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 277
+ }
+ ]
+ },
+ {
+ "name": "GdLootRoller",
+ "rustStruct": "GdLootRoller",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 1647,
+ "funcCount": 2,
+ "callerFiles": [
+ "src/game/engine/src/modules/management/item_system.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/modules/management/item_system.gd",
+ "line": 7
+ },
+ {
+ "file": "src/game/engine/src/modules/management/item_system.gd",
+ "line": 139
+ },
+ {
+ "file": "src/game/engine/src/modules/management/item_system.gd",
+ "line": 158
+ },
+ {
+ "file": "src/game/engine/src/modules/management/item_system.gd",
+ "line": 181
+ },
+ {
+ "file": "src/game/engine/src/modules/management/item_system.gd",
+ "line": 193
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 64
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 256
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 257
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 262
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 263
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 264
+ }
+ ]
+ },
+ {
+ "name": "GdMapGenerator",
+ "rustStruct": "GdMapGenerator",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 407,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 7
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 126
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 128
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 133
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 211
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 51
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 190
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 191
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 196
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 197
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 198
+ }
+ ]
+ },
+ {
+ "name": "GdMcTreeController",
+ "rustStruct": "GdMcTreeController",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/ai.rs",
+ "line": 140,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "src/game/engine/src/modules/ai/ai_turn_bridge_state.gd",
+ "src/game/engine/tests/integration/test_ai_simulation.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "src/game/engine/tests/unit/ai/test_ai_turn_bridge_stats.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "line": 6
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "line": 70
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "line": 71
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "line": 72
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "line": 76
+ },
+ {
+ "file": "src/game/engine/src/modules/ai/ai_turn_bridge_state.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_ai_simulation.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 98
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 331
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 332
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 337
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 338
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 339
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 6
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 77
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 78
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 94
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 98
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 99
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 107
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 130
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 204
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 205
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 219
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 224
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 237
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 238
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 241
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 277
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 278
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_mcts.gd",
+ "line": 290
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_stats.gd",
+ "line": 89
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_stats.gd",
+ "line": 91
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_stats.gd",
+ "line": 92
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_stats.gd",
+ "line": 124
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_stats.gd",
+ "line": 125
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_stats.gd",
+ "line": 135
+ },
+ {
+ "file": "src/game/engine/tests/unit/ai/test_ai_turn_bridge_stats.gd",
+ "line": 136
+ }
+ ]
+ },
+ {
+ "name": "GdOpenBordersAgreement",
+ "rustStruct": "GdOpenBordersAgreement",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 3176,
+ "funcCount": 6,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "src/game/engine/tests/unit/test_courier_lifecycle.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 120
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 122
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 8
+ }
+ ]
+ },
+ {
+ "name": "GdPrologue",
+ "rustStruct": "GdPrologue",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 4525,
+ "funcCount": 4,
+ "callerFiles": [
+ "src/game/engine/scenes/hud/world_map_hud.gd",
+ "src/game/engine/scenes/world_map/world_map.gd",
+ "src/game/engine/src/autoloads/event_bus.gd",
+ "src/game/engine/src/modules/management/prologue_driver.gd",
+ "src/game/engine/tests/unit/test_prologue_driver.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/hud/world_map_hud.gd",
+ "line": 207
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 286
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 371
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 379
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 413
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/world_map.gd",
+ "line": 480
+ },
+ {
+ "file": "src/game/engine/src/autoloads/event_bus.gd",
+ "line": 15
+ },
+ {
+ "file": "src/game/engine/src/autoloads/event_bus.gd",
+ "line": 16
+ },
+ {
+ "file": "src/game/engine/src/modules/management/prologue_driver.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/management/prologue_driver.gd",
+ "line": 10
+ },
+ {
+ "file": "src/game/engine/src/modules/management/prologue_driver.gd",
+ "line": 11
+ },
+ {
+ "file": "src/game/engine/src/modules/management/prologue_driver.gd",
+ "line": 23
+ },
+ {
+ "file": "src/game/engine/src/modules/management/prologue_driver.gd",
+ "line": 24
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_prologue_driver.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_prologue_driver.gd",
+ "line": 66
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_prologue_driver.gd",
+ "line": 71
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_prologue_driver.gd",
+ "line": 83
+ }
+ ]
+ },
+ {
+ "name": "GdSharedMapAgreement",
+ "rustStruct": "GdSharedMapAgreement",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 3230,
+ "funcCount": 8,
+ "callerFiles": [
+ "src/game/engine/tests/unit/test_courier_lifecycle.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 8
+ }
+ ]
+ },
+ {
+ "name": "GdStockpile",
+ "rustStruct": "GdStockpile",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 607,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/scenes/city/city_buildable_helper.gd",
+ "src/game/engine/scenes/tests/items_queue_proof.gd",
+ "src/game/engine/scenes/tests/treasury_proof.gd",
+ "src/game/engine/scenes/treasury/treasury_tab.gd",
+ "src/game/engine/tests/ffi/test_golden_economy.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/test_city_bridge.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/city/city_buildable_helper.gd",
+ "line": 179
+ },
+ {
+ "file": "src/game/engine/scenes/tests/items_queue_proof.gd",
+ "line": 38
+ },
+ {
+ "file": "src/game/engine/scenes/tests/items_queue_proof.gd",
+ "line": 39
+ },
+ {
+ "file": "src/game/engine/scenes/tests/items_queue_proof.gd",
+ "line": 43
+ },
+ {
+ "file": "src/game/engine/scenes/tests/treasury_proof.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/scenes/tests/treasury_proof.gd",
+ "line": 54
+ },
+ {
+ "file": "src/game/engine/scenes/tests/treasury_proof.gd",
+ "line": 56
+ },
+ {
+ "file": "src/game/engine/scenes/treasury/treasury_tab.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/scenes/treasury/treasury_tab.gd",
+ "line": 10
+ },
+ {
+ "file": "src/game/engine/scenes/treasury/treasury_tab.gd",
+ "line": 235
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_economy.gd",
+ "line": 13
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_economy.gd",
+ "line": 36
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_economy.gd",
+ "line": 150
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 53
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 215
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 215
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 219
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 220
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 221
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 69
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 70
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 91
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 124
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 125
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 143
+ }
+ ]
+ },
+ {
+ "name": "GdTechWeb",
+ "rustStruct": "GdTechWeb",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 3766,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/src/entities/turn_processor.gd",
+ "src/game/engine/src/modules/management/turn_processor.gd",
+ "src/game/engine/src/modules/management/turn_processor_helpers.gd",
+ "src/game/engine/src/modules/tech/knowledge_web.gd",
+ "src/game/engine/src/modules/tech/tech_web.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "src/game/engine/tests/unit/test_tech_web.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/entities/turn_processor.gd",
+ "line": 152
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor.gd",
+ "line": 148
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor_helpers.gd",
+ "line": 61
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor_helpers.gd",
+ "line": 71
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor_helpers.gd",
+ "line": 86
+ },
+ {
+ "file": "src/game/engine/src/modules/tech/knowledge_web.gd",
+ "line": 12
+ },
+ {
+ "file": "src/game/engine/src/modules/tech/tech_web.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/tech/tech_web.gd",
+ "line": 16
+ },
+ {
+ "file": "src/game/engine/src/modules/tech/tech_web.gd",
+ "line": 40
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 29
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 114
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 115
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 360
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 362
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 363
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 43
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 45
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 71
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 72
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 75
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 83
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 98
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 118
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 136
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 148
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 160
+ },
+ {
+ "file": "src/game/engine/tests/unit/management/test_research_bridge.gd",
+ "line": 184
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_tech_web.gd",
+ "line": 10
+ }
+ ]
+ },
+ {
+ "name": "GdTrade",
+ "rustStruct": "GdTrade",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 2822,
+ "funcCount": 4,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "src/game/engine/src/modules/empire/diplomacy.gd",
+ "src/game/engine/src/modules/empire/test_diplomacy.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "src/game/engine/tests/unit/test_diplomacy.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 51
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 52
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 111
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 112
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 40
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 41
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 49
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 50
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 109
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 110
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 124
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 143
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "line": 5
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "line": 14
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "line": 15
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "line": 17
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "line": 19
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/test_diplomacy.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/test_diplomacy.gd",
+ "line": 6
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/test_diplomacy.gd",
+ "line": 172
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/test_diplomacy.gd",
+ "line": 177
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/test_diplomacy.gd",
+ "line": 178
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 97
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 320
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 320
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 324
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 325
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 326
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 7
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 26
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_diplomacy.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_diplomacy.gd",
+ "line": 6
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_diplomacy.gd",
+ "line": 172
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_diplomacy.gd",
+ "line": 177
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_diplomacy.gd",
+ "line": 178
+ }
+ ]
+ },
+ {
+ "name": "GdTradeLedger",
+ "rustStruct": "GdTradeLedger",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 3300,
+ "funcCount": 3,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "src/game/engine/src/autoloads/game_state.gd",
+ "src/game/engine/src/modules/empire/diplomacy.gd",
+ "src/game/engine/tests/unit/test_courier_lifecycle.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 21
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 22
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 55
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era10_instant_sync_proof.gd",
+ "line": 116
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 13
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 14
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 55
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era2_round_trip_proof.gd",
+ "line": 56
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 20
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 21
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 54
+ },
+ {
+ "file": "src/game/engine/scenes/tests/courier_era7_severance_proof.gd",
+ "line": 114
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 113
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 114
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 116
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 117
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 140
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 141
+ },
+ {
+ "file": "src/game/engine/scenes/tests/diplomacy_courier_proof.gd",
+ "line": 146
+ },
+ {
+ "file": "src/game/engine/src/autoloads/game_state.gd",
+ "line": 125
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "line": 79
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "line": 81
+ },
+ {
+ "file": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "line": 83
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 7
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 12
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 20
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 22
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 38
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 120
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 141
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 188
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 214
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 234
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_courier_lifecycle.gd",
+ "line": 263
+ }
+ ]
+ },
+ {
+ "name": "GdTreasury",
+ "rustStruct": "GdTreasury",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 824,
+ "funcCount": 4,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/treasury_proof.gd",
+ "src/game/engine/scenes/treasury/treasury_tab.gd",
+ "src/game/engine/tests/ffi/test_golden_economy.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "src/game/engine/tests/unit/test_city_bridge.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/treasury_proof.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/scenes/tests/treasury_proof.gd",
+ "line": 42
+ },
+ {
+ "file": "src/game/engine/scenes/tests/treasury_proof.gd",
+ "line": 44
+ },
+ {
+ "file": "src/game/engine/scenes/treasury/treasury_tab.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/scenes/treasury/treasury_tab.gd",
+ "line": 10
+ },
+ {
+ "file": "src/game/engine/scenes/treasury/treasury_tab.gd",
+ "line": 214
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_economy.gd",
+ "line": 14
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_economy.gd",
+ "line": 37
+ },
+ {
+ "file": "src/game/engine/tests/ffi/test_golden_economy.gd",
+ "line": 150
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 54
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 225
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 225
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 229
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 230
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 231
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 72
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 73
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_city_bridge.gd",
+ "line": 103
+ }
+ ]
+ },
+ {
+ "name": "GdTurnProcessor",
+ "rustStruct": "GdTurnProcessor",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 2403,
+ "funcCount": 2,
+ "callerFiles": [
+ "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "src/game/engine/scenes/tests/iter_7j_encounters_only_proof.gd",
+ "src/game/engine/scenes/tests/iter_7k_turn_processor_gated_proof.gd",
+ "src/game/engine/scenes/tests/iter_7l_per_lair_tier_proof.gd",
+ "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "src/game/engine/src/modules/management/rust_fauna_integration.gd",
+ "src/game/engine/src/modules/management/turn_processor_signals.gd",
+ "src/game/engine/tests/integration/test_1000_turns.gd",
+ "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "src/game/engine/tests/integration/test_gdextension_contract.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 6
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 38
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 68
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 83
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 84
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 86
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7e_turn_bridge_proof.gd",
+ "line": 168
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 17
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 89
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 109
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 111
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7g_real_mapgen_proof.gd",
+ "line": 211
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "line": 57
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "line": 99
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "line": 101
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7h_dict_adapter_proof.gd",
+ "line": 253
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "line": 6
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "line": 60
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "line": 101
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "line": 103
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7i_unit_adapter_proof.gd",
+ "line": 222
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7j_encounters_only_proof.gd",
+ "line": 15
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7j_encounters_only_proof.gd",
+ "line": 54
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7j_encounters_only_proof.gd",
+ "line": 95
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7j_encounters_only_proof.gd",
+ "line": 97
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7j_encounters_only_proof.gd",
+ "line": 197
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7k_turn_processor_gated_proof.gd",
+ "line": 16
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7k_turn_processor_gated_proof.gd",
+ "line": 104
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7k_turn_processor_gated_proof.gd",
+ "line": 231
+ },
+ {
+ "file": "src/game/engine/scenes/tests/iter_7l_per_lair_tier_proof.gd",
+ "line": 188
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 11
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "line": 29
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_integration.gd",
+ "line": 11
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_integration.gd",
+ "line": 42
+ },
+ {
+ "file": "src/game/engine/src/modules/management/rust_fauna_integration.gd",
+ "line": 45
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor_signals.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_1000_turns.gd",
+ "line": 5
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_1000_turns.gd",
+ "line": 21
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_1000_turns.gd",
+ "line": 29
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 2
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 10
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 37
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 39
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 44
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 127
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 135
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 164
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 166
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gd_turn_processor.gd",
+ "line": 167
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 89
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 295
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 296
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 301
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 302
+ },
+ {
+ "file": "src/game/engine/tests/integration/test_gdextension_contract.gd",
+ "line": 303
+ }
+ ]
+ },
+ {
+ "name": "GdUnitActions",
+ "rustStruct": "GdUnitActions",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/action.rs",
+ "line": 14,
+ "funcCount": 1,
+ "callerFiles": [
+ "src/game/engine/scenes/hud/unit_panel.gd",
+ "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "src/game/engine/src/entities/unit.gd",
+ "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "src/game/engine/tests/unit/test_patrol.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/scenes/hud/unit_panel.gd",
+ "line": 5
+ },
+ {
+ "file": "src/game/engine/scenes/hud/unit_panel.gd",
+ "line": 169
+ },
+ {
+ "file": "src/game/engine/scenes/hud/unit_panel.gd",
+ "line": 170
+ },
+ {
+ "file": "src/game/engine/scenes/hud/unit_panel.gd",
+ "line": 259
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 82
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 84
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 87
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 89
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 96
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 97
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 99
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 107
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 109
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 112
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 120
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 121
+ },
+ {
+ "file": "src/game/engine/scenes/world_map/formation_bridge.gd",
+ "line": 123
+ },
+ {
+ "file": "src/game/engine/src/entities/unit.gd",
+ "line": 272
+ },
+ {
+ "file": "src/game/engine/src/entities/unit.gd",
+ "line": 277
+ },
+ {
+ "file": "src/game/engine/src/entities/unit.gd",
+ "line": 280
+ },
+ {
+ "file": "src/game/engine/src/entities/unit.gd",
+ "line": 282
+ },
+ {
+ "file": "src/game/engine/src/entities/unit.gd",
+ "line": 293
+ },
+ {
+ "file": "src/game/engine/src/entities/unit.gd",
+ "line": 295
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 3
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 119
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 123
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 124
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 126
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 137
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 138
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 140
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 149
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 150
+ },
+ {
+ "file": "src/game/engine/tests/unit/entities/test_unit_actions.gd",
+ "line": 152
+ },
+ {
+ "file": "src/game/engine/tests/unit/test_patrol.gd",
+ "line": 6
+ }
+ ]
+ },
+ {
+ "name": "GdWeatherPhysics",
+ "rustStruct": "GdWeatherPhysics",
+ "base": "RefCounted",
+ "file": "src/simulator/api-gdext/src/lib.rs",
+ "line": 4340,
+ "funcCount": 2,
+ "callerFiles": [
+ "src/game/engine/src/entities/turn_processor.gd",
+ "src/game/engine/src/modules/climate/weather.gd",
+ "src/game/engine/src/modules/management/turn_processor.gd"
+ ],
+ "callerLines": [
+ {
+ "file": "src/game/engine/src/entities/turn_processor.gd",
+ "line": 479
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 4
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 22
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 24
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 35
+ },
+ {
+ "file": "src/game/engine/src/modules/climate/weather.gd",
+ "line": 37
+ },
+ {
+ "file": "src/game/engine/src/modules/management/turn_processor.gd",
+ "line": 464
+ }
+ ]
+ }
+ ],
+ "gdClassNames": {
+ "AchievementTracker": "src/game/engine/src/modules/management/achievement_tracker.gd",
+ "AiTurnBridge": "src/game/engine/src/modules/ai/ai_turn_bridge.gd",
+ "AiTurnOverlay": "src/game/engine/scenes/hud/ai_turn_overlay.gd",
+ "AirFaunaModel": "src/game/engine/src/models/world/air_fauna.gd",
+ "AnchorDecay": "src/game/engine/src/modules/climate/anchor_decay.gd",
+ "Archon": "src/game/engine/src/entities/archon.gd",
+ "ArenaOverlay": "src/game/engine/scenes/world_map/arena_overlay.gd",
+ "AscensionRitual": "src/game/engine/src/modules/victory/ascension_ritual.gd",
+ "Atmosphere": "src/game/engine/src/modules/climate/atmosphere.gd",
+ "AtmosphereAnomalies": "src/game/engine/src/modules/climate/atmosphere_anomalies.gd",
+ "AudioLoader": "src/game/engine/src/audio/audio_loader.gd",
+ "AudioResolver": "src/game/engine/src/audio/audio_resolver.gd",
+ "BiomeClassifier": "src/game/engine/src/models/world/biome_classifier.gd",
+ "BiomeModel": "src/game/engine/src/models/world/biome.gd",
+ "Building": "src/game/engine/src/entities/building.gd",
+ "ChroniclePanel": "src/game/engine/scenes/hud/chronicle_panel.gd",
+ "City": "src/game/engine/src/entities/city.gd",
+ "CityDetailFormatter": "src/game/engine/scenes/city/city_detail_formatter.gd",
+ "CityRenderer": "src/game/engine/src/rendering/city_renderer.gd",
+ "CitySiteScorer": "src/game/engine/src/modules/management/city_site_scorer.gd",
+ "Climate": "src/game/engine/src/modules/climate/climate.gd",
+ "ClimateEffects": "src/game/engine/src/modules/climate/climate_effects.gd",
+ "ClimateSpecEval": "src/game/engine/src/modules/climate/climate_spec_eval.gd",
+ "CombatResolver": "src/game/engine/src/modules/combat/combat_resolver.gd",
+ "CombatUtils": "src/game/engine/src/modules/combat/combat_utils.gd",
+ "CourierRouteOverlay": "src/game/engine/scenes/world_map/courier_route_overlay.gd",
+ "Culture": "src/game/engine/src/modules/empire/culture.gd",
+ "CultureTree": "src/game/engine/scenes/culture_tree/culture_tree.gd",
+ "CultureWeb": "src/game/engine/src/modules/empire/culture_web.gd",
+ "Diplomacy": "src/game/engine/src/modules/empire/diplomacy.gd",
+ "EcologicalEvents": "src/game/engine/src/modules/climate/ecological_events.gd",
+ "EcologyDB": "src/game/engine/src/modules/ecology/ecology_db.gd",
+ "EcologyInitializer": "src/game/engine/src/modules/ecology/ecology_initializer.gd",
+ "Economy": "src/game/engine/src/modules/empire/economy.gd",
+ "EcosystemSimplified": "src/game/engine/src/modules/ecology/ecosystem_simplified.gd",
+ "EntityFinder": "src/game/engine/src/map/entity_finder.gd",
+ "FaunaDynamics": "src/game/engine/src/modules/ecology/fauna.gd",
+ "FaunaSimplified": "src/game/engine/src/modules/ecology/fauna_simplified.gd",
+ "FlavorGenerator": "src/game/engine/src/models/world/flavor_generator.gd",
+ "FloatingViewportWindow": "src/game/engine/src/ui/floating_viewport_window.gd",
+ "FloraProfile": "src/game/engine/src/models/world/flora_profile.gd",
+ "FoodWebRules": "src/game/engine/src/models/world/food_web_rules.gd",
+ "GameMap": "src/game/engine/src/map/game_map.gd",
+ "GoldenVectorLoader": "src/game/engine/tests/ffi/golden_vector_loader.gd",
+ "Government": "src/game/engine/src/modules/empire/government.gd",
+ "GutErrorTracker": "src/game/addons/gut/error_tracker.gd",
+ "GutHookScript": "src/game/addons/gut/hook_script.gd",
+ "GutInputFactory": "src/game/addons/gut/input_factory.gd",
+ "GutInputSender": "src/game/addons/gut/input_sender.gd",
+ "GutMain": "src/game/addons/gut/gut.gd",
+ "GutStringUtils": "src/game/addons/gut/strutils.gd",
+ "GutTest": "src/game/addons/gut/test.gd",
+ "GutTrackedError": "src/game/addons/gut/gut_tracked_error.gd",
+ "GutUtils": "src/game/addons/gut/utils.gd",
+ "Happiness": "src/game/engine/src/modules/empire/happiness.gd",
+ "HappinessBreakdownPanel": "src/game/engine/scenes/hud/happiness_breakdown_panel.gd",
+ "HexRenderer": "src/game/engine/src/rendering/hex_renderer.gd",
+ "HexUtils": "src/game/engine/src/map/hex_utils.gd",
+ "HotkeySheet": "src/game/engine/scenes/hud/hotkey_sheet.gd",
+ "Hydrology": "src/game/engine/src/generation/hydrology.gd",
+ "HydrologyRivers": "src/game/engine/src/generation/hydrology_rivers.gd",
+ "Improvement": "src/game/engine/src/entities/improvement.gd",
+ "ImprovementManager": "src/game/engine/src/modules/management/improvement_manager.gd",
+ "IndicatorRenderer": "src/game/engine/src/rendering/indicator_renderer.gd",
+ "ItemSystem": "src/game/engine/src/modules/management/item_system.gd",
+ "KeywordHandler": "src/game/engine/src/modules/combat/keyword_handler.gd",
+ "KnowledgeTree": "src/game/engine/scenes/knowledge_tree/knowledge_tree.gd",
+ "KnowledgeWeb": "src/game/engine/src/modules/tech/knowledge_web.gd",
+ "LairOverlayRenderer": "src/game/engine/src/rendering/lair_overlay_renderer.gd",
+ "LandFaunaModel": "src/game/engine/src/models/world/land_fauna.gd",
+ "LeyNetwork": "src/game/engine/src/modules/ley/ley_network.gd",
+ "LeyResidue": "src/game/engine/src/modules/ley/ley_residue.gd",
+ "MapGenerator": "src/game/engine/src/generation/map_generator.gd",
+ "MapLoader": "src/game/engine/src/map/map_loader.gd",
+ "MapPlacer": "src/game/engine/src/generation/map_placer.gd",
+ "MapShapeSeeds": "src/game/engine/src/generation/map_shape_seeds.gd",
+ "MarineFaunaModel": "src/game/engine/src/models/world/marine_fauna.gd",
+ "MarineHarvest": "src/game/engine/src/modules/events/marine_harvest.gd",
+ "NaturalEvents": "src/game/engine/src/modules/events/natural_events.gd",
+ "NaturalEventsConditions": "src/game/engine/src/modules/events/natural_events_conditions.gd",
+ "NaturalEventsEffects": "src/game/engine/src/modules/events/natural_events_effects.gd",
+ "OverlayRenderer": "src/game/engine/src/rendering/overlay_renderer.gd",
+ "Pathfinder": "src/game/engine/src/map/pathfinder.gd",
+ "PendingActions": "src/game/engine/src/core/pending_actions.gd",
+ "PersonalityAssigner": "src/game/engine/src/modules/ai/personality_assigner.gd",
+ "Player": "src/game/engine/src/entities/player.gd",
+ "ProductionFilter": "src/game/engine/src/modules/management/production_filter.gd",
+ "PrologueDriver": "src/game/engine/src/modules/management/prologue_driver.gd",
+ "PrologueOverlayRenderer": "src/game/engine/src/rendering/prologue_overlay_renderer.gd",
+ "RiverRenderer": "src/game/engine/src/rendering/river_renderer.gd",
+ "RoadRenderer": "src/game/engine/src/rendering/road_renderer.gd",
+ "RustFaunaBridge": "src/game/engine/src/modules/management/rust_fauna_bridge.gd",
+ "RustFaunaIntegration": "src/game/engine/src/modules/management/rust_fauna_integration.gd",
+ "SaveManager": "src/game/engine/src/core/save_manager.gd",
+ "SpeciesGenerator": "src/game/engine/src/models/world/species_generator.gd",
+ "SpellSystem": "src/game/engine/src/modules/magic/spell_system.gd",
+ "SplitPanelContainer": "src/game/engine/src/ui/split_panel_container.gd",
+ "StartBalancer": "src/game/engine/src/generation/start_balancer.gd",
+ "StartPosition": "src/game/engine/src/generation/start_position.gd",
+ "SubstrateType": "src/game/engine/src/models/world/substrate.gd",
+ "TechTree": "src/game/engine/scenes/tech_tree/tech_tree.gd",
+ "TechWeb": "src/game/engine/src/modules/tech/tech_web.gd",
+ "TerrainAffinity": "src/game/engine/src/core/terrain_affinity.gd",
+ "TerrainRefiner": "src/game/engine/src/generation/terrain_refiner.gd",
+ "Tile": "src/game/engine/src/map/tile.gd",
+ "TileSerializer": "src/game/engine/src/map/tile_serializer.gd",
+ "TraitSet": "src/game/engine/src/models/world/species_traits.gd",
+ "TurnNotification": "src/game/engine/scenes/hud/turn_notification.gd",
+ "TutorialOverlay": "src/game/engine/scenes/hud/tutorial_overlay.gd",
+ "Unit": "src/game/engine/src/entities/unit.gd",
+ "UnitManager": "src/game/engine/src/modules/management/unit_manager.gd",
+ "UnitRenderer": "src/game/engine/src/rendering/unit_renderer.gd",
+ "UnitStatHelpers": "src/game/engine/src/entities/unit_stat_helpers.gd",
+ "VictoryManager": "src/game/engine/src/modules/victory/victory_manager.gd",
+ "ViewportPanel": "src/game/engine/src/ui/viewport_panel.gd",
+ "ViewportWindowManager": "src/game/engine/src/ui/viewport_window_manager.gd",
+ "VillageLairPlacer": "src/game/engine/src/generation/village_lair_placer.gd",
+ "WaterBody": "src/game/engine/src/models/world/water_body.gd",
+ "WaterBodyFinder": "src/game/engine/src/modules/ecology/water_body_finder.gd",
+ "Weather": "src/game/engine/src/modules/climate/weather.gd",
+ "WeatherEvents": "src/game/engine/src/modules/climate/weather_events.gd",
+ "WildCreatureAI": "src/game/engine/src/modules/ai/wild_creature_ai.gd",
+ "WindCalculator": "src/game/engine/src/generation/wind_calculator.gd",
+ "WorldMapHover": "src/game/engine/scenes/world_map/world_map_hover.gd",
+ "WorldMapHud": "src/game/engine/scenes/hud/world_map_hud.gd"
+ },
+ "collisions": [],
+ "crateDeps": {
+ "magic-civ-physics": [
+ "mc-climate",
+ "mc-compute",
+ "mc-core",
+ "mc-mapgen"
+ ],
+ "magic-civ-physics-gdext": [
+ "mc-ai",
+ "mc-city",
+ "mc-climate",
+ "mc-combat",
+ "mc-compute",
+ "mc-core",
+ "mc-culture",
+ "mc-ecology",
+ "mc-economy",
+ "mc-happiness",
+ "mc-items",
+ "mc-mapgen",
+ "mc-mcts-service",
+ "mc-tech",
+ "mc-trade",
+ "mc-turn"
+ ],
+ "mc-ai": [
+ "mc-combat",
+ "mc-core",
+ "mc-trade"
+ ],
+ "mc-balance": [
+ "mc-ai"
+ ],
+ "mc-city": [
+ "mc-core",
+ "mc-economy"
+ ],
+ "mc-climate": [
+ "mc-core"
+ ],
+ "mc-combat": [
+ "mc-core"
+ ],
+ "mc-compute": [
+ "mc-climate",
+ "mc-core"
+ ],
+ "mc-core": [],
+ "mc-culture": [
+ "mc-core",
+ "mc-tech"
+ ],
+ "mc-ecology": [
+ "mc-climate",
+ "mc-compute",
+ "mc-core",
+ "mc-flora"
+ ],
+ "mc-economy": [
+ "mc-core"
+ ],
+ "mc-flora": [
+ "mc-core"
+ ],
+ "mc-happiness": [
+ "mc-core"
+ ],
+ "mc-items": [],
+ "mc-magic": [
+ "mc-core"
+ ],
+ "mc-mapgen": [
+ "mc-core",
+ "mc-turn"
+ ],
+ "mc-mcts-service": [
+ "mc-ai",
+ "mc-turn"
+ ],
+ "mc-observation": [
+ "mc-core"
+ ],
+ "mc-replay": [],
+ "mc-sim": [
+ "mc-ai",
+ "mc-balance",
+ "mc-city",
+ "mc-climate",
+ "mc-combat",
+ "mc-compute",
+ "mc-core",
+ "mc-culture",
+ "mc-ecology",
+ "mc-economy",
+ "mc-flora",
+ "mc-mapgen",
+ "mc-turn"
+ ],
+ "mc-tech": [
+ "mc-core"
+ ],
+ "mc-trade": [],
+ "mc-turn": [
+ "mc-ai",
+ "mc-city",
+ "mc-combat",
+ "mc-core",
+ "mc-culture",
+ "mc-economy",
+ "mc-happiness",
+ "mc-tech",
+ "mc-trade"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/public/games/age-of-dwarves/docs/HEX_GEOMETRY.md b/public/games/age-of-dwarves/docs/HEX_GEOMETRY.md
index a4b88282..0d7a1302 100644
--- a/public/games/age-of-dwarves/docs/HEX_GEOMETRY.md
+++ b/public/games/age-of-dwarves/docs/HEX_GEOMETRY.md
@@ -226,6 +226,7 @@ The model in this doc is the **target** spec; the code is partial.
| Pathfinding (Rust A*) | (does not yet exist in Rust) | ⚠️ No Rust A* found in `mc-core/src/algorithms/`; existing pathfinding lives GDScript-side. `validate_centre_to_centre_move` is ready for the future Rust pathfinder to call. |
| Renderer | `src/packages/guide/src/components/climate-sim/HexGLRenderer.tsx` | ✅ Hex tile rendering correct; no inner-hex / edge-slot overlay (debug-only feature pending) |
| AI evaluator | `src/simulator/crates/mc-ai/src/evaluator.rs:414-480` | ⚠️ Scores formations by size + threat; does not yet model edge-slot positioning |
+| GDExtension bridge | `src/simulator/api-gdext/src/lib.rs::GdGameState::engagement_interceptor / validate_centre_to_centre_move` | ✅ Two Godot-callable primitives expose the edge model to GDScript. Combat preview UI consults `engagement_interceptor`; movement preview consults `validate_centre_to_centre_move` and branches on `reason` (`not_adjacent / wall_blocks / edge_occupied / adjacent_clean`). |
**Test coverage** (`cargo test -p mc-core --lib`): 70 tests (was 30 before this work) covering edge identity, passability, move validation, engagement interception, ZOC reach (centre + edge), formation slot model, blend-table lookup with production-JSON round-trip, cross-file schema guard (every blend → defined terrain), river-edges migration. `cargo test -p mc-mapgen --lib`: 24 tests including 3 river-determinism guards.
diff --git a/public/games/age-of-dwarves/manifest.json b/public/games/age-of-dwarves/manifest.json
index f60df656..0f235a74 100644
--- a/public/games/age-of-dwarves/manifest.json
+++ b/public/games/age-of-dwarves/manifest.json
@@ -62,18 +62,15 @@
"dwarf_grand_scout",
"dwarf_grand_smith",
"dwarf_graven_warrior",
- "dwarf_gyrocopter",
"dwarf_hammerguard",
"dwarf_high_engineer",
"dwarf_high_sapper",
"dwarf_high_smith",
- "dwarf_iron_hawk",
"dwarf_iron_submarine",
"dwarf_iron_vanguard",
"dwarf_ironwarden",
"dwarf_master_woodcutter",
"dwarf_mithril_cruiser",
- "dwarf_mithril_hawk",
"dwarf_mithril_vanguard",
"dwarf_prospector",
"dwarf_repeating_arbalest",
diff --git a/public/resources/buildings/airfield.json b/public/resources/buildings/airfield.json
index 4429fdeb..ddf167de 100644
--- a/public/resources/buildings/airfield.json
+++ b/public/resources/buildings/airfield.json
@@ -1,7 +1,7 @@
{
"id": "airfield",
- "name": "Airfield",
- "description": "A flat expanse carved from the mountainside with launch rails and landing strips. Required for all air unit production.",
+ "name": "Airship Yard",
+ "description": "Mooring masts, gas-bag bays, and a small steam-pumping station. The first dwarven foothold in the air — built to assemble and launch armored airships. Fixed-wing flight remains beyond Game-1 dwarven engineering.",
"placement": "city",
"category": "military",
"school": null,
@@ -32,8 +32,6 @@
]
},
"produces": [
- "dwarf_gyrocopter",
- "dwarf_iron_hawk",
"dwarf_steam_bomber"
],
"stack_mode": "parallel"
diff --git a/public/resources/buildings/tank_yard.json b/public/resources/buildings/tank_yard.json
index d168e99d..21170daa 100644
--- a/public/resources/buildings/tank_yard.json
+++ b/public/resources/buildings/tank_yard.json
@@ -39,7 +39,7 @@
"strike_walker"
],
"stack_mode": "parallel",
- "requires_existing": "walker_yard",
+ "requires_existing": null,
"consumes_existing": false
}
]
diff --git a/public/resources/buildings/walker_yard.json b/public/resources/buildings/walker_yard.json
index c63857b9..a7d82627 100644
--- a/public/resources/buildings/walker_yard.json
+++ b/public/resources/buildings/walker_yard.json
@@ -38,6 +38,7 @@
"iron_sentinel",
"dwarf_steam_golem"
],
- "stack_mode": "parallel"
+ "stack_mode": "parallel",
+ "requires_existing": "tank_yard"
}
]
diff --git a/public/resources/buildings/zeppelin_dock.json b/public/resources/buildings/zeppelin_dock.json
index 19274480..714eb2a4 100644
--- a/public/resources/buildings/zeppelin_dock.json
+++ b/public/resources/buildings/zeppelin_dock.json
@@ -34,7 +34,6 @@
},
"produces": [
"dwarf_war_zeppelin",
- "dwarf_mithril_hawk",
"dwarf_sky_fortress"
],
"stack_mode": "parallel",
diff --git a/src/game/engine/tests/unit/test_victory_manager.gd b/src/game/engine/tests/unit/test_victory_manager.gd
index 7c84f66a..2fd01470 100644
--- a/src/game/engine/tests/unit/test_victory_manager.gd
+++ b/src/game/engine/tests/unit/test_victory_manager.gd
@@ -1,26 +1,84 @@
extends GutTest
-## VictoryManager unit tests — PENDING until VictoryManager is implemented.
+## VictoryManager — elimination reconciliation pass (p2-45).
##
-## `src/game/engine/src/modules/victory/victory_manager.gd` is a
-## 2-line stub (`class_name VictoryManager extends RefCounted`).
-## None of the methods the original tests exercised (`get_score`,
-## `get_scores`, `check_victory`) and none of the score constants
-## (`SCORE_CITY`, `SCORE_POP`, `SCORE_TECH`, `SCORE_UNIT`) exist.
+## `victory_manager._reconcile_eliminations` fires
+## `EventBus.player_eliminated` exactly once per player whose
+## (cities ∪ living-founder) set transitions to empty. The
+## `is_eliminated` latch on PlayerScript dedupes against the existing
+## combat-utils emit so per-turn sweeps don't double-fire.
##
-## There is also no Rust-side bridge — `mc-turn::victory` or a
-## `GdVictoryManager` extension has not been authored yet.
-## Reported to team-lead for iter 7n+.
-##
-## The original tests also referenced Player/City/Unit fields that
-## were dropped in iter 7i/7l (`is_player_controlled`, `city_name`,
-## `population`, `owned_tiles`, `type_id`, `id`). Rehydrating these
-## tests will require re-authoring both sides against the current
-## entity API.
+## (The earlier stub of this file pre-dates the VictoryManager port —
+## the manager has been real since iter 7n. Rehydrated here for p2-45.)
+
+const VictoryManagerScript: GDScript = preload("res://engine/src/modules/victory/victory_manager.gd")
+const PlayerScript: GDScript = preload("res://engine/src/entities/player.gd")
-func test_victory_manager_pending() -> void:
- pending(
- "VictoryManager is a 2-line stub in iter 7n — see"
- + " src/game/engine/src/modules/victory/victory_manager.gd."
- + " No methods to exercise yet; rehydrate when implemented."
- )
+func before_all() -> void:
+ DataLoader.load_theme("age-of-dwarves")
+
+
+func before_each() -> void:
+ GameState.players.clear()
+ var human: RefCounted = PlayerScript.new()
+ human.player_name = "Player"
+ human.is_human = true
+ human.index = 0
+ # Survivor: keeps a phantom city Dictionary so cities.size() > 0.
+ human.cities = [{"display_name": "Khazad-dum"}]
+ GameState.players.append(human)
+ var ai: RefCounted = PlayerScript.new()
+ ai.player_name = "Rival"
+ ai.is_human = false
+ ai.index = 1
+ # Eliminated: no cities, no founder. Reconciliation should fire on first sweep.
+ ai.cities = []
+ ai.units = []
+ GameState.players.append(ai)
+ GameState.current_player_index = 0
+
+
+func _capture_eliminations() -> Array[int]:
+ var captured: Array[int] = []
+ var handler: Callable = func(idx: int) -> void: captured.append(idx)
+ EventBus.player_eliminated.connect(handler)
+ var vm: RefCounted = VictoryManagerScript.new()
+ vm.call("_reconcile_eliminations")
+ EventBus.player_eliminated.disconnect(handler)
+ return captured
+
+
+func test_reconciliation_emits_for_eliminated_player() -> void:
+ var captured: Array[int] = _capture_eliminations()
+ assert_eq(captured.size(), 1, "AI with no cities + no founder must trigger one emit")
+ assert_eq(captured[0], 1, "the eliminated player's index must be the rival (1)")
+
+
+func test_reconciliation_latches_is_eliminated_flag() -> void:
+ var ai: PlayerScript = GameState.players[1] as PlayerScript
+ assert_false(ai.is_eliminated, "starts un-latched")
+ _capture_eliminations()
+ assert_true(ai.is_eliminated, "first sweep latches is_eliminated to true")
+
+
+func test_second_sweep_is_silent() -> void:
+ # First sweep emits and latches; a second sweep on the same turn must
+ # NOT re-emit. This is the dedupe contract.
+ _capture_eliminations()
+ var second: Array[int] = _capture_eliminations()
+ assert_eq(second.size(), 0, "second reconciliation sweep must not re-emit")
+
+
+func test_survivor_does_not_trigger() -> void:
+ var captured: Array[int] = _capture_eliminations()
+ for idx: int in captured:
+ assert_ne(idx, 0, "the human (still has a city) must NOT be in the eliminated set")
+
+
+func test_already_eliminated_flag_skips_emit() -> void:
+ # Simulates combat_utils having already announced the elimination —
+ # reconciliation must respect the latch and stay silent.
+ var ai: PlayerScript = GameState.players[1] as PlayerScript
+ ai.is_eliminated = true
+ var captured: Array[int] = _capture_eliminations()
+ assert_eq(captured.size(), 0, "reconciliation must not re-emit when is_eliminated already true")
diff --git a/src/simulator/api-gdext/src/lib.rs b/src/simulator/api-gdext/src/lib.rs
index 479c8c06..b3ff738e 100644
--- a/src/simulator/api-gdext/src/lib.rs
+++ b/src/simulator/api-gdext/src/lib.rs
@@ -2387,6 +2387,106 @@ impl GdGameState {
}
arr
}
+
+ // ── Edge slot bridge (HEX_GEOMETRY.md §5, §7) ─────────────────────────
+ //
+ // Three Godot-callable primitives exposing the centre + 6 edge slots
+ // model to GDScript: combat preview asks "is there an interceptor on
+ // the edge?", movement preview asks "can this unit cross the edge?".
+
+ /// Look up the edge interceptor between two adjacent hex centres.
+ ///
+ /// Returns a Dictionary:
+ /// - `has_interceptor`: bool
+ /// - `unit_id`: int (only valid when has_interceptor)
+ /// - `owner_player_id`: int (only valid when has_interceptor)
+ /// - `aligned_to`: Vector2i (parent hex of the interceptor, only valid when present)
+ ///
+ /// Returns `has_interceptor: false` for non-adjacent hexes or vacant edges.
+ /// Per `HEX_GEOMETRY.md` §5, an edge unit is hit before the defender's
+ /// centre — combat preview UIs must surface this to the player.
+ #[func]
+ pub fn engagement_interceptor(
+ &self,
+ atk_q: i64,
+ atk_r: i64,
+ def_q: i64,
+ def_r: i64,
+ ) -> Dictionary {
+ let mut d = Dictionary::new();
+ let interceptor = self.inner.grid.as_ref().and_then(|g| {
+ g.engagement_interceptor((atk_q as i32, atk_r as i32), (def_q as i32, def_r as i32))
+ });
+ match interceptor {
+ Some(occ) => {
+ d.set("has_interceptor", true);
+ d.set("unit_id", occ.unit_id as i64);
+ d.set("owner_player_id", occ.owner_player_id as i64);
+ d.set(
+ "aligned_to",
+ Vector2i::new(occ.aligned_to.0, occ.aligned_to.1),
+ );
+ }
+ None => {
+ d.set("has_interceptor", false);
+ }
+ }
+ d
+ }
+
+ /// Validate a single-step centre-to-centre move for `player_id`.
+ ///
+ /// Returns a Dictionary:
+ /// - `ok`: bool
+ /// - `reason`: String — one of `"adjacent_clean"` (when ok=true),
+ /// `"not_adjacent"`, `"wall_blocks"`, `"edge_occupied"` (when ok=false)
+ ///
+ /// Movement preview UIs branch on `reason` to show the appropriate
+ /// player feedback (greyed path, wall icon, enemy unit at edge).
+ #[func]
+ pub fn validate_centre_to_centre_move(
+ &self,
+ from_q: i64,
+ from_r: i64,
+ to_q: i64,
+ to_r: i64,
+ player_id: i64,
+ ) -> Dictionary {
+ use mc_core::grid::MoveBlockedReason;
+ let mut d = Dictionary::new();
+ let result = self.inner.grid.as_ref().map(|g| {
+ g.validate_centre_to_centre_move(
+ (from_q as i32, from_r as i32),
+ (to_q as i32, to_r as i32),
+ player_id as u32,
+ )
+ });
+ match result {
+ Some(Ok(_edge)) => {
+ d.set("ok", true);
+ d.set("reason", GString::from("adjacent_clean"));
+ }
+ Some(Err(MoveBlockedReason::NotAdjacent)) => {
+ d.set("ok", false);
+ d.set("reason", GString::from("not_adjacent"));
+ }
+ Some(Err(MoveBlockedReason::WallBlocks)) => {
+ d.set("ok", false);
+ d.set("reason", GString::from("wall_blocks"));
+ }
+ Some(Err(MoveBlockedReason::EdgeOccupied)) => {
+ d.set("ok", false);
+ d.set("reason", GString::from("edge_occupied"));
+ }
+ None => {
+ // No grid loaded — treat as not-adjacent fallback so UI
+ // doesn't try to draw a movement preview.
+ d.set("ok", false);
+ d.set("reason", GString::from("no_grid"));
+ }
+ }
+ d
+ }
}
// ── GdTurnProcessor ─────────────────────────────────────────────────────
diff --git a/tools/gd-rust-relationships.py b/tools/gd-rust-relationships.py
index ef9ddbc5..aad55da0 100755
--- a/tools/gd-rust-relationships.py
+++ b/tools/gd-rust-relationships.py
@@ -201,6 +201,43 @@ def parse_crate_deps(sim_root: Path) -> dict[str, set[str]]:
return deps
+def build_json(
+ classes: list[RustClass],
+ gd_classes: dict[str, Path],
+ deps: dict[str, set[str]],
+) -> dict:
+ rust_names = {c.name for c in classes}
+ return {
+ "generatedAt": __import__("datetime").datetime.utcnow().isoformat() + "Z",
+ "classes": [
+ {
+ "name": c.name,
+ "rustStruct": c.rust_struct,
+ "base": c.base,
+ "file": str(c.file.relative_to(REPO_ROOT)),
+ "line": c.line,
+ "funcCount": c.func_count,
+ "callerFiles": sorted(
+ {str(p.relative_to(REPO_ROOT)) for p, _ in c.callers}
+ ),
+ "callerLines": [
+ {"file": str(p.relative_to(REPO_ROOT)), "line": ln}
+ for p, ln in sorted(c.callers, key=lambda x: (str(x[0]), x[1]))
+ ],
+ }
+ for c in sorted(classes, key=lambda x: x.name)
+ ],
+ "gdClassNames": {
+ name: str(path.relative_to(REPO_ROOT))
+ for name, path in sorted(gd_classes.items())
+ },
+ "collisions": sorted(set(gd_classes) & rust_names),
+ "crateDeps": {
+ crate: sorted(ds) for crate, ds in sorted(deps.items())
+ },
+ }
+
+
def render_report(
classes: list[RustClass],
gd_classes: dict[str, Path],
@@ -296,6 +333,8 @@ def render_report(
def main() -> int:
+ import json
+
ap = argparse.ArgumentParser()
ap.add_argument(
"--out",
@@ -303,6 +342,7 @@ def main() -> int:
default=REPO_ROOT / ".project" / "reports" / "gd-rust-relationships.md",
)
args = ap.parse_args()
+ json_out = args.out.with_suffix(".json")
if not GDEXT_SRC.is_dir():
print(f"error: {GDEXT_SRC} not found", file=sys.stderr)
@@ -314,9 +354,11 @@ def main() -> int:
gd_classes = parse_gd_class_names(gd_files)
deps = parse_crate_deps(SIM_ROOT)
- report = render_report(classes, gd_classes, deps)
args.out.parent.mkdir(parents=True, exist_ok=True)
- args.out.write_text(report, encoding="utf-8")
+ args.out.write_text(render_report(classes, gd_classes, deps), encoding="utf-8")
+ json_out.write_text(
+ json.dumps(build_json(classes, gd_classes, deps), indent=2), encoding="utf-8"
+ )
referenced = sum(1 for c in classes if c.callers)
print(
@@ -324,7 +366,7 @@ def main() -> int:
f"{len(list(GDEXT_SRC.rglob('*.rs')))} api-gdext files; "
f"{referenced} referenced from {len(gd_files)} .gd files. "
f"Crates: {len(deps)}. "
- f"Report: {args.out.relative_to(REPO_ROOT)}"
+ f"Markdown: {args.out.relative_to(REPO_ROOT)} JSON: {json_out.relative_to(REPO_ROOT)}"
)
return 0