> For the complete documentation index, see [llms.txt](https://sbscripts.gitbook.io/sb-scripts/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sbscripts.gitbook.io/sb-scripts/sb-minigames/games-timing.md).

# Games: Timing

### StopBar

A bar bounces along a track. Press `Space` to stop it **inside the zone**. Each round the zone moves and gets about 12 percent narrower. One miss fails the game.

**Controls:** `Space`

```lua
exports['sbminigames']:StopBar({ speed = 220, zones = 4, zoneWidth = 12 }, cb)
```

Positional: `StopBar(speed, zones, zoneWidth, time, callback)`

| Option      | Type | Default | Range     | What it does                                     |
| ----------- | ---- | ------- | --------- | ------------------------------------------------ |
| `speed`     | int  | `180`   | 50 to 400 | Bar speed in pixels per second (track is 340 px) |
| `zones`     | int  | `3`     | 1 to 5    | Rounds to win                                    |
| `zoneWidth` | int  | `15`    | 4 to 35   | First-round zone width, percent of the track     |
| `time`      | int  | `0`     | 0 to 600  | Seconds before failing (`0` = no limit)          |

### Quickdraw

The screen says *Wait*. After a random delay it says **Draw**. React as fast as you can. Pressing early fails instantly, and so does reacting slower than the threshold.

**Controls:** `Space` or click

```lua
exports['sbminigames']:Quickdraw({ maxDelay = 2500, threshold = 350 }, cb)
```

Positional: `Quickdraw(maxDelay, threshold, callback)`

| Option      | Type | Default | Range        | What it does                              |
| ----------- | ---- | ------- | ------------ | ----------------------------------------- |
| `maxDelay`  | int  | `3000`  | 1000 to 4000 | Longest wait before Draw, in milliseconds |
| `threshold` | int  | `400`   | 100 to 700   | Slowest passing reaction, in milliseconds |

### SafeCracker

A needle sweeps around a dial. Press `Space` when it's inside the arc to set a tumbler. After each tumbler the needle reverses, speeds up, and the arc shrinks. Misses cost a try.

**Controls:** `Space`

```lua
exports['sbminigames']:SafeCracker({ tumblers = 4, speed = 2.5, lives = 2 }, cb)
```

Positional: `SafeCracker(tumblers, speed, time, callback)`

| Option     | Type  | Default | Range    | What it does                            |
| ---------- | ----- | ------- | -------- | --------------------------------------- |
| `tumblers` | int   | `3`     | 2 to 5   | Tumblers to set                         |
| `speed`    | float | `2`     | 1 to 4   | Needle speed multiplier                 |
| `lives`    | int   | `3`     | 1 to 6   | Misses allowed                          |
| `time`     | int   | `0`     | 0 to 600 | Seconds before failing (`0` = no limit) |

### Lockpick

Rotate the pick with `A` and `D`, and hold `Space` to turn the lock. The closer the pick is to the hidden sweet spot, the further the lock turns. At the sweet spot the pin sets. Stall too long and the pick snaps.

**Controls:** `A` `D` or the arrow keys to rotate, hold `Space` to turn

```lua
exports['sbminigames']:Lockpick({ pins = 5, picks = 2, tolerance = 6, time = 40 }, cb)
```

Positional: `Lockpick(pins, time, callback)`

| Option      | Type | Default | Range    | What it does                                  |
| ----------- | ---- | ------- | -------- | --------------------------------------------- |
| `pins`      | int  | `4`     | 2 to 6   | Pins to set                                   |
| `picks`     | int  | `3`     | 1 to 6   | Picks you can break before failing            |
| `tolerance` | int  | `8`     | 3 to 15  | Sweet-spot size in degrees (bigger is easier) |
| `time`      | int  | `25`    | 0 to 600 | Seconds before failing (`0` = no limit)       |

### Voltage

An arc sweeps back and forth over numbered nodes. Press `Space` when it's over the highlighted node. Nodes must be charged in order, and misses cost a try.

**Controls:** `Space`

```lua
exports['sbminigames']:Voltage({ nodes = 4, speed = 2.5 }, cb)
```

Positional: `Voltage(nodes, speed, time, callback)`

| Option  | Type  | Default | Range    | What it does                            |
| ------- | ----- | ------- | -------- | --------------------------------------- |
| `nodes` | int   | `3`     | 2 to 6   | Nodes to charge                         |
| `speed` | float | `2`     | 1 to 4   | Arc speed multiplier                    |
| `lives` | int   | `3`     | 1 to 6   | Misses allowed                          |
| `time`  | int   | `0`     | 0 to 600 | Seconds before failing (`0` = no limit) |

### Balance

A marker drifts left and right. Push it back with `A` and `D` to keep it **inside the zone**. The meter fills while you're inside and drains faster outside. Touch either edge and you fail.

**Controls:** `A` `D` or the arrow keys

```lua
exports['sbminigames']:Balance({ duration = 10, drift = 1.6, zone = 35 }, cb)
```

Positional: `Balance(duration, drift, callback)`

| Option     | Type  | Default | Range    | What it does                            |
| ---------- | ----- | ------- | -------- | --------------------------------------- |
| `duration` | int   | `8`     | 3 to 20  | Seconds you must stay in the zone       |
| `drift`    | float | `1.2`   | 0.5 to 3 | How hard the marker drifts              |
| `zone`     | int   | `40`    | 20 to 70 | Zone width, percent of the track        |
| `time`     | int   | `0`     | 0 to 600 | Seconds before failing (`0` = no limit) |
