<!-- Source: https://medius.k4tech.net/native/commands/option -->
# Option

_Set a persistent box option by id_

One command (opcode `0x11`) sets every box-level toggle: an `id` byte picks the option, the rest is its value. All persist in NVS, restore at boot, and are [fire-and-forget](/native/injection.md#fire-and-forget). An unknown id is ignored.

| Option | `id` | Value | Does | Default |
| --- | --- | --- | --- | --- |
| [`IMPERFECT`](/native/commands/option.md#imperfect) | `0` | `[allow u8]` | Clone an over-capacity device anyway | off |
| [`MOVE_RIDE`](/native/commands/option.md#move-ride) | `1` | `[timeout u16 LE]` | Inject motion only on a real move | off |
| [`EMIT`](/native/commands/option.md#emit) | `2` | `[mode u8][rate_hz u16 LE]` | Pick what paces injected motion | learnt |
| [`NAME`](/native/commands/option.md#name) | `3` | `[name ascii 0..32]` | Give the box a human-readable name | Medius-XXXX |

## OPTION

_One generic, persistent option_

`OPTION` carries an `id` byte then an id-specific value, and the box persists the setting across a reboot. One opcode covers every persistent option; the id picks which. [Opcode](/native/frame.md#opcodes) `0x11`.

```text
OPTION 0x11 · payload 1 + value bytes
```

_Fire-and-forget_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `id` | `u8` | which option |
| 1.. | `value` | `varies` | id-specific; the frame `LEN` delimits it, so a new option needs no new opcode |

No reply. Read any value back with [`QUERY(OPTIONS, id)`](/native/commands/requests.md#options).

## IMPERFECT

_Clone an over-capacity device anyway_

```text
id 0 · [allow u8]
```

#### ALLOW

| Value | Effect |
| --- | --- |
| `0` | Faithful-only: refuse a device the box can't clone exactly _(default)_ |
| `1` | Clone it anyway: every other interface byte-faithful, the over-capacity one dead |

> **Note**
>
> Some devices need more interrupt-IN endpoints than the box serves (the Wooting Two HE's analog stream wants a sixth, past the [ESP32](https://www.espressif.com/en/products/socs)\-S3's five). Changing this for an _attached_ over-capacity device reboots the box to re-clone; a normal device is unaffected.

Read [`QUERY(OPTIONS, 0)`](/native/commands/requests.md#options) (opt-in plus the over-capacity and imperfect-clone flags) · Library [`allow_imperfect_clones`](/library/options.md#allow-imperfect-clones).

#### EXAMPLE

Opt in (`allow = 1`):

```
+--------+--------+--------+--------+--------+--------+--------+
| A5     | 11     | 00     | 02 00  | 00     | 01     | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | id     | allow  | CRC16  |
+--------+--------+--------+--------+--------+--------+--------+
```

## MOVE_RIDE

_Inject motion only on a real move_

```text
id 1 · [timeout u16 LE] ms
```

#### TIMEOUT

| Value | Effect |
| --- | --- |
| `0` | Off: injection emits via the frame clock _(default)_ |
| `N` ms | Injected cursor and wheel motion only rides a native move seen within `N` ms; no synthetic motion frame, and motion left unridden is dropped (never dumped on the next move) |

This keeps injected motion's report density identical to the real mouse's, erasing the density tell (a human aims at ~270-360 Hz, idle 60-70% of the time; gap-filling injection runs gapless near 990 Hz).

> **Warning**
>
> While on, pure idle injection (moving the cursor while the hand is still) stops working: motion waits for a native move and is dropped if none comes. Button, key, and media injection are unaffected.

Read [`QUERY(OPTIONS, 1)`](/native/commands/requests.md#options) · Library [`set_movement_riding`](/library/options.md#set-movement-riding).

#### EXAMPLE

Turn it on with a 20 ms window (`timeout = 0x0014`):

```
+--------+--------+--------+--------+--------+--------+--------+
| A5     | 11     | 00     | 03 00  | 01     | 14 00  | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | id     | timeout| CRC16  |
+--------+--------+--------+--------+--------+--------+--------+
```

## EMIT

_Pick what paces injected motion_

```text
id 2 · [mode u8][rate_hz u16 LE]
```

#### MODE

| `mode` | Name | `rate_hz` | Emit paced to |
| --- | --- | --- | --- |
| `0` | Learnt _(default)_ | n/a | The rate the real mouse actually reports at |
| `1` | Interval | n/a | The cloned mouse's declared poll rate (its `bInterval`) |
| `2` | Fixed | target Hz | `rate_hz`, snapped to `1000/n` |

> **Note**
>
> Fixed snaps to `1000/n` Hz on the 1 ms frame clock and caps at 1 kHz, so 1000, 500, 333, 250… are exact and 750 lands on 1000 (`0` means 1000). Every mode raises the ceiling only: the box still emits a frame solely when injection is pending, so idle stays idle. Learnt keeps injection matched to the real mouse; the other modes are for a host that shapes its own report density and wants the box to stop re-pacing it.

Read [`QUERY(OPTIONS, 2)`](/native/commands/requests.md#options) (mode plus the rate in effect) · Library [`set_emit_pace`](/library/options.md#set-emit-pace).

#### EXAMPLE

Fixed 1 kHz (`mode = 2`, `rate_hz = 0x03E8`):

```
+--------+--------+--------+--------+--------+--------+--------+--------+
| A5     | 11     | 00     | 04 00  | 02     | 02     | E8 03  | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | id     | mode   | rate_hz| CRC16  |
+--------+--------+--------+--------+--------+--------+--------+--------+
```

## NAME

_Give the box a human-readable name_

```text
id 3 · [name ascii 1..32] (0 bytes = clear)
```

#### VALUE

| Bytes | Effect |
| --- | --- |
| `1..32` printable ASCII | Sets the box's name to those bytes. |
| `0` (the `id` alone) | Clears the name, reverting to the synthesized `Medius-XXXX` default derived from the MAC. |

> **Note**
>
> The name is the readable partner to the box [MAC](/native/commands/requests.md#version), persisted in NVS with no reboot. It rides on [`RESP(VERSION)`](/native/commands/requests.md#version) as the ASCII tail after the MAC, so it's read there, not through [`QUERY(OPTIONS)`](/native/commands/requests.md#options).

Read it back on [`RESP(VERSION)`](/native/commands/requests.md#version) · Library [`set_name`](/library/options.md#set-name).

#### EXAMPLE

Name the box "Loki" (`id = 3`, ascii `4C 6F 6B 69`):

```
+--------+--------+--------+--------+--------+--------------+--------+
| A5     | 11     | 00     | 05 00  | 03     | 4C 6F 6B 69  | lo hi  |
+--------+--------+--------+--------+--------+--------------+--------+
| SOF    | TYPE   | SEQ    | LEN    | id     | name ascii   | CRC16  |
+--------+--------+--------+--------+--------+--------------+--------+
```
