Search documentation

Find pages, sections, and content across all docs.

WavedashDocs

Environment variables

Override wavedash.toml fields with WAVEDASH_* environment variables: precedence, per-variable behavior, and running the CLI without a config file.

Every field the CLI reads out of wavedash.toml has a WAVEDASH_* counterpart in the environment. Set one and it wins for that run, which leaves the committed config as the default and lets a single repo push to a different game, from a different output directory, or with a different engine version per job — without editing a tracked file.

The variables

VariableOverridesRead by
WAVEDASH_GAME_IDgame_iddev, build push, publish, stat *, achievement *, clear-playtest-data
WAVEDASH_UPLOAD_DIRupload_dirdev, build push
WAVEDASH_ENTRYPOINTentrypointdev, build push — engine-less builds only
WAVEDASH_GODOT_VERSION[godot].versiondev, build push
WAVEDASH_UNITY_VERSION[unity].versiondev, build push
WAVEDASH_TOKENthe stored credentials fileevery command that reaches the Wavedash API

wavedash init is not in that list. It writes a wavedash.toml rather than reading one, so overrides don't affect it.

WAVEDASH_TOKEN is the one variable that isn't a wavedash.toml field — it stands in for the credentials file wavedash auth login writes, not for anything in your project config. It follows the same rules as the rest of this page, and Authentication covers how it fits into signing in.

[jsdos], [ruffle], and [renpy] have no version override. Their versions come from wavedash.toml only.

Precedence

Each field is resolved on its own, in this order:

command-line flag   >   WAVEDASH_* variable   >   wavedash.toml   >   built-in default

Two ends of that chain are narrower than they look. --game-id is the only flag in it, and only stat, achievement, and clear-playtest-data accept it — dev, build push, and publish have no flag for the game, so the variable is the only way to retarget them. And entrypoint is the only field with a built-in default (index.html); every other field reports a missing-field error when no source supplied it.

So with a committed config pointing at your production game:

game_id = "prod_game_id"
upload_dir = "./dist"

...this run uploads to a different game and leaves the file untouched:

WAVEDASH_GAME_ID=test_game_id wavedash build push -m "smoke test"

...and where a flag exists, it beats both:

# Targets third_game_id, whatever WAVEDASH_GAME_ID says
WAVEDASH_GAME_ID=test_game_id wavedash stat create \
  --game-id third_game_id --identifier KILLS_TOTAL --name "Total Kills"

The CLI announces the overrides it uses

When a value comes from the environment, the CLI says so on stdout before it acts:

env override: WAVEDASH_GAME_ID → game_id = test_game_id
env override: WAVEDASH_UPLOAD_DIR → upload_dir = ./build/web

Each field is announced once, the first time the command reads it. That means a command only ever mentions the overrides that can affect it: wavedash publish reads game_id and never looks at an entrypoint, so a stray WAVEDASH_ENTRYPOINT left over in your shell isn't reported there — while wavedash build push, which does read it, reports it.

A --game-id flag is applied silently. You're looking at the value you just typed, and it beating a differing variable is the documented precedence rather than a surprise.

If a build lands somewhere you didn't expect, scroll to the top of the output. An env override: line naming a variable you forgot you exported is the usual explanation.

Blank counts as unset

A variable that is set but empty (or only whitespace) is treated as though it weren't set at all, and the CLI falls back to wavedash.toml. This is aimed at the CI shape where a variable references something that doesn't exist:

env:
  WAVEDASH_GAME_ID: ${{ vars.STAGING_GAME_ID }}   # typo'd or unset → empty string

Without that rule, an unpopulated variable would wipe out the game_id your config file supplies and the run would fail on a missing field. With it, the committed value still applies.

Values are also trimmed, so a token read from a file keeps working despite the trailing newline:

export WAVEDASH_TOKEN=$(cat key.txt)

The same treatment applies to values written in wavedash.toml: game_id = "", upload_dir = "", and version = "" all mean unset rather than "empty string", and produce the same missing-field error as leaving the line out. That matters most for upload_dir, where an empty string would otherwise point at your project root and stage the entire repo — source files, dotfiles and all.

Running without a wavedash.toml

The config file is optional as long as the environment supplies what the command reads. If there's no file at --config (default ./wavedash.toml) but at least one config override is set, the CLI carries on and only fails when a command asks for a field that neither source provided:

export WAVEDASH_TOKEN=your_api_key
export WAVEDASH_GAME_ID=your_game_id
export WAVEDASH_UPLOAD_DIR=./dist

wavedash build push -m "no config file in sight"

This is for ephemeral checkouts, container builds, and tools that drive the CLI programmatically — anywhere checking in a wavedash.toml just to satisfy the loader would be noise. For a normal project repo, commit the file: it documents the game and output directory for everyone else working on it.

WAVEDASH_TOKEN alone does not make the config file optional. It isn't a config field, so it can't stand in for one — a directory with only a token set still reports the missing wavedash.toml.

Relative upload_dir values — from either source — resolve against the config file's directory, not your current directory. With the default ./wavedash.toml those are the same place, but when you pass --config ../other/wavedash.toml, WAVEDASH_UPLOAD_DIR=./dist means ../other/dist. An absolute path avoids the question.

Engine version overrides

When your config already declares an engine, the matching variable sets its version:

[godot]
version = "4.4-stable"
WAVEDASH_GODOT_VERSION=4.5-stable wavedash build push
env override: WAVEDASH_GODOT_VERSION → [godot].version = 4.5-stable

When your config declares no engine section, the variable brings one into play — it decides the engine for the build, not just its version. The CLI calls that out separately, along with the entrypoint the change strands, because engine builds boot through Wavedash's own entrypoint rather than a file in your upload_dir:

env override: WAVEDASH_GODOT_VERSION → [godot].version = 4.5-stable (config declared no engine, so [godot] is now in play)
env override: entrypoint = index.html from the config is no longer used — [godot] builds boot through wavedash's own entrypoint

Combinations the CLI refuses

Some combinations have no sensible winner — switching engines behind your back would upload a build the site can't boot — so wavedash dev and wavedash build push refuse them instead of guessing:

  • Both version variables are set. A build targets a single engine; unset whichever doesn't apply.
  • A version variable names a different engine than the config declares. WAVEDASH_UNITY_VERSION against a [godot] config — or against [jsdos], [ruffle], or [renpy] — is refused. Remove one so the build targets a single engine.
  • WAVEDASH_ENTRYPOINT is set while an engine is in play. Engine builds ignore it, and a silently discarded value is indistinguishable from success in CI. Unset the variable, or drop the engine that brought it into play — whether that's a section in the file or a version variable.

These checks run on the reads that a build performs. publish, stat, achievement, and clear-playtest-data only need a game_id, so a conflicting engine variable sitting in the same shell doesn't stop them — a stale export can't break commands that never look at an engine.

Example: pushing to a test game from CI

A repo whose committed wavedash.toml points at the production game, with a workflow that pushes every branch build to a separate test game instead:

name: Push test build

on:
  push:
    branches-ignore: [main]

jobs:
  push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build game
        run: npm run build

      - name: Install Wavedash CLI
        run: curl -fsSL https://wavedash.com/cli/install.sh | sh

      - name: Push build
        run: wavedash build push -m "Branch build ${{ github.sha }}"
        env:
          WAVEDASH_TOKEN: ${{ secrets.WAVEDASH_TOKEN }}
          WAVEDASH_GAME_ID: ${{ vars.TEST_GAME_ID }}
          WAVEDASH_UPLOAD_DIR: ./dist

Nothing in the repo changes between the two destinations — the environment decides, and the run's output names the override it used.

Next steps