More Reverse Engineer – SimTower

Another game from my childhood that I played a lot was SimTower. Never to the same extent as SimCity 2000, but still a fixture of my game playing time. Note that I’m writing this as I work on the reverse engineering, and I plan to update with more information on my process.

Someone in a Discord was commenting that they would like to see a viewer (and maybe editor) like the one I’ve created for SimCity 2000. I decided to take a crack at the .TDT (Tower DaTa?) format SimTower uses to store the towers, especially given I’ve got a decent amount of experience reverse engineering old game formats like what SimTower uses.

First Steps

The first step was to get the game working. I found that Winevdm worked pretty well, but I needed to copy WAVEMIX.INI from my CD into Winevdm’s WINDOWS folder, and WAVEMIX.DLL into WINDOWS\SYSTEM in order for the game to start. With that out of the way, the game started.

Now, one of the tools I used to help reverse engineer the .SC2 file format was ProcMon, because old games frequently loaded small chunks of the save file into memory, likely to save on relatively limited RAM resources as they may be stored in a more RAM efficient data structure when in use, and serialized to something that’s better for that (or not).

SimTower was luckily no different, giving me my first hints as to what the file format looks like. I’ve attached a CSV output from ProcMon, as an image from VSCode so that it’s a little nicer coloured below.

A colourized CSV from ProcMon showing the process reading from the tower file, listing offsets into the file and lengths of the read.
Part of the CSV output of ProcMon after filtering. “ReadFile” means that it’s reading a file, the next part is the path to the files and “SUCCESS” means the read was successful and returned data. But the interesting part is the offset into the file and the length.
The small, short reads are generally indicative of reading value in single variable. The repeated pattern is also really interesting, as it suggests repeated entries of the same data structure.

Floor Data

Immediately I can pick out a few things. The first 70 bytes look like a header, because it was common for games of the time to load various single variables individually, especially if they store counts or lengths of later values. Inspecting the value of a few towers confirms this is probably the case. I’ll touch on the header later. There also seems to be another 490B block common in most tower files I looked at. Past that, there’s a suspicious repetition of 360 reads following the same format. 6 Bytes, variable bytes and 188 Bytes.

Note: The game save is little-endian, so data will be in reverse order of Big-endian, which I’m more used to on x86 systems. This probably means the game was originally developed for the Mac and ported. In this case, I looked at the hex representation of several of the 4 Byte values, and saw XX YY 00 00, which is the ordering I’d expect for a small number stored little-endian. Bit-endian would be `00 00 YY XX` instead, with the unused data on the left and the byte order reversed.

As a guess, 360 reads means 120 actual values. SimTower has at least 113 floors (10 underground, 100 normal floors and a additional 3 floors for the cathedral on the 100th floor), so a few extra to pad out the window to 120 seems reasonable. I also note that each variable length piece is always a multiple of 18 Bytes long, so my first guess is that each of these is a “unit” on a floor.

The 6 Bytes repeated screams “row header” to me, and after creating a tower with 110 floors, save the first floor lobby, of empty floors, I see my first pattern. I know, from counting money spent building a full width floor, that I have 375 horizontal tiles to work with. In my empty tower, each of the 6 Bytes looks like 01 00 00 00 77 01 which interpreted as 3 integers is 1, 0, 375. Given that the floors cover the whole width, the second and third value appear to be the start and end of the floor. Inspecting several other saves confirms this, and I also noticed a pattern in the first value. It’s the count of the number of 18B entries after it.

Which means yes, we’ve got floor data here. There’s still a lot of data that isn’t accounted for. People’s and business’ nicknames (the game allows setting name for people and businesses, and this appears to be stored at the end of the file), elevators, various simulation variables, etc.

Unit Data

Now that we know, at minimum, a unit is given by an 18Byte structure, we can start sussing that out. Right away, I see that my empty tower has one unit, and the data structure mirrors the 6 Byte header, with the first 4 Bytes being 00 00 77 01 followed by 00 or 24 for my height 1 lobby, which suggests that this is a unit type field.

If I know start and end of a floor, as well as start and end of a unit and the unit’s type, then I can start figuring out what values in the field correspond to the type in the game. Rather than squint at a blast of text in a proof-of-concept Python parsing script, I decided to write a simple image generator using Pillow. Here’s an example of a 5 star tower I built to test things out.

A colourful schematic view of the floor data in a tower's data file.
A 100 story tower with empty space in blue, lobbies in purple, yellow for shops, grey for fast food, green for restaurants, salmon and cyan for hotel rooms, turquoise for offices, brown for condos and other colours for other things. Referring between this and the game is easy to figure out the index mapping.

And just like that, with randomly chosen colours, we can see a tower take shape. The smallest “block” in SimTower is a 10×45 pixel tile (or so), so I made each block 1×5 pixels in this image to maintain a similar aspect ratio. Immediately I can see the blank space (blue), various commercial units, the lobbies, the Metro station (3 stacked colours in the bottom right, as well as the Metro tunnel at the very bottom), the Cathedral’s 5 stories at the top and various other units. This allowed me to get quickly the values for the rest of the various units for the type, because I could just look at them in the game.

Looking at this simple graphic can also be useful to figure out what other data parts of the data structure mean. For example, here’s another one. For those who play the game, can you guess what the various colours mean?

A colourful schematic view of the pricing/rate data in a tower's data file.
Pricing modeled after the in-game map/overlay. Default is “average” pricing, or yellow. High is red, low is green and very low is cyan. The top part was set for testing, but I had some shops stubbornly empty due to low traffic unless I dropped the pricing.

It’s game pricing of the units. Yellow is average price, red is high, green is low and cyan is very low. I set these colours after I figured it out, to mirror what was in the game, but it made visually figuring out that part of the data structure very easy.

Others can be more perplexing, such as this one showing a specific unknown value in the Unit data structure for shops. Perhaps this is an index somewhere else, as the values look largely unique. But being able to see data like this makes finding patterns so much easier.

A colourful schematic view of all the shop unit type's data in a tower's data file.
Unknown data, with each entry coloured a random colour, or gray for the build foorprint of the tower.

Header Data

Okay, but now what about that header? Here I use another debugging tool, CheatEngine, to inspect the running memory of the game. While CheatEngine may be designed to allow cheating at games, I’ve almost exclusively used it as a debugging tool, as there are that many easy debugging tools with a similar feature set on Windows.

Unlike SimCity 2000, which had a normal start address, SimTower running under Winevdm made for a little more work. But not much. I started by looking for the values in the save file, saving the game a couple times and scanning for the new value in CheatEngine. Quickly I found that the first value was the tower’s rating (SimTower towers start at 1 star and progress through 5 stars to finally receive a tower rating) by opening towers with different ratings. I also saw that the values in the save, without using CheatEngine for some of the other values referred to money and budgetary values (the game displays the money values multiplied by $100, but would store that as 1).

I played the game and watched the values change, quickly finding a value tracking number of commercial units (fast-food, restaurant and shops), one for parking stalls, one for recycling facilities, one for security facilities as well as a few others. As of when this was written, I don’t have them all figured out.

One thing I noticed looking is that the game runs with a various number of ticks per second of in game time. The one hour period between Noon and 1:00PM has 800 ticks out of a total of 2600 ticks for the whole day associated with it. Meanwhile, between 1:00AM and 7:00AM only has 200 ticks of simulation time. When I was playing the game as a child, I assumed that was just because there was more to simulate during the day, not that the game had lower fidelity simulations then. I guess lunch time being exceptionally busy is a 90’s Japanese office-worker thing that I was never exposed to. This also means that the day starts at 7:00AM, at least as far as the game is concerned, because this is when the tick counter rolls over.

I’ve attached the whole 70 Byte header in CheatEngine with a 5-star tower with $115,300,900 in cash, paused, to show what various values look like. I added the labels myself after I figured them out, or noted it as unknown. Note that the addresses shown are likely not going to be the same after an app restart.

Final Thoughts

I got a lot more done a lot quicker than I expected, likely because I’ve spent quite a bit of time getting good at this specific sort of reverse engineering from the SimCity 2000 reverse engineering project. I’ve started a GitHub repo with my findings here, and includes my sample parsing code in all it’s gory glory. It’s quick, dirty, and gets the job done.

I’ll write a part 2 as I work on the rest of the file. Elevators and a bunch of other information still need to be determined, and I’d like to share more about the more fiddly aspects of reverse engineering, but this post is enough for tonight.

I’ve added more to part 2, here.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s