I made a rule for myself that I’d wait 2 days after any software update to announce it on the blog, just to make sure I didn’t have to go back and fix even more things and flood the blog with “fixes and performance improvement” posts. The last blog being 2 weeks ago says a lot about the release schedule lately.
Thanks to a lot of interaction with developers using the libraries after the v1 launch, I’ve been making a ton of patches and bugfixes. There’s a pretty severe lack of tests in several parts of the platform at the moment, so it’s a very “testing in production” situation. With production for our software being what it is, it means seeing bug reports like “multiple gigabyte memory leaks during hours of intimate hardware usage.”
Anyways, here’s a list of things I threw the fire extinguisher at over the past 2 weeks:
buttplug-rs is now at v1.0.5, having seen the following major updates since v1.0.2:
XInput (XBox compatible gamepads) will now emit disconnect events, as well as rescanning every 1 second during the scanning period (versus only scanning once then stopping until StartScanning is called again)
Fixed bug with Bluetooth LE scanning missing some devices in certain situations.
Contributor Patch: Fix handling of Sync/Send traits on certain future types
Contributor Patch: LTO now used on release builds, shrinking library size by about 12%.
Contributor Patch: Support for LiBo, Prettylove toys. Thanks to the good people at IOSTIndex for this patch.
buttplug-csharp is now at v1.0.8, having seen the following major updates since v1.0.2:
Updated Rust dependency to v1.0.5, so all previously mentioned fixes/additions for buttplug-rs are available
Fix issue with device disconnect/reconnect causing collisions in the C# API
Fix issue with certain commands not triggering on all features as expected (i.e. a device with multiple vibrators only has one that reacts to commands, when all should react)
Contributor Patch: Fix issue with events not doing null checks, thus throwing if no listener is available.
buttplug-js is now at v1.0.2, having seen the following major updates since v1.0.1:
Updated Rust dependency to v1.0.5, so all previously mentioned fixes/additions for buttplug-rs are available
That’s about it, really. Most of the major fixing has been in device access in our native libraries. JS certainly still has bugs, but is currently seeing less complaints about them.
Intiface Game Haptics Router
After getting all of these library updates done, I’m finally moving back to being able to work on some of our first party applications. This includes the Intiface Game Haptics Router, the gamepad-rumble-to-sex-toy-control mod maintain.
The GHR is now at v10, which includes the following major updates:
GHR can now connect to Intiface Desktop, as well as still using a standalone version of Buttplug that it comes with.
Settings are now persisted between sessions
XInput hooked processes can now be detached/reattached (Unity VR hooked processes still can’t detach yet).
Sped up process finding by a factor of however many processors you have.
Users can now set packet gaps, to reduce issues with command flooding to toys.
That’s it for now. Be on the lookout for updates to programs like Intiface Desktop and VAMLaunch, and of course more fixes and features in the core library soon!
So nice to finally be able to have release notes that aren’t tweets!
Buttplug C# v1.0.2
Really simple fix here, but it was stopping the logging system from working at all in some cases, so very important.
#44: Log Handler now held for the lifetime of the process, meaning it will no longer throw an error when the GC sees the only reference is possibly held by a bare pointer in a native library. Isn’t FFI fun?
Buttplug JS v1.0.1
#43: Forgot to include protobufjs as a dependency (was a devdep), meaning typescript would cry when trying to resolve types
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:
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?
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.
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.
Forked Rumble into btleplug (begrudgingly changing the name because rumble would’ve been GREAT to have in Buttplug but the original author was AWOL so package couldn’t be transfers on crates.io), brought up minimum BTLE capabilities in Windows, macOS, and Linux.
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.
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:
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.
The v1 slog (this was supposed to be done in October, then Hades happened. Oops.) means hardware support for things like the OSR2 and Nintendo Joycon are still in development and running behind.
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).
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!
Welcome to the new blog for Nonpolynomial! Pivoting from our previous strategy of randomtweetstorms, we’ll be using this space to post updates and in-depth technical articles about our various products. We’ll also include posts on haptics (intimate and otherwise), product design and marketing, and other topics we cover as part of our consultancy.