After 3.5 years of development, Buttplug, the open source intimate haptics controls library created and maintained by Nonpolynomial, has finally arrived at its v1 release. Fitting that it’s also the first real blog post on the new Nonpolynomial Blog!
For the project, this is actually a contraction rather than an expansion. Version 1 means that the project has slimmed down to a core Rust implementation upon which the ecosystem can continue to grow.
Buttplug v1.0.0 is available in the following flavors:
- Rust – Crates.io, Github
- C# – Nuget, Github
- JS/Typescript (via WASM, Web-only currently) – NPM, Github
The Buttplug Developer Guide covers basic usage, with examples in all of the aforementioned languages.
What Even Is Buttplug?
Buttplug is a haptics abstraction library for intimate hardware.
Which is a fancy way of saying “a way of telling a bunch of different vibrators how to vibrate”. Though it can tell hardware how to do things other than vibrate, and it supports more form factors than buttplugs.
Basically, there are hundreds of computer controlled sex toys out there. Most of them have unique protocols to control them. Buttplug tries to centralize these control protocols, handles cross platform USB/Bluetooth/serial/etc for the developer, and presents a uniform way of controlling the whatever toy the user may have. Instead of knowing what operating system the user is on and how to talk to their specific toy, developers can use Buttplug to enumerate for a supported device, then send generic commands like “vibrate/rotate at [speed]”. That’s it.
While the sex toy control part of Buttplug is probably the most recognizable and memorable feature, it’s not the only goal of the project. Buttplug was established as an experiment for creating user-focused haptics and interface device abstraction. Libraries and engines like Chai3D and H3D work as generalized haptics engines for studying mechanical systems, texture and force creation/simulation, while other systems like VRPN work as a sort of user-space HID manager for systems that may not conform to general HID protocol boundaries. Buttplug seeks to take these two paradigms, and smoosh them together while also servicing a niche that doesn’t get much engineering attention. This leads to many interesting questions, like:
- How do we quickly and reliably bring up hardware communication across multiple platforms?
- How do we interact with a user whose affective state may differ from someone using “normal” software like a word processor or database?
- How do we create a language expressive enough to generate the experience a user wants, while also abstract enough to not be device specific?
- What are the ethical implications of building open source technology for intimacy?
- Can these questions be approached through technology in a way that is maintainable by a small, possibly one person team?
We’ve heard from our community that some users are just interested in controlling sex toys, though, and that’s fine too. I guess.
If you’re curious about what users are doing with Buttplug, check out our awesome-buttplug project list repo.
A Short-ish History of Buttplug
Here’s an overview of the 16 year path from my start in sex tech to a v1 library for the field.
- Kyle gives a presentation at Arse Elektronika mentioning “Obfuscated Macros”, which at the time seemed like a great name because Kyle was a 20-something engineer. This idea would grow to become the basis of Buttplug.
- First Python implementation, known as “Fuck Everything”. Uses ZeroMQ and Python 2. Never full shipped due to issues with python application redistribution, as well as lack of hardware on the market to support.
- Fall 2016
- First Rust implementation. Stalls due to lack of platform support for Bluetooth (most hardware we interact with is Bluetooth LE) and other hardware.
- April 2017
- First C# implementation, using the recently released UWP BTLE APIs for Windows. Library gains momentum and project takes off, also establishing a protocol spec to ensure compatibility between versions.
- May 2017
- August 2017
- Kyle incorporates Nonpolynomial
- December 2017
- Generic messages added to the Buttplug Protocol Spec, making it easier to command a wide range of devices. Due to maintenance timing and life in general, this is the last change to protocol spec for the next 3 years.
- April 2019
- Python implementation of Client API for Buttplug. All hardware access was still managed via either JS or C# implementations.
- May 2019
- Sept 2019
- Realize that maintaining 2 full implementations of Buttplug was untenable for a 1 person development team, work started on a new core implementation of Buttplug in (at that point unstable) async Rust, with other language implementations would then live on top of.
- January 2020
- October 2020
- Core async Rust Buttplug implementation hits feature parity with the C# and JS libraries. Move to porting C#/JS to using Rust via FFI. C# calls into the native Rust library using exported C calls, while JS uses a WASM layer.
- December 2020
- v1 release, along with the first shipping of a new spec version since December 2017. FFI C#/JS libraries at parity with original native C#/JS libraries, original native libraries deprecated and archived. Buttplug Developer Guide in good enough shape to guide users on building simple Buttplug Applications. Metafetish closes after 16 years in order to make way for new Nonpolynomial blog.
What Buttplug Version 1 Means
To me, a lot. To you, possibly not so much.
As mentioned, Buttplug Version 1 doesn’t really come with a lot of new features. It’s mostly a point where I can cut old stuff and start looking toward the future.
Buttplug C# and Buttplug JS will now be archived, as implementations now live in our FFI repo, and their respective nuget and npm packages will still live on as v1 and beyond. There will definitely be breaking changes between the v0.x and v1 versions for C#/JS, so if you’ve been developing on those, be ready. I did my best to keep the APIs similar, but also used this as a way to clean up some problems that had cropped up along the way.
Before v1, adding new features or hardware protocols meant implementing things in at least 2 places. Now, features can be implemented in Rust, then all that is required is a rebuild of the FFI and package version numbers being rolled. At worse, the FFI API surface may require changes, but that’s fairly trivial work versus having to redo full feature implementations. Most of the FFI work is up front in the initial implementation, and the hope is that continued maintenance will be much simpler. Time will tell whether this was a total mistake.
Success will be measured via this possible reduction of rote coding work. I’d like to spend more time on design with a flexible system versus having to re-implement my ideas multiple times to test them out across all platforms.
The Version 1 release will also probably be the only time that multiple libraries are released in lockstep with the same version number. I suspect that the FFI libraries will have API surface level issues that will require major version rolls outside of when the rust library updates. Everyone who has an affinity for version numbers, enjoy these stars aligning now, because it’s probably the last time it’ll happen.
There’s so many directions to go now that it’s almost hard to pick which to start with, but here’s some general ideas of what I’d like to do next:
- Blog Posts
- I have this shiny new blog now and I’d like to use it more. I have a lot of thoughts about Rust, WASM, and other technologies I’m using that I’d like to cover here.
- Buttplug v1 is documented just enough to maybe get people started, but the developer guide and API documentation for the various implementations definitely need more love.
- More FFI Implementations
- Python is on the way soon, and C/C++ (especially for Unreal Engine suppot) and Java/Kotlin have been requested by the community.
- Application Updates
- I maintain a few applications, like Intiface Desktop and the Game Haptics Router, that have been backburnered while v1 was in progress. Would really like to get those updated and add some new features. Also need to update dependent libraries, like our Unity Game Engine and Twine Game Engine support.
- Hardware Support
- Actually Making New Stuff
- Everything listed so far is continued maintenance. It’d be nice to actually make some new things too. Don’t know what those will be, but I need to actually create with my creation, instead of just creating my creation.
Thanks go to:
- Loved ones and friends who’ve had to put up with me being “The Buttplug Guy” for the past 16 years (with no sign of that ending soon).
- My Patreon and Github Sponsors Subscribers, who’ve kept the project funded enough for me to buy new hardware.
- My consulting clients for Nonpolynomial, who’ve helped keep the business cash positive while also helping my project along with support in their products.
- Everyone who worked on reverse engineering toys and donating info to our Sex Toys Protocols I Have Known And Loved (STPIHKAL) documentation project.
- Sex tech projects like IOSTIndex, XToys, Eroscripts, and others who manage information and help grow sex tech communities in other directions. Buttplug is just a small component in what will hopefully be a larger ecosystem and community someday.
- The community of developers who’ve been using the library, either as part of project they’ve shared with communities, or even for things they’ve just done for themselves and kept closed. It’s nice to know people are using things I build.
- People who’ve been watching and interacting on social media, at conferences, etc… This project is as much if not more social than it is technical, so it’s been great to get other perspectives.
Having Buttplug hit v1 feels great, but there’s no time to rest. On to v2!