بنقرة واحدة
game-execution
// Task implementation workflow, test harnesses, screenshot/video capture, visual debugging. Load before implementing game tasks.
// Task implementation workflow, test harnesses, screenshot/video capture, visual debugging. Load before implementing game tasks.
Rules for interacting with local version control and remote platforms (GitHub, GitLab, Forgejo).
Visual target generation, risk-first game decomposition, and verification criteria. Load at pipeline start before architecture.
Manage tasks, epics, and bugs. Default to remote CVS platforms. Use local .issues/ ONLY if ISSUE_TRACKING_FS=1 in .env.ai. Require cvs skill.
Godot MCP servers reference — editor, diagnostics, testing, docs, runtime. Load when doing Godot game dev.
When this skill is loaded, the developer follows the Red-Green-Refactor cycle. The orchestrator loads this skill when the user requests TDD.
Godot 4 project scaffolding — project.godot, architecture notes, script stubs, scene builders, build order. Load after game decomposition.
| name | game-execution |
| description | Task implementation workflow, test harnesses, screenshot/video capture, visual debugging. Load before implementing game tasks. |
Implement each risk feature in isolation before the main build:
Implement everything in the game plan's Main Build:
timeout 60 godot --headless --import (generates .import files — without this, load() fails). Re-run after modifying assets..tscn.gd filestimeout 30 godot --headless --check-only -s <path> for each new/modified .gdtimeout 60 godot --headless --quit 2>&1--write-movie, produce screenshotsreference.png consistency. Check stdout for ASSERT FAIL.MCP alternative (when
godot_editoris enabled — seemcp-tools-godotskill): For step 5, userun_project+get_debug_outputinstead ofgodot --headless --quitfor interactive validation with richer console output. Usestop_projectto terminate. For pre-validation (step 4), useget_diagnosticsfromgodot_diagnosticsfor LSP-level checks. Steps 1 and 7 have no MCP equivalent — always use bash for asset import and--write-moviecapture.
After each phase: update the game plan spec status, write discoveries to knowledge graph (memory tools), git commit.
There is no fixed iteration limit — use judgment:
# Import new/modified assets (MUST run before scene builders):
timeout 60 godot --headless --import
# Compile a scene builder (produces .tscn):
timeout 60 godot --headless --script <path_to_builder.gd>
# Pre-validate a single script:
timeout 30 godot --headless --check-only -s <path_to_script.gd>
# Validate all project scripts:
timeout 60 godot --headless --quit 2>&1
Common errors:
Parser Error — syntax error, fix the line indicatedInvalid call / method not found — wrong node type or API, delegate to Mimir for class lookupCannot infer type — := used with instantiate() or polymorphic math functionsquit() in scene builderWrite test/test_{task_id}.gd — a SceneTree script that loads the scene under test and verifies the task's goal. Do NOT call quit() — the movie writer handles exit.
extends SceneTree
func _initialize() -> void:
# Setup: load scene, position camera, configure test
var scene: PackedScene = load("res://scenes/main.tscn")
var root_scene = scene.instantiate()
root.add_child(root_scene)
# Camera must be activated explicitly
var cam := Camera3D.new()
cam.position = Vector3(0, 5, 10)
cam.current = true
root.add_child(cam)
func _process(delta: float) -> bool:
# Return false to keep running
return false
Use print("ASSERT PASS/FAIL: ...") for behavioral properties hard to judge visually (positions, velocities, state changes). After capture, check stdout for ASSERT FAIL lines.
var timer := Timer.new()
timer.wait_time = 1.0
timer.one_shot = true
timer.timeout.connect(func(): Input.action_press("move_forward"))
root.add_child(timer)
timer.start()
Open-loop input (timed press/release) doesn't work for 30-second videos — per-frame errors compound. Use closed-loop waypoint steering based on actual position each frame.
Detects platform, timeout command, GPU availability. Defines run_godot wrapper for all platform differences.
PLATFORM=$(uname -s)
# Timeout command
if command -v timeout &>/dev/null; then
TIMEOUT_CMD="timeout"
elif command -v gtimeout &>/dev/null; then
TIMEOUT_CMD="gtimeout"
else
timeout_fallback() { perl -e 'alarm shift; exec @ARGV' "$@"; }
TIMEOUT_CMD="timeout_fallback"
fi
# Platform-specific Godot launcher
GPU_AVAILABLE=false
if [[ "$PLATFORM" == "Darwin" ]]; then
GPU_AVAILABLE=true
run_godot() { godot --rendering-method forward_plus "$@" 2>&1; }
elif [[ "$PLATFORM" == "MINGW"* ]] || [[ "$PLATFORM" == "MSYS"* ]] || [[ "$PLATFORM" == "CYGWIN"* ]]; then
# Windows — assume GPU available
GPU_AVAILABLE=true
run_godot() { godot --rendering-method forward_plus "$@" 2>&1; }
else
# Linux — probe for GPU display
for sock in /tmp/.X11-unix/X*; do
d=":${sock##*/X}"
if DISPLAY=$d $TIMEOUT_CMD 2 glxinfo 2>/dev/null | grep -qi nvidia; then
GPU_AVAILABLE=true
eval "run_godot() { DISPLAY=$d godot --rendering-method forward_plus \"\$@\" 2>&1; }"
break
fi
done
if ! $GPU_AVAILABLE; then
run_godot() { xvfb-run -a -s '-screen 0 1280x720x24' godot --rendering-driver vulkan "$@" 2>&1; }
fi
fi
When GPU_AVAILABLE is true — real shadows, SSR, SSAO, glow, volumetric fog. Without GPU — software rasterizer via lavapipe.
MOVIE=screenshots/{task_folder}
rm -rf "$MOVIE" && mkdir -p "$MOVIE"
touch screenshots/.gdignore
$TIMEOUT_CMD 30 run_godot \
--write-movie "$MOVIE"/frame.png \
--fixed-fps 10 --quit-after {N} \
--script test/test_task.gd
Frame rate and duration:
--fixed-fps 1. Adjust --quit-after for number of views.--fixed-fps 10. Low FPS breaks physics (delta too large → tunneling). Typical: 3-10s (30-100 frames).Requires hardware rendering. Skip if GPU_AVAILABLE is false.
if $GPU_AVAILABLE; then
VIDEO=screenshots/presentation
rm -rf "$VIDEO" && mkdir -p "$VIDEO"
touch screenshots/.gdignore
$TIMEOUT_CMD 60 run_godot \
--write-movie "$VIDEO"/output.avi \
--fixed-fps 30 --quit-after 900 \
--script test/presentation.gd
# Convert AVI (MJPEG) to MP4 (H.264)
ffmpeg -i "$VIDEO"/output.avi \
-c:v libx264 -pix_fmt yuv420p -crf 28 -preset slow \
-vf "scale='min(1280,iw)':-2" \
-movflags +faststart \
"$VIDEO"/gameplay.mp4 2>&1
else
echo "No GPU available — skipping video capture"
fi
CRF 28 + -preset slow targets ~2-5MB for 30s at 720p. -movflags +faststart enables streaming preview.
Do NOT debug in a complex scene — isolate the problem:
test/debug_{issue}.gd with only the relevant nodes. Strip everything else.--fixed-fps 10 for 3-5 seconds. Single frames cannot show timing bugs.Animations are the #1 source of silent failures — they "work" (no errors) but produce wrong results.
Common issues to probe (always capture multi-frame):
Run this checklist in order:
print(node.name, " at ", node.global_position) in _ready(). No output = not in tree.print(camera.global_position, camera.global_transform.basis.z). Force camera.look_at(object.global_position).terrain.visible = false).print(node.scale). Too small (0.001) = sub-pixel. Too large = camera inside.albedo_color = Color.RED temporarily.In test/debug_{issue}.gd:
Read the knowledge graph (memory tools) before starting work — it contains discoveries from previous tasks. After completing your task, write back: