> ## Documentation Index
> Fetch the complete documentation index at: https://docs.awokenlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Logic & Hacking

> Puzzle and hacking minigames: Lights Out, Hex Breach, Code Crack, Fingerprint, Word Crack, Symbol Search, Pipe Pressure, Untangle, Minefield, Jigsaw, Wires, Tower of Hanoi, Math Rush, 2048, Splice, Current, Data Stream, Collapse and Arrow Maze.

Nineteen puzzle and hacking games. The default settings live in `config/games/logic.lua`.

<Info>
  You can set any option in two places: in `config/games/logic.lua` to change it for the whole server, or in a single call to change it just that once. See the [Overview](/resources/awoken-minigames/configuration/overview) for how these fit together, plus the [shared options](/resources/awoken-minigames/configuration/overview#shared-options) (`canCancel`, `title`, `theme`, ...) that every game accepts.
</Info>

***

## Lights Out

Clicking a tile flips it and the four tiles next to it. Light up every tile before you run out of clicks.

**Export:** `exports['awoken_minigames']:LightsOut(opts)` - returns `true` only on a win.

| Option      | Default | Notes                                                                                                                                                                                                         |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gridSize`  | `4`     | NxN grid (`3`-`5`); gets tedious above 5.                                                                                                                                                                     |
| `scramble`  | `5`     | Random moves used to scramble (difficulty).                                                                                                                                                                   |
| `maxClicks` | `15`    | Click budget; running out = fail.                                                                                                                                                                             |
| `stages`    | *(1)*   | Run several back-to-back: an integer repeats this config N times, or an array of per-stage overrides (max 10). See [Multi-stage games](/resources/awoken-minigames/configuration/overview#multi-stage-games). |
| `canCancel` | `true`  |                                                                                                                                                                                                               |
| `autoStart` | `false` | Shows a "press to start" gate. `true` starts immediately.                                                                                                                                                     |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:LightsOut({ gridSize = 3, scramble = 3, maxClicks = 10 })
-- Easy
exports['awoken_minigames']:LightsOut({ gridSize = 4, scramble = 4, maxClicks = 14 })
-- Standard
exports['awoken_minigames']:LightsOut({ gridSize = 4, scramble = 6, maxClicks = 15 })
-- Hard
exports['awoken_minigames']:LightsOut({ gridSize = 5, scramble = 8, maxClicks = 18 })
-- Expert
exports['awoken_minigames']:LightsOut({ gridSize = 5, scramble = 10, maxClicks = 16 })
```

<Tip>
  The gap between `scramble` and `maxClicks` is the player's room for error. The closer the two numbers, the harder it gets.
</Tip>

***

## Hex Breach

Pick codes from a grid, alternating between rows and columns, to spell out each target sequence. You only have a few slots to work with, so plan your route.

**Export:** `exports['awoken_minigames']:HexBreach(opts)` - returns `true` only on a win.

| Option            | Default | Notes                                                                                                                                                                                                         |
| ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gridSize`        | `5`     | Code matrix size (`4`-`8`).                                                                                                                                                                                   |
| `sequence`        | `3`     | Length of each daemon (when `daemons` is a count).                                                                                                                                                            |
| `daemons`         | `1`     | Number of target sequences; or an array of lengths, e.g. `{ 3, 3 }`.                                                                                                                                          |
| `requiredDaemons` | *(all)* | How many must be completed (unset = all).                                                                                                                                                                     |
| `bufferSize`      | `5`     | Buffer slots (never fewer than the combined daemon length).                                                                                                                                                   |
| `stages`          | *(1)*   | Run several back-to-back: an integer repeats this config N times, or an array of per-stage overrides (max 10). See [Multi-stage games](/resources/awoken-minigames/configuration/overview#multi-stage-games). |
| `canCancel`       | `true`  |                                                                                                                                                                                                               |
| `autoStart`       | `false` | Shows a "press to start" gate. `true` starts immediately.                                                                                                                                                     |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:HexBreach({ gridSize = 4, daemons = { 2 }, bufferSize = 5 })
-- Standard
exports['awoken_minigames']:HexBreach({ gridSize = 5, daemons = { 3 }, bufferSize = 5 })
-- Hard
exports['awoken_minigames']:HexBreach({ gridSize = 6, daemons = { 5 }, bufferSize = 6 })
-- Dual daemon
exports['awoken_minigames']:HexBreach({ gridSize = 6, daemons = { 3, 3 }, bufferSize = 8 })
-- Triple daemon
exports['awoken_minigames']:HexBreach({ gridSize = 7, daemons = { 2, 3, 4 }, bufferSize = 11 })
```

<Tip>
  Set `daemons` to a list of lengths like `{ 3, 3 }` for two three-code targets. Use `requiredDaemons` to let players win by finishing only some of them.
</Tip>

***

## Code Crack

Crack a hidden code, Mastermind style. After each guess you're told how many symbols are right and how many are in the wrong spot. Work it out before your guesses run out.

**Export:** `exports['awoken_minigames']:CodeCrack(opts)` - returns `true` only on a win.

| Option       | Default | Notes                                                                                                                                                                                                         |
| ------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `codeLength` | `4`     | Digits in the hidden code (`3`-`6`).                                                                                                                                                                          |
| `symbols`    | `6`     | Distinct symbols, 1..symbols (`4`-`9`).                                                                                                                                                                       |
| `maxGuesses` | `8`     | Attempts before failure.                                                                                                                                                                                      |
| `duplicates` | `true`  | Can the code repeat a symbol?                                                                                                                                                                                 |
| `stages`     | *(1)*   | Run several back-to-back: an integer repeats this config N times, or an array of per-stage overrides (max 10). See [Multi-stage games](/resources/awoken-minigames/configuration/overview#multi-stage-games). |
| `canCancel`  | `true`  |                                                                                                                                                                                                               |
| `autoStart`  | `false` | Shows a "press to start" gate. `true` starts immediately.                                                                                                                                                     |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:CodeCrack({ codeLength = 3, symbols = 4, maxGuesses = 8, duplicates = false })
-- Easy
exports['awoken_minigames']:CodeCrack({ codeLength = 4, symbols = 5, maxGuesses = 9, duplicates = false })
-- Standard
exports['awoken_minigames']:CodeCrack({ codeLength = 4, symbols = 6, maxGuesses = 8, duplicates = true })
-- Hard
exports['awoken_minigames']:CodeCrack({ codeLength = 5, symbols = 7, maxGuesses = 8, duplicates = true })
-- Expert
exports['awoken_minigames']:CodeCrack({ codeLength = 5, symbols = 8, maxGuesses = 7, duplicates = true })
```

***

## Fingerprint

Rotate the rings until the scrambled fingerprint lines up with the target. Beat the clock.

**Export:** `exports['awoken_minigames']:Fingerprint(opts)` - returns `true` only on a win.

| Option             | Default | Notes                                                            |
| ------------------ | ------- | ---------------------------------------------------------------- |
| `timeLimit`        | `30000` | Total ms budget (`0` = no limit).                                |
| `showAlignedCount` | `true`  | Show the aligned-rows readout.                                   |
| `canCancel`        | `true`  |                                                                  |
| `autoStart`        | `true`  | Starts immediately. `false` shows a "press to start" gate first. |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:Fingerprint({ timeLimit = 45000 })
-- Standard
exports['awoken_minigames']:Fingerprint({ timeLimit = 30000 })
-- No counter
exports['awoken_minigames']:Fingerprint({ timeLimit = 30000, showAlignedCount = false })
-- Hard
exports['awoken_minigames']:Fingerprint({ timeLimit = 22000, showAlignedCount = false })
-- Expert
exports['awoken_minigames']:Fingerprint({ timeLimit = 16000, showAlignedCount = false })
```

***

## Word Crack

Guess the hidden word, Wordle style. Colours tell you which letters are right and which are in the wrong spot. Get it before your guesses or time run out.

**Export:** `exports['awoken_minigames']:WordCrack(opts)` - returns `true` only on a win.

| Option        | Default  | Notes                                                            |
| ------------- | -------- | ---------------------------------------------------------------- |
| `timeLimit`   | `120000` | Total ms budget (`0` = no limit).                                |
| `wordLength`  | `5`      | Letters in the hidden word (`3`-`8`).                            |
| `maxAttempts` | `6`      | Guesses before lockout.                                          |
| `canCancel`   | `true`   |                                                                  |
| `autoStart`   | `true`   | Starts immediately. `false` shows a "press to start" gate first. |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:WordCrack({ wordLength = 4, maxAttempts = 6, timeLimit = 0 })
-- Standard
exports['awoken_minigames']:WordCrack({ wordLength = 5, maxAttempts = 6, timeLimit = 120000 })
-- Hard
exports['awoken_minigames']:WordCrack({ wordLength = 5, maxAttempts = 5, timeLimit = 90000 })
-- Long word
exports['awoken_minigames']:WordCrack({ wordLength = 6, maxAttempts = 6, timeLimit = 120000 })
-- Blitz
exports['awoken_minigames']:WordCrack({ wordLength = 5, maxAttempts = 6, timeLimit = 45000 })
```

***

## Symbol Search

Click the shown symbols in order inside a grid that keeps reshuffling. Beat the clock.

**Export:** `exports['awoken_minigames']:SymbolSearch(opts)` - returns `true` only on a win.

| Option          | Default     | Notes                                                                                                       |
| --------------- | ----------- | ----------------------------------------------------------------------------------------------------------- |
| `gridSize`      | `8`         | NxN grid (`2`-`12`).                                                                                        |
| `shiftInterval` | `1000`      | Ms between board reshuffles (`0` = never).                                                                  |
| `timeLimit`     | `30000`     | Total ms budget (`0` = no limit).                                                                           |
| `minKeyLength`  | `3`         | Shortest target key (`1`-`6`).                                                                              |
| `maxKeyLength`  | `3`         | Longest target key (`1`-`6`, >= min).                                                                       |
| `symbolType`    | `'symbols'` | One of `'symbols'`, `'letters'`, `'numbers'`, `'emojis'`, `'dots'`.                                         |
| `symbols`       | *(unset)*   | Explicit pool override - an array of strings, e.g. `{ '@', '#', '%' }`. Takes precedence over `symbolType`. |
| `canCancel`     | `true`      |                                                                                                             |
| `autoStart`     | `true`      | Starts immediately. `false` shows a "press to start" gate first.                                            |

```lua Presets theme={"dark"}
-- Letters
exports['awoken_minigames']:SymbolSearch({ gridSize = 8, shiftInterval = 1000, timeLimit = 30000, minKeyLength = 3, maxKeyLength = 3, symbolType = 'letters' })
-- Numbers
exports['awoken_minigames']:SymbolSearch({ gridSize = 8, shiftInterval = 1000, timeLimit = 30000, minKeyLength = 4, maxKeyLength = 4, symbolType = 'numbers' })
-- Symbols
exports['awoken_minigames']:SymbolSearch({ gridSize = 8, shiftInterval = 1000, timeLimit = 30000, minKeyLength = 3, maxKeyLength = 3, symbolType = 'symbols' })
-- Your own symbols
exports['awoken_minigames']:SymbolSearch({ symbols = { '@', '#', '%', '&', '$' } })
```

<Tip>
  Use `symbols` to theme the game to the job: currency signs for a bank hack, chemical symbols for a drug lab. Any list of your own symbols works.
</Tip>

***

## Pipe Pressure

Click pipe tiles to rotate them and connect an unbroken path from the top-left corner to the bottom-right. Beat the clock.

**Export:** `exports['awoken_minigames']:PipePressure(opts)` - returns `true` only on a win.

| Option      | Default | Notes                                                            |
| ----------- | ------- | ---------------------------------------------------------------- |
| `gridSize`  | `6`     | Board is gridSize x gridSize (`3`-`8`).                          |
| `timeLimit` | `30000` | Total ms budget to link source->sink (`0` = no limit).           |
| `canCancel` | `true`  |                                                                  |
| `autoStart` | `true`  | Starts immediately. `false` shows a "press to start" gate first. |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:PipePressure({ gridSize = 4, timeLimit = 0 })
-- Easy
exports['awoken_minigames']:PipePressure({ gridSize = 5, timeLimit = 45000 })
-- Standard
exports['awoken_minigames']:PipePressure({ gridSize = 6, timeLimit = 30000 })
-- Hard
exports['awoken_minigames']:PipePressure({ gridSize = 7, timeLimit = 30000 })
-- Expert
exports['awoken_minigames']:PipePressure({ gridSize = 8, timeLimit = 25000 })
```

***

## Untangle

Drag the points around until none of the lines cross. Clear every crossing to win.

**Export:** `exports['awoken_minigames']:Untangle(opts)` - returns `true` only on a win.

| Option      | Default | Notes                                                            |
| ----------- | ------- | ---------------------------------------------------------------- |
| `nodeCount` | `8`     | Nodes in the graph (`4`-`14`).                                   |
| `timeLimit` | `60000` | Ms to solve (`0` = no limit).                                    |
| `canCancel` | `true`  |                                                                  |
| `autoStart` | `true`  | Starts immediately. `false` shows a "press to start" gate first. |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:Untangle({ nodeCount = 5, timeLimit = 0 })
-- Easy
exports['awoken_minigames']:Untangle({ nodeCount = 6, timeLimit = 90000 })
-- Standard
exports['awoken_minigames']:Untangle({ nodeCount = 8, timeLimit = 60000 })
-- Hard
exports['awoken_minigames']:Untangle({ nodeCount = 10, timeLimit = 50000 })
-- Expert
exports['awoken_minigames']:Untangle({ nodeCount = 12, timeLimit = 45000 })
```

***

## Minefield

Classic Minesweeper. Uncover every safe cell without hitting a mine. The numbers tell you how many mines are next to each cell. Right-click to place a flag.

**Export:** `exports['awoken_minigames']:Minefield(opts)` - returns `true` only on a win.

| Option      | Default | Notes                                                            |
| ----------- | ------- | ---------------------------------------------------------------- |
| `gridSize`  | `9`     | Board is gridSize x gridSize cells (`5`-`16`).                   |
| `mines`     | `10`    | Mines hidden on the board (`1`-`gridSize^2-1`).                  |
| `timeLimit` | `0`     | Ms to clear the field (`0` = no limit).                          |
| `canCancel` | `true`  |                                                                  |
| `autoStart` | `true`  | Starts immediately. `false` shows a "press to start" gate first. |

```lua Presets theme={"dark"}
-- Quick Sweep
exports['awoken_minigames']:Minefield({ gridSize = 6, mines = 6, timeLimit = 45000 })
-- (defaults)
exports['awoken_minigames']:Minefield({})
-- Time Pressure
exports['awoken_minigames']:Minefield({ mines = 12, timeLimit = 90000 })
-- Intermediate
exports['awoken_minigames']:Minefield({ gridSize = 12, mines = 30 })
-- Expert
exports['awoken_minigames']:Minefield({ gridSize = 16, mines = 55 })
```

***

## Jigsaw

Swap tiles two at a time to rebuild the shuffled picture. A small preview shows you the goal.

**Export:** `exports['awoken_minigames']:Jigsaw(opts)` - returns `true` only on a win.

| Option      | Default    | Notes                                                     |
| ----------- | ---------- | --------------------------------------------------------- |
| `gridSize`  | `3`        | Board is gridSize x gridSize tiles (`2`-`4`).             |
| `pattern`   | `'aurora'` | Pattern style: `'aurora'`, `'stripes'` or `'rings'`.      |
| `timeLimit` | `0`        | Ms to solve (`0` = no limit).                             |
| `maxMoves`  | `0`        | Swap cap (`0` = unlimited).                               |
| `canCancel` | `true`     |                                                           |
| `autoStart` | `false`    | Shows a "press to start" gate. `true` starts immediately. |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:Jigsaw({ gridSize = 2 })
-- (defaults)
exports['awoken_minigames']:Jigsaw({})
-- Standard
exports['awoken_minigames']:Jigsaw({ pattern = 'rings', timeLimit = 60000 })
-- Timed
exports['awoken_minigames']:Jigsaw({ pattern = 'stripes', timeLimit = 45000 })
-- Hard
exports['awoken_minigames']:Jigsaw({ gridSize = 4, timeLimit = 90000, maxMoves = 40 })
```

***

## Wires

Drag a wire from each terminal to its matching partner (same letter and colour) on the other side. Wrong connections count against you. Connect every pair before time runs out.

**Export:** `exports['awoken_minigames']:Wires(opts)` - returns `true` only on a win.

| Option            | Default | Notes                                                            |
| ----------------- | ------- | ---------------------------------------------------------------- |
| `pairs`           | `5`     | Terminal pairs to connect (`3`-`8`).                             |
| `mistakesAllowed` | `2`     | Wrong connections tolerated before it shorts out.                |
| `timeLimit`       | `20000` | Ms budget (`0` = no limit).                                      |
| `canCancel`       | `true`  |                                                                  |
| `autoStart`       | `true`  | Starts immediately. `false` shows a "press to start" gate first. |

```lua Presets theme={"dark"}
-- Easy
exports['awoken_minigames']:Wires({ pairs = 3, timeLimit = 30000, mistakesAllowed = 3 })
-- Standard (defaults)
exports['awoken_minigames']:Wires({})
-- Hard
exports['awoken_minigames']:Wires({ pairs = 7, timeLimit = 18000, mistakesAllowed = 1 })
-- Expert
exports['awoken_minigames']:Wires({ pairs = 8, timeLimit = 15000, mistakesAllowed = 0 })
-- Untimed
exports['awoken_minigames']:Wires({ pairs = 6, timeLimit = 0 })
```

***

## Tower of Hanoi

Move the stack of disks to the far peg, one disk at a time, and never put a bigger disk on a smaller one. More disks means a much harder puzzle.

**Export:** `exports['awoken_minigames']:TowerOfHanoi(opts)` - returns `true` only on a win.

| Option          | Default  | Notes                                                                                   |
| --------------- | -------- | --------------------------------------------------------------------------------------- |
| `disks`         | `4`      | Disks to move (`3`-`7`); minimum solve is `2^disks - 1` moves (3=7, 4=15, 5=31, 7=127). |
| `timeLimit`     | `120000` | Ms to solve it (`0` = no limit).                                                        |
| `moveAllowance` | `0`      | Extra moves allowed above the optimum (`0` = unlimited); `8` on 4 disks means 23 moves. |
| `canCancel`     | `true`   |                                                                                         |
| `autoStart`     | `false`  | Shows a "press to start" gate. `true` starts immediately.                               |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:TowerOfHanoi({ disks = 3, timeLimit = 0 })
-- Standard (defaults)
exports['awoken_minigames']:TowerOfHanoi({})
-- Hard
exports['awoken_minigames']:TowerOfHanoi({ disks = 5, timeLimit = 150000 })
-- Efficient
exports['awoken_minigames']:TowerOfHanoi({ disks = 4, moveAllowance = 8 })
-- Expert
exports['awoken_minigames']:TowerOfHanoi({ disks = 6, timeLimit = 240000 })
```

<Info>
  An illegal move is simply refused and costs nothing. RESET restacks the disks but keeps your move count and clock running, so it's a recovery, not a fresh start.
</Info>

***

## Math Rush

Two sums sit side by side. Say whether the left one is bigger, smaller, or equal to the right: Up for bigger, Down for smaller, Space for equal, or just click. Keep up across a run of quick rounds.

**Export:** `exports['awoken_minigames']:MathRush(opts)` - returns `true` only on a win.

| Option            | Default             | Notes                                                                              |
| ----------------- | ------------------- | ---------------------------------------------------------------------------------- |
| `rounds`          | `5`                 | Correct answers to win (`1`-`20`).                                                 |
| `timeLimit`       | `8000`              | Per-question answer window in ms (`0` = no limit); running it out costs a mistake. |
| `mistakesAllowed` | `1`                 | Wrong or lapsed answers tolerated; `0` = the first one ends the run.               |
| `operators`       | `{ '+', '-', '*' }` | Any of `+` `-` `*` `/`; division only ever generates exact whole-number results.   |
| `maxValue`        | `25`                | Ceiling for any operand or result (`5`-`99`).                                      |
| `maxDifference`   | `5`                 | Largest gap allowed between the two sides.                                         |
| `canCancel`       | `true`              |                                                                                    |
| `autoStart`       | `false`             | Shows a "press to start" gate. `true` starts immediately.                          |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:MathRush({ rounds = 3, operators = { '+', '-' }, maxValue = 15, timeLimit = 0 })
-- Standard (defaults)
exports['awoken_minigames']:MathRush({})
-- Hard
exports['awoken_minigames']:MathRush({ rounds = 7, operators = { '+', '-', '*', '/' }, maxDifference = 3, timeLimit = 6000 })
-- Expert
exports['awoken_minigames']:MathRush({ rounds = 8, maxDifference = 2, timeLimit = 5000, mistakesAllowed = 0 })
-- Times tables
exports['awoken_minigames']:MathRush({ rounds = 6, operators = { '*' }, maxValue = 80, timeLimit = 10000 })
```

<Tip>
  `maxDifference` sets how close the two sides are. A smaller gap is harder, since players can't tell at a glance which side wins.
</Tip>

***

## 2048

The sliding-tile classic. Arrows or WASD push every tile as far as it goes, matching tiles merge into one, and each move adds a new tile. Reach the target tile before the board fills up or time runs out.

**Export:** `exports['awoken_minigames']:Twenty48(opts)` - returns `true` only on a win.

| Option       | Default | Notes                                                                                     |
| ------------ | ------- | ----------------------------------------------------------------------------------------- |
| `boardSize`  | `4`     | Board is boardSize x boardSize (`3`-`6`).                                                 |
| `targetTile` | `128`   | Tile value that wins; a power of two (`8`-`2048`). A non-power is snapped to the nearest. |
| `timeLimit`  | `90000` | Ms to reach it (`0` = no limit).                                                          |
| `fourChance` | `0.15`  | Chance a spawned tile is a `4` rather than a `2` (`0`-`0.5`).                             |
| `canCancel`  | `true`  |                                                                                           |
| `autoStart`  | `false` | Shows a "press to start" gate. `true` starts immediately.                                 |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:Twenty48({ boardSize = 3, targetTile = 32, timeLimit = 0 })
-- Standard (defaults)
exports['awoken_minigames']:Twenty48({})
-- Hard
exports['awoken_minigames']:Twenty48({ targetTile = 256, timeLimit = 120000 })
-- Expert
exports['awoken_minigames']:Twenty48({ boardSize = 5, targetTile = 512, timeLimit = 180000 })
-- Bigger board
exports['awoken_minigames']:Twenty48({ boardSize = 6, targetTile = 256, timeLimit = 0 })
```

***

## Splice

Move a slow scanner along the tangled cables to find which ones are live, then switch to the cutters and cut each live cable at its faulty spot. Beat the clock.

**Export:** `exports['awoken_minigames']:Splice(opts)` - returns `true` only on a win.

| Option            | Default | Notes                                                                                                                       |
| ----------------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `cables`          | `8`     | Cables in the loom (`4`-`12`); routed across each other, so a cable can only be followed by tracing it.                     |
| `liveCables`      | `3`     | How many are live and must be cut (`1`-`6`, always fewer than `cables`).                                                    |
| `scanRadius`      | `28`    | Scanner radius in px (`12`-`90`); keep it under the row pitch (`294/cables`) or one placement reads several cables at once. |
| `maxScanSpeed`    | `260`   | Px/s the scanner may move and still read; sweep faster and it goes inert.                                                   |
| `faultTolerance`  | `16`    | How close to a live cable's fault a cut must land, in px along the cable (`6`-`40`).                                        |
| `mistakesAllowed` | `1`     | Bad cuts tolerated: a dead cable, or a live one cut away from its fault.                                                    |
| `timeLimit`       | `75000` | Ms budget (`0` = no limit).                                                                                                 |
| `canCancel`       | `true`  |                                                                                                                             |
| `autoStart`       | `false` | Shows a "press to start" gate. `true` starts immediately.                                                                   |

```lua Presets theme={"dark"}
-- Easy
exports['awoken_minigames']:Splice({ cables = 5, liveCables = 1, faultTolerance = 24, timeLimit = 90000 })
-- Standard (defaults)
exports['awoken_minigames']:Splice({})
-- Hard
exports['awoken_minigames']:Splice({ cables = 10, liveCables = 4, faultTolerance = 12, timeLimit = 60000 })
-- Expert
exports['awoken_minigames']:Splice({ cables = 12, liveCables = 6, faultTolerance = 8, mistakesAllowed = 0 })
```

<Tip>
  Keep `scanRadius` small (under `294/cables`), or the scanner reads several cables at once and the game loses its point.
</Tip>

***

## Current

Flip the right breaker switches so the total power lands close enough to the target, then press ENGAGE. Some switches, when on, change how much another one adds, so it takes some thought.

**Export:** `exports['awoken_minigames']:Current(opts)` - returns `true` only on a win.

| Option            | Default | Notes                                                                                                                             |
| ----------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `switches`        | `5`     | Breaker switches on the panel (`3`-`8`).                                                                                          |
| `target`          | `60`    | Load to reach, in amps. The ratings are derived from it, so it's always reachable.                                                |
| `tolerance`       | `2`     | How close the load must be, in amps.                                                                                              |
| `interference`    | `2`     | Switches that change another's contribution when on (`0`-`4`); this is what makes it a constraint puzzle rather than a sum grind. |
| `mistakesAllowed` | `1`     | Bad ENGAGE commits tolerated before failing.                                                                                      |
| `timeLimit`       | `60000` | Ms budget (`0` = no limit).                                                                                                       |
| `canCancel`       | `true`  |                                                                                                                                   |
| `autoStart`       | `false` | Shows a "press to start" gate. `true` starts immediately.                                                                         |

```lua Presets theme={"dark"}
-- Easy
exports['awoken_minigames']:Current({ switches = 3, interference = 0, tolerance = 3, timeLimit = 90000 })
-- Standard (defaults)
exports['awoken_minigames']:Current({})
-- Hard
exports['awoken_minigames']:Current({ switches = 7, interference = 3, tolerance = 1, timeLimit = 45000 })
-- Expert
exports['awoken_minigames']:Current({ switches = 8, interference = 4, tolerance = 0, mistakesAllowed = 0 })
```

<Tip>
  `interference` is the heart of the puzzle. At `0` it's just adding up numbers. Each interfering switch changes another switch's value, and the panel shows you how, so it can be worked out.
</Tip>

***

## Data Stream

Two steps per packet: pick the right packet out of a stream of look-alike decoys, then decode the scrambled message it carries. Clear every packet before you run out of tries or time.

**Export:** `exports['awoken_minigames']:DataStream(opts)` - returns `true` only on a win.

| Option            | Default                                     | Notes                                                                                                                                                                                            |
| ----------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `packets`         | `3`                                         | Packets to capture and decrypt to win (`1`-`8`).                                                                                                                                                 |
| `decoys`          | `4`                                         | Decoys alongside each target (`0`-`24`); their IDs are near-misses of the target's, so this is a reading task.                                                                                   |
| `packetSpeed`     | `70`                                        | Packet scroll speed, px/s (`20`-`600`).                                                                                                                                                          |
| `wordLength`      | `5`                                         | Max letters in the hidden plaintext (`3`-`8`).                                                                                                                                                   |
| `mistakesAllowed` | `2`                                         | Wrong captures / wrong decrypts tolerated.                                                                                                                                                       |
| `timeLimit`       | `120000`                                    | Ms across BOTH phases (`0` = no limit).                                                                                                                                                          |
| `ciphers`         | `{ 'atbash', 'a1z26', 'caesarPositional' }` | Pool one cipher is drawn from per captured packet. One of `'atbash'`, `'caesarPositional'`, `'a1z26'`, `'hexAscii'`, `'morse'`, `'binary'`. An empty or unrecognised list falls back to all six. |
| `canCancel`       | `true`                                      |                                                                                                                                                                                                  |
| `autoStart`       | `false`                                     | Shows a "press to start" gate. `true` starts immediately.                                                                                                                                        |

```lua Presets theme={"dark"}
-- Easy
exports['awoken_minigames']:DataStream({ packets = 1, decoys = 2, ciphers = { 'atbash', 'a1z26' }, timeLimit = 0 })
-- Standard (defaults)
exports['awoken_minigames']:DataStream({})
-- Hard
exports['awoken_minigames']:DataStream({ packets = 4, decoys = 6, ciphers = { 'atbash', 'caesarPositional', 'a1z26', 'hexAscii', 'morse', 'binary' }, timeLimit = 90000 })
-- Expert
exports['awoken_minigames']:DataStream({ packets = 5, decoys = 8, ciphers = { 'caesarPositional', 'hexAscii', 'binary' }, mistakesAllowed = 1 })
```

<Info>
  The ciphers vary in difficulty, so pick the list to match the challenge you want. `atbash` is the easiest and `caesarPositional` the hardest. The rule is always on screen, and TAB opens a reference chart.
</Info>

***

## Collapse

Click any cube that touches another of the same colour to clear the whole group. The rest fall down and empty columns slide over. A cube on its own can't be cleared. Clear the board to win.

**Export:** `exports['awoken_minigames']:Collapse(opts)` - returns `true` only on a win.

| Option          | Default | Notes                                                                                               |
| --------------- | ------- | --------------------------------------------------------------------------------------------------- |
| `cols`          | `8`     | Board columns (`5`-`12`).                                                                           |
| `rows`          | `6`     | Board rows (`4`-`10`).                                                                              |
| `colours`       | `3`     | Distinct colours (`2`-`5`); use `3`+, since at `2` every group is a vertical bar and it plays flat. |
| `timeLimit`     | `60000` | Ms to clear the board (`0` = no limit).                                                             |
| `moveAllowance` | `0`     | Extra clicks above par (`0` = unlimited); par is a real achievable solve length, not an estimate.   |
| `canCancel`     | `true`  |                                                                                                     |
| `autoStart`     | `false` | Shows a "press to start" gate. `true` starts immediately.                                           |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:Collapse({ cols = 6, rows = 4, timeLimit = 0 })
-- Standard (defaults)
exports['awoken_minigames']:Collapse({})
-- Hard
exports['awoken_minigames']:Collapse({ cols = 10, rows = 7, colours = 4 })
-- Expert
exports['awoken_minigames']:Collapse({ cols = 12, rows = 8, colours = 5, timeLimit = 90000 })
-- Par + 3
exports['awoken_minigames']:Collapse({ moveAllowance = 3 })
```

<Info>
  Every board is always fully solvable, and "par" is a real solve length, not a guess. Use `moveAllowance` to ask for a near-perfect solve.
</Info>

***

## Arrow Maze

A hidden path runs through the grid. Each cell shows a few arrows, and only one keeps you on the path. Click an arrow in your current cell. A wrong one costs a mistake. Reach the far end to win.

**Export:** `exports['awoken_minigames']:ArrowMaze(opts)` - returns `true` only on a win.

| Option            | Default | Notes                                                                                          |
| ----------------- | ------- | ---------------------------------------------------------------------------------------------- |
| `size`            | `6`     | Grid is size x size (`4`-`8`).                                                                 |
| `decoys`          | `2`     | Wrong arrows per cell alongside the right one (`1`-`3`).                                       |
| `hardMode`        | `false` | Bias decoys onto a narrow set of headings picked once per run, so they can't be reasoned away. |
| `timeLimit`       | `45000` | Ms to reach the far end (`0` = no limit).                                                      |
| `mistakesAllowed` | `3`     | Wrong arrows tolerated before failing.                                                         |
| `canCancel`       | `true`  |                                                                                                |
| `autoStart`       | `false` | Shows a "press to start" gate. `true` starts immediately.                                      |

```lua Presets theme={"dark"}
-- Tutorial
exports['awoken_minigames']:ArrowMaze({ size = 4, decoys = 1, timeLimit = 0 })
-- Standard (defaults)
exports['awoken_minigames']:ArrowMaze({})
-- Hard
exports['awoken_minigames']:ArrowMaze({ size = 7, decoys = 3, hardMode = true })
-- Expert
exports['awoken_minigames']:ArrowMaze({ size = 8, decoys = 3, hardMode = true, mistakesAllowed = 1 })
```
