Funscriptとは
funjackによって、Fleshlight Launchのために設計されたスクリプト。拡張子は「.funscript」。
詳細:https://godoc.org/github.com/funjack/launchcontrol/protocol/funscript
作成方法
専用エディタ(TorpFunscriptGeneratorなど)を利用するのが一般的。
テキストエディタで編集することは難しい。
仕様
内容
JSON形式で記述される。
{
"version": "1.0",
"inverted": false,
"range": 90,
"actions": [
{"pos": 0, "at": 100},
{"pos": 100, "at": 500},
...
]
}
項目名 | 説明 | 必須かどうか | デフォルト値 | 備考 |
version | Funscriptのバージョン | “1.0” | ||
inverted | 位置を反転させるかどうか | false | true または false | |
range | 可動域 | 90 | 0~100 | |
actions | ◯ | |||
pos | 指定位置 | ◯ | 0~100 | |
at | 指定位置にいる時間 | ◯ | ミリ秒 |
詳細
CSVとの主な違いは、速度の指定がないことである。
Funscriptは「この時間にこの位置に居てほしい」という内容で、速度はアプリ側が計算して、自動的に決定される。
指定位置(pos)は0~100以下の整数。0が手前、100が奥。
時間(at)の単位はミリ秒の整数。秒数を1000倍した数字を記述する。
実装
可動域
実装側は、Funscriptで指定された可動域を上書きすることができる。
ただし、実装側で最大値(max)、最小値(min)を定義したとき、以下を満たす必要がある。
(max - min) == range
(max - min) <= 90
デフォルト値:max == 95, min== 5
これは、ファームウェアのリバースエンジニアリングによって得られた値であり、この範囲外で安全に使用できるかは明らかではない。安全第一。
速度の決定
実装側は、Funscriptの時間(pos)と位置(at)をもとに、速度(speed)を算出する必要がある。速度の算出には”Magic Launch Formula”と呼ばれる以下の公式を使用する。
speed = 25000 * (duration * 90 / distance) ^ (-1.05)
speed : 送信する速度
duration : 1回の動作にかかる時間(msec)
distance : 移動距離(1~100)
速度(speed)は20~80の範囲内である必要がある。これより遅いとLaunchがクラッシュし、これより速いとノイズや故障の原因になる。
移動アルゴリズム
Funscriptでは、反転(inverted)がtrueでない限り、時間が0のとき最下部(min)に位置し、その後最上部(max)から動き始める。これは暗黙の了解であるため、必ずしもFunscriptのアクションに含める必要はない。
各アクションにおいて、
- 位置(pos)が1つ前のアクションと同じ場合は移動しない。
- このアクションを完全に無視するのではなく、次のアクションでは「1つ前のアクション」として使用する。
- 反転(inverted)がtrueの場合は、位置(pos)を反転する
- 例:0→100、25→75、70→30
- 可動域(range)を反映し、位置(pos)をスケーリングする
- オフセットとしてminを反映する
min= 0/range=50/pos=75 -> 75 * 50% + 0 -> 37 + 0 -> 37
min=10/range=90/pos=80 -> 80 * 90% + 10 -> 72 + 10 -> 82
min=20/range=80/pos=30 -> 30 * 80% + 20 -> 24 + 20 -> 44
- 1つ前のアクションからの経過時間(duration)と移動量(distance)を算出する
(例:rangeが100%のとき)
{"pos": 25, "at": 100}, {"pos": 100, "at": 500}
duration = 500 - 100 = 400
distance = (100 - 25) * 100% = 75
- 経過時間(duration)と移動量(distance)から、速度(speed)を算出する。
- 1つ前のアクションで指定された時間(at)に、これらの位置(pos)、速度(speed)を送信する。
制約
Funscriptには、以下のような制約がある。
- 速すぎる動きが不可能。
- Funscriptが短い経過時間(duration)内に大きな移動量(distance)を要求した場合。
- 算出される速度が最大速度(80)を上回るが、実際は最大速度で動作する。
- そのため、次のアクションが始まる前に現在のアクションを完了できない可能性がある。
- この場合、Funscriptが要求するよりもストロークが短くなってしまう。
- Funscriptが短い経過時間(duration)内に大きな移動量(distance)を要求した場合。
- 遅すぎる動きが不可能。
- Funscriptが小さな移動量(distance)を長い経過時間(duration)内に要求した場合。
- 算出される速度が最小速度(20)を下回るが、実際には最小速度で動作する。
- この場合、Funscriptが要求するよりも早く動作が完了してしまう。
- Funscriptが小さな移動量(distance)を長い経過時間(duration)内に要求した場合。
このように、一部のアクションが同期から外れることがある。可動域(range)を制限すると高速移動が可能になるが、低速移動が不可能になる可能性がある。
この仕様を定めたプロジェクトであるLaunchcontrolは、Fleshlight Launchへの送信間隔に100msecのしきい値を設けている。これより頻繁に送信しようとするFunscriptは、その一部が同期されない。
コメント