|
| 1 | +# Buttplug |
| 2 | + |
| 3 | +A framework for interfacing with intimate hardware devices using a client-server architecture. Clients send abstract commands (vibrate, rotate, etc.) and servers translate them into device-specific protocols over various communication buses. |
| 4 | + |
| 5 | +## Language |
| 6 | + |
| 7 | +**Protocol** (Device Protocol): |
| 8 | +The vendor- or product-specific command set used to control a particular device (e.g. Lovense, Kiiroo, WeVibe). Implemented as a `ProtocolHandler`. When unqualified, "protocol" means this. |
| 9 | +_Avoid_: Using "protocol" alone when referring to the Buttplug spec version or the communication bus. |
| 10 | + |
| 11 | +**Buttplug Protocol** (Spec Version): |
| 12 | +The versioned JSON message format (v0–v4) used for client-server communication. Negotiated during handshake. Referred to in code as `ButtplugMessageSpecVersion`. |
| 13 | +_Avoid_: "Protocol" without the "Buttplug" prefix when referring to this. |
| 14 | + |
| 15 | +**Connector**: |
| 16 | +The link between a **Client** and a **Server**. Encapsulates two concerns: the communication bus (WebSocket, direct/in-process, stdio, network) and the serialization format (JSON, CBOR, XML — anything serde can handle). |
| 17 | +_Avoid_: "Transport" (not a domain term in buttplug). |
| 18 | + |
| 19 | +**Hardware Manager**: |
| 20 | +A component that discovers and communicates with devices over a specific communication bus — Bluetooth LE, HID, Serial, USB, etc. Each bus has its own manager implementation (`HardwareCommunicationManager` trait). Named by bus: `btleplug` (BLE), `serial`, `hid`, `xinput`, etc. |
| 21 | +_Avoid_: "Transport" when referring to hardware communication. |
| 22 | + |
| 23 | +**Client**: |
| 24 | +The consumer of the buttplug API. Sends abstract commands (vibrate at 50%, rotate clockwise), receives device lists and events. Never communicates with hardware directly — always goes through a **Server** via a **Connector**. |
| 25 | +_Avoid_: Conflating with HTTP or network clients. |
| 26 | + |
| 27 | +**Server**: |
| 28 | +The device management engine. Receives abstract commands from a **Client**, manages **Hardware Managers**, matches discovered hardware to **Protocols**, and translates commands into device-specific operations. Owns the entire device lifecycle. Can run in a separate process or embedded in-process with the client. |
| 29 | +_Avoid_: Conflating with web servers or HTTP servers. |
| 30 | + |
| 31 | +**Device**: |
| 32 | +The abstract thing a user controls — a collection of features and capabilities. In client context, a `ButtplugClientDevice`; in server context, a managed entry in `ServerDeviceManager` wrapping a protocol handler and hardware. The unqualified term refers to the concept, not a specific layer. |
| 33 | +_Avoid_: Using "device" when specifically meaning the physical communication channel (use **Hardware**) or the static capability description (use **Device Definition**). |
| 34 | + |
| 35 | +**Hardware**: |
| 36 | +The physical or simulated communication channel to an actual thing. Represented by the `Hardware` struct, which wraps bus-specific I/O behind a common interface. Created and managed by a **Hardware Manager**. |
| 37 | +_Avoid_: "Device" when referring specifically to the communication layer. |
| 38 | + |
| 39 | +**Device Definition**: |
| 40 | +The static description of what a device model supports — features, endpoints, display name. `BaseDeviceDefinition` in config files, `ServerDeviceDefinition` at runtime. |
| 41 | +_Avoid_: "Device config" (ambiguous with user configuration). |
| 42 | + |
| 43 | +**Feature**: |
| 44 | +A discrete capability of a **Device**, identified by `feature_index`. A feature can have an **Output**, an **Input**, or both — grouping a related actuator and sensor together (e.g. a motor with an encoder). Represented by `DeviceFeature`. |
| 45 | +_Avoid_: "Actuator" or "sensor" as top-level terms; use Output and Input. |
| 46 | + |
| 47 | +**Output**: |
| 48 | +The actuator side of a **Feature** — something that makes the device do something physical. Types include Vibrate, Rotate, Oscillate, Constrict, Temperature, Led, Position, Spray. |
| 49 | +_Avoid_: "Actuator" (used historically but Output is canonical). |
| 50 | + |
| 51 | +**Input**: |
| 52 | +The sensor side of a **Feature** — something that reports a value from the device. Types include Battery, Rssi, Button, Pressure, Depth, Position. |
| 53 | +_Avoid_: "Sensor" (used historically but Input is canonical). |
| 54 | + |
| 55 | +**Specifier**: |
| 56 | +A description of how to detect a device on a given communication bus — BLE service UUIDs, HID vendor/product IDs, serial port patterns, etc. Tells the system what to look for during scanning. Represented by `ProtocolCommunicationSpecifier` variants. |
| 57 | +_Avoid_: "Identifier" when referring to detection criteria. |
| 58 | + |
| 59 | +**Device Identifier**: |
| 60 | +The fingerprint of a discovered device — protocol name, optional model/variant string, and address. Ranges from general (model-level `BaseDeviceIdentifier`) to specific (instance-level `UserDeviceIdentifier` with a unique address). The identification pipeline narrows from **Specifier** (what to look for) → discovery → **Device Identifier** (what we found). |
| 61 | +_Avoid_: "Specifier" when referring to a matched/discovered device. |
| 62 | + |
| 63 | +**Endpoint**: |
| 64 | +A communication channel on a piece of **Hardware** — the target for reads and writes. Borrowed from USB terminology. Named variants (`Tx`, `Rx`, `Command`, `Firmware`, `TxVibrate`) cover common uses; `Generic0`–`Generic31` cover protocols that don't fit named slots. |
| 65 | +_Avoid_: Conflating with API or network endpoints. |
| 66 | + |
| 67 | +**Intiface**: |
| 68 | +The user-facing brand for the buttplug ecosystem. Exists because "Buttplug" can't go on app stores. Buttplug is the library (embedded in applications); Intiface is anything user-facing built on top of it. |
| 69 | +_Avoid_: Using "Buttplug" when referring to user-facing products or applications. |
| 70 | + |
| 71 | +**Intiface Engine**: |
| 72 | +The bridge between the buttplug library and external frontends. Wraps a **Server** with connector support, CLI options, and frontend message broadcasting. Where "library" becomes "runnable service." Lives in this repo as the `intiface_engine` crate. |
| 73 | +_Avoid_: Conflating with Intiface Central (the GUI, separate repo). |
| 74 | + |
| 75 | +**Simulated Device**: |
| 76 | +A virtual **Device** that runs the full device lifecycle without real hardware. Configured in **User Configuration** by referencing an archetype (e.g. simulated-1vibe, simulated-rotator). User-facing feature for testing and development of applications built on buttplug — not just internal test infrastructure. Combined with **Output Observations**, lets developers see exactly what their application would do with real hardware. |
| 77 | +_Avoid_: "Mock device" (simulated devices run through the real device lifecycle, not a mock). |
| 78 | + |
| 79 | +**Device Configuration**: |
| 80 | +The built-in database of known devices — what protocols exist, what specifiers identify them, what features they support. Ships with buttplug, sourced from YAML files in `buttplug_server_device_config`. |
| 81 | +_Avoid_: "Device config" without qualification (ambiguous with **User Configuration**). |
| 82 | + |
| 83 | +**User Configuration**: |
| 84 | +User-supplied overrides layered on top of **Device Configuration** — display names, feature allows/denies, simulated device entries. Represented by `UserConfigDefinition`. |
| 85 | +_Avoid_: "Device config" when referring to user overrides. |
| 86 | + |
| 87 | +**Scanning**: |
| 88 | +The process of **Hardware Managers** searching their communication buses for devices. Triggered by the client via `StartScanning`. When hardware is found, identification happens immediately — each **Protocol**'s **Specifiers** determine both "we can talk to this" and "this device uses this protocol" in a single step. |
| 89 | +_Avoid_: "Discovery" as a distinct stage from identification — they're the same step. |
| 90 | + |
| 91 | +**Output Observation**: |
| 92 | +An opt-in broadcast of every output command sent to a **Device** — device index, feature index, output type, and value. Used by frontends (e.g. Intiface Central) to visually display real-time device activity, verify hardware behaviour matches commands, and let developers see what *would* happen with simulated devices. Disabled by default to avoid overhead. |
| 93 | +_Avoid_: Treating as internal-only debugging; it's a user-facing observability feature. |
| 94 | + |
| 95 | +**Command**: |
| 96 | +A message from **Client** to **Server** requesting an action — controlling a device, starting a scan, requesting device lists. Always has a non-zero message ID; the server responds with an `Ok` or `Error` using the same ID. |
| 97 | +_Avoid_: Referring to server-initiated messages as commands. |
| 98 | + |
| 99 | +**Event**: |
| 100 | +A message from **Server** to **Client** that the client didn't explicitly request — device added/removed, scanning finished, input readings from subscribed sensors. Always has message ID `0`. |
| 101 | +_Avoid_: "Notification" (not used in the spec). |
| 102 | + |
| 103 | +**Device Lifecycle**: |
| 104 | +The stages a device moves through: Scanning → Identification → Connection → Configuration → Operation. Identification and protocol matching are a single step — a device is identified *via* its protocol's specifiers. |
| 105 | + |
| 106 | +## Example Dialogue |
| 107 | + |
| 108 | +> **Dev**: A user says their device isn't showing up. Where do I start? |
| 109 | +> |
| 110 | +> **Domain expert**: First check which **Hardware Manager** covers their communication bus — if it's BLE, that's the btleplug manager. Is **Scanning** even finding the hardware? If so, the **Specifiers** for that **Protocol** might not match the device's advertisement data. Check the **Device Configuration** for the protocol's BLE specifier — service UUIDs, manufacturer data patterns. |
| 111 | +> |
| 112 | +> **Dev**: It shows up but all the **Features** are wrong — it's showing two **Outputs** but the device only vibrates. |
| 113 | +> |
| 114 | +> **Domain expert**: That's a **Device Definition** issue. The protocol's base definition might be wrong, or the user's **User Configuration** could be overriding it. Check the YAML in `buttplug_server_device_config` first, then see if there's a user config layered on top. Also check whether the **Device Identifier** is matching the right variant — some protocols have multiple identifier strings for different models. |
| 115 | +> |
| 116 | +> **Dev**: Can I test this without the physical device? |
| 117 | +> |
| 118 | +> **Domain expert**: Set up a **Simulated Device** using one of the archetypes in user config. Enable **Output Observations** and you'll see every command that *would* go to hardware. **Intiface Engine** will broadcast those to any connected frontend. |
0 commit comments