Image to Three.js Model
img2threejs/img2threejs
Rebuilds the object in a reference image as a procedural, animation-ready Three.js model written entirely in code, using staged sculpting with quality checks.
Start, stop, and query Play-In-Editor (PIE) sessions for runtime testing of Blueprints, gameplay logic, widgets, AI, and any in-game behavior.
$ npx skills add kevinpbuckley/VibeUE --skill pie-testing -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install kevinpbuckley/VibeUE pie-testing --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .claude/skills && cp -r skills-src/Content/Skills/pie-testing .claude/skills/pie-testing && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "pie-testing" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/pie-testing into .claude/skills/pie-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pie-testing", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/pie-testingType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add kevinpbuckley/VibeUE --skill pie-testing -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install kevinpbuckley/VibeUE pie-testing --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .agents/skills && cp -r skills-src/Content/Skills/pie-testing .agents/skills/pie-testing && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "pie-testing" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/pie-testing into .agents/skills/pie-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pie-testing", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kevinpbuckley/VibeUE --skill pie-testing -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install kevinpbuckley/VibeUE pie-testing --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/Content/Skills/pie-testing .cursor/skills/pie-testing && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "pie-testing" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/pie-testing into .cursor/skills/pie-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pie-testing", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/kevinpbuckley/VibeUE.git --path Content/Skills/pie-testing--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add kevinpbuckley/VibeUE --skill pie-testing -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install kevinpbuckley/VibeUE pie-testing --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/Content/Skills/pie-testing .gemini/skills/pie-testing && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "pie-testing" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/pie-testing into .gemini/skills/pie-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pie-testing", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install kevinpbuckley/VibeUE pie-testingInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add kevinpbuckley/VibeUE --skill pie-testing -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .github/skills && cp -r skills-src/Content/Skills/pie-testing .github/skills/pie-testing && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "pie-testing" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/pie-testing into .github/skills/pie-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pie-testing", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kevinpbuckley/VibeUE --skill pie-testing -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install kevinpbuckley/VibeUE pie-testing --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/Content/Skills/pie-testing .opencode/skills/pie-testing && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "pie-testing" agent skill from https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/pie-testing into .opencode/skills/pie-testing/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pie-testing", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
pie-testingStart, stop, and query Play-In-Editor (PIE) sessions for runtime testing of Blueprints, gameplay logic, widgets, AI, and any in-game behavior.
Pie Testing is an agent skill from kevinpbuckley/VibeUE. Start, stop, and query Play-In-Editor (PIE) sessions for runtime testing of Blueprints, gameplay logic, widgets, AI, and any in-game behavior. Use when the user asks you to "play", "test", "run", "PIE", "start/stop the game", or otherwise needs a live game world to validate changes.
Its SKILL.md is about 5.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including scripts.
It sits in Game Development. The repository describes itself as: Unreal Engine Vibe Coding tool. The licence is MIT.
Read from SKILL.md and the folder at commit dc051be. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 1 file in scripts/, which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
github.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Pie Testing loads about 5.6k tokens when it runs. Until then it costs about 74 tokens; SKILL.md has 2,316 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from kevinpbuckley/VibeUE at commit dc051be, republished under its MIT licence (© kevinpbuckley). 2,316 words, ~5,551 tokens.
.claude/skills/pie-testing/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.🧠 Brains complement: IF an
unreal-engine-skills-managertool (external MCP) exists in this session, call it with{action: "load", skill: "automation-and-testing"}for UE domain knowledge on this topic — correct APIs, architecture, best practices — and treat it as the rubric for any review / "best practices" question. If no such tool is available (e.g. running under Claude Code or Codex without that MCP), skip this line entirely and proceed with this skill alone — do NOT attempt the call.
PIE is the only way to validate runtime behavior — Blueprint logic, AI ticking, animation, input, widget interaction, gameplay events. Without starting PIE, your "fix" is unverified.
EditorAppToolsetGeneric PIE start/stop/status is owned by Unreal 5.8's native EditorToolset.EditorAppToolset,
invoked through call_tool (run describe_toolset on it for exact action names/params):
| Action | Description |
|---|---|
StartPIE | Start PIE if not already running. Succeeds (no-op) if already running. |
StopPIE | End the current PIE session. Succeeds if stopped or already stopped. |
IsPIERunning | True if PIE or Simulate-In-Editor is active. |
CaptureViewport | Screenshot the active viewport (use to visually verify runtime state). |
call_tool(toolset="EditorToolset.EditorAppToolset", tool="IsPIERunning")
call_tool(toolset="EditorToolset.EditorAppToolset", tool="StartPIE")
call_tool(toolset="EditorToolset.EditorAppToolset", tool="StopPIE")PIE start/stop/query is not on
WidgetServiceanymore for general testing — use the engine toolset above.WidgetServicestill owns the widget-in-PIE validation helpers below.
For repeatable multi-step verification, prefer WorkflowService.run_scenario() over hand-composing
the loop. It queues a state machine on editor ticks, waits for actual PIE readiness, scopes log
assertions to the scenario start, uses VibeUE's focus-free input injection, captures evidence, and
always tears PIE down on pass, failure, or cancellation. Poll get_scenario(id) until its status
is passed, failed, cancelled, smoke_passed, or stale:
import json, unreal
spec = {
"name": "secondary fire consumes ammo",
"preflight": {"save_dirty_assets": True, "compile_blueprints": ["/Game/Weapons/BP_Rifle"]},
"steps": [
{"action":"start_pie"},
{"action":"wait_for_pie", "timeout_seconds":30},
{"action":"inject_action", "path":"/Game/Input/IA_Fire_Secondary"},
{"action":"wait", "seconds":0.25},
{"action":"assert_log", "contains":"SecondaryFire"},
{"action":"capture_game", "name":"after-secondary-fire"}
],
"teardown": {"stop_pie": True}
}
queued = json.loads(unreal.WorkflowService.run_scenario(json.dumps(spec)))
# Poll in separate tool calls; do not block the editor game thread with time.sleep.Use the lower-level primitives below for interactive investigation, one-off probes, or actions not in the scenario schema. Never spin/sleep inside one editor Python call while waiting for a scenario.
A normal scenario must declare at least one assert_log, python_assert, or
python_assert_number step. Completing input/wait/capture steps alone does not verify gameplay.
For a deliberate boot-only check, set "smoke": true: an assertion-free run finishes with
status="smoke_passed" and passed=false. Pollers must treat smoke_passed and stale as terminal
alongside passed, failed, and cancelled.
python_assert compares the Python result with a required string expected.
python_assert_number evaluates an expression and requires a finite numeric result:
{"action":"python_assert_number", "expression":"0.1 + 0.2",
"operator":"eq", "expected":0.3, "tolerance":0.00001}Operators are eq, lt, le, gt, and ge; nonnegative tolerance is supported only for eq
and defaults to zero. For gameplay, use an expression reading a live actor/property instead of
the arithmetic example. Expected/actual values are recorded per assertion; an expression error,
nonnumeric result, or unmet comparison fails the scenario. Do not cache PIE objects in globals.
If an assert_log supplies both contains and not_contains, both conditions must hold.
Log assertions use the active log (including -abslog overrides); unavailable or truncated logs
fail the assertion, including negative checks.
Reports include assertionsDeclared and assertionsEvaluated, including failed assertions.
To detect stale evidence, add a top-level dependencies array of actual file paths relative to the
project directory (or absolute paths), for example Content/Ships/BP_Ship.uasset and relevant
source/config files. Dependencies must exist. VibeUE hashes their contents after preflight,
records the scenario hash and engine version, and automatically tracks its plugin DLL when
dependencies are provided. It does not persist the submitted Python source as provenance.
get_scenario() checks those hashes again for completed reports, including reports loaded from
disk. A changed/missing file or changed engine version produces validity="stale"; a historical
pass then returns status="stale", passed=false, and historicalPassed=true.
verifiedCurrent=true requires passing assertions and unchanged tracked inputs. Without
dependencies, validity="untracked" and verifiedCurrent=false, even if assertions passed.
Freshness covers only explicitly listed files plus the plugin DLL: it does not infer transitive
asset dependencies, detect unsaved edits, or prove a newly changed project binary is loaded.
Save and compile first, list all relevant inputs, and rerun after changes. Hashes are freshness
checks, not tamper-proof attestations. Large dependency sets increase polling cost.
These verification improvements were inspired by PageMastr/Gatekeeper, particularly its assertion coverage and source-bound verdicts. The VibeUE implementation is independently written for Unreal.
# 1. Make sure you're starting from a clean state
call_tool(toolset="EditorToolset.EditorAppToolset", tool="StopPIE") # no-op if not running
# 2. Start the session (uses the editor's current PIE settings — default map, viewport)
call_tool(toolset="EditorToolset.EditorAppToolset", tool="StartPIE")
# 3. Let the test run / inspect log output (LogsToolset) / interact via other services
# 4. Stop when done
call_tool(toolset="EditorToolset.EditorAppToolset", tool="StopPIE")EngineSettingsServiceStartPIE uses the editor's saved PIE settings, so set the net mode BEFORE starting the session.
EngineSettingsService reads and writes ULevelEditorPlaySettings directly and persists the
change, so a dedicated-server PIE gate no longer means quitting the editor to hand-edit
EditorPerProjectUserSettings.ini and relaunching:
import unreal
# Read the current PIE multiplayer settings
info = unreal.EngineSettingsService.get_pie_settings()
print(info.net_mode, info.num_clients, info.run_under_one_process)
# Set dedicated-server PIE: 1 client, all windows in one process
ok = unreal.EngineSettingsService.set_pie_settings("Client", 1, True) # returns True only on verified write
# Verify by readback, never by return value alone
assert unreal.EngineSettingsService.get_pie_settings().net_mode == "Client"net_mode maps EPlayNetMode: "Standalone" | "ListenServer" | "Client". "Client" is
dedicated-server PIE — the editor's "Play As Client", where a windowless dedicated server is
spawned behind the scenes and PIE instance 0 is that server ("DedicatedServer" is accepted as an
alias for "Client").set_pie_settings refuses an unknown net mode or a num_clients outside 1-10 (returns False,
logs a Warning), and returns False if any written value fails to read back.Saved/Config/<Platform>/EditorPerProjectUserSettings.ini and follow the machine, not the repo.
Do not expect a teammate or CI to inherit them; set them from the gate itself.WidgetServiceVibeUE keeps a small set of widget-in-PIE helpers on unreal.WidgetService (run them via
execute_python_code). These spawn and inspect live widget instances once PIE is running:
import unreal
# After StartPIE, spawn a widget instance into the running viewport
handle = unreal.WidgetService.spawn_widget_in_pie("/Game/UI/WBP_HUD", 0)
# Read a live property off the running instance
val = unreal.WidgetService.get_live_property(handle, "HealthText", "Text")
# Tear it down before stopping PIE
unreal.WidgetService.remove_widget_from_pie(handle)unreal.WidgetService.is_pie_running() also still exists and is handy from inside Python; for
tool-level control prefer the engine EditorAppToolset actions above.
PIEActorServiceWhy this exists: you cannot spawn an actor into a running PIE world from Python any other way.
unreal.World / unreal.GameplayStatics expose no spawn (the deferred-spawn entry points are
BlueprintInternalUseOnly), EditorActorSubsystem.spawn_actor_from_class targets the editor
world, and the engine SceneTools toolset refuses with "Cannot create actors while PIE is active".
PIEActorService resolves the live PIE world by role and spawns a transient actor into it — a
blocker, a test dummy, a trigger volume — with no Blueprint and no editor-world contamination. Run it
via execute_python_code.
Selector grammar (strict — anything else returns INVALID_SELECTOR):
| Selector | Resolves to |
|---|---|
"server" | PIE instance 0 — the standalone world, the listen host, or the dedicated server |
"client" | the single client world (instance ≥ 1); AMBIGUOUS_WORLD if >1, WORLD_NOT_FOUND if none |
"client:N" | client instance N (N ≥ 1) |
"instance:N" | the exact PIE instance N (N ≥ 0) |
Worlds come from the PIE world contexts only; the editor world and the ~100 stale /Memory/UEDPIE_*
shells are never used. No PIE at all → PIE_NOT_RUNNING.
Authority rule: a spawn into a client world is cosmetic and never replicates, so it is refused
with CLIENT_REQUIRES_OPT_IN unless you pass allow_client_local=True. Spawn on "server" for
anything that must exist for every player.
import unreal, json
# Drop a static-mesh actor as a blocker in front of the host, then verify and clean up.
t = unreal.Transform(location=unreal.Vector(500, 0, 100))
res = json.loads(unreal.PIEActorService.spawn_actor(
"server", "/Script/Engine.StaticMeshActor", t))
assert res["success"], res
handle = res["handle"] # "<session_serial>:<guid>" — dies with this PIE session
print(res["actor_path"], res["net_mode"], res["is_authority"])
# ... run whatever movement / collision check needs the blocker ...
# Idempotent teardown before StopPIE.
print(unreal.PIEActorService.destroy_all()) # {"success": true, "destroyed": 1, "already_gone": 0}resolve_world("server") returns {success, world_path, net_mode, pie_instance, is_authority, actor_count} and is the cheap way to confirm a session's role before spawning. destroy_actor(handle)
is idempotent per handle: it destroys the actor and keeps the record, so calling it again returns
success: true, already_gone: true (never UNKNOWN_HANDLE). A consumed handle stays in
list_spawned() as alive: false until PIE ends — list_spawned() is the full spawn ledger for the
session, not just the live actors — and destroy_all() counts an already-consumed actor under
already_gone rather than destroyed.
Error codes: INVALID_SELECTOR, PIE_NOT_RUNNING, WORLD_NOT_FOUND, AMBIGUOUS_WORLD,
CLASS_NOT_FOUND, NOT_AN_ACTOR_CLASS, CLASS_ABSTRACT, CLASS_DEPRECATED, CLASS_REINSTANCED,
INVALID_TRANSFORM, INVALID_COLLISION_HANDLING, CLIENT_REQUIRES_OPT_IN, SPAWN_REJECTED
(the placement collided under the chosen collision policy), UNKNOWN_HANDLE, STALE_HANDLE.
Gotcha — handles die with the PIE session.
EndPIEbumps an internal session serial and clears the registry, so a handle kept across a stop/start reportsSTALE_HANDLE. And the same Python-globals rule as everywhere else applies with teeth here: release any global holding a spawned actor beforeStopPIE(del blocker/ set toNone, orvibeue.release_globals), or the editor asserts on PIE teardown ("Object from PIE level still referenced"). The returned JSON is a string, so keepingres/handleis safe — only a live actor reference is the hazard.
InputService (issue #550)Never remap game input assets or send OS keystrokes (SendKeys/AppActivate) to test a mechanic — inject input directly; no OS window focus needed:
import unreal
# Fire an Enhanced Input action once: QUEUED for the next input tick, released on the tick after.
# X/Y/Z map onto the action's value type; Boolean uses X != 0.
print(unreal.InputService.inject_action("/Game/Input/IA_Fire_Secondary"))
# Hold it for 1.5 s of real time, then release (returns at once; stop_injection releases early).
print(unreal.InputService.inject_action_for("/Game/Input/IA_Fire_Secondary", 1.5))
# Or send a raw key to the game viewport through Slate ("tap" = down+up; also "down"/"up",
# and "hold" with a duration: inject_key("RightMouseButton", "hold", 1.5)).
print(unreal.InputService.inject_key("SpaceBar"))A Python call blocks the game thread, so PIE does not tick while it runs: inject in one call and
read the game state in a LATER call, two or more frames on. While a hold is active the editor stays
off its background frame rate, so an unfocused editor does not starve the hold. The action calls
take pie_instance to pick a PIE world: -1, the default, is the first PIE world with a local player
(the lowest instance number — the listen server's window, or client 1 under a dedicated server), and
replies report the instance actually used. A hold is one hold per action and PIE world whatever the
path spelling; holding a held key again extends it; StopPIE drops every hold, so nothing from an
ended session is released into the editor or reported active in the next one.
All return JSON with success and an error_code naming the problem (PIE not running,
NO_LOCAL_PLAYER / NO_PLAYER_CONTROLLER while PIE or a client's join is still starting — retry on
a later call —, unknown key, ...). inject_key additionally rejects a Simulate In Editor session
with SIMULATE_NOT_PLAY: Simulate has no player game viewport, so the Slate key events would be
dropped. Use StartPIE (Play), not Simulate, when driving keys. Its handled_down / handled_up
fields report whether a Slate widget consumed the event, not whether the key reached the player — a
key the game polls with WasInputKeyJustPressed lands with handled_down: false. Verify from game
state, not from those flags.
capture_image (issues #544/#546)The capture_image MCP tool with source="game" screenshots the PIE viewport including the
Slate/UMG HUD and returns a real image block you can look at (plus a PNG under
Saved/VibeUE/Captures). This replaces the old Shot showui + read-the-file workaround — and
CaptureViewport can never see PIE or UI at all.
PerformanceService (issue #549)An unfocused editor throttles to ~3 FPS, wrecking timed PIE runs. Disable throttling for the session instead of focus-hacking the window:
unreal.PerformanceService.set_background_throttling(False) # before the run
unreal.PerformanceService.set_background_throttling(True) # afterPython blocks the game thread, so you cannot sample a value over time in one call. A loop with time.sleep() between reads returns the same number every iteration — the world never ticks while your script holds the thread. This makes a working animation look frozen and a stuck one look identical to a healthy one. Take each sample in a separate execute_python_code call and compare across them:
# WRONG - three identical readings, proves nothing
for i in range(3):
print(ai.get_editor_property("SailAngle")); time.sleep(0.4)
# CORRECT - one reading per call; the elapsed wall-clock between calls is real tick time
print(ai.get_editor_property("SailAngle"))Convert the difference into the engineering unit you expect and check it: 306° → 709° across ~8 s is 48°/s, which is exactly the 8 RPM that was configured — that is a pass, "the number changed" is not.
PIE start is asynchronous. StartPIE returns immediately after RequestPlaySession is queued. The world isn't actually playing until the editor processes the request on its next tick. If you need to act inside the running world, give it a tick or poll IsPIERunning.
Already-running is treated as success. StartPIE succeeds if a PIE session already exists — it does NOT restart. Stop first if you need a fresh session.
StopPIE tears down the world via RequestEndPlayMap. Spawned PIE widget instances should be removed with WidgetService.remove_widget_from_pie(handle) before stopping.
Save before starting. Dirty asset changes are NOT picked up by PIE unless saved/compiled. Always compile_blueprint(...) before launching PIE to test Blueprint changes.
Don't leave PIE running between tasks. Subsequent edits (recompiles, asset moves, hot reload) can fail or behave oddly while a PIE world is alive. Call StopPIE before returning control to the user.
Map-load delegates never fire on PIE start. FCoreUObjectDelegates::PreLoadMap / PostLoadMapWithWorld (loading screens, post-load hooks, subsystem map handlers) are skipped because the PIE world is duplicated from the editor world, not loaded. To exercise them, trigger a real in-game transition once PIE is up: unreal.GameplayStatics.open_level(pie_world, "MapName").
Python globals holding PIE objects CRASH the editor on PIE end. Module-level variables from execute_python_code persist between calls and are GC roots (FPyReferenceCollector). If any still reference a PIE object (pawn, subsystem instance, quest/objective, widget) when PIE tears down, the engine asserts in PlayLevel.cpp ("Object from PIE level still referenced") and the editor dies. Before stopping PIE — or as the last statement of any call that inspected PIE objects — release them: del pawn, sub, quest or set them to None. Also holds for a world pointer cached across an in-game open <map> travel: it goes stale and using it raises "WorldContext requested with invalid context object"; re-fetch get_game_world() in the same call that uses it.
LogsToolset)umg-widgets skill's spawn_widget_in_pie)compile_blueprint, find_assets, etc.)get_nodes_in_graph, get_node_pins)StopPIE then StartPIE in one Python call fails with "A play session is already running" — the editor does not tick between statements. Split them across calls and confirm with IsPIERunning.EditorAssetLibrary.load_asset returns None while PIE runs, and downstream calls then return 0/None instead of raising (a fake negative). Load assets before StartPIE, or find live objects with ObjectIterator./Game/<path>/UEDPIE_0_<Map> (server/host) and UEDPIE_1_ (client) object paths, not by name — roughly 100 stale /Memory/UEDPIE_* shells match by name. vibeue.pie_worlds() returns them keyed by role, and UnrealEditorSubsystem.get_game_world() gives the local one.ROLE_AUTHORITY, so confirm get_editor_property("role") (or vibeue.role(actor)) before claiming a host/client result. Read and set the PIE net mode with get_pie_settings/set_pie_settings (dedicated server = PlayNetMode 2).slomo 0.1 stretches a 2 s timer to 20 s of wall time so a transient state survives between calls; restore slomo 1 after. PIE time restarts each run.execute_python_code script namespace persist across calls (it is a separate dict from sys.modules["__main__"], so import __main__ does not see them): use them to collect async tool results (vibeue.exec_tool_async/collect_tool_result), and release PIE object references (vibeue.release_globals) before StopPIE.© kevinpbuckley, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file (scripts) in Content/Skills/pie-testing of kevinpbuckley/VibeUE.
Open the folder on GitHubat commit dc051be
Pie Testing next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Pie Testing this skillkevinpbuckley/VibeUE | 726 | — | ~5.6k | Automated safety check: Pass | MIT | |
| Image to Three.js Modelimg2threejs/img2threejs | 18k | 1 repos | ~8.2k | Automated safety check: Pass | Apache-2.0 | |
| Web CloneJane-xiaoer/claude-skill-web-clone | 1k | 1 repos | ~2.7k | Automated safety check: Pass | MIT | |
| Threejs Game Directormajidmanzarpour/threejs-game-skills | 2.5k | — | ~2.2k | Automated safety check: Pass | MIT | |
| Game Asset Generatorhtdt/godogen | 7.1k | — | ~2.8k | Automated safety check: Pass | MIT | |
| Threejs Gameplay Systemsvalkor-ai/loom | 1.2k | 1 repos | ~1.4k | Automated safety check: Pass | Apache-2.0 |
img2threejs/img2threejs
Rebuilds the object in a reference image as a procedural, animation-ready Three.js model written entirely in code, using staged sculpting with quality checks.
Jane-xiaoer/claude-skill-web-clone
网站复刻 / 克隆方法论。USE WHEN 用户说 复刻网站、克隆网站、clone website、抄个站、仿站、 照着这个站做一个、reproduce site、还原某个网页效果、把这个站搬下来改成我的、 复刻某个交互/WebGL/Canvas/Three.js 效果。提供「先拿真源码 → 判路径 → 逆向拆解 → 搭工程 → 替换内容」的可移植决策树,覆盖静态站 /…
majidmanzarpour/threejs-game-skills
Entrypoint for building, upgrading, and finishing Three.js browser games.
htdt/godogen
Generates game art from text prompts: PNG images, GLB 3D models, rigged characters, animations and sprites, with background removal.
valkor-ai/loom
Build and iterate playable Three.js game systems: starter scaffold, architecture, design briefs, core loops, level and encounter design, entities, input, camera, collision and physics, scoring…
CyberAgentGameEntertainment/NovaShader
Execute C with Unity APIs when existing uloop tools cannot inspect or edit enough.
kevinpbuckley/VibeUE
Previews, validates and bakes bone-rotation edits on Unreal Engine AnimSequences, enforcing a coordinate space and a constraint-checked preview-validate-bake loop.
kevinpbuckley/VibeUE
Creates and edits Unreal Engine Animation Montages through AnimMontageService: sections, slots, segments, branching points, notifies and blend settings.
kevinpbuckley/VibeUE
Creates and edits AnimSequence keyframes and bone tracks in Unreal Engine through AnimSequenceService, following an inspect, preview, validate and bake workflow with correct bone-space handling.
kevinpbuckley/VibeUE
Imports files into Unreal Engine, exports textures, reads the Content Browser selection and checks open assets via VibeUE, plus mesh reimport material fixes.
kevinpbuckley/VibeUE
Changes Unreal Engine console variables, scalability levels and raw INI values through VibeUE's Python API, now that registered settings moved to the engine's own toolset.
kevinpbuckley/VibeUE
Creates and wires Unreal Engine Enhanced Input assets through VibeUE's InputService: Input Actions, Mapping Contexts, key bindings, triggers and modifiers.
Categories
Start, stop, and query Play-In-Editor (PIE) sessions for runtime testing of Blueprints, gameplay logic, widgets, AI, and any in-game behavior. Pie Testing is an agent skill from kevinpbuckley/VibeUE. Start, stop, and query Play-In-Editor (PIE) sessions for runtime testing of Blueprints, gameplay logic, widgets, AI, and any in-game behavior.
Pie Testing fits situations like: the user asks you to play; start/stop the game; otherwise needs a live game world to validate changes.
Run `npx skills add kevinpbuckley/VibeUE --skill pie-testing -a claude-code`. Or copy the skill folder (Content/Skills/pie-testing in kevinpbuckley/VibeUE) into .claude/skills/pie-testing in your project. Claude Code loads it when a task matches its description.
Run `npx skills add kevinpbuckley/VibeUE --skill pie-testing -a codex`. Or copy the skill folder (Content/Skills/pie-testing in kevinpbuckley/VibeUE) into .agents/skills/pie-testing in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kevinpbuckley/VibeUE --skill pie-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/pie-testing, .gemini/skills/pie-testing, .github/skills/pie-testing and .opencode/skills/pie-testing in your project.
SKILL.md names no scripts, command-line tools or credentials: Pie Testing is instructions for the agent only. Our summary lists: Python 3.
SKILL.md names 1 domain. As links in the text: github.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Pie Testing is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.6k tokens (SKILL.md is roughly 22k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Pie Testing: Image to Three.js Model (img2threejs/img2threejs, 18k stars), Web Clone (Jane-xiaoer/claude-skill-web-clone, 1k stars), Threejs Game Director (majidmanzarpour/threejs-game-skills, 2.5k stars) and Game Asset Generator (htdt/godogen, 7.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
kevinpbuckley (a GitHub user) maintains it in kevinpbuckley/VibeUE, which has 726 GitHub stars. The repository holds 39 skills in this directory. The repository was last updated on October 7, 2026.
Source: kevinpbuckley/VibeUE on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.