[Game Integration] Modding Tyranoscript Games

In the case for Avy, I think it’s due to the game stalling before the video begins to play. So the scene switches, scripts are played, but the video playback starts ~200ms after.

This doesn’t happen with Momiji, which is made with Tyrano V5 and reads much more faster.

I’ll try out the code anyway and see if they helps.

I also noticed this and thought it was an engine related problem, not a Funscript Player related problem.

I checked video event cycle and found that timeupdate event is called 200~300ms after play event is occured.

with Momiji, timeupdate event is called 50~80ms before play event, I don’t think we need to update the code on the other games if they don’t have sync related problem.
image

or just adding a little delay when calling the playScript function on the video play event will work too.

1 Like

Tested the Timeupdate event listener code and it greatly improved sync with Avy (FunscriptPlayer v1.2 and v1.12.1 beta).

This is the modded file:
kag.tag_ext.txt (42.8 KB)

I guess this is definitely the method to use for this particular game. I will update the game mod once the new version drops.

Also might worth notifying @to4st for this discovery.

1 Like

@affqprow

Another Tyrano V5 game, Otutome Sakuya, has been modded by the community. I have attempted to mod the game using our code but have encountered some issues.

The game had an interesting file structure. Under \data\video, scenes for the same stage are grouped into individual folders.
image

Say the game plays 1.mp4 on stage 1, the application will try to play 1/1. This is impossible to provide a matching script for because filename cannot include “/”.
pr

Curiously, in the mod provided by @vylon, the name formatting have changed to 1-1.

I wondered how this was done. And it turns out vylon did more modification to app.asar and have reworked the file structure completely. If i have not mistaken, they must have also touched other code to make the game run.
image

So what I’m thinking is, is it possible to achieve this name conversion (either announced by the game or interpreted in Funscript Player) without heavily modifying the game files like this? Games can get updates and it’d be better to not carry out such rework each time.

It can be easily done by editing this part, replacing “/” with “-” will work.

	filterScriptName: function(scriptName) {
		return scriptName.substr(0, scriptName.lastIndexOf('.')) || scriptName;
	},
	filterScriptName: function(scriptName) {
		scriptName = scriptName.replace("/", "-");
		return scriptName.substr(0, scriptName.lastIndexOf('.')) || scriptName;
	},
1 Like

Thank you! Knowing how to read JavaScript helps… kag.tag_ext.txt
Here, a lite version of the Sakuya mod with modified kag.tag_ext.js and 99DM’s script only.

1 Like

It’s just simple
Tyrano games are controlled by scenario files in app.asar
You can modify the scenario file yourself

For example

Original script in main.ks
image

Use / symbols for folder structure in Tyrano games
But funscript players don’t have a deep folder structure
Also, you cannot use the / symbol in the file name

So I changed it like this
image

‘/’ Modified to use the ‘-’ symbol instead
The ‘-’ symbol does not have any special function in Tyrannogames, and can also be used in file names
All scripts associated with .mp4 have been modified

Rename all videos to new rules
After that, take it out of its original location and put it in the video folder

like this

As a result, the funscript player can access the video without going deeper into the structure

I apologize for my poor English
If you have the original game, you can easily find the difference
title_screen.ks, main.ks, bossrush.ks three files changed

1 Like

I can’t believe I didn’t know an easy way
image

1 Like

Thank you for the insight! We are not familiar with Tyranoscripts, so this will be very helpful when modding other games. :grin:

2 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.

Some useful information discovered by @ZeroScripts :

TyranoBuilder can utilize “.tpatch” files to add additional data, or overwrite existing files, even if they’re still compiled in the .exe or app.asar. This allows us to include all the mod-specific content into a single file, which then can be easily added to the game.

The “.tpatch” file itself is simply made out of a .zip, containing all the necessary files in their original folder structure (e.g., [gamename]\tyrano\plugins\kag\kag.tag_ext.js), which is then changed to the extension .tpatch. The file must also have the same name as the game’s .exe and be in the same directory.

1 Like

I’ve gathered and am testing quite a few Tyrano games now.
For most of them, I managed to get the integration working and it’s just a matter of making the scripts (since I’m new to scripting, this is gonna take me some time tho :snail:).
Some of the games however, don’t just call or have video files, but instead use Live2D assets for the animation.
Other games, like MountBatten’s Aesop’s Fables (and maybe his upcoming game as well), even seem to use a combination of both, videos that are then called by .csv files in the scenarios.
@affqprow & @vylon do you maybe have an idea on how to intercept the animations in those cases?

1 Like

The Tyranno builder seems to play the video with the mtn number in the model file.

When specifying the mtn number in the scenario file, it must be sent to the player.

But I’m sorry I don’t know how.

1 Like

Thank you, that’s some quite useful info. :smiley:

All live2d animations are handled in data/others/plugin/live2d/driver/index.js (included in live2d.tpatch)

beautify js using https://beautifier.io/, and add the code below to index.js line 3604.
scriptPlayer.playScript(${this._modelSetting.getModelFileName().replace(“.moc3”, “”)}/${n});

I guess the hardest part here is scripting these motion files.

And maybe we need to filter out some models like Doris_Heart, Doris_goddess, Doris_talk.

3 Likes

Awesome, that’s gonna be a big help! Thank you :grin:

1 Like

Looks like the formatting caused some issues with the apostrophe in code snippet you provided.
With a small change, I was able to intercept the animations as well.

Like you said, since many of the motion elements are playing at the same time, they’re interfering with the FunscriptPlayer.
So I’m only filtering out those models that we don’t want for the scripts.
Which then looks like this:

if (!this._modelSetting.getModelFileName().startsWith('Doris_goddess') && !this._modelSetting.getModelFileName().startsWith('Doris_Heart')){
	scriptPlayer.playScript(`${this._modelSetting.getModelFileName().replace(".moc3", "")}/${n}`);
}				

I’m currently working on a good way to script these motion files.

Still unsure about how to get the later parts of the game working tho, since the animations switch back to video files, instead of Live2D.

1 Like

I think kag.tag_ext.txt patch + index.js patch can handle both video and live2d.
Not sure as I only tested the trial version.

I tried that before, but couldn’t get the video interception to work.
Turns out I had an issue with the code format as well and needed to adjust it a bit for this game’s unique structure.

So now just comes the hard part :laughing:

2 Likes