Skip to content

Repository files navigation

buttplug-go

The (unofficial) Go implementation of the Buttplug Intimate Hardware Control Protocol (v4) client — a 1:1 port of the official Python buttplug-py library. This was translated with the assistance of generative AI tools, but has been thoroughly tested with Intiface Central's simulations.

image

Installation

go get github.com/hirusha-adi/buttplug-go

Quick Start

  1. Install and start Intiface Central — This is the server that connects to your devices.

  2. Connect and control devices:

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/hirusha-adi/buttplug-go"
)

func main() {
    ctx := context.Background()
    client := buttplug.NewClient("My App")

    if err := client.Connect(ctx, "ws://127.0.0.1:12345"); err != nil {
        log.Fatal(err)
    }

    if err := client.StartScanning(ctx); err != nil {
        log.Fatal(err)
    }
    time.Sleep(5 * time.Second)
    _ = client.StopScanning(ctx)

    for _, device := range client.Devices() {
        fmt.Printf("Found: %s\n", device.Name())

        if device.HasOutput(buttplug.OutputTypeVibrate) {
            _ = device.RunOutput(ctx, buttplug.DeviceOutputCommand{
                OutputType: buttplug.OutputTypeVibrate,
                Value:      0.5,
            })
            time.Sleep(2 * time.Second)
            _ = device.Stop(ctx, true, true)
        }
    }

    _ = client.Disconnect(ctx)
}

Features

  • Simple API: Unified RunOutput() method for all output types
  • Full Protocol Support: Implements Buttplug protocol v4
  • Idiomatic Go: Context-based I/O and strong typing throughout
  • Event Callbacks: Get notified when devices connect/disconnect

Device Control

// Check device capabilities and send commands
if device.HasOutput(buttplug.OutputTypeVibrate) {
    _ = device.RunOutput(ctx, buttplug.DeviceOutputCommand{
        OutputType: buttplug.OutputTypeVibrate,
        Value:      0.75,
    })
}

if device.HasOutput(buttplug.OutputTypeRotate) {
    _ = device.RunOutput(ctx, buttplug.DeviceOutputCommand{
        OutputType: buttplug.OutputTypeRotate,
        Value:      0.5,
    })
}

if device.HasOutput(buttplug.OutputTypePositionWithDuration) {
    duration := 500
    _ = device.RunOutput(ctx, buttplug.DeviceOutputCommand{
        OutputType: buttplug.OutputTypePositionWithDuration,
        Value:      1.0,
        Duration:   &duration,
    })
}

// Read sensors
if device.HasInput(buttplug.InputTypeBattery) {
    battery, err := device.Battery(ctx)
    if err == nil {
        fmt.Printf("Battery: %.0f%%\n", battery*100)
    }
}

// Stop device
_ = device.Stop(ctx, true, true)

Event Handling

// Set up callbacks before connecting
client.OnDeviceAdded = func(d *buttplug.ButtplugDevice) {
    fmt.Printf("Connected: %s\n", d.Name())
}
client.OnDeviceRemoved = func(d *buttplug.ButtplugDevice) {
    fmt.Printf("Disconnected: %s\n", d.Name())
}
client.OnScanningFinished = func() {
    fmt.Println("Scan complete")
}
client.OnServerDisconnect = func() {
    fmt.Println("Server disconnected!")
}

// Callbacks can start goroutines for async-style handling
client.OnDeviceAdded = func(device *buttplug.ButtplugDevice) {
    if device.HasOutput(buttplug.OutputTypeVibrate) {
        go func() {
            _ = device.RunOutput(ctx, buttplug.DeviceOutputCommand{
                OutputType: buttplug.OutputTypeVibrate,
                Value:      0.25,
            })
        }()
    }
}

Examples

See the examples/ directory for more detailed examples:

  • application — Complete application workflow
  • connection — Connecting to a server
  • device_control — Vibrate, rotate, and position commands
  • device_control_simulated_stroker — Simulated stroker control
  • device_enumeration — Discovering devices
  • device_info — Inspecting device features
  • sensors — Battery and signal strength
  • errors — Error handling

Ported from the official Python examples in buttplug-py:

Example Run
application go run ./examples/application
connection go run ./examples/connection
device_control go run ./examples/device_control
device_control_simulated_stroker go run ./examples/device_control_simulated_stroker
device_enumeration go run ./examples/device_enumeration
device_info go run ./examples/device_info
errors go run ./examples/errors
sensors go run ./examples/sensors

To run examples from a clone of this repo (from the repository root):

go run ./examples/application
go run ./examples/device_control

All examples expect Intiface Central running at ws://127.0.0.1:12345.

Tests

Unit tests live alongside the library source as *_test.go files in the repository root. They exercise the public API and protocol message handling without requiring a live Buttplug server.

Test file Coverage
client_test.go Client creation, event callbacks, and disconnected-state guards
device_test.go Device and feature capability helpers
message_sorter_test.go Request/response message correlation
messages_test.go Protocol message serialization and parsing

Run the full test suite from the repository root:

go test ./...

Other useful commands:

# Verbose output
go test -v ./...

# Run tests matching a name pattern
go test -run TestClient ./...

# Run with race detection
go test -race ./...

Package layout

Python (buttplug-py) Go (buttplug-go)
buttplug.client client.go
buttplug.device device.go
buttplug.feature feature.go
buttplug.command command.go
buttplug.connector connector.go
buttplug.enums enums.go
buttplug.errors errors.go
buttplug._messages internal/messages/
buttplug._utils internal/utils/

API notes

  • Python async/await maps to Go context.Context on all I/O methods.
  • Event callbacks (OnDeviceAdded, etc.) are synchronous functions; set them before calling Connect.
  • ButtplugClient / NewButtplugClient aliases are provided for parity with the Python naming.

Requirements

Documentation

Support

License

This project is licensed under the BSD 3-Clause License. See LICENSE.

The Go client is a port of buttplug-py; the Buttplug protocol is maintained by Nonpolynomial Labs.

About

The (unofficial) Go implementation of core message system and client for the Buttplug Sex Toy Protocol Standard.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages