-
Notifications
You must be signed in to change notification settings - Fork 15
Test Runs
A GM-only harness, not part of normal play. One command rolls a random five-bot party, levels and gears it, sends it to a dungeon entrance and lets it clear the place on its own. You stay out of the party and watch. Every run records its seed, so a run that hits a bug can be replayed with the exact same party.
It exists to answer "did my change help?" with a number instead of an anecdote — run the same dungeon fifty times and compare success rates. If you would rather drive that from a browser than from chat, see the Test Deck.
Everything below is SEC_GAMEMASTER.
| Command | What it does |
|---|---|
.dc test list |
Supported dungeons, their tokens, map ids and default levels (and heroic level, where there is one). |
.dc test start <dungeon> [options] |
Start a run. See Starting a run. |
.dc test status |
Progress of every live run, and of every live plan. |
.dc test stop [runId|dungeon|all] |
Abort runs. Bare stops the single active run; all also stops every plan first, so the scheduler cannot relaunch what you just aborted. |
.dc test gear <dungeon> [heroic] |
The item-level ceilings worth running that dungeon at. |
.dc test watch [runId|dungeon|next|off] |
Ride a live run's camera. See Watching. |
.dc test plan start <dungeon> total=N [options] |
Run the same dungeon N times, up to concurrent at once, then write a summary. |
.dc test plan status |
Progress of each live plan. |
.dc test plan stop [planId|all] |
Stop a plan and its runs. |
Everything except watch also works from the worldserver console and from
the Test Deck — see Running without a player, below.
.dc test start <dungeon> [heroic] [level=N] [seed=N] [ilvl=N|none] [quality=normal|uncommon|rare|epic|legendary]
.dc test start <dungeon> party=Tank,Heal,Dps1,Dps2,Dps3 [heroic]
<dungeon> is a token from .dc test list (sfk, dm-west, mgt, …) or a
raw map id. Wing-split dungeons are separate tokens — dm-east, sm-cath — and
run one wing at a time.
| Option | Effect |
|---|---|
heroic |
Run the heroic version. Only offered for the TBC dungeons that have one; .dc test list shows which. |
level=N |
Level the bots to N instead of the dungeon's recommended level. |
seed=N |
Replay a specific comp. Omitted or 0 rolls a fresh one. |
ilvl=N / ilvl=none
|
Cap the item level the bots are geared to (1–400, or no limit). |
quality=… |
Cap the gear quality (normal…legendary, or 1–5). |
party=… |
Use five real player characters instead of pool bots, roles positional (tank, healer, then three DPS). |
The gear options exist because bots are normally geared to the server-wide
AiPlayerbot.AutoGearScoreLimit / AutoGearQualityLimit, so comparing a party
in Karazhan-era gear against the same party in Sunwell gear used to mean editing
the conf and reloading between runs. A run now carries its own ceiling.
.dc test gear <dungeon> lists the ceilings worth using for that dungeon —
steps around its own level band, plus the named raid tiers at the level cap.
level=, seed= and the gear options are rejected on a party= run rather
than silently ignored: the level comes from the characters, the roster is the
comp, and real characters are never relevelled or re-geared.
Five bots — one tank, one healer, three DPS — on five different classes, drawn per run from the role pools and seeded so the same seed always yields the same comp. Tanks come from protection warrior / protection paladin / bear druid; healers from holy and discipline priest, holy paladin, restoration shaman and restoration druid; DPS from every remaining PvE spec. Death knights are excluded, because their level floor breaks low-level dungeons.
Each spec is named by its playerbots premade-spec template
(AiPlayerbot.PremadeSpecName.<class>.<n>) and resolved at provisioning time. A
tank or healer spec with no matching template fails the run loudly rather than
silently rolling a random build.
.dc test plan start <dungeon> [heroic] total=N [concurrent=N] [level=N] [seed=N] [ilvl=N|none] [quality=…]
A plan launches total runs of one dungeon, keeping at most concurrent of
them in flight, and appends a summary line when it finishes. This is how you get
a success rate. Global ceilings live in the conf
(DungeonClear.TestRun.MaxConcurrent, .MaxPlans, .Plan.MaxTotal), with 0
meaning "no limit".
.dc test watch <runId|dungeon> hides you, binds and teleports you to that
run's instance entrance (your body stays out of the party's way — the camera
is farsight), and follows its tank on arrival.
- Running it again for another run hops you straight there; the previous instance is left and unbound for you, so a finished heroic copy does not sit there holding your daily lockout.
-
.dc test watch nexthops to the next live run and wraps, so you can tour a whole plan without reading run ids off.dc test status. It stays put when there is nowhere to go. -
.dc test watch offends the camera, returns you to where you started, and drops the binds it made.
From a follow camera, a bare .dc spectate steps into the free-flying camera at
the bot you were watching; press it again to stop.
watch is the one subcommand with no console form — a camera needs a session to
attach to.
The harness is built around an issuing GM: the party bots log in under that
player's account and keep them as their playerbots master, which is what holds
them on the stock real-player fast path. When a GM types .dc test start
in-game, they are it.
A console or Test Deck launch has no such player, so the module logs one dedicated character in headlessly and parks it as the stand-in GM. It creates that character and its account the first time one is needed:
| Setting | Default | Notes |
|---|---|---|
DungeonClear.TestRun.DriverCharacter |
Dcdriver |
Resolved by exact, case-sensitive lookup. The module refuses to create a name it could not look up again. |
DungeonClear.TestRun.DriverAccount |
dcdriver |
Created as a plain player account; the session is elevated, not the account. Must not be a RandomBotAccounts or addclass-pool account, or the bot rotation would log the driver out from under a live run. Set to "" to turn provisioning off and supply the character yourself. |
The very first console launch may answer "is logging in — retry in a few seconds" while that happens.
A run succeeds when every boss is down. Otherwise the first of these to match ends it:
| Verdict | Trigger |
|---|---|
aborted |
.dc test stop, the GM logging out, or the leader going missing. |
party_wiped |
Every member dead past a 15s grace — long enough for a battle rez or soulstone to un-wipe it. |
paused_timeout |
A pause outlasting DungeonClear.TestRun.PauseGraceS (default 60). A test run never gets the human input a pause waits for. |
stalled_timeout |
A stall outlasting DungeonClear.TestRun.StallGraceS (default 120), giving the stall-recovery ladder time to work. |
no_progress |
No boss or objective progress for DungeonClear.TestRun.NoProgressS (default 600) — the silent-livelock net. |
overall_timeout |
DungeonClear.TestRun.OverallTimeoutS (default 3600). |
disabled |
The run's own disable funnel fired for a non-"all cleared" reason. |
All of these are written by relative name, so they land in the worldserver's working directory — which is not necessarily the directory the binary lives in.
| File | Contents |
|---|---|
dc_testruns.jsonl |
One JSON line per finished run: comp, result, fail reason, boss/status/pull timelines, deaths, pauses, watchdog budgets, and the teardown diagnostic snapshot. Override with DC_TESTRUNS_FILE. |
dc_testplans.jsonl |
One summary line per finished plan. Override with DC_TESTPLANS_FILE. |
dc_testrun_live.json |
Live state of every in-flight run and plan; this is what the Test Deck's Live panel reads. |
dc_test_dungeons.json |
The dungeon catalogue, written shortly after startup. |
In the log, each run's lines are bracketed by TESTRUN START and TESTRUN END
markers. Note that the log appenders open in truncate mode, so a worldserver
restart wipes them — for an older run, the JSONL record and its diagnostic
snapshot are all that survive.
-
Heroic lockouts are real. A heroic run spends the map's daily lockout, and
so does parking a watcher in a finished copy — which is why
watch offdrops its binds on the way out. -
Bot parties fire no client packets. An area trigger is a client-side
volume: nothing server-side notices a unit entering one, so a party of five
bots with no game client behind any of them fires no
at_*scripts at all, and several boss set-pieces simply never start. A test run closes that gap by relaying the packet itself — but deliberately only for bot-only groups (a human or self-bot in the party is already sending it), and only for scripted, non-teleport triggers (relaying the instance exit would end the run by walking past it). Outside that scope the gap is still there, which is why several encounters carry an explicit event to start them (see Scripted Dungeon Events). It remains the first thing to suspect when a set-piece is skipped in a test run but works when you play it yourself. - A global instance reset ends every run at once. If a whole batch fails within the same second with the party standing at a graveyard, that is the server's scheduled reset, not your change.