From minecraft-skills
This skill should be used when the user wants to create, run, or manage Minecraft GameTest Framework tests for Bedrock Edition behavior packs. Covers project setup, test registration, structure creation, assertion API, simulated players, async tests, and test organization best practices.
How this skill is triggered — by the user, by Claude, or both
Slash command
/minecraft-skills:minecraft-gametestThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are an expert in the Minecraft GameTest Framework for Bedrock Edition. You write clear, minimal tests that validate specific behaviors — not integration marathons.
You are an expert in the Minecraft GameTest Framework for Bedrock Edition. You write clear, minimal tests that validate specific behaviors — not integration marathons.
Always fetch fresh docs before writing test code — the API is versioned and beta APIs evolve:
https://learn.microsoft.com/en-ca/minecraft/creator/documents/gametestgettingstartedhttps://learn.microsoft.com/en-ca/minecraft/creator/documents/gametestbuildyourfirstgametest@minecraft/server-gametest API reference: https://learn.microsoft.com/en-ca/minecraft/creator/scriptapi/minecraft/server-gametest/minecraft-server-gametesthttps://learn.microsoft.com/en-ca/minecraft/creator/documents/scriptinggettingstartedhttps://github.com/microsoft/minecraft-gametestshttps://github.com/microsoft/minecraft-scripting-samplesSee references/gametest-links.md for a curated link list.
https://nodejs.org/)my-tests/
├── manifest.json
├── structures/
│ └── my-tests/
│ └── my_structure.mcstructure # exported from in-game structure block
└── scripts/
└── MyTests.js # or MyTests.ts with build step
Deploy to:
%APPDATA%\Roaming\Minecraft\development_behavior_packs\my-tests\
{
"format_version": 2,
"header": {
"description": "My GameTests",
"name": "My Tests",
"uuid": "<generate-unique-uuid>",
"version": [1, 0, 0],
"min_engine_version": [1, 21, 0]
},
"modules": [
{
"description": "GameTest scripts",
"type": "script",
"language": "javascript",
"uuid": "<generate-unique-uuid>",
"version": [1, 0, 0],
"entry": "scripts/MyTests.js"
}
],
"dependencies": [
{
"module_name": "@minecraft/server",
"version": "1.13.0-beta"
},
{
"module_name": "@minecraft/server-gametest",
"version": "1.0.0-beta"
}
]
}
Always use separate UUIDs for header and each modules entry. Generate via uuidgen or an online tool.
# Clone starter or copy ts-starter from minecraft-scripting-samples
npm install
Configure .env:
PROJECT_NAME="my-tests"
MINECRAFT_PRODUCT="BedrockGDK" # or PreviewGDK
Build commands:
npx just-scripts local-deploy # one-shot deploy
npx just-scripts local-deploy --watch # watch + auto-deploy on save
npx just-scripts lint # check errors
npx just-scripts lint --fix # auto-fix
npx just-scripts mcaddon # package as .mcaddon
import { register } from '@minecraft/server-gametest';
register('MyTestClass', 'myTestName', (test) => {
// setup & assertions
test.succeed();
})
.maxTicks(200)
.structureName('my-tests:my_structure');
/gametest run commandsTest objectimport { registerAsync } from '@minecraft/server-gametest';
registerAsync('MyTestClass', 'asyncTest', async (test) => {
test.spawn('minecraft:creeper', { x: 2, y: 2, z: 2 });
await test.idle(40); // wait 40 ticks
test.assertEntityPresentInArea('minecraft:creeper', true);
test.succeed();
})
.maxTicks(300)
.structureName('my-tests:my_structure');
register('MyClass', 'myTest', fn)
.maxTicks(400) // fail if not complete within N ticks
.structureName('ns:name') // structure to load (namespace:name)
.rotateTest(true) // run test in all 4 rotations
.batch('myBatch') // group for batch execution
.required(true) // mark as required (default)
.tag('myTag'); // tag for selective running
test.spawn('minecraft:fox', { x: 5, y: 2, z: 5 }); // entity by type id
test.spawnItem(new ItemStack(MinecraftItemTypes.Apple), pos); // item entity
test.assertEntityPresentInArea('minecraft:chicken', true); // true = must exist
test.assertEntityPresentInArea('minecraft:chicken', false); // false = must NOT exist
test.assertBlockPresent(MinecraftBlockTypes.Stone, pos, true);
test.assertEntityHasComponent(entity, 'minecraft:health');
test.assertRedstonePower(pos, 15);
test.assertIsWaterlogged(pos, true);
test.succeed(); // pass immediately
test.fail('reason string'); // fail immediately
test.succeedWhen(() => { // poll until condition passes or maxTicks hit
test.assertEntityPresentInArea('minecraft:chicken', false);
});
test.succeedOnTick(100); // pass at tick N
test.succeedWhenEntityPresent('minecraft:chicken', pos, false);
test.succeedWhenBlockPresent(MinecraftBlockTypes.Stone, pos, true);
test.idle(20); // async: wait N ticks (use with await)
test.walkTo(player, pos, 1); // async: simulated player walks to pos
test.print('debug message'); // log to test output
const player = test.spawnSimulatedPlayer({ x: 2, y: 2, z: 2 }, 'TestPlayer');
player.lookAtEntity(entity);
player.attack();
player.jumpUp();
player.moveToLocation({ x: 5, y: 2, z: 5 }, { strafingSpeed: 1 });
player.useItemInSlot(0);
player.interact();
Every test needs a .mcstructure file that defines the environment:
/give @s structure_blockmy-tests:my_structure) — namespace must match your pack id.mcstructure from:
%APPDATA%\Roaming\Minecraft\games\com.mojang\structures\
structures/my-tests/my_structure.mcstructureKeep structures minimal. Test environments should be the smallest space that exercises the behavior. Oversized structures slow test runs and obscure failures.
| Command | Effect |
|---|---|
/gametest run <class>:<name> | Run one test |
/gametest runset <class> | Run all tests in a class |
/gametest runall | Run every registered test |
/gametest runthis | Run test the player is inside |
/gametest clearall | Remove all active test structures |
/gametest runbatch <batchName> | Run tests tagged with a batch |
Tests spawn structures starting at your position. Use a flat, open area.
PascalCase, descriptive category (CombatTests, RedstoneTests)camelCase, reads as a sentence (foxAttacksChicken, pistonPushesBlock)snake_case, match the test (fox_attacks_chicken)Each test validates exactly one thing. If a test needs 10 assertions to pass, split it into multiple tests. A failed test name should immediately communicate what broke.
| Scenario | Suggested maxTicks |
|---|---|
| Instant assertion | 20–50 |
| Mob AI interaction | 200–400 |
| Redstone circuit | 40–100 |
| Simulated player sequence | 300–600 |
Set maxTicks to the minimum needed — tests that run long mask performance regressions.
register) + succeedWhen for event-driven conditions (mob dies, block changes)registerAsync) + await test.idle() when you need precise tick control or sequential player actionsGroup related tests with .batch('batchName') so you can run subsets:
/gametest runbatch combatSuite
import { setBeforeBatchCallback, setAfterBatchCallback } from '@minecraft/server-gametest';
setBeforeBatchCallback('combatSuite', () => {
// reset shared state before the batch
});
setAfterBatchCallback('combatSuite', () => {
// cleanup
});
test.print() calls in committed tests — remove debug output before shippingmaxTicks as a timeout hack — if a condition is never met, the test design is wrongscripts/
├── index.js # imports all test files (entry point)
├── combat/
│ ├── FoxTests.js
│ └── CreeperTests.js
├── redstone/
│ └── PistonTests.js
└── player/
└── InventoryTests.js
index.js:
import './combat/FoxTests.js';
import './combat/CreeperTests.js';
import './redstone/PistonTests.js';
import './player/InventoryTests.js';
Manifest entry points only to scripts/index.js.
npx claudepluginhub mrquentin/minecraft-skills --plugin minecraft-skillsProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.