Test Area and Time
TestArea
The game leaves only a few blocks between test areas. If a test places blocks beyond one block or moves mobs, reserve space with TestArea. Otherwise it overlaps with neighboring tests and fails now and then.
mod.gameTests().register("ore_vein", 100, TestArea.cube(9), test -> {
test.runCommand("fill ~1 ~1 ~1 ~7 ~7 ~7 minecraft:stone");
test.assertTrue(test.runCommand("place feature ruby_mod:ruby_ore ~4 ~4 ~4") == 1, "place the ore");
test.succeed();
});
TestArea.cube(size)is a cube, andnew TestArea(width, height, depth)is a cuboid.- If you do not set one, it is
TestArea.SINGLE_BLOCK(1×1×1). - Poly Mod Loader writes an empty structure of that size into the generation pack.
Tests that take time
Raise the maximum number of ticks, and check later with runAfter.
mod.gameTests().register("machine_finishes", 80, test -> {
// …place the machine and insert the ingredients…
test.runAfter(45, () -> {
test.assertTrue(output.count() == 1, "1 output after 40 ticks");
test.succeed();
});
});
Wait until a condition is true
When you do not know the exact tick count, check again at short intervals. If the condition does not become true in time, the test fails with a timeout.
/** Checks condition every 5 ticks and runs then once it is true. */
static void poll(GameTestContext test, BooleanSupplier condition, Runnable then) {
test.runAfter(5, () -> {
if (condition.getAsBoolean()) {
then.run();
} else {
poll(test, condition, then);
}
});
}
Test a scheduled task
mod.gameTests().register("scheduled_task_runs", 20, test -> {
AtomicInteger runs = new AtomicInteger();
test.world().schedule(3, runs::incrementAndGet);
test.runAfter(1, () -> test.assertTrue(runs.get() == 0, "task did not run early"));
test.runAfter(6, () -> {
test.assertTrue(runs.get() == 1, "task ran once, ran " + runs.get());
test.succeed();
});
});
Game test server limits
The game test server creates dimensions only from the flat preset, so there are no data dimensions. Check mod dimensions in a normal world.