Wiki 9Minecraft Wiki 9Minecraft

GameTest Framework and @minecraft/server-gametest

Automate in-world testing and spawn SimulatedPlayer instances using the GameTest script module.

6Sections
3Code examples
3Known errors

The GameTest Framework (`@minecraft/server-gametest`) is a scripting module designed for automated in-world testing of add-on mechanics, vanilla behaviors, and redstone contraptions. Beyond unit testing, creators frequently reach for this module because it is the only official way to spawn and control `SimulatedPlayer` entities in a Bedrock world. Because it requires an experimental toggle, it is primarily used for development environments, quality assurance suites, or dedicated servers that do not mind running with experimental flags enabled.

Manifest Setup and Dependencies

To use GameTests, your behavior pack manifest must declare a script module entry and a dependency on `@minecraft/server-gametest`. Unlike the core `@minecraft/server` module, `@minecraft/server-gametest` has remained on beta versions and requires the Beta APIs experimental toggle to be enabled in the world settings.

Almost every GameTest script also imports classes or types from `@minecraft/server` to interact with the entities and blocks spawned inside the test boundary. Therefore, you should list both dependencies in your `manifest.json` file.

BP/manifest.json
{
  "format_version": 2,
  "header": {
    "name": "GameTest Suite",
    "description": "Automated tests for custom mechanics",
    "uuid": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
    "version": [1, 0, 0],
    "min_engine_version": [1, 20, 80]
  },
  "modules": [
    {
      "type": "script",
      "language": "javascript",
      "uuid": "f1e2d3c4-b5a6-4958-8796-a5b4c3d2e1f0",
      "entry": "scripts/main.js",
      "version": [1, 0, 0]
    }
  ],
  "dependencies": [
    {
      "module_name": "@minecraft/server",
      "version": "1.11.0"
    },
    {
      "module_name": "@minecraft/server-gametest",
      "version": "1.0.0-beta"
    }
  ]
}

Registering a Basic Test and Structure

A GameTest is registered at script load time by calling `GameTest.register(className, testName, callback)`. The `className` and `testName` strings combine to form the full test identifier, formatted as `className:testName`, which you pass to the `/gametest run` command in-game. The callback function receives a `Test` helper object that controls the lifecycle of that specific test instance.

Every GameTest requires a `.mcstructure` file to define its physical bounds and initial block layout. By default, the engine looks for a structure in the `BP/structures/<className>/<testName>.mcstructure` path, though you can override this using the `.structureName()` method on the registration builder. Coordinates passed to methods on the `Test` object are always relative to the northwest bottom corner of the loaded structure, making your tests completely independent of where they are spawned in the world.

BP/scripts/main.js
import * as GameTest from "@minecraft/server-gametest";
import { MinecraftBlockTypes } from "@minecraft/server";

GameTest.register("custom_mechanics", "creeper_trap", (test) => {
  const spawnPos = { x: 2, y: 2, z: 2 };
  const creeper = test.spawn("minecraft:creeper", spawnPos);

  test.succeedWhen(() => {
    test.assertEntityPresentInArea("minecraft:item", true);
    test.assertEntityInstancePresent(creeper, false);
  });
})
  .structureName("custom_mechanics:trap_room")
  .maxTicks(200)
  .tag(GameTest.Tags.suiteDefault);

Registration Builder Methods

When you call `GameTest.register()`, it returns a `RegistrationBuilder` object. You can chain methods onto this return value to configure how long the test is allowed to run, what structure it loads, and how it is grouped.

MethodWhat it doesNotes
structureName(name)Sets the structure to load from BP/structures/Format is folder:filename without the .mcstructure extension.
maxTicks(ticks)Sets the timeout limit in game ticks (20 ticks = 1 second)Defaults to 100 ticks if omitted. Test fails if time runs out.
setupTicks(ticks)Wait time after loading structure before callback runsUseful for letting water flow or sand fall before logic starts.
tag(tagName)Assigns a category tag for batch runningAllows running groups via /gametest runset <tag>.
required(isRequired)Marks whether failure fails the entire test batchDefaults to true. Set false for flaky or optional tests.

The Test Helper and Assertions

Inside your test callback, the `test` argument provides two main categories of methods: actions and assertions. Action methods manipulate the area inside the structure, such as `test.spawn()`, `test.setBlockType()`, `test.pressButton()`, and `test.pullLever()`. Because all coordinates passed to these methods are relative to the structure origin, you never need to calculate world offsets yourself. If you need to pass a location to a standard `@minecraft/server` method, you can convert between coordinate spaces using `test.worldLocation(relativePos)` and `test.relativeLocation(worldPos)`.

A test does not pass simply because its callback finishes executing. You must explicitly resolve the test by calling `test.succeed()`, `test.fail(errorMessage)`, or by setting up a polling condition like `test.succeedWhen(callback)`. Inside `succeedWhen`, you call assertion methods such as `test.assertBlockPresent()`, `test.assertEntityPresent()`, or `test.assert(condition, message)`. The engine runs the `succeedWhen` callback every tick; if an assertion throws an error, the engine catches it and waits for the next tick. If all assertions inside `succeedWhen` run without throwing before `maxTicks` expires, the test immediately succeeds and the structure beacon turns green.

Spawning and Controlling Simulated Players

One of the most powerful features of `@minecraft/server-gametest` is the `SimulatedPlayer` class. By calling `test.spawnSimulatedPlayer(relativeLocation, name, gameMode)`, you spawn a fake player entity that loads chunks, triggers player-only sensors, and can perform complex interactions like attacking, using items, breaking blocks, and navigating paths.

Developers often use a dummy GameTest with a massive `maxTicks` value and an empty 1x1x1 structure just to spawn a `SimulatedPlayer` for general gameplay automation or stress testing. Note that a `SimulatedPlayer` is automatically despawned when the GameTest that created it finishes or is cleared via `/gametest clearall`.

BP/scripts/sim_player.js
import * as GameTest from "@minecraft/server-gametest";
import { GameMode } from "@minecraft/server";

GameTest.register("bot_util", "miner_bot", (test) => {
  const bot = test.spawnSimulatedPlayer({ x: 1, y: 2, z: 1 }, "MinerBot", GameMode.survival);

  test.runAfterDelay(20, () => {
    bot.lookAtBlock({ x: 1, y: 2, z: 2 });
    bot.breakBlock({ x: 1, y: 2, z: 2 });
  });

  test.succeedWhen(() => {
    test.assertBlockPresent("minecraft:air", { x: 1, y: 2, z: 2 }, true);
  });
})
  .structureName("bot_util:stone_room")
  .maxTicks(400);

Running Tests In-Game

Once your behavior pack is active in a world with Beta APIs enabled, you interact with your tests using the `/gametest` slash command. Running `/gametest run <className>:<testName>` spawns the structure in front of you, places a status beacon block at the corner, and executes the script.

During active development, `/gametest runthis` will re-run the nearest test structure in the world, and `/gametest clearall` removes all spawned test structures and simulated players within range. You can also create a new `.mcstructure` directly in-game by running `/gametest create <name> <width> <height> <length>`, building your test setup inside the generated frame, and exporting the structure using the structure block UI into your behavior pack's `structures` folder.

Which versions this applies to

Available since Bedrock Edition 1.16.210. Because `@minecraft/server-gametest` only exists as a `1.0.0-beta` version module, it strictly requires the 'Beta APIs' (or 'Enable GameTest Framework' in older versions) experimental toggle to be turned on in the world settings.

When it does not work

What you seeWhyThe fix
Content Log error: Module [@minecraft/server-gametest] with version [1.0.0] was not found.You declared version "1.0.0" in your manifest.json dependencies, but @minecraft/server-gametest has not had a stable release and only exists under the -beta tag, or the Beta APIs toggle is turned off on the world.Change the version in manifest.json dependencies to "1.0.0-beta" and enable the Beta APIs experimental toggle in the world settings.
Running /gametest run fails immediately with an error stating it could not load or find the structure.The engine could not find a matching .mcstructure file in your behavior pack's structures sub-directory.Ensure you have a valid .mcstructure file placed at BP/structures/<folder>/<name>.mcstructure, and pass "<folder>:<name>" to the .structureName() builder method.
The test finishes all code inside the callback, the structure sits idle for a few seconds, and then the beacon turns red with a timeout error.A GameTest does not automatically pass when the callback function returns; it waits until maxTicks is reached unless told otherwise.Call test.succeed() at the end of your logic, or wrap your completion checks inside test.succeedWhen(() => { ... }).

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.