When Buttplug Won’t Buttplug, Part 1: Oh No

There comes a time in every software poorly planned open source software project where you have to sit back and say “Wait, am I completely off the mark? Did I totally fuck this up?”.

Of course, these times really shouldn’t happen at a frequency of once a month, but here we are. Unlike prior fuckups, this time I have a blog, so instead of fixing things, I can write about them!

But to be fair, a bit of self reflection is good before starting on the fixings.

Buttplugging So Far

Buttplug is itself an experiment with a general goal but no real focused direction to get there. The idea is to hand developers a way to easily access sex toys (this will come back to haunt us very soon) and then see what they do with this newfound raunchy power.

Thanks to the glorious lack of direction on how to achieve that goal of easy access, it’s also ended up as an exploration of technical niches like hardware drivers, implementation languages, and platform features. Its how we’ve gone from being a single library written in C# to two libraries written in C# and Javascript back to one library written in Rust with C# and Javascript/WASM layers on top of it, while also ending up maintaining a cross-platform Bluetooth LE library along the way. Buttplug at this point is balanced between being a useful sex toy library and a shitpost made of bleeding-edge development technologies, and I wouldn’t have it any other way.

One of the core philosophies of the library is that it should only maintain direct access with the hardware it works with. Currently, it uses only local communications systems like Bluetooth, Serial, or USB to talk to hardware. This means that, even if a company’s services go away, I can still provide users with a way to access their toy across software that works with our library. The library already supports out-of-production toys like the Real Touch, and many toys it can connect to now will suffer this same fate of obsolescence in the future, and we will be there, make sure they vibrate until the heat death of the sun or the usable lifetime of their $0.43 motor. This work has even gotten us to the point where sex toy manufacturers like The Handy actively engage with library development to provide support for their hardware. This strategy also helps preserve the privacy of the user, letting them choose hardware while being free of having to live on whatever ecosystem is provided by that hardware’s manufacturer.

During this time, Buttplug has stayed mostly desktop focused. While there have been web apps that work on Android and some via some alternative iOS web browsers, mobile offerings have been sparse at best, mostly due to lack of development resources. This happened while pretty much every sex toy manufacturer focused solely on mobile.

While all of this has been a mostly successful endeavor, it also assumes a usage model that may not always work for users of certain kinds of toys or in certain situations. Ironically, this includes many situations involving the type of toy from which I took the project name.

Buttplug, Buttplugs, and Social VR Worlds

Up until 2020, most applications for Buttplug assumed that a user was near their computer. Be it media players, single player game interaction, or other interactive applications, I mostly assumed that the user would stay still and near whatever computer was controlling the toy while using it. Even in teledildonics situations or mobile applications, there hadn’t really been any applications built where the device user and the controlling computer were assumed to be all that far away from each other.

Every so often I’d hear about random hardware disconnection issues in Buttplug (my library, not the toy), mostly with insertable toys, and in that niche, mostly with buttplugs (the toy, not my library). These toys use Bluetooth LE, a system that was not really made for fast updates, or butts, or updating things in butts in a fast, reliable way. Bluetooth LE is fine when you have line of sight or not much distance between radios and their hosts, and just need to throw data around in a leisurely way. Since Bluetooth is radio, it also would very much like to not be impeded by things like water. Overall, this means Bluetooth LE is great for things like mobile phones and small IoT devices that will stay near each other, not so much for desktops or gaming laptops, and definitely not for desktops/laptops talking to devices is in one of the deeper, harder to reach parts of a (mostly water based) human body. The past few years have been a lesson in doing this the hard way, as developing cross-platform bluetooth applications for desktop operating systems for body-immersed hardware has been nothing short of an absolute nightmare.

This user is fine and normal and good.

Unfortunately, I just don’t have many options to offer otherwise. No one seems to want a USB cable coming out of their butt (the luddites), and most people want their toy to be able to talk to their phone (as those are considered the most “private”/”intimate” technology accessing device), and phones either need WiFi (which is power hungry and complex to configure and implement) or Bluetooth to talk to the devices.

Doesn’t stop me from yelling into the void though. I’ve groused in the media for years about Bluetooth LE being bad for sex toys, though people that actually manufacture products and are better at this than I am have said otherwise.

“The antennas aren’t good enough!”

“There’s not enough transmit power in the toy!”

“Sex toy manufacturers don’t have the experience to build what’s needed!”

Up until 2020, it wasn’t much of an issue though. A few reports here and there, some recommendations on dongles and buying USB extension cables, and we’d be on our way.

Then Buttplug integration with VR social worlds like Neos and VRChat happened, and suddenly disconnection reports spiked. Thanks to COVID-19, these worlds went from social outliers to life-saving spaces, and as with any and all spaces, people fucked in it. The invariant of people being near their computers while using their toys was broken, thanks to being able to inhabit, walk around in, and hump these new shared virtual spaces instead of just sitting quietly like a good user. Not only do they move more, their sessions are longer, with reports of some users using VR social worlds plus Buttplug related plugins (both hardware and software) for upwards of 6 hours at a time.

This user is a support problem, and also an asshole

The combination of “Room scale” VR plus lengthy sessions plus hiding radios in the meat and water caves we call butts means devices often lose connections as users move around and power levels decrease, and thus cause the support channel on my discord server to see far more traffic.

This is not good.

What now?

Buttplug’s current connection methods aren’t cutting it. It works fine for people being near their machines, but that doesn’t work for VR, nor for those who just want to use their phone for certain situations. The current development strategy also puts the library at odds with toy manufacturers, who develop for and test on mobile and basically ignores desktops.

To fix this, I need to figure out ways to combine phones (or small machines like Raspberry Pis) and desktops/laptops in order to work with more situations. This needs to happen while balancing three considerations:

  • Not ceding ground to manufacturers for online services, so the library isn’t just a frontend for a bunch of services we don’t own or can’t replicate.
  • Preserving the privacy of the user, making sure that someone who is fine with their local connection setup and doesn’t want to use network/remote control never has to.
  • Making sure development ergonomics don’t suffer, while also making sure developers understand and expose features to their users in a way that doesn’t undo the preserving privacy point.

A few solutions to this problem already exist, in the form of the Lovense Connect application, as well as the XToys web based toy control and scripting system. In the next couple of blog posts, I’ll be outlining how these two systems have built their solutions, and what the next iterations of Buttplug can steal from their products. I’ll finish out with a concrete overview of where Buttplug is headed, both in terms of fixing insertable toy connectivity issues as well as thinking ahead to building remote services with the library. Along the way we’ll learn about how to design these kind of services, check out new technologies available to speed development, and most importantly, have ample time to appreciate the selection of clip art images I hastily googled for while writing these posts.

Onward and inward!

Buttplug Rust v3.0 Released: Less is Less

When I released Buttplug Rust v1, I figured I’d be rolling major versions whenever we updated the Buttplug Protocol. Here we are, at major version 3.0, still running the same protocol, but with more surface API changes. So much for those plans.

Why v3.0?

Since the release of Buttplug Rust v1, I’ve been getting steady pings from game developers asking when the Buttplug Unity plugin would be updated, in order to support new hardware as well as IL2CPP compilation. I finally got time to start work on this project a couple of weeks ago. Unfortunately it didn’t get off to a great start.

Using the C# FFI to Buttplug Rust worked fine, everything basically compiled with no real changes outside of some module paths, which was great. However, the development cycle after that basically became unusable. We found we could run Unity in Play Mode once, but any subsequent run would stall.

There’s more info in the related bug, but long story short, Unity’s Mono implementation wasn’t able to properly shut down Buttplug Rust’s async handling runtime. This meant threads got left open, and when Mono tries to reset itself (as is common, to save Unity game developers from having to manage their own state resets), it’d just stall forever.

The fix to this was moving from our current runtime (async-std on top of smol) to Tokio. Tokio provided far more granular runtime lifetime handling and passing, meaning we can easily manage when we bring up and take down the system. We now don’t spin up any runtimes (which brings up a number of threads) until we need to, and we can tear it down once all of our devices and clients disappear.

With that work done, Unity seems to be pretty happy. It compiles Buttplug support to either Mono or IL2CPP, and the development loop seems stable. I also took some time to work more with the fantastic tracing crate to improve logging in the library, making it easier to follow device connection lifetimes. This work also made me realize that my “batteries included” philosophy for Buttplug Rust maybe included a few too many batteries.

What Got Removed

One of the original tenets of Buttplug followed my philosophy about sex toy design: that it should be as quick as possible to start using, and able to run basically standalone while also having the ability to extend where needed. Developers can just get the library and integrate it with their program, not having to worry about how devices connect, how IPC mechanisms works, or other boring details. This hopefully allows for developers to concentrate on implementing interesting things with sex toys.

Sometimes though, this gets overrun by me learning things while implementing the library, so we end up with more features than might really be needed, or that I can support. Optimizing the library for Unity brought up a few things that could be removed.

Removing async-std and ThreadPool Runtimes

Unlike many languages with async capabilities (C#, JS, etc…), Rust’s async execution system is designed in such a way that the language comes without a way to execute tasks. Rather, it depends on outside implementations that can tune to the specific requirements of an application. While this is overall a win for the ecosystem, it can sometimes cause frustration.

Supporting multiple runtimes in Rust is common, but usually for libraries that will have widespread use: network services, database connectors, etc… While there are certainly developers using Rust to develop Buttplug applications, they are a minority compared to developers using FFI libraries, where this runtime selection will be hidden.

Buttplug Rust as it exists now was started in September 2019, slightly before the release of async features in Rust 1.36. At the time, async-std was developing alongside the nightly branch of rust, and looked more like what the async ecosystem does now. Thanks to that, I ended up going with that for our initial execution system, and it has worked great up until our current issues with Unity.

This also functioned as a way for me to learn how to live as a library developer in the new Rust async ecosystem. This was a combination of interesting and frustrating, especially as requirements sometimes differed greatly between libraries.

With subsequent releases of Tokio over the past 18 months, it has grown to integrate with the async facilities of Rust in a more ergonomic way, while still providing more granular control (and the cost of some added complexity sometimes, i.e. runtime handle management). Thanks to this, it now fits Buttplug’s needs better, and comes stocked with some very useful sync primitives and channels, including Broadcast (which I use heavily to simulate the event systems we had in C#/Javascript).

On top of this, most of the async work we still need to happen (Windows Named Pipes, serial ports) is farther along in tokio/mio (as far as I’m aware, and it’s currently stalled), meaning we can just integrate with that when it comes along by using tokio as our main implementation.

After switching Buttplug to Tokio, it became apparent that maintaining 4 runtimes (tokio, async-std, futures crate ThreadPool, and wasm-bindgen) was silly, since I don’t really have users split across those (and many users may not even know why the runtimes are there). Some of our other dependencies like async-tungstenite could handle the differences, but the complexity of the feature system for Buttplug was getting out of hand, as was remembering where to put all of the relevant #[cfg()] calls. I’ve now removed async-std and ThreadPool implementations, leaving us with just Tokio and wasm-bindgen (required for WASM). Ideally it’d be great if we could use Tokio’s executor for everything, but that’s not quite possible as of yet. The current system is managed using an internal system similar to the async_executors crate, which works well enough for abstracting task systems.

This does not mean that Buttplug isn’t usable with other runtimes now. Outside of the Device Communication Managers (which, granted, are possibly the most important part of the library), most of the library is runtime agnostic, and async-std contains tokio compatibility systems that will allow the library to run using its runtime also. This change mostly reduces the amount of thinking I have to do when updating the library and its direct dependencies. This is open source self care more than anything.

Removing Secure Sockets for Buttplug Servers

When Buttplug C# first started in 2017, Chrome allowed for localhost websocket connections via mixed contexts (i.e. https:// website calling through ws:// for localhost websockets). Firefox did not have a feature like this, so we implemented the ability to create self signed certs and load them into the server to run a self signed websocket server for Buttplug. This allowed us to get applications working in Firefox.

Firefox changed this in 2020, now also allowing mixed context localhost connections. With this addition meaning that Chrome, Firefox, and Edge all supported mixed context connections, the need for including the batteries of a secure socket connection went away. Any users that require this feature can still set up a reverse proxy in front the server port, but managing the certificate generation and loading system is well out of scope of Buttplug’s core goals. Removing this will hopefully simplify changes to our connector system in the future, and also removes the burden of keeping cert libraries in lockstep.

For most of the talk of async in this post, the secure socket change is actually what drove the major version update. Removing secure sockets changes our Websocket connection API, which is exposed to developers, and therefore is a breaking change in the general public API. This change only happens in the Rust library, as the server is not exposed in the FFI, so while Rust moves to v3, the FFI APIs will continue on the v1 track.

What’s Next

Now that Buttplug v3 is done, there are quite a few releases to make on top of it:

  • Updating the C# and WASM FFIs, though only C# will see much of a change.
  • Finishing the Buttplug Unity update and releasing v1 of that package
  • Updating Intiface to remove the Secure Socket options

These updates will be happening throughout the next week.

After that, the main focus is going to be more documentation and the implementation of a WebRTC based proxy system. This stems from the rather startling discovery that Buttplug (the library) doesn’t work very well with buttplugs (the sex toy), which I’ll be making another post about soon.

With this proxy system (inspired by the work of xtoys.app), we can start using mobile hardware (phones, linux SoCs like RPis, etc) as connection points, giving users more freedom in where and how they use toys. Alongside this will be more hardware and QoL updates, but the goal for now is making our system usable to the wave of social VR users we’ve seen over the past few months.

Onto v4! But hopefully via many v3 point releases first.

Nonpolynomial Software Updates for January 19, 2021

Another week, another release of almost every piece of software in our stack!

btleplug 0.5.5

btleplug is our cross platform Rust Bluetooth LE library, which Buttplug uses for all bluetooth access.

Updates include:

  • Dependency update to fix issues with async-std v1.9 API move, needed so apps using Buttplug would build at all (we depended on some unstable things that ended up disappearing).
  • Preparation for bringing in a new Bluez core thanks to some contributor work!

Buttplug Rust v2.0.2

It’s been almost a month since releasing Buttplug Rust v1, so now obviously it’s time to release v2!…?

This is mostly a cleanup release, but some of that cleanup had fairly major effects on the surface API, hence the major version roll.

v2.0.0 and v2.0.1 were both yanked due to bugs found quickly after release, so v2.0.2 is really the first released version of the v2 chain.

Updates include:

  • Move our internal channel structures to using tokio-rs‘s sync module, as its mpsc and broadcast modules are more suited for our needs (blog post on this endeavor coming soon).
  • Restructured internal event loops to make things cleaner
  • Fixes for device scanning and discovery issues with the Lovense Dongle
  • Added hardware support for the Lovense Ferri

Buttplug JS v1.0.3, Buttplug C# v1.0.9

Not a lot to say here, other than “there were updates”. Both Buttplug JS and Buttplug C# got updates to Buttplug Rust v2.0.2, but the only change that may be visible is that Rust panics (crashes) are now communicated through the logging system, so more information can be provided for debugging.

Intiface CLI v25, Intiface GHR v11

Same as the FFI libraries, Intiface CLI (used in Intiface Desktop) and the Game Haptics Router was mostly an update to Buttplug Rust v2.0.2, along with the same addition for more crash logging.

Here’s hoping it’s more than a month before Buttplug Rust v3 needs to be a thing.

Nonpolynomial Software Updates for January 10, 2021

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 Rust

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 C#

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

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!

Buttplug C# v1.0.2 and JS v1.0.1 Released

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

Even simpler:

  • #43: Forgot to include protobufjs as a dependency (was a devdep), meaning typescript would cry when trying to resolve types

That’s it. That’s the change list.

Buttplug Hits v1 Milestone

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:

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.

  • 2004
  • 2007
  • 2013
  • 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
  • May 2017
    • First JS implementation, using WebBluetooth to access BTLE through the Chrome web browser. Later included native Node implementation using noble and other hardware libraries.
  • August 2017
  • 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
  • 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
    • 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.
  • 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.

What’s Next

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.
  • Documentation
    • 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
  • Hardware Support
    • 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).
  • 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!

Welcome to Nonpolynomial

Welcome to the new blog for Nonpolynomial! Pivoting from our previous strategy of random tweetstorms, 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.

Stay tuned for more content!