Automatically convert hardcore funscripts to Handy (while preserving sync)

I’m liking a lot having this control over the funscripts, I wish this was implemented on some script player so I can configure the values real time,

what’s the speed threshold value for? the one that defaults to 500
could you please also add it as a variable? I guess I could edit " speed_threshold = 500.0 # 500 is ‘Handy’ limit"

it’s because I’ll keep using the drag and drop method

could you please show examples of what vibe_amount does? I still don’t understand, maybe I’ll understand better after I test more

1.02 version added above with a fix for this (added height value sanity checks to allow only 0-100).

1 Like

now it’s working, thanks, will test a lot, I want to learn more about what every option does, I increased min interval to 134 and it was not moving at some vibrations, I tought they were replaced, not just flatened?

…I could edit " speed_threshold = 500.0 # 500 is ‘Handy’ limit"

That’s what I recommend if you’re going to drag-drop. speed_threshold limits all script action to that speed or lower. 500 is around the Handy’s limit. Setting the value lower limits the speed (thus sometimes limits the upper/lower height position values too). For the Handy, I would leave it at 500.

could you please show examples of what vibe_amount does? I still don’t understand, maybe I’ll understand better after I test more

If you set vibe_amount to 0, any detected vibrations will just be a flat(ish) line; little or no movement where the vibration used to be.

Example changing from 10 to 0:
10


0

I see, maybe if I increase interval too much (134), I should increase the vibe_amount, because there will be less movements and might become too flat

Yea, increasing the interval values too much can start to remove action points which need to exist in order to retain synchronization.

I’m afraid changing too many values might wreck the script, maybe I should go with your default values

how does speed_threshold works? when it detects a stroke faster than 500 speed, it reduces the lenght so it gets slower? or is it applied to all movements?
is this?
image

main objective for all modifications is to keep the same pace, right?

I guess vibrations become like some disible amount of movements so it keeps sincronized but at a slower bpm?

I want to understand why on your example, green marked movements became lower bpm, but the blue marked ones, became flat

when it detects a stroke faster than 500 speed, it reduces the lenght so it gets slower?

Correct (more below). Basic design is to:

  • Remove actions which happen too quickly, next to another action
  • Attempt to recognize and replace flat sections (identified by actions still pretty close together) resulting from step 1, with vibration patterns
  • Lastly, look for any actions which cause a speed over the set threshold and reduce each point’s movement just enough to fall under the limit

main objective for all modifications is to keep the same pace, right?
I want to understand why on your example, green marked movements became lower bpm, but the blue marked ones, became flat

That is intentional via the other logic in the script. At one point, I had vibration added back into the blue section, but it caused problems in other circumstances. I though it was better/safer to protect sync wherever possible, essentially by modifying each funscript as little as possible while aiming to have the funscript feeling more like it was always designed that way.

That’s why I love JS you just open web page and it works
Lemme check the script

I’m using default settings and it’s helping a lot, still vibrates a bit too much for my liking but it’s way better than default, it’s really nice being able to remove vibrations so easy, thanks, I was discarding almost half the scripts I downloaded because they vibrated too much

1 Like

Cool. Glad you’re finding a use for it. Might try setting vibe_amount from 10, down to the 0-5 range since you don’t prefer the vibrations (unless you mean vibrations which are not deemed too fast for Handy since those aren’t modified at all).

yep. it’s the unmodified one, I guess I must increase the
min_interval = 60
shoud I keep it on some multiplier or something?

I would go for a more dynamic approach and allow a speed limit setting. This then could be used to limit vibration sections to a lower speed, while still using the same frequency.
Instead of removing vibrations this is a more constant way of making them calm, regardless of amplitide. Lets say we are working with a script that has them at 500. If after reducing its 20 actions per second at 10 units, or 40 actions at 5 units, these would end up being somewhat equal in how they are performed (and limit it to 200), yet if it was scripted at 40 actions, it at least would preserve that.

I’ll define a vibration as a repeating pattern no more than about 80ms, plus a decent amplitude. However, the main goal of this script is not to remove vibrations, so you might think about starting a new topic if you want to chase that further. Feel free to notify me if you do that.

One way I think could add more control would be to do multiple passes where the first pass might be to just identify and label sections which are ‘vibrations’ (whatever those criteria end up being). Then, go back and calc an average middle line and replace it with whatever amplitude makes sense, perhaps with some fancy fading and randomness.

If I find time to do any of that in the future, I’ll post a new py script version. But personally, I think it works well already.

Well, detecting vibrations isnt too hard. As node density is a key feature here. Even if its a straight line upward, the middle nodes cause stutter, and therefor are vibration.

But if we exclude that nuance, i would say that a vibration has a direction change involved. This change doesnt always mean the values increase and decrease in order. but the change oscilates instead. +0,+10, +0,+10, +0,+10, +0,+10, +0,+10, +0,+10 is a valid vibration. Even +2,+8,+2,+8,+2,+8,+2,+8,+2,+8 is.

This oscilation is what you can use. As once you know enough points in the oscilation, you can average it out, and figure out what the amplitude was, and compensate.

My make vibrations plugin already uses a similar method to apply fades.

The real trick is to also remove middle nodes on an action. As that will truly remove vibrations. So in the +2,+8,etc example, it should figure out that only the start and end of the entire movement are needed. Its obviously easier when doing a double pass here though, as then you can perform that check afterward. But this doesnt have to happen as 2 complete passes. You can always look back at corrected nodes in the first pass upon detecting an actual direction change*, and then remove all the nodes up to the previous detected change…

  • note that change here just means a point where it detects that the vibration pattern cannot be held, this can include just a speed change in the same direction.

no I don’t want to remove them, but making them a bit less count of crests and troughs, on the unmodified parts, I mean just increasing that number to 70 fixed the problem for the script I was testing

Oh, sweet. Glad that worked and thanks for the updated number.

I think it’s a personal liking thing, I like 70 you might like 60

To be clear, for others reading this thread, 60ms was chosen for the python script because it is what the Handy is capable of in Bluetooth mode (as of firmware 3.x); the main goal of this script being to retain the original funscript author’s intent as much as possible.

Again though, I’m glad you’re able to find another use for the .py, and other’s who want to use it primarily to reduce vibrations might find your values useful.

1 Like