Workflow·Gaming & Entertainment·v1.2.0

Godot

Develop, test, build and deploy Godot 4.x games, with GdUnit4 unit tests, PlayGodot E2E automation, web/desktop exports and CI/CD…

You say
Buy it · $24 Read it before you buy $24 Written by Randroids-Dojo · unverified publisher
Context cost
19.1k tokensestimated from the bundle, loaded when it triggers
Bundle
11 files · 76.5 kB4 scripts among them — read before you run
Licence
MITpaid listing
Last change
v1.2.0
Servers it uses
Noneruns standalone

What it does

Develop, test, build, and deploy Godot 4.x games. Includes GdUnit4 for GDScript unit tests and PlayGodot for game automation and E2E testing. Supports web/desktop exports, CI/CD pipelines, and deployment to Vercel/GitHub Pages/itch.io.

Installed, it changes the agent in these ways.

What this skill changes about the agent is not written down here yet. The listing was collected from its source, and the description is in its own SKILL.md.

Workflow

Runs a procedure end to end.

godottestingdeploymentgamedev

The skill itself

This is the whole product. A skill is instructions the model reads, so there is nothing behind the listing you cannot see first — the front matter loads with every session, and the body below it loads when the skill triggers.

SKILL.md9.6 kB · 391 lines
--- name: godot version: 1.2.0 description: Develop, test, build, and deploy Godot 4.x games. Includes GdUnit4 for GDScript unit tests and PlayGodot for game automation and E2E testing. Supports web/desktop exports, CI/CD pipelines, and deployment to Vercel/GitHub Pages/itch.io. ---
7# Godot Skill
8
9Develop, test, build, and deploy Godot 4.x games.
10
11## Quick Reference
12
13```bash
14# GdUnit4 - Unit testing framework (GDScript, runs inside Godot)
15godot --headless --path . -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd --run-tests
16
17# PlayGodot - Game automation framework (Python, like Playwright for games)
18export GODOT_PATH=/path/to/godot-automation-fork
19pytest tests/ -v
20
21# Export web build
22godot --headless --export-release "Web" ./build/index.html
23
24# Deploy to Vercel
25vercel deploy ./build --prod
26```
27
28---
29
30## Testing Overview
31
32| | GdUnit4 | PlayGodot |
33|---|---------|-----------|
34| Type | Unit testing | Game automation |
35| Language | GDScript | Python |
36| Runs | Inside Godot | External (like Playwright) |
37| Requires | Addon | Custom Godot fork |
38| Best for | Unit/component tests | E2E/integration tests |
39
40---
41
42## GdUnit4 (GDScript Tests)
43
44GdUnit4 runs tests written in GDScript directly inside Godot.
45
46### Project Structure
47
48```
49project/
50├── addons/gdUnit4/ # GdUnit4 addon
51├── test/ # Test directory
52│ ├── game_test.gd
53│ └── player_test.gd
54└── scripts/
55 └── game.gd
56```
57
58### Setup
59
60```bash
61# Install GdUnit4
62git clone --depth 1 https://github.com/MikeSchulze/gdUnit4.git addons/gdUnit4
63
64# Enable plugin in Project Settings → Plugins
65```
66
67### Basic Unit Test
68
69```gdscript
70# test/game_test.gd
71extends GdUnitTestSuite
72
73var game: Node
74
75func before_test() -> void:
76 game = auto_free(load("res://scripts/game.gd").new())
77
78func test_initial_state() -> void:
79 assert_that(game.is_game_active()).is_true()
80 assert_that(game.get_current_player()).is_equal("X")
81
82func test_make_move() -> void:
83 var success := game.make_move(4)
84 assert_that(success).is_true()
85 assert_that(game.get_board_state()[4]).is_equal("X")
86```
87
88### Scene Test with Input Simulation
89
90```gdscript
91# test/game_scene_test.gd
92extends GdUnitTestSuite
93
94var runner: GdUnitSceneRunner
95
96func before_test() -> void:
97 runner = scene_runner("res://scenes/main.tscn")
98
99func after_test() -> void:
100 runner.free()
101
102func test_click_cell() -> void:
103 await runner.await_idle_frame()
104
105 var cell = runner.find_child("Cell4")
106 runner.set_mouse_position(cell.global_position + cell.size / 2)
107 runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT)
108 await runner.await_input_processed()
109
110 var game = runner.scene()
111 assert_that(game.get_board_state()[4]).is_equal("X")
112
113func test_keyboard_restart() -> void:
114 runner.simulate_key_pressed(KEY_R)
115 await runner.await_input_processed()
116 assert_that(runner.scene().is_game_active()).is_true()
117```
118
119### Running GdUnit4 Tests
120
121```bash
122# All tests
123godot --headless --path . -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd --run-tests
124
125# Specific test file
126godot --headless --path . -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd \
127 --run-tests --add res://test/my_test.gd
128
129# Generate reports for CI
130godot --headless --path . -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd \
131 --run-tests --report-directory ./reports
132```
133
134### GdUnit4 Assertions
135
136```gdscript
137# Values
138assert_that(value).is_equal(expected)
139assert_that(value).is_not_null()
140assert_that(condition).is_true()
141
142# Numbers
143assert_that(number).is_greater(5)
144assert_that(number).is_between(1, 100)
145
146# Strings
147assert_that(text).contains("expected")
148assert_that(text).starts_with("prefix")
149
150# Arrays
151assert_that(array).contains(element)
152assert_that(array).has_size(5)
153
154# Signals
155await assert_signal(node).is_emitted("signal_name")
156```
157
158### Scene Runner Input API
159
160```gdscript
161# Mouse
162runner.set_mouse_position(Vector2(100, 100))
163runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT)
164runner.simulate_mouse_button_released(MOUSE_BUTTON_LEFT)
165
166# Keyboard
167runner.simulate_key_pressed(KEY_SPACE)
168runner.simulate_key_pressed(KEY_S, false, true) # Ctrl+S
169
170# Input actions
171runner.simulate_action_pressed("jump")
172runner.simulate_action_released("jump")
173
174# Waiting
175await runner.await_input_processed()
176await runner.await_idle_frame()
177await runner.await_signal("game_over", [], 5000)
178```
179
180---
181
182## PlayGodot (Game Automation)
183
184PlayGodot is a game automation framework for Godot - like Playwright, but for games. It enables E2E testing, automated gameplay, and external control of Godot games via the native RemoteDebugger protocol.
185
186**Requirements:**
187- Custom Godot fork: [Randroids-Dojo/godot](https://github.com/Randroids-Dojo/godot) (automation branch)
188- [PlayGodot](https://github.com/Randroids-Dojo/PlayGodot) Python library
189
190### Setup
191
192```bash
193# Install PlayGodot
194python -m venv .venv
195source .venv/bin/activate # Windows: .venv\Scripts\activate
196pip install playgodot
197
198# Build custom Godot fork
199git clone https://github.com/Randroids-Dojo/godot.git
200cd godot && git checkout automation
201scons platform=macos arch=arm64 target=editor -j8 # macOS Apple Silicon
202# scons platform=macos arch=x86_64 target=editor -j8 # macOS Intel
203# scons platform=linuxbsd target=editor -j8 # Linux
204# scons platform=windows target=editor -j8 # Windows
205```
206
207### Test Configuration (conftest.py)
208
209```python
210import os
211import pytest_asyncio
212from pathlib import Path
213from playgodot import Godot
214
215GODOT_PROJECT = Path(__file__).parent.parent
216GODOT_PATH = os.environ.get("GODOT_PATH", "/path/to/godot-fork")
217
218@pytest_asyncio.fixture
219async def game():
220 async with Godot.launch(
221 str(GODOT_PROJECT),
222 headless=True,
223 timeout=15.0,
224 godot_path=GODOT_PATH,
225 ) as g:
226 await g.wait_for_node("/root/Game")
227 yield g
228```
229
230### Writing PlayGodot Tests
231
232```python
233import pytest
234
235GAME = "/root/Game"
236
237@pytest.mark.asyncio
238async def test_game_starts_empty(game):
239 board = await game.call(GAME, "get_board_state")
240 assert board == ["", "", "", "", "", "", "", "", ""]
241
242@pytest.mark.asyncio
243async def test_clicking_cell(game):
244 await game.click("/root/Game/VBoxContainer/GameBoard/GridContainer/Cell4")
245 board = await game.call(GAME, "get_board_state")
246 assert board[4] == "X"
247
248@pytest.mark.asyncio
249async def test_game_win(game):
250 for pos in [0, 3, 1, 4, 2]: # X wins top row
251 await game.call(GAME, "make_move", [pos])
252
253 is_active = await game.call(GAME, "is_game_active")
254 assert is_active is False
255```
256
257### Running PlayGodot Tests
258
259```bash
260export GODOT_PATH=/path/to/godot-automation-fork
261pytest tests/ -v
262pytest tests/test_game.py::test_clicking_cell -v
263```
264
265### PlayGodot API
266
267```python
268# Node interaction
269node = await game.get_node("/root/Game")
270await game.wait_for_node("/root/Game", timeout=10.0)
271exists = await game.node_exists("/root/Game")
272result = await game.call("/root/Node", "method", [arg1, arg2])
273value = await game.get_property("/root/Node", "property")
274await game.set_property("/root/Node", "property", value)
275
276# Node queries
277paths = await game.query_nodes("*Button*")
278count = await game.count_nodes("*Label*")
279
280# Mouse input
281await game.click("/root/Button")
282await game.click(300, 200)
283await game.double_click("/root/Button")
284await game.right_click(100, 100)
285await game.drag("/root/Item", "/root/Slot")
286
287# Keyboard input
288await game.press_key("space")
289await game.press_key("ctrl+s")
290await game.type_text("hello")
291
292# Input actions
293await game.press_action("jump")
294await game.hold_action("sprint", 2.0)
295
296# Touch input
297await game.tap(300, 200)
298await game.swipe(100, 100, 400, 100)
299await game.pinch((200, 200), 0.5)
300
301# Screenshots
302png_bytes = await game.screenshot()
303await game.screenshot("/tmp/screenshot.png")
304similarity = await game.compare_screenshot("expected.png")
305await game.assert_screenshot("reference.png", threshold=0.99)
306
307# Scene management
308scene = await game.get_current_scene()
309await game.change_scene("res://scenes/level2.tscn")
310await game.reload_scene()
311
312# Game state
313await game.pause()
314await game.unpause()
315is_paused = await game.is_paused()
316await game.set_time_scale(0.5)
317scale = await game.get_time_scale()
318
319# Waiting
320await game.wait_for_node("/root/Game/SpawnedEnemy", timeout=5.0)
321await game.wait_for_visible("/root/Game/UI/GameOverPanel", timeout=10.0)
322await game.wait_for_signal("game_over")
323await game.wait_for_signal("health_changed", source="/root/Game/Player")
324```
325
326---
327
328## Building & Deployment
329
330### Web Export
331
332```bash
333# Requires export_presets.cfg with Web preset
334godot --headless --export-release "Web" ./build/index.html
335```
336
337### Export Preset (export_presets.cfg)
338
339```ini
340[preset.0]
341name="Web"
342platform="Web"
343runnable=true
344export_path="build/index.html"
345```
346
347### Deploy to Vercel
348
349```bash
350npm i -g vercel
351vercel deploy ./build --prod
352```
353
354---
355
356## CI/CD
357
358### GitHub Actions Example
359
360```yaml
361- name: Setup Godot
362 uses: chickensoft-games/setup-godot@v2
363 with:
364 version: 4.3.0
365 include-templates: true
366
367- name: Run GdUnit4 Tests
368 run: |
369 godot --headless --path . \
370 -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd \
371 --run-tests --report-directory ./reports
372
373- name: Upload Results
374 uses: actions/upload-artifact@v4
375 if: always()
376 with:
377 name: test-results
378 path: reports/
379```
380
381---
382
383## References
384
385- references/gdunit4-quickstart.md - GdUnit4 setup
386- references/scene-runner.md - Input simulation API
387- references/assertions.md - Assertion methods
388- references/playgodot.md - PlayGodot guide
389- references/deployment.md - Deployment guide
390- references/ci-integration.md - CI/CD setup
391
In the file
SKILL.md952 words
Files11
LicenceMIT
Why you can read it

Nothing in a skill executes. The client loads the text and the model follows it, so a skill can be audited the way a runbook is — by reading it.

What it costs in context

Skills are not billed by the call. They are paid for in context: every token the instructions occupy is a token your code, your diff and your conversation cannot use. Here is what this one takes and when it takes it.

≈70
always loaded
The name and description, so the model knows the skill exists and when to reach for it.
19,055
on trigger
The instruction body and 10 supporting files, read only when the skill fires.
9.6%
of a 200k window
Ten skills this size would take about 96% of the window before you open a file.
050k100k150k200k context window

19.1k tokens, estimated from the bundle at four bytes to the token, held for the rest of the session once it triggers. Heavy. Teams tend to install this one per project rather than globally, and load it only when the job comes up.

Servers bill, skills cost

A server charges by the month. A skill charges once per session, in context, and then keeps charging it for as long as the session lives.

Before and after

The same question, put to the same model twice: once as it comes, and once with these instructions loaded.

No worked example has been published for this skill yet.

Adoption
Installsnone yet
Ratingno reviews yet

The procedure it runs

The procedure has not been published here. It is in the skill’s own SKILL.md, which its author has not sent to the marketplace yet.

Prose, not code

These steps are written for a model to follow, not executed by a runtime. It can still be told to skip one, and it will say so when it does.

Servers it uses

None. This skill calls no MCP servers at all.

Everything it needs is in the instructions, so it works in a project with nothing connected — the model reads the file and changes how it works with what it can already reach.

It writes no files and reaches no network. All it changes is how the model reasons and writes.

What it asks for
Writes filesno
Network accessno

Read from the allowed-tools line of this skill’s own SKILL.md. A skill grants no permissions of its own — it can only ask for tools your client already has.

What it will not do

Every skill is narrow, and the useful ones say where they stop. These are the jobs this one is the wrong tool for.

What this skill is not for has not been published here. Nothing is implied by that: it is a section the author has not filled in.

What is in the bundle

11 files, 76.5 kB on disk. Mostly text — the instructions the model reads — with 4 scripts in it that your client would run only if the instructions tell it to.

  • SKILL.md9.6 kB
  • references/assertions.md5.6 kB
  • references/ci-integration.md9.4 kB
  • references/deployment.md8.6 kB
  • references/gdunit4-quickstart.md4.0 kB
  • references/playgodot.md8.7 kB
  • references/scene-runner.md5.7 kB
  • scripts/export_build.py7.0 kB
  • scripts/parse_results.py8.1 kB
  • scripts/run_tests.py4.4 kB
  • scripts/validate_project.py5.4 kB
What is not in it

A skill installs nothing and depends on nothing: it is a folder your client reads. This one carries 4 scripts beside the text, so the bundle is 11 files you can review in full before installing. The MIT licence covers the templates and examples as well as the instructions.

Install

Installing copies the bundle into your project. Nothing runs at install time — the files sit on disk until the model reads them.

$24 once
Godot · MIT · Randroids-Dojo
one-time
Price$24 once
LicenceMIT — the author’s, unchanged by this purchase
Paid throughStripe, once, on the card you add at the checkout
Keeps workingfor good — the files are yours once they are on disk
Updatesevery release of 1.x through this account

You can read the whole bundle before paying — the SKILL.md above is the product, not a preview of it. What the money buys is the delivery: the folder packaged and handed to your machine by key, every update its author ships, and our support if it does not do what this listing says. The terms of use are MIT, set by the author and unchanged by buying it here.

Payment runs through Stripe, on a page like this one rather than a redirect. Once there is an account it joins the same mcprush invoice as everything else you run, so there is never a second card to enter.

Which clients pick it up on their own

A skill is a folder of text. A client with a skills folder reads it without being told; everywhere else the same text works, it is just handed to the model rather than found.

Claude Code.claude/skills/
Claude Desktop
ChatGPT
Cursor.cursor/skills/
VS Code.github/skills/
Codex CLI.agents/skills/
Gemini CLI.gemini/skills/
Grok.grok/skills/
Zed.agents/skills/
Windsurf.windsurf/skills/
Agent SDK.claude/skills/
HTTP / API
This release
Version1.2.0
Publishedno release date on file
Price$24
Referencerandroids-dojo/godot

Versions

v1.2.0 is what is on the shelf; no release here carries a date. Instructions change more often than APIs do — a skill can be rewritten entirely without anything it depends on moving.

v1.2.0
  • No earlier releases have been published to the marketplace.
Pinning

Put randroids-dojo/godot@1.2.0 in the install command to hold this exact version. Without the suffix you get whatever is current the day you install, and nothing moves under you afterwards.

Reviews

no reviews yet · no installs yet

Nobody has reviewed this skill yet. The rating is the mean of the reviews written here, so there is none until somebody writes the first.

Who can post

Only accounts that have had the skill installed for fourteen days, so a review is written after living with it rather than after reading it. Publishers may reply once.

Who wrote it

RA
Randroids-Dojo

Publishes on mcprush.

0 servers listed1 skill listednot claimed
Profile
Publisher
Servers0