Skip to content

M1.1 — What Gauntlet is (and isn't)

What you'll learn

  • The one-sentence definition of Gauntlet and how to unpack each word in it.
  • What a session means in Gauntlet, and why "run the game" is more than one process.
  • The three hard boundaries: Gauntlet does not cook builds, does not require game-side test code, and is not opinionated about how you assert.
  • Why those boundaries are the most important thing a QA owner learns first.

How it applies (QA)

Most early Gauntlet confusion is a category error: someone expects it to behave like an in-engine test framework (write a test, press a button, it builds and runs) and is surprised when it demands a pre-cooked build and shrugs about assertions. Knowing the boundaries up front tells you what you must supply, what the framework supplies, and where a failure is your problem versus the framework's. That triage instinct is the whole reason to start here.

Concepts

The definition, word by word

Epic's definition is one sentence:

Gauntlet is a framework to run sessions of projects in Unreal Engine that perform tests and validate results.

Three load-bearing phrases:

  • "sessions" — not "a process." A Gauntlet run launches and supervises all the processes needed to execute the game. For a single-player title that is one client. For a multiplayer title it might be four clients and a dedicated server, started in the right order, on the right hardware, wired to talk to each other. Gauntlet's job is to stand that whole arrangement up, watch it, and tear it down.
  • "perform tests" — Gauntlet drives the run and decides when a test is over and whether it passed. It does not dictate what the test does inside the game.
  • "validate results" — the framework gives you the raw material to judge a run: parsed logs, detected crashes and ensures, exit codes, and access to the /Saved directory the run produced.

A useful one-liner to carry: Gauntlet is a session orchestrator with a results harness bolted on. It launches a configuration of game processes, supervises them to a verdict, and hands you the wreckage to inspect.

What a session actually contains

A session — all the processes needed to execute the game with the Unreal engine, launched and supervised as one unit — is what Gauntlet operates on. Pulling it apart:

  • One or more roles — a role is "one participant in the session," e.g. a client, a server, or an editor instance. M3 is entirely about roles.
  • Each role runs on a device — local PC, a remote PC, or a console devkit. Same test, different target hardware, is just a different device.
  • Each role runs a build — a pre-cooked, ready-to-run output for that platform. Gauntlet installs/launches it; it does not produce it.

So "run the game" expands to: for each role, install the right build on the right device, launch it with the right arguments, in the right order, and watch all of them at once. That expansion is why Gauntlet exists — doing it by hand across platforms is the tedious, error-prone work it automates.

The three boundaries

These are the lines that catch newcomers. Memorize them.

Gauntlet consumes a build; it does not create one. You must hand it an already-compiled, already-cooked, staged or packaged build for the target platform. If you point Gauntlet at a project that was never cooked for Win64, it has nothing to launch — and the failure looks like "build not found," not "test failed."

This is the single most common first-day mistake: treating RunUnreal as if it will build the thing it runs. It won't. Cooking and staging are upstream steps (usually a BuildGraph node or a manual BuildCookRun).

Gauntlet "does not require any specific game-side automation code or test framework." You can write a meaningful Gauntlet test — for example, "boot the game and confirm it reaches the main menu without crashing" — with zero new C++ in the game. The test logic that decides pass/fail can live entirely in the C# orchestration layer, reading the game's existing log output.

This is what separates Gauntlet from in-engine automation (M1.2). It can puppeteer a game that knows nothing about being tested.

Gauntlet is unopinionated about how you decide a run passed. Log-string matching, exit codes, a custom marker your game prints, a screenshot comparison, a perf threshold — all are fair game. The framework hands you the data and a place to put your verdict; the verdict logic is yours.

Freedom with a cost: there is no built-in "assert" vocabulary to lean on. M4 and M5 are about the patterns teams adopt to impose structure on this freedom.

The one optional convenience: TestController

Gauntlet ships an optional engine plugin that provides a TestController C++ class to help puppeteer and monitor a game instance from inside the game. It is genuinely optional — it exists because boundary #2 (no game-side code required) makes simple smoke tests easy but makes multi-step in-game sequences ("load level, spawn player, fire weapon, confirm hit") awkward to drive purely from logs. TestController gives those a home on the C++ side. M5 covers it. For now: know it exists, know it is not mandatory.

Pitfall: 'build not found' is usually a cook problem, not a Gauntlet problem

When a brand-new Gauntlet command fails immediately with a missing-build error, your first instinct should be "was this platform actually cooked and staged?" — not "is my test wrong?" The boundary (Gauntlet doesn't cook) means the failure is upstream of the framework nine times out of ten.

Worked example

A QA lead is asked, "Can Gauntlet just run our smoke test on the nightly build?" Walk the boundaries to a real answer:

Question Boundary that answers it Conclusion
Will Gauntlet build tonight's CL? #1 — doesn't cook/build No. The nightly pipeline must already produce a cooked, staged build; Gauntlet runs that.
Do we need engineers to add test hooks first? #2 — no game-side code required Not for a boot/smoke test. Log-driven pass/fail can ship without game changes.
How does it know "smoke passed"? #3 — assertions are yours You define it — e.g. "log contains LogLoad: ... reached MainMenu and no Fatal lines."

The honest answer: "Yes, once the nightly produces a cooked build — and the first smoke test needs no game-side code, but we have to define what 'passed' means ourselves."

Exercise 1 — Sort the responsibilities

For each item, mark G (Gauntlet's job) or Y (yours, supplied to Gauntlet):

  1. Compiling the Win64 game target.
  2. Launching a dedicated server and two clients in the right order.
  3. Deciding that "reached the main menu" means the smoke test passed.
  4. Detecting that one of the clients crashed during the run.
  5. Cooking content for Android.
  6. Tearing down all processes when the test ends.

Exercise 2 — Spot the category error

A teammate writes: "Gauntlet keeps failing — it won't compile our test even though the C++ builds fine in the editor." In one sentence, name the misconception and the boundary it violates.

Self-check — answers

Exercise 1:

  1. Y — cooking/compiling is upstream; Gauntlet consumes the result (boundary #1).
  2. G — orchestrating roles in order is exactly Gauntlet's job (the session).
  3. Y — assertions/verdict logic are yours (boundary #3).
  4. G — crash/ensure detection is part of the results harness Gauntlet provides.
  5. Y — cooking, again upstream (boundary #1).
  6. G — session teardown is Gauntlet's responsibility.

Exercise 2: The teammate expects Gauntlet to build the test/game. Gauntlet doesn't cook or compile (boundary #1); it runs pre-built outputs. "Gauntlet failing to compile" is a category error — compilation is UBT/UAT's job upstream, not Gauntlet's. The real failure is almost certainly a missing or stale build, not a broken test.

Done when

  • [ ] You can recite the one-sentence definition and unpack sessions, perform tests, and validate results.
  • [ ] You can state the three boundaries from memory.
  • [ ] Given a responsibility, you can say whether it's Gauntlet's or yours.
  • [ ] You can explain why "build not found" is usually an upstream cook/stage problem.
  • [ ] You know TestController is optional and what gap it fills.

Next: M1.2 — Gauntlet vs. other UE automation — where Gauntlet sits relative to the in-engine automation systems you may already know.