Files
settled-reach/client/tests/visual_scenarios.gd
T
jpmschweitzerandClaude Opus 4.6 4eb54a6f7a fix(client): resolve all gdlint warnings — zero warnings policy
Fix 354 gdlint warnings across 65 files: 194 class-definitions-order
(reorder declarations), 138 max-line-length (split long lines),
22 code issues (unused args, no-else-return, naming). Update .gdlintrc
to exclude addons/ and raise max-public-methods for test files.
No logic changes — declaration order, whitespace, and naming only.

Ticket: #783

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 09:59:56 +02:00

154 lines
5.4 KiB
GDScript

extends RefCounted
## Setup hooks for visual test scenarios.
## Config (tests/visual.json) controls WHAT to run; this file controls HOW to
## set up each scenario in-engine. Called by visual_capture.gd after main.tscn
## is loaded and settled.
##
## Autoload globals (FogState, SimBridge, GameState) are NOT available as
## compile-time identifiers in -s mode. All methods receive tree_root and
## look up autoloads via get_node("/root/...").
## Apply scenario-specific setup before tick advancement.
## Returns true if the scenario is recognized, false otherwise.
func apply_setup(scenario_name: String, tree_root: Node) -> bool:
var sim_bridge := tree_root.get_node("/root/SimBridge")
var fog_state := tree_root.get_node("/root/FogState")
var game_state := tree_root.get_node("/root/GameState")
match scenario_name:
"fog_3state":
# Default TestHarness state — player at (10,10), 8x8 room.
# All 3 fog states naturally visible: clear (cone), explored (out of cone), unexplored.
pass
"fog_diagonal":
# Diagonal LOS boundary — staircase regression target.
# Default room works: the diamond-shaped visibility radius creates diagonal edges.
# 10 ticks builds enough explored tiles to show the boundary.
pass
"fog_boundary":
# Explored/unexplored transition centered.
# Move player south so the northern explored boundary is center-frame.
if sim_bridge.harness:
sim_bridge.harness.player_pos = Vector2i(10, 12)
"fog_zone_tint":
# Bar zone warm amber tint (D-046).
# Inject zone_id into visible_tiles so fog_state.gd writes bar tint.
# TestHarness tiles don't include zone_id by default — patch them.
if sim_bridge.harness:
sim_bridge.harness.player_pos = Vector2i(10, 10)
# Zone tint is written from visible_tiles with zone_id field.
# We patch GameState.visible_tiles after the first snapshot in post_setup().
"fog_debug":
# Raw exploration overlay (green/blue/red).
fog_state.debug_exploration = true
"npc_in_fog":
# NPC sprite visible above fog (D-033).
# Position player so NPC at (12,9) is at the fog edge.
if sim_bridge.harness:
sim_bridge.harness.player_pos = Vector2i(10, 10)
"hud_default":
# Full HUD: time, Careful stance, minimap, monologue.
# Tick 1 triggers monologue from TestHarness.
# Inject Careful stance for visible green indicator.
game_state.player_stance = "Careful"
"dialogue_open":
# Dialogue box + interaction prompt + key bar.
# Move adjacent to NPC and interact.
if sim_bridge.harness:
sim_bridge.harness.player_pos = Vector2i(11, 9)
sim_bridge.harness.process_input("Interact")
"dialogue_with_monologue":
# Confrontation beat: dialogue + monologue overlap.
if sim_bridge.harness:
sim_bridge.harness.player_pos = Vector2i(11, 9)
sim_bridge.harness.process_input("Interact")
# Monologue will be injected in post_setup after dialogue is active.
"minimap_stance":
# Minimap + Sprint stance indicator overlap (top-right).
game_state.player_stance = "Sprint"
"cursor_menu":
# Cursor rendering over dialogue option area.
if sim_bridge.harness:
sim_bridge.harness.player_pos = Vector2i(11, 9)
sim_bridge.harness.process_input("Interact")
"fog_live_replay", "fog_theater_replay", "fog_boundary_replay":
# Replay real server snapshots via MessagePack → Protocol.decode_snapshot().
# Setup handled by visual_capture.gd (reads replay_snapshot from config).
pass
"fog_live_hub":
# Live server connection — Hub spawn position.
# No setup needed: server starts in --test-mode with Gauntlet,
# player spawns at Hub (50,58). Captures real fog pipeline output.
pass
_:
push_warning("VisualScenarios: unknown scenario '%s'" % scenario_name)
return false
return true
## Post-tick setup — called after N ticks have been advanced.
## Use for state that depends on tick processing (e.g. zone tint patching).
func post_setup(scenario_name: String, tree_root: Node) -> void:
var fog_state := tree_root.get_node("/root/FogState")
var game_state := tree_root.get_node("/root/GameState")
match scenario_name:
"fog_zone_tint":
# Patch visible_tiles with zone_id for fog_state.gd zone tint pipeline.
var patched: Array = []
for tile in game_state.visible_tiles:
if tile is Dictionary:
var t: Dictionary = tile.duplicate()
t["zone_id"] = "bar"
patched.append(t)
game_state.visible_tiles = patched
# Force fog_state to re-process with zone tint data
fog_state.update_from_state()
"dialogue_with_monologue":
# Inject monologue to create the overlap condition.
game_state.current_monologue = {
"id": "test_confrontation",
"text": "Something about that answer doesn't add up.",
"duration_seconds": 5.0,
"priority": "high",
"is_urgent": true,
}
"hud_default":
# Ensure stance is still Careful after ticks (TestHarness may override).
game_state.player_stance = "Careful"
## Apply flow action — called for each step in a movie flow.
func apply_flow_action(action: String, tree_root: Node) -> void:
var sim_bridge := tree_root.get_node("/root/SimBridge")
match action:
"wait":
pass # No-op — just captures current state
"select_option_1":
# Simulate selecting the first dialogue option
if sim_bridge.harness:
sim_bridge.harness.process_input("DialogueOption1")
_:
# Movement actions and Interact pass through to TestHarness
if sim_bridge.harness:
sim_bridge.harness.process_input(action)