diff --git a/Game/scripts/arena.gd b/Game/scripts/arena.gd index 47124714..a6b52a6e 100644 --- a/Game/scripts/arena.gd +++ b/Game/scripts/arena.gd @@ -23,7 +23,8 @@ func _ready(): add_to_group("arena") var world_env := get_node_or_null("WorldEnvironment") as WorldEnvironment if world_env and world_env.environment: - var env := world_env.environment + var env := world_env.environment.duplicate(true) as Environment + world_env.environment = env if sky_material: if not env.sky: env.sky = Sky.new() diff --git a/TODO.md b/TODO.md index f1fd7027..40158eaa 100644 --- a/TODO.md +++ b/TODO.md @@ -14,7 +14,7 @@ The training pipeline is built — see `TRAINING.md` (self-play PPO via the vend Bugs found in an adversarial review. None are gameplay- or physics-affecting, so all are safe to land against the current `Game/bots/` checkpoints. -- [ ] `VideoSettings.apply_to_environment()` (`scripts/video_settings.gd`) compounds on every arena load: `env.glow_intensity *= glow_scale` mutates an `Environment` that is a `[sub_resource]` of the arena scene, and Godot shares sub-resources across instantiations of a cached `PackedScene`. Glow at 50% becomes 25% then 12.5% across repeat entries. Fix by duplicating the Environment in `Arena._ready()` (`scripts/arena.gd`). Regression test: set glow to 50%, enter/leave Free Play three times, confirm it's still 50%. +- [x] `VideoSettings.apply_to_environment()` (`scripts/video_settings.gd`) compounds on every arena load: `env.glow_intensity *= glow_scale` mutates an `Environment` that is a `[sub_resource]` of the arena scene, and Godot shares sub-resources across instantiations of a cached `PackedScene`. Glow at 50% becomes 25% then 12.5% across repeat entries. Fix by duplicating the Environment in `Arena._ready()` (`scripts/arena.gd`). Regression test: set glow to 50%, enter/leave Free Play three times, confirm it's still 50%. - [ ] Collapse the four disagreeing team palettes into one source of truth — `ship.gd`, `HUDController.gd` and `goal.gd` each declare `TEAM_COLORS`, `arena_boundary.gd` exports `team0_tint`/`team1_tint`, and `arena_deck.gdshader` defaults to a fifth pair. Three of them disagree, so nose, goal rim, end zone and scoreboard are all different blues. - [ ] Goal scoring volume (3.5 x 1.5, `objects/goal.tscn`) is smaller than the drawn mouth (3.7 x 1.65, `ArenaBoundary.GOAL_APERTURE_*`) — a ball crossing the visible edge doesn't score. Derive the aperture constants from the goal's collision shape, the way `goal.gd:53` already measures its own visuals. - [ ] `match_mode.gd`: full time can fire mid-kickoff-countdown, and the stalled coroutine resumes into the dying scene (can re-emit `kickoff_countdown` / unfreeze bodies for a frame). Guard `_run_kickoff_countdown` with a match-over flag.