refactor(*): DRY up arena scenes, game modes, and HUD instruments

Arenas inherit from a new arena_base.tscn instead of restating ~40 shared
lines each; only sky/ambient/glow/tint/decoration vary, exposed via new
Arena exports since nested Environment properties aren't overridable
through scene inheritance. Bot construction and score-keeping move onto
GameMode, shared by match and spectate modes while preserving their
differing GameSettings-override behavior and the HUD's score-row
duck-typing. HUD instruments share a HudInstrument base for the
smoothing-weight calc and angle-lerp helper. Also dedupes
MAIN_MENU_SCENE_PATH into ScenePaths and documents why DIFFICULTIES
tiers share one checkpoint.
This commit is contained in:
Josh Creek
2026-08-04 15:07:33 +01:00
parent b285d012dc
commit 08a0f74391
18 changed files with 203 additions and 268 deletions
+3 -19
View File
@@ -16,9 +16,6 @@ signal score_changed(score: Dictionary)
@export_range(1, 60) var bot_b_reaction_ticks: int = 8
@export_range(0.0, 1.0) var bot_b_action_noise: float = 0.0
var score := {0: 0, 1: 0}
func _get_arena_scene_path() -> String:
return ArenaRegistry.random_path()
@@ -29,28 +26,15 @@ func _start() -> void:
# scene's exports, which stay as the fallback for direct-scene runs.
var path_a := bot_a_model_path if GameSettings.spectate_bot_a_path.is_empty() else GameSettings.spectate_bot_a_path
var path_b := bot_b_model_path if GameSettings.spectate_bot_b_path.is_empty() else GameSettings.spectate_bot_b_path
var ship_a := spawn_ship(0, 0, _make_bot(path_a, bot_a_reaction_ticks, bot_a_action_noise))
spawn_ship(1, 0, _make_bot(path_b, bot_b_reaction_ticks, bot_b_action_noise))
var ship_a := spawn_ship(0, 0, _build_opponent(path_a, bot_a_reaction_ticks, bot_a_action_noise, "SpectateMode"))
spawn_ship(1, 0, _build_opponent(path_b, bot_b_reaction_ticks, bot_b_action_noise, "SpectateMode"))
spawn_camera_rig(ship_a)
func _make_bot(model_path: String, reaction_ticks: int, action_noise: float) -> ShipController:
if not model_path.is_empty() and FileAccess.file_exists(model_path):
var bot := AIShipController.new()
bot.model_path = model_path
bot.reaction_ticks = reaction_ticks
bot.action_noise = action_noise
return bot
if not model_path.is_empty():
push_warning("SpectateMode: bot model not found at %s, spawning inert ship" % model_path)
return ShipController.new() # inert placeholder
func _on_goal_scored(conceding_team: int) -> void:
var scoring_team := 1 - conceding_team
score[scoring_team] += 1
_record_goal(scoring_team)
score_changed.emit(score.duplicate())
print("Goal for team %d! Score: %d - %d" % [scoring_team, score[0], score[1]])
reset_ball()
reset_ships()