OFS script converter extension for rotary fuck machines (Hismith, Lovense, etc)

OFS script converter extension for rotary fuck machines


This is an OpenFunscripter extension that can convert funscript patterns into power level variations suitable for any buttplug.io-supported rotary fuck machine.

Most penetrative fuck machines are built using piston motion systems. This makes them cheap to produce, but it also means their stroke position cannot be controlled in the same way that linear motion systems can. By contrast, most funscripts are made for masturbation sleeve devices, which can precisely adjust their stroke position. This allows them to be controlled effectively by alternating motion between 0-100 position values.

However, attempting to play back a regular funscript while connected to a rotary fuck machine results in irregular, uncontrollable bursts of power, which is very dangerous and can cause serious injuries. This extension aims to solve that problem, giving you control over the power level of your fuck machine while also attempting to match the machine’s RPM to the rhythm of the action.


  • A simple yet accurate cycle-time-to-power-level converter that only requires the min. and max. RPM of your device (with the toy attached) to work effectively
  • Create and store custom device profiles for faster conversion
  • A built-in unit converter utility helps you quickly translate between several types of values (cycle duration, power level, RPM, etc.)
  • A built-in device profile estimator automatically computes the min. and max. RPM values for your device profile from just a few measurements
  • Conversion logic based fully on peaks and troughs means not having to worry about how detailed the funscript patterns are
  • Ample conversion options help you tailor the power level graph to better fit the content you are working on
  • Quickly test your converted script by following the funscript-to-machine setup guide!
  • Developed for OFS v3


  1. Download and extract the latest version of the extension from Releases
  2. Copy the FM script converter directory and add it to the OFS extensions directory (%appdata%/OFS3_data/extensions/)
  3. Start OpenFunscripter
  4. In the Extensions tab, hover over the FM script converter list item and tick Enabled and Show window
  5. Optionally, you can pin the extension window to the OFS GUI. I prefer dedicating the left side of the GUI to this extension


v1.1.0 (02-Nov-23)
  • Added device profile persistence via a Lua JSON library and profile management options (create/modify/remove)
  • Renamed the “Device power level calculator” utility into a broader “Unit converter” utility and added “Number of cycles” and “Time period” fields to it
  • Added a “Min./Max. RPM estimator” utility to make it easier to create custom device profiles
  • Combined utilities into a “Device profile calibration utilities” menu
  • Restructured the code into separate modules (main.lua now only handles the GUI)
  • Updated README to reflect new enhancements
v1.0.1 (26-Oct-23)
  • Added functionality for debug options that was excluded by accident from the initial release.
v1.0.0 (25-Oct-23)
  • Initial release.

Usage & Guides

Please read through the GitHub README as it contains ample usage instructions and several useful guides, such as measuring the RPM of devices and setting up the funscript-to-machine connection.

GUI Showcase

Example 1 Example 2

If you like this extension, please spread the word about it! May you happen to find the perfect configuration for your device? Be sure to share that knowledge in the comment sections where this is posted, or through GitHub issues (include your test results if possible)! Any feedback is welcome, so feel free to share your thoughts, suggestions for improvements or any bugs you may find.

Also, check out my other OFS extension project:


Thank you so much for this. This is an awesome and much needed tool!

May I suggest an improvement though? Do you think some sort of “tap to RPM” feature could be implemented? I’m thinking tapping the space key in sync with the action in a video to directly map the speed/frequency.
That way (rotary) fuck machine funscripts could be created a lot quicker and easier!

Hi! Thank you for the kind words :3
I think what you’re looking for may already be included in the default OFS interface. The scripting mode tab already provides several ways to add actions on the funscript, including by recording your mouse/controller position, using a set of two alternating action positions and so on. Here’s an example of how that looks:


On top of that, you should check out the OFS keybinding menu (Options > Keys), which gives you many ways to bind keys for your scripting needs.

Holy shit you’re the GOAT

1 Like

Hey all, I’ve just released v1.1.0 of the extension. It includes several enhancements, such as persistent device profiles, more helpful built-in utilities and a code restructure for easier continued support.

If you have any suggestions for improvements or found any bugs, please share these in the comments below! Likewise, feel free to share your own device profiles (name and min./max. RPM) and measurements! Having community-outsourced profiles makes it easier for people to find the right configuration for their device.

1 Like

Thanks for explanation, much appreciated!

I do have another suggestion (though I’m not sure if a lua that achieves this might exist already). Would it be possible to include an option that limits the converter output to discrete power levels steps (e.g. 5%)? Any value in between is rounded up or down. This would result in a smoother run and require less spinning up/down from the machine.

Thanks again for your work, I’m really enjoying it so far!

Yeah, that should be an easy option to add, as the converter is already using rounding to the nearest percent when computing the power level. I will queue this up together with GUI tooltips which I am planning to add in the next patch (hopefully next week).

Did you make any progress with this?

After playing around with your tool a bit more, I can confirm that quite often the converted power levels fluctuate quite a bit (depending on the frame rate of the video, 1-frame differences in cycle time can result in power level differences of >5%). To solve this I believe it would be best to add an option that averages the conversion result of multiple cycles (rolling average).

I think that would be more effective than my previous suggestion at achieving a smooth yet accurate script conversion.

Hey again! Sorry for having been absent, but a lot of interesting developments have been in the works behind the scenes regarding this extension!

First of all, I actually already implemented the feature you suggested some time ago, but haven’t yet made that into a release of its own. If you look at the latest GitHub commit, you’ll see it there. You can actually just download the code of the latest commit from GitHub and follow the installation steps. Just make sure to preserve your config.json file when updating the extension to a new version, that file stores the device profiles you created using the extension.

But yeah, the reason for my absence is that I’ve actually been working together with a friend on a complete revamp of the converter “engine” so to say. My original implementation was fairly simple and based on trying to reduce complexity as much as possible. It just took the peaks and troughs of the graph and used a manually written decision tree based on the finite amount of possibilities it could encounter.

While that works reasonably fine for some scripts, it has edge cases where it won’t work well. It also wouldn’t work with most of the scripts on this website, since they are meant for linear devices that can handle very intense patterns like vibrations. Those would give you super crazy speeds with the original converter.

With the new converter engine, we’re basically trying to actually physically simulate the piston movement system of the machine. While it is more complicated, this should do away with any kind of edge case while delivering the same kind of script the original converter could. It also will enable more accurate thrusting simulation mode(s), which attempt to match half-stroke timings by varying the power levels very accurately. We call it the “hard difficulty” in our testing :stuck_out_tongue: I believe Hismith has a default pattern on their app that also kinda does this, but ours should be way more accurate and not create (too much) uncontrolled/uneven thrusting behavior. But that’s still experimental, and will be labelled as such when implemented.

Anyway, we’ve been working on this for over a month now. The implementation is currently done in Matlab as my friend used that for his simulation calculations, but in a few days I will start porting his code over to Lua for use in this extension. I’m estimating it will take until early next year to get that ready and make a full v2 release. Until then, the jury’s still out on whether I’ll have enough time to keep updating the existing extension code with small improvements, as i’ve also had a pretty busy time IRL with getting a new job and also working on some other hobby projects.

But yeah, expect interesting developments from this in the near future! And definitely I will consider adding more features to control the outputted script such as the rolling average you suggested!

1 Like