Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

Added

TUI Logs Tab Enhancements

See Logs Panel for the full keyboard reference.

Event Tree Viewer — Scrollback and Overflow Expansion

See Events Panel for the full navigation reference.

Driven-Device Abstraction Layer

See Driven Devices for the architecture overview and Device API reference for the full schema.

Synthesis Subsystem

Runtime Expression Bindings

See Runtime Bindings for the full namespace reference and Synthesis for synth-specific binding examples.

Exhaustive Automated Testing of Cade Config Language

Scenario Testing Infrastructure

See Scenario Testing for the full file format reference and usage guide.

Session Variable Scope

variable "int" "table_bonus_level" {
  initial = 0
  scope   = "session"
  max     = 5
}

Game-End Variable Reset

Variable Change Events

event_handler "sync_on" {
  event     = "variable.l6_lit.changed"
  condition = "l6_lit == true"
  actions {
    set_light "light" { device = "l6"; state = "on" }
  }
}

Player-Switch Variable Re-Sync

Nightly Fuzz CI Pipeline

Async Log Sink With Drop-Oldest Backpressure

Changed

Rollover Light Examples Updated to Player Scope

Drop- and Standup-Target Examples Migrated to New Subtypes

New Example: Modes + Synth Bumper Table

Example Bumper Synth Patches Retuned to Sci-Fi Textures

Quieter Logs During Event Floods

Fixed

Variable-Driven Outputs Not Clearing at Game End or Engine Stop

Scoring Compiler Constants Collision in Multi-Update Rules

Synth Silence on Percussive Patches

Crash When mode.<name>.active Referenced With No module {} Blocks

Audio Stalls During Event Floods

Parser Rejected Canonical Two-Label variable Blocks

v0.1.0 — 2026-04-14

Initial versioned release of the Cade Runtime. Ships the declarative HCL configuration surface (.cade files, fragments, assemblies, modules), the compile-time-optimised scoring and expression engine, the event processing pipeline with aggregation primitives, the TUI console with Logs/Events/Console tabs, the VPX and FAST drivers, hot reload, scenario and replay tooling, and cross-platform builds for Linux, Windows, and macOS (arm64/amd64). Versioning is now tracked via the cade version command and the --version flag.

Added

Assembly Tag Propagation — Three-Source Union Merge

assembly "bumper" {
  tags = ["autofire", "scoring_device"]

  parameter "int" "switch_id" { required = true }
  parameter "int" "coil_id"   { required = true }

  device "switch" "bumper" "sensor" {
    id   = param.switch_id
    tags = ["active_switch"]
  }

  device "coil" "bumper" "ring" {
    id = param.coil_id
  }
}

use "bumper" "pop_1" {
  switch_id = 0x40
  coil_id   = 0x30
  tags      = ["upper_playfield"]
  # After expansion:
  #   switch "bumper" "sensor" tags: ["autofire", "scoring_device", "upper_playfield", "active_switch"]
  #   coil   "bumper" "ring"   tags: ["autofire", "scoring_device", "upper_playfield"]
}

Event Aggregation Example Configurations

Examples Conversion — game_mode to module Syntax

Event Aggregation System

Event Tree Viewer Improvements

Active-on-Startup Mode Auto-Launch

module "base" {
  mode {
    priority          = 100
    active_on_startup = true

    events {
      on game.ball_end { end_mode = "base" }
    }
  }
}

Engine-Level Multiplayer and Mid-Game Joins

Config Primitive Cleanup — Mode Removal, Passive Mode Primitives, Signal Guidance

# Before
game_mode "stop_and_go" {
  priority = 800

  events {
    on device.left_flipper__button.activated { emit "menu_select_left" }
  }
}

# After
module "stop_and_go" {
  mode {
    priority = 800

    device_control {
      target "device" {
        select { tags = ["flipper"] }
        apply  { enabled = false }
      }
    }

    events {
      on device.left_flipper__button.activated { emit "menu_select_left" }
    }
  }
}

Game-Passive Modes & Device Control Design

Kick Ball Action — Driver-Agnostic Kicker-Kick Primitive

device "switch" "kicker" "Kicker1" {
  id = 41
  settings {
    kick_angle    = 190
    kick_strength = 10
  }
}

event_handler "gate_hit" {
  event = "device.Gate1.cleared"

  actions {
    kick_ball { device = "Kicker1" }
    increment  = "balls_in_play"
    start_mode = "multiball"
  }
}

Noise Context Configuration

noise_context "scoring" {
  algorithm  = "hash"
  seed_base  = "time"
  quality    = "balanced"
  cache_size = 256
}

noise_context "testing" {
  algorithm = "hash"
  seed_base = "deterministic"
}

Variable Auto-Decay and Auto-Grow

Show Dispatch from Event Handlers

ActionBlock Naming Fixes and Trigger Wiring

event_handler "combo_complete" {
  when = "shot.left_orbit.complete"

  actions {
    fire_signal = "combo_jackpot"   # activates signal through signal processing layer
    emit        = "combo_scored"    # injects event into event handler layer
    points      = 25000
  }
}

score "jackpot_rule" {
  when   = "combo_jackpot.complete"
  points = 100000
}

ActionBlock Execution Pipeline — Scoring and Emit Data

Mode Control from Event Handler Action Blocks

event_handler "multiball_lock" {
  when = "device.lock.activated"

  actions {
    start_mode       = "multiball"
    toggle_variable  = "lock_active"
    emit             = "multiball_started"
  }
}

event_handler "drain_handler" {
  when = "game.ball_drain"

  actions {
    end_mode = "multiball"
  }
}

Event Router Deduplication

Expression String & List Built-in Function Libraries

Reserved Keyword Validation

Expression Compile-Time Optimization

Hot Reload and Session Unification

Assembly System

Module System

Replay Analyze Command

Replay Tree Command

Activity Watchdog

Config Hash Validation for Scenarios

Platform Conformance Tests

Light System

Stacking Contract Validation

Event Tree Viewer

TUI Layout

TUI Header Redesign

Game Status Bar

Event Compression and Viewer Improvements

Event Handler Mode Actions

Validate Command Path Scoping

Other Recent Additions

Debug Console - Pipe Mode Support

Multiball Lifecycle Management

Module Active Condition in Scoring Engine

Mode Event Bridge in Console

Other Recent Additions

Changed

TUI Mode Lifecycle Display

TUI Console Cleanup

VPX Driver

Example Tables

Other Changes

Fixed