Funscripts - Amethyst-Sysadmin/Howl GitHub Wiki

Howl can use funscript files to produce output that is in sync with videos. The funscript format was originally created for use with "stroker" type toys. Funscripts contain a series of timestamps and positions that tell the stroker how to move as the video progresses.

Howl plays funscripts by converting that series of stroking motions into output suitable for a stereo estim device in real-time. This includes:

  • Using a positional panning effect between channels so that actions feel like they're occurring in the right places.
  • Scaling the output power appropriately, so that slow movements feel more gentle than fast ones.
  • Subtle sensation differences between up and down strokes.

Funscript playback essentials

It's necessary to use Howl's suggested electrode setup (where channel A creates a "lower down" sensation, and channel B creates a "higher up" one) in order for the positions of actions to feel correct.

Using our Howl Sync add-on for Kodi (or other similar software) is highly recommended for convenience. This allows Howl to automatically play a funscript when you start watching the associated video. It also keeps Howl's playback position in sync with the video if you skip around.

If you are not using synchronisation software, you can instead load your .funscript file into Howl's player manually, and press the play button at the same time as you start the video (on whatever device you're using to view that). But this is a relatively clumsy method that is prone to small timing errors, and will not follow skips.

For maximum immersion you will probably need to make some adjustments to get correct sync with your chosen video. If using Howl Sync (or similar add-ons), adjust the player's "Remote Latency" setting. This is a permanent adjustment and will be applied for all files, so should be used to correct for the typical latency you experience.

If you are not using the add-on, or just want to correct one file where the sync is off, you can instead use the player's "Sync fine tune" setting. This makes a temporary timing adjustment that will be reset whenever a new file is loaded.

Where to find funscript files

Thousands of funscripts have been created by the community for a wide range of different videos. Eroscripts is currently the most popular site for sharing these (free registration required to view scripts).

Funscript type

Howl's algorithm is designed for the most common type of funscript, where the actions it contains represent physical movements (the same scripts a stroker toy would use).

"Action based" funscripts (which follow physical actions in a video) usually give a more immersive experience with our algorithm than "beat based" ones (which follow music).

Funscripts intended for Restim will not work well, since they are storing its own parameters (more like how Howl uses HWL files) and do not represent physical movements.

Multi-axis funscripts

Some advanced funscript files contain multiple axes of movement. In addition to the up/down movements you'd find in a basic funscript, these multi-axis files can contain different types of motions such as rotation, side-to-side movement etc.

Howl supports multi-axis scripts with up to 6 motion axes, specifically: stroke (L0), surge (L1), sway (L2), twist (R0), roll (R1) and pitch (R2).

Howl requires that all the axes are present in a single funscript file. If you have scripts in the older format that provided a separate file for each axis (like "example.funscript", "example.pitch.funscript" and "example.roll.funscript"), it's possible to combine them into a single file using the handy "funscript_combiner.py" Python script that I've provided in this repository.

Of course it's not technically possible to get a complete 3D effect from a two channel system, so we instead focus on representing these multi-axis scripts in an interesting and fun way. Howl's support works by feeding motion on all axes into our power algorithm, so that any kind of movement creates a sensation that can be felt. Then we apply some special axis specific frequency effects on top of that. For example leaning forward in R2 has a subtly different feel to leaning back.

Advanced funscript settings

Howl offers a number of settings to control exactly how its funscript playback algorithm works (located in Settings / Funscript). Adjusting these is not required and the default settings are expected to work well.

Scaling coefficient Controls how our algorithm scales power. At higher values, slow and medium speed movements will produce more powerful output (very fast movements will be high power regardless of the setting). At lower values, there will be more dynamic range, and you will notice a bigger power difference between fast and slow movements.

Motion profile Controls how Howl interpolates funscript paths (the way it assumes a stroker device would move). The minimum setting of 0.0 represents linear movement by an unrealistic device that can change speed and direction instantly. The maximum setting of 1.0 is a cubic interpolated path, representing a device that takes some time to turn round (spending more time at the ends of strokes and less in the middle).

Positional effect strength This adjusts the strength of the positional effect that Howl uses to "pan" between the channels when playing funscripts. At 0.0 there is no positional effect, and both channels always have the same power level. At 1.0 there is the maximum possible positional effect, with only channel B used for funscript positions at the very top, and only channel A used for positions at the very bottom.

Amplitude calculation window Sets the length in seconds of the window that Howl uses to smooth its power level calculation (with Gaussian weighting towards more current values). Lower values are more responsive to the script, and higher values provide a smoother experience (avoiding jarring on and off between each stroke).

Frequency energy proportion Controls how much the speed of each stroke affects the frequency used. For example at the default value of 0.2, the stroke speed has a 20% weighting in our frequency value, so faster strokes are assigned slightly higher frequencies. The remaining 80% comes from the stroker position (with low positions having low frequencies, and high positions having high ones).

Setting this to 1.0 gives a completely different feel, where the frequency is determined entirely by the stroke speed, and position is not used at all.

Frequency directional shift Adjusts the strength of the directional shift component of our frequency calculation. This gives upward and downward strokes subtle differences in sensation by adjusting the frequencies used on each channel depending on the direction and speed of the stroke. At 0.0 there is no difference between up and down strokes.

Flip frequency directional shift When enabled, our frequency directional shift adjustment is applied the other way round (so the sensation of upward and downward strokes is effectively swapped).

Normalise axes When enabled, Howl expands funscript axes that do not make use of their full range. For example if a script only utilises 3/4 of the stroker device, Howl would expand it to use full top to bottom strokes. Multi-axis scripts are expanded in a smart way, with additional axes favouring preserving balance around their central point over maximal expansion.

When disabled Howl uses the values from the funscript file exactly as provided, with no range expansion.

Normalisation is applied as we load a funscript file. So if you change the setting and already have a funscript loaded, you will need to reload it in order to see any difference.

Additional notes

Avoid having Howl's recorder in active (switched on) mode when playing back funscripts. Recording mode is not time accurate, so it will cause your funscripts to go out of sync (and any latency adjustments will not work).

Keep in mind that funscripts are usually made for physical stroker devices, which cannot just jump instantly from the bottom to the top like an estim device can, and will have a maximum movement speed. Even a very well written script cannot always mirror a video perfectly, because the author will probably have been observing these limitations.