Getting Started
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, macOS, or Windows (on Windows, WSL gives the best TUI experience)
- A Go toolchain, to build the binary from source
Cade is currently distributed as source. Clone the repository and build it:
git clone https://cade.run/cade.git
cd cade
go build .
If you have task installed, task build does the same thing with the project’s standard build flags.
Put the resulting cade binary somewhere on your PATH, then verify the install:
cade --version
You can also print the full build details — version, commit, build time, 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 iswhen;triggeris accepted as a synonym, and if a rule somehow carries both,whenwins. Older tables often usetrigger— those load, but preferwhenin anything you write. - Expressions are written bare, with a
var.prefix. Usepoints = var.target_value. Wrapping an expression in${...}is a parse error inside a.cadefile 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:
✓ Configuration loaded successfully
Summary
──────────────────────────────────────────────────────
Files Validated: 1
Valid Files: 1
Files with Issues: 0
✓ Validation PASSED
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:
| Flag | Effect |
|---|---|
--dir <dir> | Validate a specific directory |
-r, --recursive | Recurse into subdirectories of a directory target |
-s, --strict | Enable strict validation, including reserved-word checks |
-f, --format <fmt> | Output as text (default), json, or yaml |
--show-graph | Print 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:
- Evaluate expressions —
eval ${var.target_value} * 2 - Trigger events —
trigger device.pop_target.hit - Inspect state —
inspect target_value - List commands with
help, or press Tab for completion
Note: The console’s
evalcommand uses${...}around variable references. This is console-only syntax — inside a.cadefile, expressions stay bare (points = var.target_value).
A few flags worth knowing on first contact:
| Flag | Effect |
|---|---|
--start | Start the engine automatically on launch |
--theme <name> | Choose the color theme: dark (default), light, or nord |
--no-audio | Disable the audio subsystem — useful in headless or WSL environments |
--no-tui | Run in pipe mode, reading commands from stdin |
Pipe mode makes the console scriptable:
echo "trigger device.pop_target.hit" | 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:
--configpoints at acade.confruntime config, never at a.cadetable file. To load tables from a particular place, use-d.
See the Cade config reference for every available setting.
Where to Go Next
- Learn the building blocks — Table Design Basics walks through creating a scoring element and a mode, the two pieces most tables are built from.
- Build out your table — The table configuration reference covers devices, events, variables, scoring rules, fragments, and platforms.
- Wire up hardware — The driver guides cover the FAST Framework, Visual Pinball, and the virtual driver for testing without hardware.
- Write expressions — The expressions guide explains the formula language used inside
when,points, andupdatefields. - Learn the console — The console panels and cascade viewer pages show how to debug live games.