Settings and admin

Where a setting can be set and which one wins, the admin panel's tabs and sections, the Test backend probe, and the reference table of every environment variable the server reads.

Server

Which setting wins

The same setting can exist in several places. Resolution, first match wins:

  1. Campaign settings: the 's story fields (, URL, model, key, ).
  2. The at /admin, stored in the database.
  3. , from the process environment or .env.server.
  4. Built-in defaults.

Blank fields name the startup value or inherited model where available. A blank story model follows an endpoint that lists exactly one chat model; multiple models need an explicit choice. Blank image models mean no pictures. A blank uses the storyteller.

The admin panel

Seven tabs: Server settings, (world packs), , Users, Usage, Reports and Server log, the server's own console kept in memory, so a that failed can be read from the browser. Addons are separate programs extending importers, map generation or board views; world packs reskin a setting. See Addons. Above them, asks the same settings one question at a time. Server settings has these sections:

SectionHolds
ServerServer name, .
AccountsNew account (with codes when invite-only), who may start campaigns and , paid AI backends, the deletion grace period, and the server's rolled-stat rule: keep the first pool, reroll below a chosen total, or reroll freely. Each campaign can inherit or override it.
Default provider, backend , model name, , and Test backend.
A cheaper second model for summaries, compaction, checks and ; provider, model, URL, key, and its own Test backend.
ImagesDefault backend, URL and checkpoint (or Z-Image Turbo), URL, OpenAI image model, base URL and key.
SpeechThe server (, any speech server, or off) with its address, model, key and default voice, and Test narration; the speech-to-text URL, and the built-in Whisper, installed on demand.
Download or reinstall the sound pack, with progress.
Voice chatEnable, transport ( or ), , , voice domain.
DiscordClient ID and secret.
AgentClaude Code, Codex, opencode or Grok Build as the storyteller. Details.
Player agentsReceiver addresses, receiver testing, and Allow for hosted agents; poll links are off by default.
StorageDisk usage and cleanup controls.
Create, verify, download, delete and restore archives. Details.

On a world hosted from the desktop or Android app, the sections the app manages (Server, Accounts, Voice chat, Discord, Player agents and Backup) and the guided setup are hidden. The About dialog in the account menu shows the server's exact build and whether a newer release is out; the server asks GitHub at most every six hours unless ODM_UPDATE_CHECK=off.

Saving and service status

A save bar follows the settings page, says when changes are unsaved, and offers Save or Undo. Test buttons can check the draft before saving. The section row's status lamps distinguish working, not answering, not set up and switched off. Saving admin settings is separate from the table settings that save as you change them.

Test backend

The text and utility sections can probe the configured backend the way a campaign uses it: streamed text, a real function call with exact arguments, and the continuation after the tool's output. A backend that passes will roll dice at the table; one that fails the tool step will narrate fights it never starts. The same probe runs from a shell:

node scripts/probe-openai-backend.mjs --url http://127.0.0.1:8001/v1 --model qwen3.6-35b

Environment variables

Set in .env.server (host install) or .env beside the compose file (). Secrets belong here or in the , never in code.

Required

VariableMeaning
DB_ENCRYPTION_KEYThe . Docker generates one if unset; a host install refuses to start without it.

Text

VariableDefaultMeaning
DEFAULT_TEXT_PROVIDERcustomcustom (), local ( native), none, harness ().
OPENAI_COMPAT_BASE_URLhttp://127.0.0.1:8001/v1The OpenAI-compatible endpoint.
OPENAI_COMPAT_MODELNone selectedChoose a listed model; blank uses the endpoint's sole chat model, if it has exactly one.
OPENAI_COMPAT_API_KEYKey for that endpoint.
OPENAI_COMPAT_CONTEXTOverride the in tokens.
OLLAMA_BASE_URL, LOCAL_TEXT_MODELhttp://127.0.0.1:11434The Ollama-native provider.
OPENROUTER_API_KEY, OPENROUTER_MODEL as a backend.
UTILITY_TEXT_PROVIDER, UTILITY_TEXT_MODEL, UTILITY_TEXT_BASE_URLThe .
EMBEDDING_MODEL, EMBEDDING_DTYPEXenova/all-MiniLM-L6-v2The story memory model. English only by default; Xenova/multilingual-e5-small with q8 for tables in other languages. Changing it re-reads the story in the background.
DM_THINKING10 forces thinking off everywhere (fast, unreliable tools).
LOCAL_TEXT_TIMEOUT_MS, ARC_TEXT_TIMEOUT_MS360000, 480000Per-call timeouts.
HARNESS_MCP_URL, HARNESS_CONTEXTAgent program plumbing; rarely needed.

Images and speech

VariableDefaultMeaning
DEFAULT_IMAGE_BACKENDcomfyuicomfyui, openai, mflux-hs, sdnq-hs, harness.
COMFYUI_URLhttp://127.0.0.1:8188.
OPENAI_IMAGE_API_KEY, OPENAI_IMAGE_MODEL, OPENAI_IMAGE_BASE_URLNo image model selectedOpenAI-compatible images; select a model before pictures run. OPENAI_API_KEY is read as a fallback.
FLUX_WORKER_URLhttp://127.0.0.1:7869The FLUX image worker.
TTS_PROVIDERkokoroThe kind of server: kokoro, openai (any server with OpenAI's speech endpoint) or off.
KOKORO_URLhttp://127.0.0.1:8880 text-to-speech.
TTS_BASE_URL, TTS_MODEL, TTS_API_KEY, TTS_VOICEOpenAI's address; model selected from its listThe openai kind of narration server. A blank key on OpenAI itself falls back to the key saved for pictures.
TTS_CONCURRENCY2Speech requests sent at once across every table (1 to 8).
STT_URL, STT_MODELhttp://127.0.0.1:8870; no model selectedSpeech-to-text for and transcription. Blank uses a service's sole listed model; choose explicitly if it lists several.
STT_OPENAI_MODELNone selectedPaid OpenAI dictation model; without a selection OpenAI is not used for transcription.
FREESOUND_API_KEYLets the fetcher use Freesound.

Voice, network and platform

VariableDefaultMeaning
VOICE_ENABLED0 voice chat on.
VOICE_RTC_PORT, VOICE_LISTEN_IP44444, 0.0.0.0The and bind address.
VOICE_ANNOUNCED_IP, VOICE_DOMAINWhat clients are told to connect to. Required behind NAT or Docker.
ODM_ICE_BROKER_URLthe project's STUN and TURN for ; off for public STUN only.
APP_PUBLIC_URLThe address players use, behind a proxy.
COOKIE_SECUREauto1 behind , 0 on plain http.
PORT, HOSTNAME3005, 0.0.0.0 (Docker)Where the server listens.
SQLITE_DB_PATH, CONTENT_DB_PATH, WORLD_PACKS_DIRunder data/Where the database, and live.
WORLD_REGISTRY_URLnoneA of campaign plugins to browse; none is built in. The Admin field wins, and off there browses nothing.
ODM_MODEL_CATALOGonoff stops the daily models.dev catalog refresh; the snapshot and cached catalog still work.
ODM_ADDONS, ADDON_REGISTRY_URL, ADDONS_DIRon, project list, data/Addon availability, list and package storage.
ODM_BACKUP_DIR~/odm-backupsWhere are written.
ODM_SETUP_CODEgenerated and printedThe one-time code the first account needs.
ODM_UPDATE_CHECKonoff stops the server asking GitHub about newer releases.
UPLOAD_DAILY_BYTES, UPLOAD_DAILY_FILES, UPLOAD_MIN_FREE_BYTES500 MB, 200, 1 GBEach account's daily upload budget, and the free disk uploads keep. 0 turns one off.
DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET.
ODM_APP_ORIGINSExtra origins allowed for the apps' cross-origin calls.
ALLOWED_DEV_ORIGINSHostnames allowed to hit next dev from a phone.

The configuration reference in the repository has the same list with longer notes.

Checked against desktop and Android app 0.19.4 and server 0.28.4 on 2026-10-21. Something wrong or missing? Open an issue.

Download · v0.21.2
Server app · v0.30.2

Optional. Runs the table for a whole group on one machine that stays on. Everyone else just installs the app.

Free & open source · MIT licensed · served from GitHub releases