The **Delay Node** (`DelayNode`) is a stateful numeric delay line and multi-tap sequence generator. It captures the temporal history of an incoming scalar signal and outputs both a delayed scalar value and an ordered multi-tap sequence suitable for driving tagged fixture groups.

---

## ⏳ Concept & Signal Architecture

While traditional LFO chasers generate purely mathematical wave offsets, `DelayNode` records real-time temporal history. Any dynamic motion—such as a live manual fader bump, an envelope follower pulse, or an unpredictable audio spike—travels down the delay line across multiple fixtures like a physical ripple through water.

### Outputs
- **Delayed**: The single scalar value from exactly `Delay` steps ago.
- **Sequence**: A multi-tap sequence array structured as:
  ```text
  [current, value(-Delay), value(-2 * Delay), value(-3 * Delay), ...]
  ```
  Spans up to `Length` taps (1–64) with tap spacing configured by `Delay` (0–1024 steps). When `Delay = 0`, all taps reflect the current real-time value.

---

## ⏱️ Clock Modes

The delay clock defines when a historical step is recorded into the buffer:

- **Updates Mode**:
  - A sample is pushed into history every time an input request is delivered to the `Value` socket, even if the numerical value has not changed.
  - Continuous generators (such as oscillators) advance the buffer at their own render rate.
  - Manual UI faders or MIDI controls advance the buffer only while they are being moved. When the fader stops moving, the buffer pauses.
  - Adjusting the `Delay` or `Length` knobs resizes the buffer dynamically without polluting history.
- **Frames Mode**:
  - The delay line samples the latest input exactly once per node-graph frame tick, locked to the project's shared frame rate clock (40+ Hz).
  - A single momentary flash or button tap will continue propagating forward through all sequence taps over time, even after the input source has become idle.

---

## 🌡️ Warm-Up Modes

Configures how history is initialized before sufficient samples have arrived:

- **Zeros (Default)**: Unpopulated historical steps are filled with `0.0`. Ideal for intensity pulses where lights should remain dark until the signal arrives.
- **First Value**: The unpopulated buffer is pre-filled with the first received sample value. Ideal for pan/tilt positioning or color parameters to prevent fixtures from jumping to zero on graph startup.

> [!NOTE]
> Delay history is maintained purely in runtime memory and is not serialized into project files. History is automatically flushed when the graph starts, is toggled on/off, or when the clock or warm-up mode is altered.

---

## 💡 Lighting Design Workflows

### 1. Manual Fader Ripple Chaser
Connect a manual fader ([Value Node](https://unilighter.cc/info/for-ai/docs/node-graphs/value.md)) to `DelayNode.Value` with `Length = 12` and `Delay = 3` in **Frames** mode. Route `DelayNode.Sequence` to the Dimmer channel of a 12-fixture Tag. Snapping the fader up and down sends a cascading wave of light traveling down the line of fixtures.

### 2. Temporal Echo Delay
Connect an envelope trigger or LFO into `Value` and tap the scalar **Delayed** output to synchronize delayed secondary actions (e.g. flashing backlight blinders 200ms after downstage strobes).

---

## 🔌 Sockets Reference

| Socket | Direction | Data Type | Description |
| :--- | :--- | :--- | :--- |
| **Value** | Input | `Number` | Scalar input signal to sample and record. |
| **Delay** | Input | `Number` | Number of delay steps between taps (integer `0 – 1024`). |
| **Length** | Input | `Number` | Number of sequence output taps (integer `1 – 64`). |
| **Delayed** | Output | `Number` | Historical scalar value from `Delay` steps ago. |
| **Sequence** | Output | `Sequence` | Multi-tap historical array `[t0, t-d, t-2d, ...]`. |

