Sunday, November 15, 2020

Bytecode Adventures: Cartographers Wrath

Dear Monopolis employees,

thanks to our Super Hacker Ethanol we managed to figure out something new about the script files from both Growlanser 5 and 6 (and possibly 1).
At the very beginning of our translation project people might remember that i created a blog post which explained how the pointer table for script files is made:

https://growlanser6english.blogspot.com/2019/03/another-little-test.html

At that point in time, i only knew what the second SDF section was used for (mainly the game's script).
But, thanks to Ethanol, we now know the purpose of the first SDF section!
All those bytes that seem like they make no sense at all are something called "Bytecode".
The developers probably used some kind of proprietary scripting language to tell the game what kind of character should appear when X script line is being triggered.
And, just like the game script, the bytecode section has a pointer table on top of it.
The header (the place where the pointers start counting bytes) always starts at the first byte of the first pointer, which is always "DC 00 00 00" in a .SCEN file. 
Every pointer, just like in the second SDF, is 4 bytes long and little endian.
The 40th & 41th pointer are important, they indicate the start and the end of the bytecode that tells the game what character image, character expression and textbox should be drawn on the screen when X scriptline is triggered. Before and after that also lies more bytecode, but we didn't figure those out yet.
Heres a quick look at the pointer table:


There is a short (2 bytes) that tells the bytecode how many local actors exist in the script.
This is important, because in order to find the scriptline that the bytecode points to you need to add the local actor bytes to the code.
Heres a quick example of what i mean:
 
Inside our script we use abcde's Cartographer to dump and Atlas to reinsert the script of the game.
Each scriptline has a pointer assigned to it, which looks like this:
 
//POINTER #60 @ $10010 - STRING #60 @ $11BB6
 
Inside the bytecode the scriptline would not be 60 (0x3C), it would be 57 (0x39):
 
[SCRIPTLINE-0039+X] = Real scriptline location is +3 (both hexademical)
 
Once we go into the bytecode section we will find another pointertable, this time with 2 bytes/pointer.
The header is the same as before, starts at the very top of "DC 00 00 00".
Below the pointer table you will see that there is just a bunch of bytes, but this is the bytecode that controls the script.



Ethanol was able to figure out some of the codes that reside in there and create a program that takes the original + translated SCEN file and adds textbox names to each string.
This is super useful, because we can now automaticly add names to each string with the click of a button.
But i thought that we might be able to further utilize the bytecode to create an better script.
Since i have some experience with abcde's Cartographer already, i checked if it might supports these kinds of Bytecodes - Maybe even allow a simple "IF" function.
And after taking a look at abcde so called "multitable" files, i managed to create a simple IF logic that is usable for our bytecode:




You can group up different tables inside on big table file and assign conditions to them.
For example:
 
!42000018=<\n[42000018-Portrait Textbox ??? ]>,<@NPCID>:1,<@IMAGEID>:1,<@FACEID>:1,<@TEXTBOXID>:1,<@SCENNAMEID>:1,<@LINEID>:1
 
 <@NPCID>:1
 
  <@NPCID> = Name of the table file

1 = Amount of matches it needs to find before it moves to the next entry
 
And, after some trial and error, we are able to dump a lot of the bytecode and make it somewhat human readable!:


abcde is truly an awesome tool to work with.
We can now add things like the starting character image, character's face expressions and more to our dumped script.
This should help our translator tremendously in being able to follow the flow of the script and make an even more accurate translation.
Of course, there is still a lot of work to do here (actually combining the game script with the bytecode), but most of the unknown bytes that are important for the script have been figured out.
And, in the far future, we might be able to develope a program that is able to utilize the script + the bytecode and combine those information for an easily accessible translation tool (taking the Fate Extra CCC translation program as an example):



And for anybody interested, you are also able to break the characters and their textboxes: