Getting Started

install onboarding first-table cli

Getting Started

This guide walks you through installing Cade, writing your first table configuration, validating and running it, and exploring it in the interactive console.

Prerequisites

  • A terminal on Linux or Windows — on Windows, WSL gives the best TUI experience

Cade ships as a single self-contained binary, so there is nothing to compile and no runtime to install. The Downloads page lists the current release for every platform, with the install commands for each package format and the SHA-256 checksums for verifying what you downloaded. Take the build for your platform and put cade on your PATH.

Releases cover Linux on x86-64 and ARM64, and Windows on x86-64. There is no prebuilt macOS binary — on a Mac, build from source using the instructions on that page.

Verify the install:

cade --version

You can also print the full build details — version, commit, build time, Go version, and platform — with:

cade version

Your First Table

A table configuration is a .cade file written in HCL that describes your machine: its devices, variables, and scoring rules. Cade loads every .cade file it finds in the current directory, or in a directory you point it at with -d.

Create a file named my-first-table.cade:

name    = "My First Table"
version = "0.1.0"

# A single standup target switch on the playfield.
device "switch" "standard" "pop_target" {
  id   = 54
  type = "NO"
}

# How many points a target hit is currently worth.
variable "int" "target_value" {
  initial = 1000
  min     = 100
  max     = 10000
  scope   = "global"
}

# Award points every time the target is hit.
score "event" "target_hit" {
  when   = device.pop_target.hit
  points = var.target_value
}

Three things are happening here. The device block declares a physical switch and gives it the name pop_target. The variable block declares a value the table can read and change while a game runs. The score block ties them together: when the pop_target switch reports a hit, award whatever target_value currently holds.

Two syntax rules are worth internalizing now, because they are the most common source of a table that loads but never scores:

  • Event names are written bare. Use when = device.pop_target.hit. The attribute is when; trigger is accepted as a synonym, and if a rule somehow carries both, when wins. Older tables often use trigger — those load, but prefer when in anything you write.
  • Expressions are written bare, with a var. prefix. Use points = var.target_value. Wrapping an expression in ${...} is a parse error inside a .cade file and will stop the table from loading.

Validate the Configuration

Before running the table, check it for syntax errors, missing references, and structural issues:

cade validate my-first-table.cade

A clean run reports:

Validating Configuration

✓ Configuration loaded successfully

Summary
──────────────────────────────────────────────────────
Files Validated:     1
Valid Files:         1
Files with Issues:   0

Issues by Severity:

Total Issues:        0

✓ Validation PASSED

Cade also prints a few structured log lines around that report; the line that matters is the final ✓ Validation PASSED, and the exit code is non-zero when validation fails.

Run validate with no arguments to validate every .cade file in the current directory:

cade validate

Validation reports HCL syntax errors, missing or unresolved references, type mismatches, and circular dependencies. Useful flags:

FlagEffect
--dir <dir>Validate a specific directory
-r, --recursiveRecurse into subdirectories of a directory target
-s, --strictEnable strict validation, including reserved-word checks
-f, --format <fmt>Output as text (default), json, or yaml
--show-graphPrint the dependency graph between blocks

See the table configuration reference for the full set of blocks available inside a .cade file.

Run the Table

Launch Cade from the directory containing your table:

cade

By default, Cade loads every .cade file it finds in the current directory. To search subdirectories as well, pass -r:

cade -r

To point at a specific directory of table files, use -d:

cade -d examples/

To bring up the built-in web server for health monitoring and debugging alongside the runtime, add -w:

cade -w

Explore in the Console

The interactive console is the quickest way to experiment with a table. It evaluates expressions, triggers events, and inspects variables in real time, in a multi-panel TUI.

Launch it from the directory containing your table — it discovers .cade files exactly the way cade does:

cade console

At the cade:debug> prompt you can:

  • List the events your table can score on — inspect events prints device.pop_target.hit → points: var.target_value, straight from the rule you just wrote
  • Evaluate expressions — eval 100 + 50
  • Set a value and use it — set var.target_value 1000, then eval ${var.target_value} * 2
  • Trigger events — trigger device.pop_target.hit
  • Switch the color scheme — theme lists the built-in themes, theme light applies one
  • List commands with help, or press Tab for completion

Note: The console’s eval command uses ${...} around variable references, and resolves those names from the console session — the values you set, plus built-ins like score. This is console-only syntax; inside a .cade file, expressions stay bare (points = var.target_value).

Watch the rule score

trigger pushes the event into the engine, but points are only awarded once a game is in progress and the console is pointed at an active player. Put the machine on free play by adding this to cade.conf next to your table:

credits {
  free_play = true
}

Then, at the prompt:

start
go
player 1
trigger device.pop_target.hit

start adds player 1, go begins the game, and player 1 makes that player the target of the debug commands. The trigger now reports the points the rule awarded and the player’s running score.

A few flags worth knowing on first contact:

FlagEffect
--watch=falseHide the watch panel the TUI shows by default
--no-audioDisable the audio subsystem — useful in headless or WSL environments
--no-tuiRun in pipe mode, reading commands from stdin

Pipe mode makes the console scriptable:

echo "inspect events" | cade console --no-tui

See the console overview for a full tour of the panels, commands, and keyboard shortcuts.

Optional: Runtime Configuration

Table files describe what your machine is. A separate runtime configuration file, cade.conf, describes how to run it — whether to start the web server, which logging level to use, and which platform driver to bridge to. Cade looks for cade.conf in the current directory first, then at $XDG_CONFIG_HOME/cade/cade.conf (defaulting to ~/.config/cade/cade.conf).

A minimal cade.conf that enables the web server and sets the logging level:

web {
  enabled = true
}

logging {
  level = "info"
}

You only need to specify the settings you want to change; everything else uses sensible defaults. To override the config path explicitly, pass --config:

cade --config ./cade.conf

Note: --config points at a cade.conf runtime config, never at a .cade table file. To load tables from a particular place, use -d.

See the Cade config reference for every available setting.

Where to Go Next