Tool Others Script to cut data file out of combined TyranoBuilder exe

Surgy

Member
Modder
Apr 23, 2018
363
1,518
This PowerShell script is helpful when TyranoBuilder game is merged with copy /b tyranoscript.exe+app.nw game.exe command into single exe. It allows separating main TyranoScript executable and game resources for translation. Run this script first and use -Unpack in command line (or manually unpack data.zip file to the game folder) then run resulting exe file to use unpacked resources. data.zip and game.old files can be deleted afterwards or kept as backup.

Usage:
Code:
cd D:\the game dir\
powershell -executionPolicy bypass -file "tyranocut.ps1" -Unpack -GameExeName "game.exe"
The script should be copied to and started in command line from directory containing game executable. The directory's path mustn't contain [ or ] characters due to PowerShell quirks.

Edit: Added option to unpack data.zip automatically, just add -Unpack to command line.
 
Last edited:

Big Daddy

Member
Jul 17, 2017
404
929
Thanks for making this, solves a lot of modding issues. I'm currently running into the 'System.OutOfMemoryException' discussed on this thread when trying to unpack this game. The games full unzipped size is 1.21 GB. My system has 16 GB installed, and I ran the script with 13 GB of free RAM available, but still ran into this error. I tried running both the standard and -unpack option line, to no avail. Any thoughts on what the issue could be or if the script could utilize the pagefile?

Full error:
Processing MHAT v.0.10.0 (64-bit).exe...
ConvertTo-BinaryString : Exception calling "ReadToEnd" with "0" argument(s): "Exception of type
'System.OutOfMemoryException' was thrown."
At D:\My Hunting Adventure Time\MHAT v.0.10.0
(64-bit)\tyranocut.ps1:56 char:15
+ $binString = ConvertTo-BinaryString -Path $inputFile
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: :)) [ConvertTo-BinaryString], MethodInvocationException
+ FullyQualifiedErrorId : OutOfMemoryException,ConvertTo-BinaryString
 

Surgy

Member
Modder
Apr 23, 2018
363
1,518
I'm currently running into the 'System.OutOfMemoryException' discussed on this thread when trying to unpack this game.
Unicode string in .NET/PowerShell takes 2 bytes per character and there is a hard limit of 2Gb per string. So files >1Gb raw bytes are impossible to cut, because currently the script attempts to load the entire file to memory at once as a searchable string.

I will try to fix it at some point.

For now you can open the exe in any unpacker that takes malformed zip archives to unpack data and cut out the original tyranoscript.exe (all bytes before first occurence of 50 4B 03 04 0A 00 00 00 00 bytes) manually in a .
 
Last edited:

Big Daddy

Member
Jul 17, 2017
404
929
Unicode string in .NET/PowerShell takes 2 bytes per character and there is a hard limit of 2Gb per string. So files >1Gb raw bytes are impossible to cut, because currently the script attempts to load the entire file to memory at once as a searchable string.

I will try to fix it at some point.

For now you can open the exe in any unpacker that takes malformed zip archives to unpack data and cut out the original tyranoscript.exe (all bytes before first occurence of 50 4B 03 04 0A 00 00 00 00 bytes) manually in a .
Makes sense, figured it was an architecture cap. For those that stumble across this thread and are looking for another way to modify tyranobuilder files, this guide will take you through the process (similar to what Surgy outlined above, but with more detail.)

The downsides to this method compared to Surgy's script is that it's a bit more involved and you can't change the .exe data folder on the fly, which is a bummer. Still worth doing though in many cases to fiddle with the config files and add menu shortcuts. Tyranoscript is certainly not as modifiable at a script level than ren'py though.
 

S3ri4l

Member
Jun 7, 2020
261
528
Hello, so with this I'm able to extract script of a tyrano vn? Just thinking about translating one.
 

Lies.

New Member
Jun 5, 2019
10
15
Thanks for writing this script! I've written a version using Python, which avoids loading the whole file into memory and just unpacks the zip contents to the current directory:

Python:
#!/usr/bin/env python

"""Extract data from combined TyranoBuilder executable."""

import sys, zipfile


def main():
    if len(sys.argv) != 2:
        print ('usage: ./tyranocut.py Game.exe')
        return

    with open(sys.argv[1], 'rb') as f:
        with zipfile.ZipFile(f) as zf:
            zf.extractall()


if __name__ == "__main__":
    main()
Note this doesn't seek for the magic bytes first, as the zip directory is at the end of the file anyway.
 

Surgy

Member
Modder
Apr 23, 2018
363
1,518
Lies.: Cool, it's nice to have this too, but the point was not only extracting the game, which can be done in any archiver that supports non-standard zips, but also to separate the main executable so the game could load those unpacked resources.

Here I modified this script to do just that:
 

Lies.

New Member
Jun 5, 2019
10
15
Lies.: Cool, it's nice to have this too, but the point was not only extracting the game, which can be done in any archiver that supports non-standard zips, but also to separate the main executable so the game could load those unpacked resources.
Ah, makes sense. If using ./nw to run the game, the exe isn't required, but when you want to modify the contents but run on Windows still you might want the original exe rather than downloading a nw.js release to run the unpacked game. Your adjustment to find the magic bytes and copy out up till that point looks reasonable to me.
 

pixvoliv

Newbie
Aug 18, 2018
58
288
I have to confess that I did not search for this (I probably should have!) and just ended up whipping up some of my own tools and wrapper scripts to create and apply a . This would have saved me a bit of work, and I think I might still use it - thanks!

I know that when TyranoBuilder games start up, they extract the data into a temporary directory (%TEMP%/nwSOMENUMBER_SOMENUMBER on Windows) every time and use the files there, so my scripts just wait for that extraction process to complete, then swap out the translated files. Those can even be hot-swapped, which is very useful during development! I have made a script for Windows (batch script in the .bat file) and another for Linux (bash script in the .sh file, requires Wine). It should be as simple as putting the translated files into a "translation" folder (following the same directory structure as the original game) and setting the "game_executable" variable to the name of the main executable. It's a bit hacky in a quick-and-dirty sort of way, but it doesn't require anything in the main game directory to be overwritten or modified, which I find rather neat.

What do you think?
 
Last edited: