feat(world-map): Add screenshot capture logic for AI match visualization in WorldMapArena

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-04-10 21:40:59 -07:00
parent 52afaca4ec
commit 33c66cbb35

View file

@ -29,6 +29,7 @@ var _seed: int = 0
var _result_dir: String = ""
var _victory_manager: RefCounted = null
var _finished: bool = false
var _screenshot_taken: bool = false
func setup(world_map: Node) -> void:
@ -155,6 +156,15 @@ func _on_turn_ended(_turn_number: int, _player_index: int) -> void:
if _turn_label != null:
_turn_label.text = "turn %d / %d" % [GameState.turn_number, _turn_limit]
# Capture a viewport PNG at a configurable turn so the orchestrator can
# composite the 4 per-match screenshots into a quad-grid image — host
# screenshot tools don't see native Wayland windows via x11grab, so we
# capture from inside each Godot process and stitch them externally.
var shot_turn: int = EnvConfig.get_int("AI_ARENA_SCREENSHOT_TURN", -1)
if shot_turn > 0 and GameState.turn_number == shot_turn and not _screenshot_taken:
_screenshot_taken = true
_capture_viewport_screenshot.call_deferred()
if Time.get_ticks_msec() - _start_ticks_msec > WALL_CLOCK_LIMIT_MSEC:
var winner_clock: int = _pick_winner_by_score()
_finish(winner_clock, "wall_clock_timeout")
@ -165,6 +175,27 @@ func _on_turn_ended(_turn_number: int, _player_index: int) -> void:
_finish(winner_score, "score")
func _capture_viewport_screenshot() -> void:
if _result_dir.is_empty():
return
var viewport: Viewport = _world_map.get_viewport()
if viewport == null:
return
var texture: ViewportTexture = viewport.get_texture()
if texture == null:
return
var image: Image = texture.get_image()
if image == null:
return
DirAccess.make_dir_recursive_absolute(_result_dir)
var path: String = "%s/%s_shot.png" % [_result_dir, _match_id]
var err: Error = image.save_png(path)
if err != OK:
push_warning("[AI ARENA] screenshot save failed: %s" % error_string(err))
return
print("[AI ARENA] screenshot saved: %s" % path)
func _on_victory(player_index: int, victory_type: String) -> void:
if _finished:
return