fix(world-map): 🐛 Fix async rendering pipeline to ensure proper draw pass before texture capture in Wayland

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Claude Code 2026-04-11 06:26:50 -07:00
parent 268c93951f
commit fd986357c4

View file

@ -172,7 +172,7 @@ func _on_turn_ended(_turn_number: int, _player_index: int) -> void:
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()
_capture_viewport_screenshot_async()
if Time.get_ticks_msec() - _start_ticks_msec > WALL_CLOCK_LIMIT_MSEC:
var winner_clock: int = _pick_winner_by_score()
@ -184,9 +184,22 @@ func _on_turn_ended(_turn_number: int, _player_index: int) -> void:
_finish(winner_score, "score")
func _capture_viewport_screenshot() -> void:
func _capture_viewport_screenshot_async() -> void:
## Godot on Wayland skips rendering occluded/unfocused windows, so a
## raw `get_viewport().get_texture().get_image()` here grabs whatever
## stale frame was last drawn — which for windows stacked behind
## other arena instances is the loading-screen splash. Wait a few
## idle frames AND force an explicit draw pass before grabbing, so
## every window renders at least one real gameplay frame to its
## texture before we read it back.
if _result_dir.is_empty():
return
var tree: SceneTree = _world_map.get_tree()
for _i: int in range(3):
await tree.process_frame
RenderingServer.force_draw()
await tree.process_frame
var viewport: Viewport = _world_map.get_viewport()
if viewport == null:
return