MultiFunPlayer v1.32.1 - Multi axis funscript player - Now with SLR script streaming

Thanks I was able to get it connected after adjusting my endpoint to the VR headset

1 Like

Hi Yoooi, are you sure you send me the patreon version? The SLR button is missing and I cannot connect to SLR to test out the changes.

image

I forgot it needs to be patreon version to test, sent new build on patreon.

1 Like

Tried the new version but got the error below. How do I fix that?

The type or namespace name 'IToggleInputGestureData' could not be found (are you missing a using directive or an assembly reference?)

You can register actions without IToggleInputGestureData.
But you are missing using MultiFunPlayer.Input;

1 Like

Now playing with pipping Live2D animation into MFP in realtime

https://discuss.eroscripts.com/t/game-mod-request-tomins-playable-fap-hero-game/213733/44

@Yoooi please take a look on the mod (the MFP plugin impl to be exact) and please tell me what’s the best way to make curves in MFP in realtime (my solution does work but not exactly great)

I dont know what exactly you are trying to do, or whats wrong with your current solution.
If you want to drive an axis in realtime you probably should use Axis::Value::Set passing in target value and duration.
If you want to constantly push new keyframes to a script you would have to push them slightly in the future but that will cause desync. Also you might want to disable interpolation in this case because interpolation depends on 1-2 keyframes in the future, so it will probably cause the value to stutter a little bit.

@Yoooi


I just write class Foo{} and it fails to compile

I don’t know as well, so whatever you say will probably be better then whatever I have now

Will do, gonna set linear + 20ms offset for now
And try Axis::Value::Set as well
Does Axis::Value::Set overrides previous Axis::Value::Set?
Is it better to Axis::Value::Set three frames forward so it’d keep constant speed if frames will miss 1/60 s? How can I read the current Axis::Value to get the same value I’d write to it?

How does desync work? Ik it’s “bad” but what exact problems will it cause?

Yea thats a bug, add a dummy base class until next version: public class Foo : object {}

Axis::Value::Set transitions the axis from the current value to your target value with some duration.
They dont stack so you cant send three frames forward.
You have to have a loop that sets the value in a fixed interval (like fixed update), or if you receive moves from the game with a move duration then you can send on each move (like polled update).

With Axis::Value::Set you could still update and send the script so that the heatmap is updated. Just enable script bypass on L0 so you can send axis values yourself.
Also you will probably have to disable sync on script changed, dont know if you have it disabled now.

ReadProperty<DeviceAxis, double>("Axis::Value", ...);
But why would you write the same value?
With Axis::Value::Set there is no “from” value, only target value + duration.

I meant desync as in desync between device movement and the game/video.

I mean, I can use it to set constant velocity for the next 3 frames I don’t have values for yet, and then override it with new velocity

I did mean “If I write 0.123 I read 0.123” as there are Axis::ScriptValue Axis::TransitionValue and probably some more of them



Okay I guess I will new Foo().OnInitialize() lol

Yea thats a bug too, fixed.

Yeah did it without too. But I’ll try it with the import

Can I make the mod reload itself on save?

Why TF I have to do THIS


Seeking doesn’t work properly unleast I Invoke it AND send ForceSeek message
It was a very good idea to say “meh, lemme just use every seek at once”


You should use forceSeek here or it won’t work for <1s loops
BTW can I subscribe to this event?

Please let me know how the toggles work now, I tested them and they should work better now. I want to release v1.32.1

The plugin is recompiled on each file save/rename/move etc.

  1. If you are using InvokeActionAsync you have to await them
  2. Media::Position::Time::Set does not change the media position, it only sends MediaSeekMessage that is handled by each media player differently. You have to handle that message if you want seek via heatmap click or AB loop to work, change your internal current media position to the one from MediaSeekMessage and then send it back with MediaPositionChangedMessage to update MFP internal position
  3. MediaPositionChangedMessage is enough to seek, if you want to seek less than 1 second you have to force seek.

This just sends a request to seek to the media player via MediaSeekMessage, the actual seek happens when the media player responds with MediaPositionChangedMessage

Weirdly enough doesn’t seem to work on save for me. rename/move does work.
Please check if it works for you (e.g. if you edit [DisplayName] in regular Notepad and save) and tell me so I can keep looking for why

Okay I see it’s a problem of Internal source which I just happen to use somehow
Internal seek used on graph click and in AB loop is not a force seek
Test case: make an 1.5s filler script, load it in Internal source, you can’t seek ±0.5s, you can’t make a working AB loop with duration 0.5s
In MPV this does work tho


Can I subscribe to the UpdateThread with its high resolution interval?

Hey, whenever I loop a video and it starts playing it starts of slowly. Is this like a safety mechanism? And is there a way to turn it off so it’s 100% right from the moment the script starts playing?

Hi sorry for the delay, I’m away from home a few days. Can test on Wednesday

Yes its for safety.
Click the button to the right of the play/pause button, and disable sync on media seek.

Change log level to trace and check the logs.
In Visual Studio you dont even have to make changes to the file for it to save and trigger a recompile.

Because MPV has an actually usable api, and it differentiates between seek and position change.
All media players except mpv dont force seek on changes smaller than 1 second.
They could be updated to support that but is this actually a reasonable use case? What do you want to loop that is less than 1 second.

No, you have to create you own thread.
You can use Stopwatch.SleepPrecise extension method which is used by MFP internally, but don’t make it run at some insane update rate, 100hz should be enough which is the default for outputs fixed update.

Awesome, thank you!

create/move/delete does show a event, saving doesn’t. The event exists in the system as VSCode does notice it.
Tried with a clean v1.32.0 from 7MB zip on C drive, same.


There are chapters with duration below 1s
AB loop on them doesn’t work (Internal source)
And you can’t precisely seek as near seek doesn’t work (Internal source)


I’m unsure if there’s a reasonable use case, but please fix it for Internal source I guess? I seem to hijack over it