refactor(client): decompose main.gd and game_state.gd god objects

Extract SnapshotHandler (static snapshot parsing), SnapshotConsumers
(non-dialogue consumers + audio handlers), and DialogueCoordinator
(dialogue consumers + signal handlers) as class_name scripts.

main.gd: 28KB → 13KB. game_state.gd: 20KB → 8.5KB.
Autoload parse-order safety maintained via load() inline pattern.

Ticket: #775

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-05 09:59:34 +02:00
co-authored by Claude Opus 4.6
parent 8eb9e0a383
commit 260eefcdd1
8 changed files with 694 additions and 665 deletions
+7 -3
View File
@@ -19,7 +19,7 @@ func before_each() -> void:
GameState.player_stance = "Walk"
GameState.player_inventory = []
GameState.stationary_ticks = 0
GameState._prev_player_position = Vector2(-1e9, -1e9)
SnapshotHandler._prev_player_position = Vector2(-1e9, -1e9)
GameState.current_zone_id = ""
GameState.insert_active = true
@@ -67,7 +67,8 @@ func test_apply_snapshot_player_facing_missing_keeps_default() -> void:
func test_apply_snapshot_sets_nearby_interactions() -> void:
var interactions := [
{"entity_id": 5, "entity_type": "Npc", "distance": 1.2, "verbs": [{"kind": "Talk", "label": "Talk", "priority": 1, "available": true}]},
{"entity_id": 5, "entity_type": "Npc", "distance": 1.2,
"verbs": [{"kind": "Talk", "label": "Talk", "priority": 1, "available": true}]},
]
GameState.apply_snapshot({"tick": 1, "entities": [], "nearby_interactions": interactions})
assert_that(GameState.nearby_interactions.size()).is_equal(1)
@@ -83,7 +84,10 @@ func test_apply_snapshot_nearby_interactions_absent_clears_list() -> void:
# -- v5: current_monologue (#414) -----------------------------------------
func test_apply_snapshot_sets_monologue() -> void:
var monologue := {"id": "m1", "text": "Something is off here.", "duration_seconds": 4.0, "priority": 1, "is_urgent": false}
var monologue := {
"id": "m1", "text": "Something is off here.",
"duration_seconds": 4.0, "priority": 1, "is_urgent": false,
}
GameState.apply_snapshot({"tick": 1, "entities": [], "current_monologue": monologue})
assert_that(GameState.current_monologue).is_not_null()
assert_that(GameState.current_monologue.get("text")).is_equal("Something is off here.")
+1 -1
View File
@@ -14,7 +14,7 @@ extends GdUnitTestSuite
func before_each() -> void:
GameState.stationary_ticks = 0
GameState._prev_player_position = Vector2(-1e9, -1e9)
SnapshotHandler._prev_player_position = Vector2(-1e9, -1e9)
GameState.current_zone_id = ""
GameState.player_position = Vector2.ZERO
GameState.visible_tiles = []
+2 -1
View File
@@ -1,5 +1,6 @@
## Smoke tests for main scene initialization
## Run with: godot4 --headless --path . -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd --ignoreHeadlessMode -a res://tests/
## Run with: godot4 --headless --path . -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd
## --ignoreHeadlessMode -a res://tests/
class_name TestMainScene
extends GdUnitTestSuite