-
Notifications
You must be signed in to change notification settings - Fork 15
Test Deck
A web frontend for test runs, built to be handed to testers: log in with a game GM account, pick a dungeon, and a full five-bot party runs it while you watch live. No service control, no shell access — just testing.
It ships inside the module, at modules/mod-dungeon-clear/testdeck/. This page
is the tour; testdeck/README.md in the repo is the operational reference
and goes further on troubleshooting, configuration keys and the API.
| Panel | What it does |
|---|---|
| Launch | Dungeon grid. Start a single run, an N-run campaign ("plan"), or a hand-picked roster of real characters. Difficulty, bot level, comp seed and the gear ceiling are all on the one form. |
| Live | Every active run: party HP/mana chips, boss progress, a full status timeline, stop buttons. Plan progress bars. |
| Roster | Browse real characters (class colours, talent spec, instance budget), fill the five positional slots — tank / heal / dps ×3 — and save named rosters. |
| History | Finished runs with the post-mortem (party, boss kills, deaths, status timeline) and campaign summaries. Rerun relaunches a run with its own dungeon, difficulty, level, gear ceiling and comp seed — same party, new run id. |
| Logs | Live tail of the server's *.log files. |
The three launch modes map onto three questions:
- Quick run — one run, now. The loop for "did my change help?"
- Plan — the same run N times, for a success rate rather than an anecdote.
- Roster — a hand-picked party of real characters instead of pool bots.
Test Deck runs on the machine your worldserver runs on — Linux, macOS or Windows. It needs:
- Python 3.9+ (on Windows, tick "Add python.exe to PATH" in the installer).
- A MySQL client (
mysql/mysql.exe) — how it reads the game databases. -
SOAP enabled on the worldserver — how it issues
.dc test …commands.
No Node.js: the UI ships pre-built in dist/.
1. Turn on SOAP in worldserver.conf and restart the worldserver:
SOAP.Enabled = 1
SOAP.IP = "127.0.0.1"
SOAP.Port = 7878
2. Create the bridge account on the worldserver console. SOAP requires administrator level:
account create tdbridge <a long random password>
account set gmlevel tdbridge 3 -1
3. Start it, from modules/mod-dungeon-clear/testdeck:
| Windows | double-click testdeck.bat
|
| Linux / macOS | ./testdeck.sh |
| either, by hand | python3 launch.py |
The first run creates a private Python environment, installs what it needs, asks
a handful of questions (mostly confirming what it already worked out), writes
testdeck.toml, then serves the deck and opens your browser at it. Later runs
skip straight to serving. It prints both the local URL and the LAN one —
testers elsewhere on the network need nothing installed, just that second
address in a browser.
4. Log in with any game account that has gmlevel >= 1. There is no
separate Test Deck password.
Then pick a dungeon, leave every option alone, and press Start run.
Easy to conflate, so:
| What it is | Who creates it | |
|---|---|---|
tdbridge |
The account SOAP authenticates as. No character, never enters the world. Needs gmlevel 3 — the core refuses SOAP below administrator. |
You, in quick-start step 2. |
Dcdriver |
The test driver character the module logs in headlessly to stand in as the issuing GM, because a console launch has no player behind it. Nothing the deck starts works without it. | The module, on first need. See Test Runs. |
| tester accounts | Ordinary game accounts with gmlevel >= 1, used to log into the deck. |
You: account create alice <pw> then account set gmlevel alice 1 -1. |
On a host that has never launched anything, Dcdriver is simply absent and the
first launch may report that it is logging in. The deck handles that by queueing
the run as a one-run plan, which waits the driver out server-side.
From the worldserver console (or via SOAP):
account create alice <password>
account set gmlevel alice 1 -1
Verify one end to end with python3 -m testdeck check-auth alice.
gmlevel 1 can log in, launch pool runs and plans, and draft characters on
its own account. Anything that affects someone else — clearing shared run and
plan history, deleting or overwriting another tester's saved roster, or running
characters that belong to another account — needs [auth] admin_gmlevel
(default 3). That last one matters: a roster run logs a character in, teleports
it and re-gears it.
Revoking access is account set gmlevel <user> 0 -1, and it takes effect within
about a minute — authorization re-reads the account's GM level and ban state
from the auth database on every request rather than trusting the cookie.
python3 -m testdeck check # every problem this host has, in one listcheck names the config key behind each finding, and prints the two directories
that most findings come down to:
server C:\WoW\SingleCraft (worldserver working directory)
log_dir C:\WoW\SingleCraft\logs
sidecars C:\WoW\SingleCraft (found)
server_root is the setting that decides the most. It is the directory the
worldserver runs in, not necessarily where the binary sits — the module writes
its dc_* files there by relative name, so the Launch, Live and History panels
all read out of it, and LogsDir / DataDir in worldserver.conf are relative
to it too. Set [paths] server_root explicitly if the server is started from
somewhere the binary is not: a service with its own working directory, or a
launcher script that cds first. Most "No dungeon catalogue yet" and "Live
stays empty" reports are this one setting.
The repo README has the full symptom-to-cause table.
Test Deck is a LAN tool. Defence in depth, outermost first: a Host header
check ([server] allowed_hosts), a source-address allowlist ([server] allowed_nets), GM-account login against the auth database's SRP6 salt and
verifier (per-IP and per-username throttled, generic failure messages), a signed
HttpOnly session cookie, and a CSRF header on every mutation. Command strings
are built server-side from validated fields only — nothing typed in the browser
is ever spliced into a console command. Every start and stop is audit-logged
with the account name.
Two things to get right:
- Reach the deck by address (what the startup banner prints) and you need no
extra config. If testers use a hostname — a reverse proxy, a DNS or hosts
entry — list it in
[server] allowed_hosts. That check is what stops a hostile page a tester visits from pointing a name it controls at your server and driving it from their browser. -
[paths] data_dirholds the session secret and is kept at mode 0700. A readable copy of that file is enough to forge an admin session.
Do not expose it to the internet without a TLS reverse proxy in front. The
session cookie rides plain HTTP on a LAN, which is what [auth] session_hours
(default 12) is really sizing: how long a sniffed one stays useful.
SOAP is the recommended transport and the only one that exists on Windows — it
works no matter how the worldserver is launched and needs no privileges. Two
POSIX-only alternatives exist for hosts that would rather not enable it:
screen (set screen_session) and tmux (set tmux_target). If the session
belongs to another user, set use_sudo = true and install the snippet
python3 -m testdeck sudoers prints.
Keep the bridge password out of the config file with TESTDECK_SOAP_PASS if you
prefer.
Nothing about the launcher is required — any supervisor that runs
python3 -m testdeck serve works. ac-testdeck.service.in is a systemd unit to
fill in; on Windows, Task Scheduler with "Run whether user is logged on or
not" pointed at testdeck.bat does the same job.
testdeck.example.toml documents every setting. The config file is looked for
in this order: --config PATH, $TESTDECK_CONFIG, ./testdeck.toml, the
checkout's own testdeck.toml, ~/.config/testdeck.toml, /etc/testdeck.toml.
Missing config is never fatal — the server boots on derived defaults and says
what is wrong in its own banner, because a server that refuses to start cannot
tell you why it refuses to start.
For UI work: cd web && npm install && npm run dev (hot reload, /api proxied
to 127.0.0.1:8790); npm run build writes ../dist, and the result is
committed. Tests are bash t/run_tests.sh — no root, no live worldserver, no
database needed. The HTTP API is documented in testdeck/docs/api.md.