Skip to content

Enable & run

Horizon-QA starts in interactive mode by default. Adding the mod to a workspace enables /horizonqa commands, test discovery, and visual debugging without extra JVM flags.

Select a mode

Set horizonqa.mode on the server JVM when you need a mode other than the default:

./gradlew runServer --mcJvmArgs="-Dhorizonqa.mode=interactive"
./gradlew runServer --mcJvmArgs="-Dhorizonqa.mode=ci"
./gradlew runServer --mcJvmArgs="-Dhorizonqa.mode=off"

interactive enables commands, overlays, and manual test runs. It is the default when horizonqa.mode is not set.

ci enables the deterministic headless path:

  • The dedicated GameTest void world type is used by default.
  • ASM-based discovery runs across every @GameTestHolder class on the classpath.
  • Selected tests run automatically.
  • TEST-horizonqa.xml and horizonqa-result.json are written before the server exits.

off loads the mod but disables commands, discovery, runner behavior, and test visuals.

Modes are presets. You can override the main runtime choices without adding another mode:

./gradlew runServer --mcJvmArgs="-Dhorizonqa.mode=ci -Dhorizonqa.world=normal -Dhorizonqa.stopServer=false"
./gradlew runServer --mcJvmArgs="-Dhorizonqa.mode=ci -Dhorizonqa.autoRun=false"
./gradlew runServer --mcJvmArgs="-Dhorizonqa.mode=ci -Dhorizonqa.autoRun=false -Dhorizonqa.world=normal -Dhorizonqa.gridOrigin=0,128,0"

Pick the mode for the job

Use the default interactive mode for local authoring, ci for automated server runs, and ci with -Dhorizonqa.autoRun=false when you want report files from a manually-started batch.

Run the examples

From the repository root, with GTNH caches already configured:

./gradlew --info --stacktrace :examples:runServer

runServer is provided by Retrofuturagradle. When you need to pass a JVM flag, forward it to the Minecraft server via --mcJvmArgs. Passing -Dhorizonqa.mode=ci directly to Gradle sets it on the Gradle daemon, where the runner never sees it.

For a CI-style example run:

./gradlew --info --stacktrace :examples:runServer --mcJvmArgs="-Dhorizonqa.mode=ci -Dhorizonqa.reportDir=build/horizonqa"

In-game (operator permission level 2):

Command Purpose
/horizonqa runall Run every discovered test
/horizonqa runall <namespace> Run tests whose id starts with <namespace>:
/horizonqa run <testId> Run one test by id, e.g. horizonqaexamples:BasicTests.simplePass
/horizonqa runfailed Re-run only the tests that failed in the last batch
/qa Alias for /horizonqa

In ci mode with -Dhorizonqa.autoRun=false, /horizonqa run, /horizonqa runall, and /horizonqa runfailed write TEST-horizonqa.xml and horizonqa-result.json after the batch completes. The files are written in the working directory unless report paths are overridden. See CI & JUnit reports.

Horizon Wand

A creative-tab item used to define export bounds.

  1. Left Button a block → position 1.
  2. Right Button a block → position 2. Right-click also works at range via the targeted block, and sneaking selects the adjacent (air) block instead, which is useful for capturing clearance above a multiblock.
  3. /horizonqa export <name> → writes horizonqastructures/<name>.json and <name>_tiles.nbt under the server directory.

Move the exported files into src/main/resources/assets/<modid>/horizonqastructures/ in your mod. Full export details: Structure templates.

Interactive debugging

After /horizonqa runall, failed cells stay placed on the grid with their overlays. These commands are designed for the in-world triage loop:

Command Purpose
/horizonqa tp <testId> Teleport to the placed cell for a specific test id
/horizonqa pos Print world + test-relative coordinates; suggest helper.absolute(x, y, z)
/horizonqa runthis Re-run the test cell you are standing inside
/horizonqa runthat Re-run the test cell you are looking at
/horizonqa clearall Remove placed test cells and overlays

Iterate without restarting

Edit a test, recompile (hotswap or gradlew classes), then /horizonqa runthis on the failed cell. You do not need to restart the server for most code changes.

The full triage workflow (reading the event trace, failure signatures, in-game reproduction) is in Debugging failed tests.

Disable event recording (optional)

Event logging is on by default. Disable only for micro-benchmarking; you lose your main failure diagnostic.

-Dhorizonqa.events=off

See Test event log.