Take note that editing the breeding data for the game, while still relatively easy, can be a bit tedious and mind numbing because of the way the data is split up. You have been warned.
|0x3a208||Species + Species: Mate pointers|
|0x3a508||Species + Species: Lists of mates|
|0x3ae14||Species + Species: Results pointers|
|0x3b114||Species + Species: Lists of results|
|0x3b34e||Species + Family: Mate pointers|
|0x3b64e||Species + Family: Lists of mates|
|0x3b74f||Species + Family: Results pointers|
|0x3ba4f||Species + Family: Lists of results|
|0x3bb83||Family + Species: Mate pointers|
|0x3bb99||Family + Species: Lists of mates|
|0x3bdbf||Family + Species: Results pointers|
|0x3bdd5||Family + Species: Lists of results|
|0x3be99||Family + Family|
DWM2_DD gave an amazing explanation of this structure over at GameFaqs so I'll be borrowing heavily from that. First note that all pointers are 2 byte, little endian, and work off of address 0x34000. All of these tables are in order by species ID or, in the case of Family + (something), family ID.
Let's start by studying the breedings for Slime, which has a species ID of 0xa. First we get the pointer for its mates. So multiply Slime's ID by 2 (because of the 2 byte pointers) and add it to the address for the mates pointers.
3a208 + (a*2) = 3a212
The pointer at 3a212 is [18 65]. Reverse the bytes and add 0x34000.
34000 + 6518 = 3a518
This is the address for Slime's mate data. There are some important things to note. [FD FD] is a set delimiter, showing that a list of possible mates for a specific result has ended. [FB FB] is another set delimiter that also indicates EVERY set after it will only work over a link cable. [FF FF] is the end of the monster's mate lists. Last but not least, we have [04 FE 04 FC] which tells you that there is a +5 breed for the monster. The rest of the values there are just species ID values for Slime's possible mates. With that in mind, it decodes like this:
|04 FE 04 FC||+5 Breed|
|FD FD||End of set|
|4A 00||Mate: Pillowrat|
|53 00||Mate: Mommonja|
|FD FD||End of set|
|0D 01||Mate: CopyCat|
|FB FB||End of set; following sets require link cable|
|75 00||Mate: BigRoost|
|FF FF||End of lists|
If Slime+5 and Slime+5 breed they will produce result a. If Slime and Pillowrat OR Mommonja breed they will produce result b. If Slime and CopyCat breed they will produce result c. And if Slime breeds with BigRoost over a link cable, result d will be the result.
Now let's get those results. Start with the same basic process as before, but using the result pointer table instead of the mate pointer table.
3ae14 + (a*2) = 3ae28 (pointer is [1C 71])
711C + 34000 = 3B11C
Here you'll be thrown into the midst of a list of monster IDs. Only read to the number of results you would get from the mate data (in this case, that would be four ID values).
|ID value||Result||Corresponds to?|
|10 00||KingSlime||Slime(+5) + Slime(+5)|
|14 00||TropicGel||Slime + Pillowrat OR Mommonja|
|16 00||HaloSlime||Slime + CopyCat|
|1A 00||WonderEgg||Slime + BigRoost; link cable only|
Species + Family and Family + Species can generally be edited the same way. Do take note that family IDs are not inherently 2 bytes long though.
Family + Family breeding data is a bit different. It starts with a list of pointers that increment by 0x16, then has the actual data which is basically a table of results. The actual data starts with:
FFFF 0100 0200...
FFFF returns base monster (Slime + Slime) and then you would have Slime + Dragon and so on, following the natural order of the family ID values.