First run, accounts and sign-ups
The first account
The first account registered on a fresh server becomes its administrator, and creating it takes a one-time setup code, so whoever reaches a fresh server first cannot claim it. While the server has no accounts it prints the code in its log at every start, with a link that fills it in; open the link on the server's computer, or type the code into the sign-up form's Setup code field. Under Docker, docker compose logs | grep -A12 "no accounts yet" shows it. Set ODM_SETUP_CODE to choose the code yourself. The first account cannot be made with Discord: create it with a password and link Discord afterwards. Servers that already have an account are not affected.
The guided setup follows the first account: the storyteller, pictures and voice, players, and your own agent, one question at a time, each tested before you move on. It saves ordinary admin settings and can be run again from Admin, Guided setup; an administrator whose storyteller is not answering is offered it on the home screen.
To promote someone later, use the Users tab in the admin panel, or from a shell:
node scripts/make-admin.mjs <username>
# under Docker:
docker compose exec open-dungeon-master ./scripts/docker-entrypoint.sh node scripts/make-admin.mjs <username>Sign-up modes
Admin, Server settings, Accounts, New account sign-ups:
| Mode | Who can register |
|---|---|
| Open | Anyone who reaches the address. Fine on a LAN; close it once your party is in if the server faces the internet. |
| Invite-only | People with an account invite code from you, or people arriving with a live room code from one of your campaigns, which vouches for them without a separate invite. |
| Closed | Nobody. Existing accounts sign in as before. |
The first account always bypasses the policy (it takes the setup code instead). Registration and campaign joining share the login throttle, so guessing costs something, and wrong passwords are also counted per account: 20 misses in 15 minutes lock that name for a while, however many addresses the guesses come from.
Who may start campaigns, and who may spend
The same Accounts section decides who may start campaigns and workshops (everyone, or administrators only; for everyone else New campaign and Quick start do not appear) and whose tables may use a paid AI backend, meaning a keyed backend on a public host. The Usage tab keeps a ledger of tokens spent per account and per campaign. Only an administrator can point a campaign at a backend address or key of its own.
Account invites
With sign-ups set to invite-only, the Accounts section mints codes of the form ODM-XXXXXXXXXX (an alphabet with no lookalike characters), each with a note, a maximum number of uses (1 to 1000) and an optional expiry. Hand one to a new player; the sign-up form asks for it on an invite-only server. The apps show the same field.
Room codes as invitations
A campaign's room code admits a newcomer to the campaign and, on an invite-only server, to an account. The code must name a table that would actually seat them: it exists, has not ended, has a free seat, and is not mid-game with the door shut. Invite links show a preview of the table before sign-in.
Users
The Users tab lists every account: promote or demote administrators, delete an account (immediately), and reset a password, which shows a one-time temporary password the user must replace at their next sign-in. Reports filed at the table land in the Reports tab.
Each account has a daily upload budget, 500 MB and 200 files by default (UPLOAD_DAILY_BYTES, UPLOAD_DAILY_FILES), and uploads stop for everyone before the disk falls under 1 GB free (UPLOAD_MIN_FREE_BYTES). Administrators have no budget. Uploads, generated pictures and narration audio are served only to signed-in members, and are cached privately.
Discord sign-in
- Create an application at discord.com/developers.
- Under OAuth2, add the redirect URI
<public-url>/api/auth/discord/callback, using the exact address players reach the server on (with the reverse proxy's scheme and host if there is one). - Paste the client ID and secret into Admin, Server settings, Discord sign-in, or set
DISCORD_CLIENT_IDandDISCORD_CLIENT_SECRET. Behind a proxy, set the Public URL too.
The sign-in button appears once both are set. A room code survives the Discord round trip, so an invite link still lands on the right table. An account that only ever signed in with Discord can set a password from Settings, which is what the desktop and Android apps need to sign in.
Account deletion
Any user can delete their own account from Account settings. The purge runs after the grace period you set under Accounts: 0 to 90 days, 14 by default. Zero erases immediately. Signing in before the date shows the user a Keep my account banner. Administrators can keep or erase a pending account from the Users tab. What the purge removes is listed in Accounts, friends and notifications.
Server name and public URL
The server name in Settings is what the apps show in their server list before anyone signs in. The Public URL is the address players use; it is what share links, QR codes and Discord redirects are built from when the server sits behind a proxy or a tunnel.