diff --git a/src/game/engine/src/autoloads/game_state.gd b/src/game/engine/src/autoloads/game_state.gd index 3db64402..d6230369 100644 --- a/src/game/engine/src/autoloads/game_state.gd +++ b/src/game/engine/src/autoloads/game_state.gd @@ -59,12 +59,6 @@ var replay_settings: Dictionary = {} ## Tracks wonders built: {wonder_id -> player_index} var wonders_built: Dictionary = {} -## Per-player Ascension Ritual instances: {player_index -> AscensionRitual} -var ascension_rituals: Dictionary = {} - -## Shared SpellSystem instance (singleton-style, managed here) -var spell_system: RefCounted = null - ## Random seed used to generate this map. Stored so climate and other systems ## can derive per-turn deterministic seeds from it. var map_seed: int = 0 @@ -102,16 +96,6 @@ var ai_per_player_research_mult: Dictionary = {} ## Key: "min_idx_max_idx", value: "neutral" | "war" | "peace" | "alliance". var diplomacy: Dictionary = {} -## Ley line anchor registry. Each entry: {position, strength, school, source, owner} -## position: Vector2i, strength: int 1-5, school: String ("" = neutral), -## source: String ("wellspring"|"mountain"|"wonder"|"terrain"), owner: int (-1 = world) -var ley_anchors: Array = [] - -## Dynamic ley resonance/disruption edges between wonder anchors. -## Rebuilt each climate turn by LeyNetwork.build_network(). -## Array of LeyNetwork.LeyEdge objects — used by renderer for visualization. -var ley_edges: Array = [] - ## NPC buildings on the world map (lairs, villages, ruins). Array of Building. var npc_buildings: Array = [] ## Spatial index: "col,row" -> Array[Building] for quick tile lookups. @@ -134,8 +118,6 @@ func initialize_game(settings: Dictionary) -> void: players = [] layers = [] transit_nodes = [] - ley_anchors = [] - ley_edges = [] diplomacy = {} npc_buildings = [] _npc_buildings_by_tile = {} @@ -348,18 +330,9 @@ func serialize() -> Dictionary: "players": [], "layers": [], "transit_nodes": transit_nodes, - "ley_anchors": _serialize_ley_anchors(), "npc_buildings": _serialize_npc_buildings(), } - # Serialize ascension rituals: {player_index_str -> ritual_dict} - var rituals_data: Dictionary = {} - for pi: Variant in ascension_rituals: - var ritual: Variant = ascension_rituals[pi] - if ritual != null and ritual.has_method("serialize"): - rituals_data[str(pi)] = ritual.serialize() - data["ascension_rituals"] = rituals_data - for player: Variant in players: if player is PlayerScript: data["players"].append(player.serialize()) @@ -391,23 +364,8 @@ func deserialize(data: Dictionary) -> void: game_rng.seed = map_seed if map_seed != 0 else hash(turn_number) seed(game_rng.seed) - _deserialize_ley_anchors(data.get("ley_anchors", [])) _deserialize_npc_buildings(data.get("npc_buildings", [])) - # Deserialize ascension rituals - var AscensionRitualScript: GDScript = preload( - "res://engine/src/modules/victory/ascension_ritual.gd" - ) - ascension_rituals = {} - var rituals_raw: Variant = data.get("ascension_rituals", {}) - if rituals_raw is Dictionary: - for key: Variant in rituals_raw: - var ritual_data: Variant = rituals_raw[key] - if ritual_data is Dictionary: - var ritual: RefCounted = AscensionRitualScript.new() - ritual.deserialize(ritual_data) - ascension_rituals[int(str(key))] = ritual - players = [] for player_data: Variant in data.get("players", []): if player_data is Dictionary: @@ -455,7 +413,7 @@ func _deserialize_layer(layer_data: Dictionary) -> Dictionary: ## ------------------------------------------------------------------ -## Magic system helpers +## Wonder system helpers ## ------------------------------------------------------------------ @@ -485,14 +443,6 @@ func get_player_era(_player_index: int) -> int: return era + 1 # era 0-indexed internally; design spec uses 1-indexed -func _serialize_ley_anchors() -> Array: - return _SerializationHelpers.serialize_ley_anchors(ley_anchors) - - -func _deserialize_ley_anchors(raw: Array) -> void: - ley_anchors = _SerializationHelpers.deserialize_ley_anchors(raw) - - func _serialize_npc_buildings() -> Array: return _SerializationHelpers.serialize_npc_buildings(npc_buildings) diff --git a/src/game/engine/src/autoloads/game_state_serialization_helpers.gd b/src/game/engine/src/autoloads/game_state_serialization_helpers.gd index b9211ec1..864ded05 100644 --- a/src/game/engine/src/autoloads/game_state_serialization_helpers.gd +++ b/src/game/engine/src/autoloads/game_state_serialization_helpers.gd @@ -6,38 +6,6 @@ const BuildingScript: GDScript = preload("res://engine/src/entities/building.gd" const GameMapScript: GDScript = preload("res://engine/src/map/game_map.gd") -static func serialize_ley_anchors(ley_anchors: Array) -> Array: - var result: Array[Dictionary] = [] - for anchor: Dictionary in ley_anchors: - var pos: Vector2i = anchor.get("position", Vector2i.ZERO) - result.append( - { - "position": [pos.x, pos.y], - "strength": anchor.get("strength", 1), - "school": anchor.get("school", ""), - "source": anchor.get("source", ""), - "owner": anchor.get("owner", -1), - } - ) - return result - - -static func deserialize_ley_anchors(raw: Array) -> Array: - var result: Array[Dictionary] = [] - for entry: Dictionary in raw: - var pos_arr: Array = entry.get("position", [0, 0]) - result.append( - { - "position": Vector2i(pos_arr[0], pos_arr[1]), - "strength": entry.get("strength", 1), - "school": entry.get("school", ""), - "source": entry.get("source", ""), - "owner": entry.get("owner", -1), - } - ) - return result - - static func serialize_npc_buildings(npc_buildings: Array) -> Array: var result: Array[Dictionary] = [] for b: RefCounted in npc_buildings: diff --git a/src/game/engine/src/entities/player.gd b/src/game/engine/src/entities/player.gd index c05c12be..53005ccd 100644 --- a/src/game/engine/src/entities/player.gd +++ b/src/game/engine/src/entities/player.gd @@ -1,8 +1,8 @@ class_name Player extends RefCounted ## Game-side player entity. Holds per-player runtime state: identity, -## owned units and cities, economy, research, magic, happiness, culture, -## and ascension progress. Stats originate from JSON race data via +## owned units and cities, economy, research, happiness, and culture. +## Stats originate from JSON race data via ## DataLoader; this class tracks per-instance mutable runtime state. ## ## Restored in iter 7l from a 23-line stub. The field set is the union @@ -106,16 +106,6 @@ var culture_research_progress: int = 0 ## culture-tier wonders / Golden-Age effects / culture-victory progress. var researched_traditions: Array[String] = [] -# ── Magic ───────────────────────────────────────────────────────────── -## Unlocked magic school ids (max 2 under current school-lock rules). -var schools: Array[String] = [] -## Per-school mana reserves, keyed by school id (String -> int). -var mana_pool: Dictionary = {} -## Per-school mana income, keyed by school id (String -> float/int). -var mana_income: Dictionary = {} -## Per-school reservoir cap. -var mana_cap: int = 100 - # ── Improvements ────────────────────────────────────────────────────── ## In-progress tile improvements: Array[Dictionary] with keys ## `tile_pos: Vector2i`, `improvement_id: String`, `turns_remaining: int`. @@ -135,11 +125,6 @@ var clan_id: String = "" ## decremented when a gated unit is built, restored on unit death. var strategic_ledger: Dictionary = {} -# ── Ascension ───────────────────────────────────────────────────────── -## True once the player has begun an ascension ritual. -var ascension_active: bool = false - - # ── Lifecycle ───────────────────────────────────────────────────────── func _init(p_index: int = -1, p_player_name: String = "", p_race_id: String = "") -> void: @@ -173,17 +158,11 @@ func add_tradition(tradition_id: String) -> void: researched_traditions.append(tradition_id) -## Mark `tech_id` as researched and, if it unlocks a magic school, -## append that school to `schools` (capped at 2 under current rules). +## Mark `tech_id` as researched. No-op on duplicate. func add_tech(tech_id: String) -> void: if tech_id.is_empty() or researched_techs.has(tech_id): return researched_techs.append(tech_id) - var tech_data: Dictionary = DataLoader.get_tech(tech_id) - var unlocked_school: String = tech_data.get("unlocks_school", "") - if not unlocked_school.is_empty() and unlocked_school not in schools: - if schools.size() < 2: - schools.append(unlocked_school) # ── Iter 7k bridge adapter ──────────────────────────────────────────── @@ -199,7 +178,6 @@ func to_bridge_dict() -> Dictionary: "gold": gold, "happiness": happiness, "researched_techs": researched_techs.duplicate(), - "schools": schools.duplicate(), } @@ -242,14 +220,9 @@ func serialize() -> Dictionary: "research_progress": research_progress, "science_per_turn": science_per_turn, "researched_techs": researched_techs.duplicate(), - "schools": schools.duplicate(), - "mana_pool": mana_pool.duplicate(), - "mana_income": mana_income.duplicate(), - "mana_cap": mana_cap, "pending_improvements": pending_improvements.duplicate(true), "strategic_axes": strategic_axes.duplicate(), "clan_id": clan_id, - "ascension_active": ascension_active, "strategic_ledger": strategic_ledger.duplicate(), } @@ -293,17 +266,9 @@ func deserialize(data: Dictionary) -> void: researched_techs = [] for t: String in techs_raw: researched_techs.append(t) - var schools_raw: Array = data.get("schools", []) as Array - schools = [] - for s: String in schools_raw: - schools.append(s) - mana_pool = (data.get("mana_pool", {}) as Dictionary).duplicate() - mana_income = (data.get("mana_income", {}) as Dictionary).duplicate() - mana_cap = int(data.get("mana_cap", mana_cap)) pending_improvements = (data.get("pending_improvements", []) as Array).duplicate(true) strategic_axes = (data.get("strategic_axes", {}) as Dictionary).duplicate() clan_id = str(data.get("clan_id", clan_id)) - ascension_active = bool(data.get("ascension_active", ascension_active)) strategic_ledger = (data.get("strategic_ledger", {}) as Dictionary).duplicate() cities = [] for city_raw: Dictionary in data.get("cities", []) as Array: diff --git a/src/game/engine/src/modules/management/turn_processor_helpers.gd b/src/game/engine/src/modules/management/turn_processor_helpers.gd index cb6781f5..c6ce2175 100644 --- a/src/game/engine/src/modules/management/turn_processor_helpers.gd +++ b/src/game/engine/src/modules/management/turn_processor_helpers.gd @@ -7,7 +7,6 @@ const UnitScript: GDScript = preload("res://engine/src/entities/unit.gd") const CityScript: GDScript = preload("res://engine/src/entities/city.gd") const BuildingScript: GDScript = preload("res://engine/src/entities/building.gd") const TerrainAffinityScript: GDScript = preload("res://engine/src/core/terrain_affinity.gd") -const SpellSystemScript: GDScript = preload("res://engine/src/modules/magic/spell_system.gd") const HappinessScript: GDScript = preload("res://engine/src/modules/empire/happiness.gd") const TechWebScript: GDScript = preload("res://engine/src/modules/tech/tech_web.gd") @@ -62,27 +61,12 @@ static func process_production( static func process_research( - player: RefCounted, spell_system: RefCounted, tech_web: RefCounted, + player: RefCounted, tech_web: RefCounted, ) -> void: if player.researching.is_empty(): return var science: int = _calculate_science_income(player) - # Spell research stays in GDScript — GdTechWeb handles techs only. - var spell_data: Dictionary = DataLoader.get_spell(player.researching) - if not spell_data.is_empty(): - if EnvConfig.get_bool("FORCE_UNLIMITED_RESEARCH"): - science = 999999 - player.research_progress += science - var spell_cost: int = spell_data.get("research_cost", 999999) - if player.research_progress >= spell_cost: - var completed_spell: String = player.researching - player.research_progress = 0 - player.researching = "" - var sys: SpellSystemScript = spell_system as SpellSystemScript - sys.research_spell(player.index, completed_spell) - return - # Tech research — delegate to GdTechWeb (Rust). if EnvConfig.get_bool("FORCE_UNLIMITED_RESEARCH"): science = 999999 @@ -144,35 +128,6 @@ static func process_healing(player: RefCounted) -> void: EventBus.unit_healed.emit(unit, heal_amount) -# ── Mana income (iter 7w: move to mc-magic::process_mana) ──────── - - -static func process_mana( - player: RefCounted, game_map: RefCounted = null, -) -> void: - var new_income: Dictionary = {} - if game_map != null: - for city: RefCounted in player.cities: - if not city is CityScript: - continue - var c: CityScript = city as CityScript - var tile_json: String = build_tile_yields_json(c, game_map) - var city_yields: Dictionary = c.get_yields(tile_json) - var city_mana: Dictionary = city_yields.get("mana", {}) as Dictionary - for school: String in city_mana: - new_income[school] = ( - new_income.get(school, 0.0) + float(city_mana[school]) - ) - player.mana_income = new_income - if player.mana_income.is_empty(): - return - for school: String in player.mana_income: - var income: int = roundi(player.mana_income[school]) - var current: int = player.mana_pool.get(school, 0) - player.mana_pool[school] = mini(current + income, player.mana_cap) - EventBus.mana_changed.emit(player.index, player.mana_pool) - - # ── Improvements (trivial loop, acceptable in GDScript) ──────────