PokeHacking

Join our Discord community

Editing the type effectiveness between types and inserting the Fairy type in Pokemon Platinum without expanding the overlays

Mikelan98, BagBoy, DavveDP (Translation)

Target games:


Introduction

This tutorial will consist of two parts: one explaining and modifying the type effectiveness chart and another one covering the graphical insertion of the fairy type. Although they are not explicitly divided in the tutorial, it is recommended that one follows the parts (effectiveness table and fairy graphics) separately when performing the modification as to not get confused.

Before starting one must have a clear understanding of the following:

With this in mind it won’t be possible to expand the type effectiveness table (from here on out known as TET), and even if it was, the table is so large that it becomes very difficult to find space for it anyway. This means that we must devise a different strategy for adding our beloved fairy type.


A Fairy-type Clefairy in Pokemon Platinum.

What strategy will we use then? Well, one that works very well when working with large strings of binary data in the arm9 or overlays and reducing them is: reducing bytes to nibbles. It should be noted that this strategy is valid only when it is worthwhile in certain cases, that is, when this reduction is more practical than looking for blank spaces. As the effectiveness table is very large and we also want to expand it with quite a few bytes (In theory more than 30 bytes) this strategy is justifiable. Reducing bytes to nibbles frees up space because many hex numbers can be represented with only 1 nibble, leaving space for other data.

To be able to actually apply this strategy we need to know precisely when and how these pieces of data are read and all the routines involved. Therefore, tracing* is going to be of great use to us.

*Tracing basically means to follow all the reading from RAM/writting to RAM instructions for a specific memory address, in order to find the subroutines with these instructions


Research

Firstly the TET consists of groups of 3 bytes known as “triplets” in the formation AA | DD | EE. Here the AA byte is the type-ID of the attacking type, DD the type-ID of the defending type, and the EE byte the effectiveness.

AA DD EE
Definition: Attacking type-ID Defending type-ID Effectiveness
Values: 00 = Normal
01 = Fighting
02 = Flying
03 = Poison
04 = Ground
05 = Rock
06 = Bug
07 = Ghost
08 = Steel
09 = ???
0A = Fire
0B = Water
0C = Grass
0D = Electric
0E = Psychic
0F = Ice
10 = Dragon
11 = Dark
00 = Normal
01 = Fighting
02 = Flying
03 = Poison
04 = Ground
05 = Rock
06 = Bug
07 = Ghost
08 = Steel
09 = ???
0A = Fire
0B = Water
0C = Grass
0D = Electric
0E = Psychic
0F = Ice
10 = Dragon
11 = Dark
00 = Immune
05 = Not-very-effective
0A = Neutral
14 = Super-effective

The original routine used by the game to read the data in the TET is activated whenever a move is used in battle and works as follows:

  1. The game stores the the value of the attacking type and the type/s of the defending pokemon in the stack.
  2. Then the game retrieves a memory address from R0: 0x0226ECD4. This is the address in memory where the TET starts. In other words the game starts reading the first byte of the TET.
  3. At this point the game enters a loop comparing each triplet in the TET to the two values stored in the stack until it finds the correct one. It does this by firstly checking the first triplet. Then, if it’s incorrect, returns to the starting address +3 bytes and repeats. The adding of 3 bytes per iteration will be important later on so remember it.
  4. If the game doesn’t find a matching triplet it sets the effectiveness type to neutral. However if it finds a matching triplet it reads its EE byte and sets the effectiveness type to that of said byte. “Setting the effectiveness type” is basically what the game uses the EE byte for and is later used in damage calculation. However this is irrelevant to us.

For the actual implementation of the theory things get interesting. Starting with the TET, as previously mentioned we are going to use the strategy of reducing bytes to nibbles. However the only bytes that we can reduce are the effectiveness bytes (EE) since they can only have 4 different values assigned to them. Additionally all of the values in the EE bytes (see table above) are multiples of five (0, 5, 10 and 20) meaning that we can store them as 0, 1, 2 and 4 and multiply them before use by using an instruction. By storing them as a smaller value we are creating more free space. In practical terms we will be creating a smaller table below the TET containing only the EE bytes reduced to nibbles (divided by 5), the reason for this will be explained later.


Compressed effectiveness table. Notice the separation between the AA | DD values and the EE ones.

In the offsets 0x1A01A and 0x01A074 in overlay 16 are the lines of code that compare the attacking Pokemon's type-ID to the defending one in the TET, checks the EE value, and passes it on to damage calculation. Now what we are going to do is branch the code before it checks the EE value to some free space in the arm9 and tell it to fetch the EE value from the smaller table of nibbles we created.

Additionally, the graphical part of the Pokédex also needs an ASM touch-up in order for it to correctly display the fairy type. This is because the Pokédex also uses a table, albeit a different one, to determine which type to display. Each entry in that table points to a set of instructions that does the actual displaying of the type. By changing the instructions or repointing them to some other place in memory we can make it display whatever we want. Conveniently this table has two entries that display the ghost type which means we could easily use one of those for our own purposes.

If we head over to overlay 21 at offset 0xE40A we find two asm instructions that are, by all means, “obsolete”. They appear to be the remnants of a 32-bit to 16-bit variable conversion during compilation. Nonetheless these 4 “obsolete” bytes will serve as our own “fairy type branch”. By repointing one of the two aforementioned ghost type entries to these 4 bytes we can replace it with something else.


Tutorial

Firstly we will create our new set of tables by pasting the following in overlay 16:

Game Code Table Offset Table Data Table Read 1 Offset Table Read 1 Code Table Read 2 Offset Table Read 2 Code
CPUE 0x33B94 (Overlay 16) 00 05 00 08 0A 0A 0A 0B 0A 0C 0A 0F 0A 06 0A 05 0A 10 0A 08 0B 0A 0B 0B 0B 0C 0B 04 0B 05 0B 10 0D 0B 0D 0D 0D 0C 0D 04 0D 02 0D 10 0C 0A 0C 0B 0C 0C 0C 03 0C 04 0C 02 0C 06 0C 05 0C 10 0C 08 0F 0B 0F 0C 0F 0F 0F 04 0F 02 0F 10 0F 08 0F 0A 01 00 01 0F 01 03 01 02 01 0E 01 06 01 05 01 11 01 08 03 0C 03 03 03 04 03 05 03 07 03 08 04 0A 04 0D 04 0C 04 03 04 02 04 06 04 05 04 08 02 0D 02 0C 02 01 02 06 02 05 02 08 0E 01 0E 03 0E 0E 0E 11 0E 08 06 0A 06 0C 06 01 06 03 06 02 06 0E 06 07 06 11 06 08 05 0A 05 0F 05 01 05 04 05 02 05 06 05 08 07 00 07 0E 07 11 07 08 07 07 10 10 10 08 11 01 11 0E 11 07 11 11 11 08 08 0A 08 0B 08 0D 08 0F 08 05 08 08 FE FE 00 07 01 07 10 09 01 09 06 09 11 09 03 09 08 09 09 10 09 01 09 11 09 08 09 0A 09 03 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 11 11 44 41 14 41 14 41 41 10 41 14 11 41 14 11 14 14 44 11 44 11 11 44 44 11 11 04 41 40 14 41 44 41 14 41 01 14 11 14 14 14 41 14 41 04 12 44 11 44 12 11 14 41 00 00 11 14 44 44 11 1F FF FF FF FF FF 0x1A01A (Overlay 16) C0 46 00 49 88 47 01 94 0F 02 C0 46 0x1A074 (Overlay 16) 00 49 88 47 01 94 0F 02 C0 46 C0 46

Now we have successfully redirected the game’s code to offset 0x020F9400, a small region of free space in RAM. There we will put our code that fetches the values from our newly-inserted table of EE values. The code to be pasted in offset 0xF9400 (since arm9.bin starts from offset 0x02000000) in arm9.bin is the following:

Game Code Effectiveness Subroutine Offset Effectiveness Subroutine Code
CPUE 0xF9400 (ARM9) 01 90 38 B4 0C 4B D2 1A 52 08 86 24 64 00 1B 19 52 08 9B 5C 03 D2 F0 25 2B 40 1A 09 02 E0 0F 25 2B 40 1A 46 05 25 6A 43 75 46 06 35 AE 46 38 BC 28 46 39 46 01 49 08 47 D4 EC 26 02 3D B6 25 02

Unfortunately all of these insertions still won’t work. This is because of the way the game checks the TET. Since we have turned all of our triplets into doubles we now have to change the “loop-code” to add +2 to the starting address after each iteration instead of the original +3. This is done by changing the following values at the following addresses in overlay 16:

Game Code Offset 0x19FB6 Offset 0x1A084 Offset 0x1A766
CPUE C046 6100 C046 C046

If one wishes to add extra relationships to the TET it can be done by removing the first set of pair of FF bytes, adding extra relationships, then appending the two FF bytes afterwards (see image above). The last relationship must be followed by two sets of FF bytes or else the game won’t stop reading. Additionally one must add nibbles for type effectiveness in the EE value table too by appending them to the table followed by FF.

Here’s an example of how to make the dark type hit for neutral damage on steel types:

First we must find the matching double in the TET for the attacking type-ID of dark and the defending type-ID of steel. By looking at the values in the first image of this tutorial we know that dark = 11 and steel = 08. Now we just have to find the following double: 11 08


AA | DD and EE values for Dark-type attack against Steel-type Pokemon in the compressed effectiveness table.

Now we look for the EE value that corresponds to this relationship. We do this by calculating how many doubles from the starting offset our relationship is. In our case 102. And then we the nibble in the EE value table 102 nibbles from the start of that table. Now we simply change the value of that nibble from 1 (not-very-effective) to 2 (neutral).

For making the pokedex display the type correctly we will be creating our own fairy branch, as mentioned earlier, in overlay 21 at offset 0xE40A, overwriting the aforementioned “obsolete” bytes. This can be done by inserting the following code at Offset 0xE408 of overlay 21:

Game Code Pokedex Display Subroutine Offset Pokedex Display Subroutine Code
CPUE 0xE408 (Overlay 21) 49 88 8F 44 22 00 26 00 2A 00 2E 00 32 00 36 00 3A 00 3E 00 42 00 66 00 46 00 4A 00 4E 00 52 00 56 00 5A 00 5E 00 62 00 00 20 70 47 06 20 70 47 0E 20 70 47 0A 20 70 47 08 20 70 47 05 20 70 47 0B 20 70 47 07 20 70 47 09 20 70 47 01 20 70 47 03 20 70 47 02 20 70 47 04 20 70 47 0F 20 70 47 0D 20 70 47 10 20 70 47 0C 20 70 47 12 20 70 47

Now we only need to make the graphical changes because without them the game will display the ??? or ghost-type. In order to do this we must first change the type icon and palette in addition to the palette of the move selection box. We will be using Tinke 0.9.2 and ConsoleTool for this section.

  1. First, extract the “pl_batt_obj_74.RLCN” file from: battle/graphic/pl_batt_obj.narc
  2. Open up the file in ConsoleTool, this will display all the colours of the palette file.
  3. Now change the following 3 colours to a pink of your liking and export it with a new name. The tool will automatically adjust the chosen colour to a multiple of 8, since the game won’t accept it otherwise. The result should look something like this:


    Palettes for in-battle move boxes.

  4. Now just export the new palette and in tinke select “change file” and select the modified palette.
  5. Now scroll down to “pl_batt_obj_236.bin” and unpack it. The unpacked file is the icon for the ??? - type. We will be replacing it with our own fairy-type icon. Download the the new icon and import it in tinke over the old one.
  6. Now we must recompress everything. This is done by selecting the parent “pl_batt_obj_236.bin” and clicking “Pack”. The same needs to be done for the narc.
  7. To ensure the palette and icon are correctly edited, double click the “pl_batt_obj_74.RLCN” file and then view the unpacked “pl_batt_obj_236.bin” file. Then change the palette to palette 2 and the result should like this:


    Inserting the Fairy type icon with Tinke.

  8. Now the icon has been successfully been replaced. All that is left now is to edit the colours of the move selection box since it currently looks like this:


    New move box for Fairy-type moves.

  9. This is done by typing: “overlay9_11” into the search field in tinke and hex-viewing the first file in the resulting list. Scroll down to to the address in the image below and insert the following code:
    DF 7E 3F F2 1E 6A DD 59 5B CD 17 C1 D6 B4 3F FB


    Color data for Fairy-type move boxes.

  10. Save the file and close it. Save the ROM.

Demanded credits

If you are planning to use this research on your project, credits for Mikelan98 and BagBoy are needed. You can cite this research by copying the following reference in the credits section of your project's thread or webpage:

Mikelan98, BagBoy: Fairy Type in Pokemon Platinum (pokehacking.com/r/20071800)

Total or partial reproduction of this research in other site is forbidden without prior authorization of the authors.






© 2020 PokeHacking

Pokémon characters and images belong to The Pokémon Company International and Nintendo.
This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International.