[Game Integration] Modding Tyranoscript Games

Posting to say that I’ve had this game for a long time and would also like to see it if possible. Otherwise, long video would do.

2 Likes

Simple solution here

Credits to @to4st , codes are based on ButtplugImplementation.js from Succubus Academia mod.

  1. Download Custom Player from the link above
  2. Edit “Game Directory/tyrano/plugins/kag/kag.tag_ext.js”
    2-1. It’s really hard to read, just beautify js file using https://beautifier.io/
    2-2. Add code into “Game Directory/tyrano/plugins/kag/kag.tag_ext.js” file line 1
    (change gameName to anything you want)
scriptPlayer = {
	gameName: "avy_game",
	activeScriptName: null,
	getRequest: function(url) {
		var xhr = new XMLHttpRequest();
		xhr.open('get', url);
		xhr.setRequestHeader('Host', '127.0.0.1:5050');
		xhr.setRequestHeader('Accept', '*/*');
		xhr.setRequestHeader('User-Agent', 'SA');
		xhr.send();
	},
	filterScriptName: function(scriptName) {
		return scriptName.substr(0, scriptName.lastIndexOf('.')) || scriptName;
	},
	playScript: function(scriptName) {
		scriptName = this.filterScriptName(scriptName);
		this.activeScriptName = scriptName;
		var url = `http://127.0.0.1:5050/game/gallery?game=${this.gameName}&code=${scriptName}&speed=1`;
		this.getRequest(url);
	},
	stopScript: function(scriptName) {
		var filteredScriptName = this.filterScriptName(scriptName);
		if (this.activeScriptName == filteredScriptName) {
			var url = `http://127.0.0.1:5050/game/gallery`;
			this.getRequest(url);
		}
	}
};

2-3. Add code into “Game Directory/tyrano/plugins/kag/kag.tag_ext.js” file line 89, right before “that.kag.tmp.video_playing = false;” code

					scriptPlayer.stopScript(pm.storage);

image

2-4. Add code into “Game Directory/tyrano/plugins/kag/kag.tag_ext.js” file line 110, right before “video2.load();” code

					video2.addEventListener("play", function(event) {scriptPlayer.playScript(video_pm.storage);});
					video2.addEventListener("seeked", function(event) {scriptPlayer.playScript(video_pm.storage);});
					video2.addEventListener("pause", function(event) {scriptPlayer.stopScript(video_pm.storage);});

2-5. Add code into “Game Directory/tyrano/plugins/kag/kag.tag_ext.js” file line 155, right before “video.load();” code

		video.addEventListener("play", function(event) {scriptPlayer.playScript(pm.storage);});
		video.addEventListener("seeked", function(event) {scriptPlayer.playScript(pm.storage);});
		video.addEventListener("pause", function(event) {scriptPlayer.stopScript(pm.storage);});

  1. Add funscripts to “Custom Player Directory/scripts/game_name_you_defined_in_step_2-2”
5 Likes

The js files can’t be located under the directory as the game comes in a executable file.
image

Unpacking the executable reveals the files. However I’m not sure how to pack it back.

I think the executable is exported using TyranoRider (what people use for Tyrano V4). I tried to use that and pack modified files back into an executable, which crashes after the loading screen… More research needed.

Here’s the modified file. Rename to .js
kag.tag_ext.txt (42.1 KB)

1 Like

I haven’t tried repacking the game, as I’m not familiar with this engine.
Copying all .tpatch files to unpacked directory will make the game work.

1 Like

That worked… Holy. Thank you for the enlightenment.

I’m guessing all videos under avy_game\data\video will need a matchings script… There’s 531 videos in total. It’s a lot but can be handled.

And I’ve noticed that in these .tpatch files there are videos as well. Some of them already exists under data\video whilst some are not. I wonder what these are for…

1 Like

@hugecat Is it possible to extend the life of this topic? Since some progress has been made we may need more time with it.
image

Just checked some videos, many of them were duplicates.

3-4-4-1-2_抽送_速い_019_sex_2_0_1
3-4-4-1-2_抽送_速い_021_sex_2_0_3
3-4-4-1-2_抽送_速い_023_sex_2_0_5

If a videos have the same prefix like ‘3-4-4-1-2_抽送_速い’, they are likely videos with the same pattern.
Filtering with “抽送_速い” didn’t worked as they seems like same video but there were some frame differences.

1 Like

After some tinkering it worked. Awesome image
Many thanks to @to4st and @affqprow!

Started making scripts. There are a lot of videos but most share the same pattern. Spent more effort organising and renaming files than actual scripting.


The only problem I’ve noticed so far is that there seems to be a considerable delay, which becomes very noticeable at fast movement (it will feels like the strokes are basically inverted). Not sure if this can be overcome…

4 Likes

I think I have most if not all scripts ready. Would need a few more rounds of testing before releasing it.

5 Likes

It’s out! Thanks for everyone who helped on this! :smiling_face_with_three_hearts:

https://discuss.eroscripts.com/t/game-integration-a-tale-where-avy-moves-and-oniichan-cums-honey-moon-edition/108019

2 Likes

I’ve found this method also works on a few other Tyranoscript V5 games.

This is 白狼天狗とイチャイチャするやつ, developed with Tyrano V5.

Under \resources folder find “app.asar”. Unpack it. Modify the same “kag.tag_ext.js” mentioned above. You can repack it using 7zip, or just leave them in the app folder.

Game works and the custom player detects it pretty well.

2 Likes

This quote does not seem to work for the game I’m modding (the one mentioned above). Is there any other event listener other than “pause” such as “stopped” or “removed”?

Just noticed that I’ve attached wrong code, try changing pm.storage to null.

video.addEventListener("pause", function(event) {
    playScript(null);
});

and also add similar one to code below

            video2.addEventListener("play", function(event) {
                playScript(video_pm.storage);
            });
            video2.addEventListener("seeked", function(event) {
                playScript(video_pm.storage);
            });
            video2.addEventListener("pause", function(event) {
                playScript(null);
            });
1 Like

Thanks. In the case of momiji this still doesn’t work quite right, though.

Line114 -

            video2.addEventListener("pause", function(event) {
                playScript(null);
            });

This code doesn’t seem to do anything. The game does not use video2 to handle its scene playback I suppose?


Line 75 -

video.addEventListener("pause", function(event) {
    playScript(null);
});

This code had an effect. It does stop the script playback if one attends the pause menu. But it also stops script playback whenever the scene has been switched.
demo

(The game had a cross-fade transition between scenes which makes the previous video stops after the new one begins to play. Could this be the cause of this issue?)


:page_facing_up: kag.tag_ext.csv (rename to .js)

kag.tag_ext.txt (43.9 KB)

Can you test if this code works?

Added scriptPlayer on the top of the js file, and changed event listeners

video2.addEventListener(“play”, function(event) {scriptPlayer.playScript(video_pm.storage);});
video2.addEventListener(“seeked”, function(event) {scriptPlayer.playScript(video_pm.storage);});
video2.addEventListener(“pause”, function(event) {scriptPlayer.stopScript(video_pm.storage);});

video.addEventListener(“play”, function(event) {scriptPlayer.playScript(pm.storage);});
video.addEventListener(“seeked”, function(event) {scriptPlayer.playScript(pm.storage);});
video.addEventListener(“pause”, function(event) {scriptPlayer.stopScript(pm.storage);});

  • just reuploaded file, updated guide above.
1 Like

Works flawlessly! This will also be helpful when modding other games.
Incorporated your code into the game’s mod. Thanks so much for the contribution!

1 Like

I’m not sure if this is the correct way to fix this problem, try replacing play event listener with timeupdate event listener.

video.addEventListener("play", function(event) {scriptPlayer.playScript(pm.storage);});

to

video.addEventListener("timeupdate", function(event) {
	video.removeEventListener("timeupdate", arguments.callee);
	scriptPlayer.playScript(pm.storage);
});

,

video2.addEventListener("play", function(event) {scriptPlayer.playScript(video_pm.storage);});

to

video2.addEventListener("timeupdate", function(event) {
	video2.removeEventListener("timeupdate", arguments.callee);
	scriptPlayer.playScript(video_pm.storage);
});

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