Test the Race to the Crystal game rendering in both 2D and 3D modes by taking internal screenshots using arcade.get_image(). Use when verifying graphics rendering, debugging visual issues, testing camera configurations, or validating game display after code changes.
Use this skill when:
This skill creates a test script that:
arcade.get_image()/tmp/ for reviewarcade.get_image() from within the game loop, NOT external tools like maim or scrotmaimDISPLAY=:0 setCreates a test that captures 2D mode after 30 frames:
#!/usr/bin/env python3
import sys
sys.path.insert(0, '/var/home/tluker/repos/python/race-to-the-crystal')
import arcade
from game.game_state import GameState
from game.generator import Generator
from game.crystal import Crystal
from shared.enums import PlayerColor
from shared.constants import DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT
from client.game_window import GameView
# Create game state
game_state = GameState()
game_state.add_player("p1", "Player 1", PlayerColor.CYAN)
game_state.add_player("p2", "Player 2", PlayerColor.MAGENTA)
game_state.start_game()
# Initialize generators
generator_positions = game_state.board.get_generator_positions()
for i, pos in enumerate(generator_positions):
generator = Generator(id=i, position=pos)
game_state.generators.append(generator)
# Initialize crystal
crystal_pos = game_state.board.get_crystal_position()
game_state.crystal = Crystal(position=crystal_pos)
# Create window and game view
window = arcade.Window(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT, "Game Test", resizable=True)
game_view = GameView(game_state, start_in_3d=False)
window.show_view(game_view)
print(f"Testing 2D mode (camera_mode: {game_view.camera_controller.camera_mode})")
frame_count = [0]
original_draw = game_view.on_draw
def new_draw():
frame_count[0] += 1
original_draw()
if frame_count[0] == 30:
print(f"Frame {frame_count[0]}: Saving 2D screenshot...")
image = arcade.get_image()
image.save('/tmp/game_2d_test.png')
print("Screenshot saved to /tmp/game_2d_test.png")
arcade.exit()
game_view.on_draw = new_draw
arcade.run()
Same structure but starts in 3D mode:
# ... (same setup as above) ...
# Create window and game view in 3D mode
window = arcade.Window(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT, "Game Test", resizable=True)
game_view = GameView(game_state, start_in_3d=True)
window.show_view(game_view)
print(f"Testing 3D mode")
print(f"Camera position: {game_view.camera_controller.camera_3d.position}")
print(f"Camera pitch: {game_view.camera_controller.camera_3d.pitch}, yaw: {game_view.camera_controller.camera_3d.yaw}")
# ... (same screenshot code as above, save to /tmp/game_3d_test.png) ...
For 3D debugging, position the camera manually:
import numpy as np
from shared.constants import CELL_SIZE
# ... (setup code) ...
# Position camera at center of board, high up, looking down
game_view.camera_controller.camera_3d.position = np.array([12 * CELL_SIZE, 12 * CELL_SIZE, 100.0], dtype=np.float32)
game_view.camera_controller.camera_3d.pitch = -60.0 # Looking down
game_view.camera_controller.camera_3d.yaw = 45.0 # Rotated for better view
# ... (take screenshot) ...
Always run with DISPLAY set and use uv run:
DISPLAY=:0 uv run python /tmp/test_graphics.py
Problem: Using maim or external screenshot tools shows black screen
Solution: Always use arcade.get_image() from within the game loop
Check:
Debug:
Screenshots saved to:
/tmp/game_2d_test.png - 2D mode rendering/tmp/game_3d_test.png - 3D mode renderingReview these images to verify rendering is working correctly.