Configuration
Traverse is configured in two places: environment variables for the deployment, and per-world settings edited in the admin console.
Environment variables
PORT=3000
DATABASE_URL="mysql://user:password@localhost:3306/traverse"
ADMIN_EMAIL="admin@example.com"
ADMIN_PASSWORD="change-me"
PLUGIN_API_KEY="change-me"
SESSION_SECRET="change-me"
PUBLIC_BASE_URL="https://traverse.example.net"
# Seed the one world the first time the server starts (all optional).
TRAVERSE_WORLD_NAME="Traverse"
TRAVERSE_SEED="0"
TRAVERSE_MINECRAFT_VERSION="MC_1_21_3"
| Variable | Required | Purpose |
|---|---|---|
PORT | no | Port the server listens on. |
DATABASE_URL | yes | MySQL connection string used by Prisma. |
ADMIN_EMAIL / ADMIN_PASSWORD | seed only | Credentials for the admin user created by npm run seed. Change the password after first login. |
PLUGIN_API_KEY | yes | Shared secret the Paper plugin authenticates with. Must match the plugin's api-key. |
SESSION_SECRET | yes | Signs admin session cookies. Must be at least 32 bytes; the server refuses to start otherwise. |
PUBLIC_BASE_URL | yes | The app's public root. Access links are built from it, and it decides whether cookies are marked secure. The server refuses to start without it. |
TRAVERSE_WORLD_NAME | no | Name given to the world the first time the server starts. Editable afterwards in the admin console. |
TRAVERSE_SEED | no | Seed for that initial world. Stays editable until the first search, then locks. |
TRAVERSE_MINECRAFT_VERSION | no | Generator version for that initial world, defaulting to MC_1_21_3. Also editable until the first search. |
The TRAVERSE_* trio only seeds the world on the very first start; after that they are ignored and the values live in the database. The world is created disabled, so nothing is handed out until you finish setup and enable it.
Generate a session secret with:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Secure cookies are dropped by browsers on plain HTTP origins, and WebKit enforces that even on localhost. Traverse derives the secure flag from PUBLIC_BASE_URL's scheme, so an HTTP dev origin keeps working and Safari clients are not silently signed out.
Access tokens appear in the URL path of /access/:token, so the request logger redacts that segment. Keep that in mind if you add your own logging or proxy access logs in front of the app.
World settings
Traverse runs exactly one world per installation: one seed, one qualification rule, one time window, one set of search constraints. You do not create worlds - the server creates the single world on first start (seeded from the TRAVERSE_* variables above), and you edit its settings on the admin console's World Settings page.
Most of these settings are on the World Settings page. A few lower-level tuning values - the candidate origin (originX / originZ), the selection gap, the candidate separation, and the preview halo - are fixed at the defaults shown in the current release and are not surfaced in the console.
Identity
| Setting | Default | Meaning |
|---|---|---|
name | - | Display name shown to supporters. |
seed | - | The Minecraft world seed. Locks once previews or claims exist for the world. |
minecraftVersion | MC_1_21_3 | Which generator the biome engine uses. See Installation. |
enabled | true | Turning this off puts the world in DISABLED and stops all access. |
startAt / endAt / timezone | now / now / UTC | The campaign window. Before startAt the world is SCHEDULED, after endAt it is ENDED, in between it is ACTIVE. Only an ACTIVE world issues access. |
reminderHoursBeforeClose | 24 | How many hours before endAt the plugin reminds a supporter who still has access but has not revealed. 0 turns the reminder off. |
Qualification
| Setting | Default | Meaning |
|---|---|---|
qualificationMode | PERMISSION | PERMISSION matches against permission nodes; GROUP matches against LuckPerms group names. |
qualificationValues | [] | The list of nodes or groups that qualify. Any one match is enough. Comparison is case insensitive. |
Server operators bypass this check.
Search area
| Setting | Default | Meaning |
|---|---|---|
originX / originZ | 0 | Candidate draws radiate from this point. |
minimumSearchDistance | 0 | Nothing is offered closer than this to the origin. |
maximumSearchDistance | 20000 | Nothing is offered further than this. This is the knob that actually controls search spread. |
borderEnabled | false | Whether the world border is enforced as an outer cap. |
borderCenterX / borderCenterZ / borderSize | 0 / 0 / 60000000 | The square border. |
borderSafetyMargin | 32 | Extra blocks a plot must stay inside the border by. |
Candidates are drawn uniformly in distance, not in area. borderSize defaults to the vanilla maximum of 60,000,000, and stretching the search across that would make draws so sparse they essentially never land in any biome cluster. Keep maximumSearchDistance at the distance you actually want supporters spread over; the border only acts as a safety cap when it is the smaller of the two.
Keep-out rules
| Setting | Default | Meaning |
|---|---|---|
spawnEnabled | true | Whether the spawn keep-out is enforced. |
spawnX / spawnZ / spawnRadius | 0 / 0 / 500 | The protected spawn area. |
spawnBuffer | 100 | Extra clearance between a plot and that area. |
minimumSelectionGap | 200 | Minimum blocks between a new plot and any existing claim. |
minimumPreviewCandidateSeparation | 300 | Minimum blocks between two candidates in the same supporter's set, so their options are genuinely different places. |
Exclusion zones are managed separately; see the Admin Guide.
Match quality thresholds
| Setting | Default | Meaning |
|---|---|---|
minimumCombinedCoveragePct | 70 | How much of the plot must be covered by the requested landscapes in total. |
minimumConnectedCoveragePct | 20 | How much of the primary landscape must be one connected piece rather than scattered fragments. |
maximumAdjacencyGapBlocks | 32 | With a neighbouring biome, how far apart the primary and the neighbour may sit. |
These three are the thresholds the search actually enforces. Raising them gives purer plots and fewer results; lowering them finds more, scruffier ones. See How Matching Works.
Previews
| Setting | Default | Meaning |
|---|---|---|
previewCount | 3 | How many candidates a supporter is offered. |
previewHalo | 150 | Extra blocks rendered around the plot on the preview map. |
previewZoomOutFactor | 1.6 | How far the preview zooms out, so the image cannot be matched to a coordinate. |
Copy shown to supporters
| Setting | Meaning |
|---|---|
heroPhrase | Headline on the supporter welcome screen. |
welcomeDescription | Body text under it. |
dialogTitle / dialogMessage | The in-game onboarding dialog. Both must be set, or the dialog never shows. |
dialogYesLabel / dialogNoLabel | Button labels, defaulting to "Yes" and "No". |
The in-game closing reminder is governed by reminderHoursBeforeClose in the Identity section above.
Instance settings
Separate from any world, the admin console holds instance-wide settings:
| Setting | Meaning |
|---|---|
discordWebhookUrl | Webhook that support requests are relayed to. |
discordWebhookEnabled | Whether that relay is on. |
Biome categories
Categories are what supporters see alongside individual biomes: a named group of biomes, where picking the category matches any member of it. They are defined by the application rather than edited per world, and the search is overworld-only, so Nether and End biomes (and any category that only contains them) are never offered. The category that ships today is "Any Cold Biome", grouping the snowy and frozen variants.
Moving settings between installs
World Settings has Export settings and Import settings. Export downloads every editable world setting plus the exclusion zones as a JSON file; import applies such a file to this world. See the Admin Guide.
Token and session lifetimes
| Item | Lifetime | Notes |
|---|---|---|
| Plugin access token | 15 minutes | Single use. Hashed at rest; the raw value only exists in the link. |
| Access code | 24 hours | Single use. Issuing a new one revokes any earlier active code for that entitlement. |
| Redemption session | 3 days | The supporter's browser session cookie. |
These are fixed in the application, not configurable.