How I determine unknown values

For Terminal Velocity I am currently working on integrating tunnels. I'll talk about the implementation of that in a future post, but this time I wanted to talk about something else first: one of the methods I use to figure out what a value means when I encounter unknown ones.

While I don't have many unknown values left in the game files, the tunnels contain some and this allows me to write about this part of reverse engineering, a nice opportunity given that I reverse engineerd most of the files a long time ago already (a lot of them over 20 years ago!)
The file
So to start, let's look at the file in question. These files contain information on where the tunnel entrance and exit integrates into the heightmap levels.
artic-t1.lvl
28830976,1486686,14188624
20439760,2050976,2659752
1
DBROWN.RAW
icehole.raw
1
DBROWN.RAW
icehole.raw
0
Most of these values were not particularly hard to figure out. Level file name of the tunnel itself, 3d coordinates of the entrance and the exit, specific textures to replace the standard heightmap textures. The unknown values that i still had to figure out are on line 4, 7 and 10 - three very small integers.
So what to do now? Enter: the humble spreadsheet.
Initial data
First, since I can already read the basic files I can easily dump a csv file with literally every single tunnel integration definition per row. From that, I can start doing some analysis. My first go-to for these small integers is to simply look at exactly which values occur across the entire game. This helps to get a feel for what data type I'm dealing with.

I have very creatively named the three values Unknown1, Unknown2 and Unknown3, in the order in which they appear in the file. From this, I intuited that unknown1 is some type of enum, and unknown2 and unknown3 likely booleans. Since the two booleans also appear in the same place relative to the blocks for entrance and exit, it's likely they are related to that.
Now I have to start gathering actual data. That just involves going into the game and paying attention to relevant things near the tunnel entrances and exits. I'm particularly looking for a number of things that I know should be stored:
- Different entrance and exit types;
- Entrances that are not open until you defeat the boss; and
- Whether a cave exits into the open world or inside a cave.



First analysis


Now that I have some data to compare, I can start to look for patterns in the sheet, and it's quite easy to make new columns that check any hypotheses I make. For example, column G in the sheet above (which is where I note if a tunnel exits outside or inside) seems to exactly match Unknown3, and column I (is the custom exit texture used) seems to match Unknown2.


So I add some columns that check this, and add conditional formatting to really make things stand out. Column H above tests the exit type, and column K tests the exit texture. With the coloring, it's pretty obvious that this should be correct!
But wait...
Correcting earlier mistakes
Earlier I estimated that unknown2 would be related to the entrance, and unknown3 related to the exit. This seemed reasonable due to the similar placement relative to those blocks and them using the same value range. But if unknown2 contains exit texture information, and unknown3 has the flag to exit into caves, this cannot be right!

It now seems that it is unknown1 and unknown2 that are the entrance and exit information, and this means that entrance state is a bit more complicated. This also makes some sense, as I earlier mentioned that bosses seem have some influence on entrance availability. With this new insight, it now also becomes easier to figure out those four values of unknown1 as I know they have something to do with using the entrance texture and some other yet unknown state.
The last unknown
Now as the statistics for unknown1 show, its most common value is 1, so it would make sense to label that as "regular entrance", and it means it's good to focus specifically on the handful of places where it is not 1.

One thing is clear: Type 2 is only used for entrances in boss rooms, so this is likely the value for "do not show the entrance until the boss is defeated". Type 0 is only used in one level, and flying through that showed that this is a situation where the entrance texture is simply never used. This makes sense, since unknown2 is the exit equivalent and this would make values 0 and 1 mean the same for both.

Finally, there's value 3. Used only once in the game, for a regular tunnel. It appears to behave the same as type 1 in a regular level. I even went as far as editing the game file to put a type 3 entrance in a boss room, which behaved exactly the same as type 2. This makes me think that the 3 is actually a typo from the makers - there is some evidence in the other text-style data files that these are at least partially hand-authored, and I suspect the game simply treats any value over 2 as 2.
This leaves one thing: What makes a tunnel be unavailable until after the boss? This is what I tried to sort out in the above column H. As you can see, the hypothesis I put into that column is wrong, and given the specific selection of entrance types and how they are used among boss rooms and non-boss regions seems to indicate that there is actually no specific data for this behaviour! The game simply makes you unable to enter any tunnel as long as a boss is active.
All done

And after all this hypothesizing, data gathering, and endless staring at spreadsheets I finally figured out three tiny integer values. But it's another step along the way of understanding this game and being able to copy its behaviour.
Now I can fully integrate the tunnels into my implementation! And that should be the next topic of my TV series.