Skip to content
Back to skills

2940 Playgodot 8ad79088

BSecurity

[PlayGodot](https://github.com/Randroids-Dojo/PlayGodot) is a game automation framework for Godot - like Playwright, but for games. Control games from Python, write E2E tests, capture screenshots, and simulate input via Godot's native debugger protocol.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
testingpythongobashnodetestingdebugginggitapi

Works with

  • cli
  • api

Security analysis

B80/100
  • criticalAccesses sensitive system or user directories
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2940-playgodot_8ad79088 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2940 Playgodot 8ad79088?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2940 Playgodot 8ad79088
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2940-playgodot-8ad79088/badge)](https://www.skillsdirectory.com/skills/tools-only-2940-playgodot-8ad79088)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# PlayGodot Game Automation Guide

[PlayGodot](https://github.com/Randroids-Dojo/PlayGodot) is a game automation framework for Godot - like Playwright, but for games. Control games from Python, write E2E tests, capture screenshots, and simulate input via Godot's native debugger protocol.

## Requirements

- **Custom Godot build** - [Randroids-Dojo/godot](https://github.com/Randroids-Dojo/godot) (automation branch)
- **Python 3.9+** - For running automation scripts
- **PlayGodot package** - `pip install playgodot`

## Installation

```bash
# Install PlayGodot
python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install playgodot

# Option 1: Download pre-built binary (recommended)
# See releases: https://github.com/Randroids-Dojo/godot/releases/tag/automation-latest
# - godot-automation-linux-x86_64.zip
# - godot-automation-macos-universal.zip (Intel + Apple Silicon)

# Option 2: Build custom Godot fork from source
git clone https://github.com/Randroids-Dojo/godot.git
cd godot && git checkout automation
scons platform=macos arch=arm64 target=editor -j8  # macOS Apple Silicon
# scons platform=macos arch=x86_64 target=editor -j8  # macOS Intel
# scons platform=linuxbsd target=editor -j8  # Linux
# scons platform=windows target=editor -j8  # Windows
```

## Quick Start

```python
import asyncio
from playgodot import Godot

async def automate_game():
    async with Godot.launch("path/to/project", godot_path="/path/to/godot-fork") as game:
        await game.wait_for_node("/root/Main")
        await game.click("/root/Main/UI/StartButton")
        await game.screenshot("game_started.png")

asyncio.run(automate_game())
```

## Test Configuration

Create a `conftest.py` file for pytest:

```python
import os
import pytest_asyncio
from pathlib import Path
from playgodot import Godot

GODOT_PROJECT = Path(__file__).parent.parent
GODOT_PATH = os.environ.get("GODOT_PATH", "/path/to/godot-fork")

@pytest_asyncio.fixture
async def game():
    async with Godot.launch(
        str(GODOT_PROJECT),
        headless=True,
        timeout=15.0,
        godot_path=GODOT_PATH,
    ) as g:
        await g.wait_for_node("/root/Game")
        yield g
```

## API Reference

### Node Interaction

```python
# Get node info
node = await game.get_node("/root/Game/Player")

# Properties
health = await game.get_property("/root/Game/Player", "health")
await game.set_property("/root/Game/Player", "health", 50)

# Call methods
result = await game.call("/root/Game/Player", "take_damage", [25])

# Check existence
exists = await game.node_exists("/root/Game/Enemy")
```

### Input Simulation

```python
# Mouse
await game.click("/root/Game/StartButton")
await game.click(400, 300)
await game.double_click("/root/Game/Item")
await game.right_click(100, 100)
await game.drag("/root/Game/DragItem", "/root/Game/DropZone")

# Keyboard
await game.press_key("space")
await game.press_key("ctrl+s")
await game.type_text("Hello World")

# Input actions
await game.press_action("jump")
await game.hold_action("sprint", 2.0)

# Touch
await game.tap(300, 200)
await game.swipe(100, 100, 400, 100)
await game.pinch((200, 200), 0.5)
```

### Node Queries

```python
# Find nodes by pattern
buttons = await game.query_nodes("*Button*")

# Count matching nodes
count = await game.count_nodes("*Enemy*")
```

### Screenshots

```python
# Capture viewport
png_data = await game.screenshot()

# Save to file
await game.screenshot("/tmp/screenshot.png")

# Capture specific node
await game.screenshot(node="/root/Game/UI")

# Compare screenshots (returns similarity 0.0-1.0)
similarity = await game.compare_screenshot("expected.png")
assert similarity > 0.99

# Assert screenshot matches reference
await game.assert_screenshot("reference.png", threshold=0.99)
await game.assert_screenshot("reference.png", threshold=0.95, save_diff="diff.png")
```

### Scene Management

```python
# Get current scene
scene = await game.get_current_scene()

# Change scene
await game.change_scene("res://scenes/level2.tscn")

# Reload
await game.reload_scene()
```

### Game State Control

```python
# Pause/unpause
await game.pause()
await game.unpause()
is_paused = await game.is_paused()

# Time scale
await game.set_time_scale(0.5)  # Slow motion
await game.set_time_scale(2.0)  # Fast forward
scale = await game.get_time_scale()
```

### Waiting

```python
# Wait for node
node = await game.wait_for_node("/root/Game/SpawnedEnemy", timeout=5.0)

# Wait for visibility
await game.wait_for_visible("/root/Game/UI/GameOverPanel", timeout=10.0)

# Wait for signal
await game.wait_for_signal("game_over")
await game.wait_for_signal("health_changed", source="/root/Game/Player")
result = await game.wait_for_signal("score_updated", timeout=10.0)
print(result["args"])  # Signal arguments

# Wait for condition
async def check_score():
    score = await game.call("/root/Game", "get_score")
    return score >= 100

await game.wait_for(check_score, timeout=30.0)
```

## E2E Testing Example

```python
import pytest

GAME = "/root/Game"

@pytest.mark.asyncio
async def test_game_starts_empty(game):
    board = await game.call(GAME, "get_board_state")
    assert board == ["", "", "", "", "", "", "", "", ""]

@pytest.mark.asyncio
async def test_clicking_cell(game):
    await game.click("/root/Game/Board/Cell4")
    board = await game.call(GAME, "get_board_state")
    assert board[4] == "X"

@pytest.mark.asyncio
async def test_win_condition(game):
    for pos in [0, 3, 1, 4, 2]:  # X wins top row
        await game.call(GAME, "make_move", [pos])

    is_active = await game.call(GAME, "is_game_active")
    assert is_active == False

    winner = await game.call(GAME, "get_winner")
    assert winner == "X"
```

## Running Tests

```bash
# Set Godot path
export GODOT_PATH=/path/to/godot-automation-fork

# Run all tests
pytest tests/ -v

# Run specific test
pytest tests/test_game.py::test_clicking_cell -v

# Stop on first failure
pytest tests/ -v -x
```

## Debugging

### Verbose Output

```python
async with Godot.launch(
    str(GODOT_PROJECT),
    verbose=True,  # Enable debug logging
) as g:
    ...
```

### Visible Window

```python
async with Godot.launch(
    str(GODOT_PROJECT),
    headless=False,  # Show game window
    resolution=(1280, 720),
) as g:
    ...
```

### Custom Port

```python
async with Godot.launch(
    str(GODOT_PROJECT),
    port=6008,  # Custom port (default is 6007)
) as g:
    ...
```

## How It Works

PlayGodot uses Godot's native RemoteDebugger protocol:

1. PlayGodot starts a TCP server on port 6007
2. Godot is launched with `--remote-debug tcp://127.0.0.1:6007`
3. Godot connects to PlayGodot as a debugging client
4. PlayGodot sends automation commands (`automation:get_node`, `automation:click`, etc.)
5. Commands are serialized using Godot's binary Variant format

This requires no addons or game modifications - just the automation-enabled Godot fork.

## Resources

- [PlayGodot Repository](https://github.com/Randroids-Dojo/PlayGodot)
- [Godot Automation Fork](https://github.com/Randroids-Dojo/godot)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.