Where are we?

In the previous post, I suggested you to find Ro’s HP and change the (max) HP and MP for each of the characters. Using the current value of 177 (dec), we can convert this online to a B1 (hex). Using an ASCII character table, we see the corresponding character is a ±. Searching for this character, we find a candidate on the second result (address #2384). This B1 is followed by a 00 (We will call this value ’00B1′ from now on. remember, in the Z80 the values are reversed). If you look further, you see that this is followed by another 00B1 (hex). So there another 177 (dec) is stored. So it would make sense if these values are the HP and the max HP. Then we see a 00A5. If you convert this online, you will see that this is 165 in dec. If you look in the game, that is exactly RO’s current MP. Then another 00B1, which must be his max MP.

To find the other characters, I suggest you make the Memory window as wide so that you can see 16 values next to each other. This means above it, you see +0 +1 up until +F. This makes sense, because then below address #2380 is address #2390, and below #2381 is address #2391.

Our characters’ stats in memory

As you can see, there is a nice pattern in the data of all our characters. The HP for SELIOS is at address #2304. We find his name from address #2330. RUNAN’s data is exactly four rows below this, so HP at #2344 and name at #2370. Note that even GALE is in memory already, although he is not a member of the party yet.

In fact, the data for the characters start at #2300. Each character has 40(hex), which is 64(dec) bytes of data. So the data for the second character starts at #2300+40=#2340(hex). The data for the third character is #2300+80=#2380(hex) etc.

The first byte of each character is the index of the character. As you can see, the index of GALE is not 03 as you might expect, but 83. This 8 indicates he is not a party member yet. Change this to 03 and GALE is a member of the party too! You will have to fight some monsters, for example, to see this.

The current HP, for example is always 4 bytes further than the start address of that character. That can be calculated as [StartAddress]+4.

The name of the character is always 3 lines below the start address. This can be calculated as [StartAddress]+30. These calculations may not make much sense yet, but we will see them being used a lot when we will look into the program logic in future blogs.

Now if we want to change the (max) HP and MP to the 1024 as was the assignment in the previous post, you will have to alter the values like in the following illustration. You will have to fight some enemies or sleep somewhere to see the new values.

Our characters in memory with 1024 (max) HP and MP

Our Enemies

Now I want you to find some enemies and then in the fight, start debugging again. Look at the memory just beyond the stats of the characters.

The monsters’ statistics

During a fight, you can see all the monsters stats are in memory. Do you recognize the pattern? It is exactly the same as from the characters! The monster stats start from #2400, instead of #2300, but the rest is the same. Each monster has 40(hex) bytes of data. Each HP is at startaddress+4. The name for each monster is at startaddress+30. The index for each monster counts from 4. The fourth monster, in my case, has an index of 87, meaning this one is not present.

This data layout is not only beautiful, it plays a vital role in a lot of game logic which is executed during a fight. This will become clear if we look into the actual game logic. We will start doing that from the next post. For some parts in these posts it will be helpful if you understand the difference between decimal, hex and binary. I suggest you study online what they mean and why they are used, if you don’t know already. You will have a clear understanding if you can answer these questions:

  • What is a bit? How many values can a bit contain?
  • What is a byte? How many values can a byte contain?
  • How many values can a hex digit contain? How many digits does a byte have in hex?
  • Why is 16 the magic number in the memory window?