Here is a detailed explanation of the .ott script syntax used for RealTouch scripts from the original CDK, “Guide to Creating RealTouch Video Content” version 1.0.0.
I wrote a funscript to .ott parser at one point in JavaScript and it was relatively straightforward but never tried .ott to funscript. For example magnitude / velocity ranges from 0-255 in .ott files, so you could apply a scale factor to convert those into a 0-100 movement scale.
The main command types to look at are V (vector movement) and P (periodic movement, i.e. patterns). H = heat and L = lube so those only make sense for devices with those capabilities.
The axis parameter determined whether the command applied to T (Top Belt), B (Bottom Belt), U (both belts), or S (squeeze orifice at the entrance).
I looked at the Syncydink Github link and it lists “RealTouchScripter Format (RealTouch format)” under Supported Haptic File Formats but I couldn’t find where in the code that’s implemented. src/utils/HapticsToButtplug.ts has other conversion functions like FunScriptToFleshlightLaunchCommands.
buttplugio had a RealTouch plugin that parsed .ott format, but for applying them to USB commands for the RealTouch rather than funscript.
Excerpt from Guide to Creating RealTouch Video Content version 1.0.0:
3.1: Statements
Each script statement follows the general form:
<comment> <statement><newline>
The comment field can contain any textual data (as long as it doesn’t contain spaces). We use the comment field to record time offsets when preparing scripts for integration into video content — we’ll explain that convention in a later section.
The statement field is separated from the comment field by a single space. The contents of the statement vary depending on the type of command that is being represented. Each statement type is detailed below.
3.1.1: Movement (Vector)
Vector movements are represented with statements in the following format:
V <magnitude> <axis> <direction> <duration> [<inMagnitude> <inDuration> <outMagnitude> <outDuration>]
An example of a vector movement command would be the following:
@ V 192 T IN 1000 96 250 64 250
In this example, @ is our comment. V represents that this is a vector movement. The magnitude is 192. This command will move the top belt in the device (T) inwards (IN) for 1000 milliseconds (1 second). Additionally it contains an “envelope” (fade in and out)–it will fade in from magnitude 96 for 250 milliseconds (¼ of a second) and then will reach the full magnitude of the movement (192). It will then run the full movement for 500 milliseconds (½ of a second) . The last 250 milliseconds will fade from magnitude 192 to magnitude 64. The main magnitude is played for 500 milliseconds because of the fade-in and fade-out in the envelope.
Here are the possible values for each part of the statement:
• Magnitude values range from 0 (no movement) to 255 (the fastest possible
movement)
• Axes can be represented as: “U”—both top and bottom belts, “T”—top belt, “B”—
bottom belt and “S”—squeeze (orifice)
• Directions are represented as either “IN” or “OUT”—and are from the perspective of
the user of the device
• Duration values are expressed in milliseconds (1/1000th of a second) and the
available range is from 0 to 65535
3.1.2: Periodic Movements
Periodic movements are very similar to vector movements. The primary difference is that they contain a “period”. They start out in the direction that is specified in the statement, and then after the period has elapsed, they direction is reversed. Periodic statements have
the form:
P <period> <magnitude> <axis> <direction> <duration> [<inMagnitude> <inDuration> <outMagnitude> <outDuration>]
An example of a periodic movement statement looks like this:
@ P 2 127 U OUT 1500
The optional envelope is omitted from this example statement.
This example creations a vibration with a period of 2 milliseconds, a magnitude of 127 (out of 255—so 50% intensity) affecting both belts (U), starting with an outward movement (OUT) and lasting for 1500 milliseconds (one and a half seconds). The ranges and values of the statement work the same as a vector movement. The only addition is a period value. Periods are expressed in milliseconds and can range from 0 to 255. They are intended to create short, vibratory pulses or persistent vibrations and other special effects when combined with vector movements. If a vector movement is currently being played back on the device, and then a periodic movement command is issued, as long as both commands have the same directionality then the effect will be additive—in other words the vibration will be overlaid over the top of the movement. If the directions disagree, then the second command will terminate the first command.
3.1.3: Heat
Heat can be turned on or off. The format of the heat statement is as follows:
H <magnitude>
An example would look like the following:
@ H 224
As with the other examples, @ is our comment. H defines this as a heat statement. The magnitude is set to 224. The current revision of the device ignores heat magnitudes, and simply turns the heat on in response to a heat command. This was done in order to provide a margin of safety. Future revisions of the output device will likely allow much more fine-grained control over the heat and other environmental properties.
3.1.4: Lube [the lube pump stopped working on many RealTouch devices so in practice these commands often had no effect]
Lube is dispensed into the device based on “bursts”. You can release more lube into the device by sending more volume, longer bursts or more frequent bursts. It is up to you as a content developer to determine how much lube volume is appropriate for your application.
Below is the format of a lube statement:
L <magnitude> <duration>
An example would look like the following:
@ L 192 1000
The magnitude and duration values work the same way as they do in the other statements — magnitude ranges from 0 to 255 and the duration is expressed in milliseconds and ranges from 0 to 65535.
3.1.5: Stop
It is possible to stop each component of the device independently — each of the axes, the dispensing of lube and the heater. Stop commands have the following structure:
S <axis>
An example would be:
@ S T
This example tells the device to stop the top belt. Possible values for the “axis” parameter
include:
• “A”: “All”—stop every component of the device
• “H”: “Heater”—turn off the heater
• “L”: “Lube”—stop the dispensing of lube
• “T”: “Top Belt”—stop the top belt
• “B”: “Bottom Belt”—stop the bottom belt
• “U”: “Both Belts”—stop both the top and bottom belt
• “S”: “Squeeze” (orifice)—stop the orifice
In practice, you will probably not issue stop commands for most of these axes. Most of the movement or environmental commands you issue already have durations and as such will end on their own. The two most useful stop commands are for the heater and the “all” stop.