Jump to content

Part 6: Editing Move data


Recommended Posts

** You will need to understand Part 1 of this tutorial before you can decompress the files used in any other parts**

Editing moves works pretty much like in the GBA games. You can attempt to make new moves by mixing and matching the different move effects available and manipulating accuracy, damage etc. I remember seeing a post on a forum somewhere where someone posted every Gen IV - VI move that was possible to remake using gen III effects so you can try searching for that if you want ideas.

The move data is pretty much the same in Colosseum and XD but differs slightly for a few bytes. A significant difference is that XD has the Gen IV style physical/special split on shadow moves.

Also of note is that all the shadow moves are simply recorded as normal type moves and the battle routine automatically calculates the move effectiveness as a shadow move (always neutral in colo; super effective on non-shadow pokemon, not very effective on shadow pokemon in XD) when it detects a move that is meant to be a shadow move. There doesn't appear to be any marker for the shadow moves in the move data. The game seems to decide based on the id of the move (i.e. move 0x164 in colo which is shadow rush and moves 0x164-175 in XD which are the shadow moves starting with shadow blitz and ending with shadow half).

The full move list is available on Github. There is also a list of each of the move effects (same as in RS/FRLG) in order and an enumeration for each of the possible values for the target.

A lot of data that was represented by 1 bit in the gba games gets a whole byte in these games. Each move has a series of flags in its data like whether or not it is blocked by protected or affected by the king's rock. Set the value to 1 for true or 0 for false. I represent these boolean variables by putting a '?' at the end because a full description takes up a lot of room on the table.

The first move (pound) is in common_rel.fdat at offset 0x11E048 in colo and offset 0xA2748 in XD. The size of each move is 0x38 (56) in colo and in XD. The offsets are how many bytes from the first byte of the move's entry the data for that variable is.

N.B. Setting the physical/special flag on a normal move is not enough to make it adopt the physical/special split. It sucks, I know...

Also HMs aren't available in the game and the only effect they have is that they can't be deleted without a move tutor. Removing the HM flag should allow the moves to be deleted. However, this hasn't been tested yet and there is also an HM flag in the TM and HM list in the start.dol which could have an effect.

Damage seems to be part of a move effect. This means that no matter how much base power you give a move, if the move's effect is the same as leer's then it will decrease the target's defense and do no damage. You would need to use rock smash's effect which is damage as well as lowering defense and you could change the effect accuracy as you like.

Move data table

Variable Size (bytes) Colosseum Offset XD Offset  
Move Priority 1 0x00 0x00 (Look up a gen III move tutorial to understand how priority works. It isn't obvious for negative priorities like counter but is basically 255 minus the value you want. i.e. a priority of -3 is represented by 252 = 0xFC)
Base PP 1 0x01 0x01  
Type 1 0x02 0x02  
Targets 1 0x03 0x03  
Accuracy 1 0x04 0x04  
Effect Accuracy 1 0x05 0x05  
Makes contact? 1 0x06 0x06  
Blocked by protect? 1 0x07 0x07  
Magic coat reflects? 1 0x08 0x08  
Snatch steals move? 1 0x09 0x09  
Mirror move copies? 1 0x0A 0x0A  
King's rock affects? 1 0x0B 0x0B  
Is sound-based? 1 0x10 0x10  
Is an HM? 1 0x12 0x12  
Base Power 1 0x17 0x19  
Effect 1 0x1B 0x1D  
ID for Move's Name 2 0x22 0x22  
ID for Animation 2 0x32 0x32  
Physical/Special 1 N/A 0x13 XD Shadow Moves Only
Description Text ID 2 0x2E 0x2E This points to text in the string table contained in start.dol.
Recoil Flat 1 0x13 0x14 Moves like Hyper Beam, Jump Kick, Thrash, Psycho Boost, and Double edge have this flag set.

Interestingly there is an entry after shadow half in XD which doesn't appear in the game and has a little bit of data missing. If you navigate to the string its name id points to then you find the text "????". The move is unselectable in battle probably because it doesn't have an animation set in its data and one probably doesn't exist for it. The id for the string of its description points to the text "this move can't be used because the heart's door is shut".

Similarly in Colosseum there is an entry after shadow rush with incomplete data which shares a few values with the XD move. Its name id also points to the text "????".

Part 7:

 


View full tutorial

Link to comment
Share on other sites

  • 4 weeks later...

I've been messing around with dolphin's debugger on xD. It turns out that the physical/ special split was really easy to use on all moves instead of just shadow moves. ( I converted the implementation to only 5 lines of action replay code). of course actually editing each move to incorporate the physical special byte is a bit more effort but I've tested it and it works almost perfectly since it was already in the game just largely unused. It is to be noted that the flash fire ability just boosted the pokemon's special attack when using fire moves in this gen (since fire moves were expected to always be special. This means flash fire only boosts special fire moves with the split. I need to test whether it would boost attack instead ifni edit fire type to be physical.

Another interesting thing I've found is that setting a move's accuracy to 0 doesn't provide perfect accuracy like in the gba games but rather (more intuitively) just results in always missing. The interesting thing though, is that you can set the accuracy to more than 100 and that value is displayed. I set dragon claw to 200% accuracy and at -2 accuracy still had 100% accuracy. I don't know if this is the case in any other games. haven't seen anyone try it.

[EDIT:] So I tested flash fire and it seems its hard coded to boost special attack (oh well).

Edited by StarsMmd
Link to comment
Share on other sites

  • 4 weeks later...

Even though it's not in the list of tables I -hacking-tutorial-part-7-Editing-Trainers-(Colosseum)&p=205678&viewfull=1#post205678'>found in Colosseum's common_rel, I noticed that the move table starts one entry earlier than you said it does above (at 0x11E010). Also...

Interestingly there is an entry after shadow half in xD which doesn't appear in the game and has a little bit of data missing. If you navigate to the string its name id points to then you find the text "????". The move is unselectable in battle probably because it doesn't have an animation set in it's data and one probably doesn't exist for it. The id for the string of its description points to the text "this move can't be used because the heart's door is shut"

Similarly in colosseum there is an entry after shadow rush with incomplete data which shares a few values with the xD move. It's name id also points to the text "????"

This is certainly in the games. Shadow Pokemon can only use Shadow moves at first, so this "????" is a placeholder that just hides the other moves until the Pokemon has been purified enough. (I'm not exactly sure at what point that move ID gets substituted over the Pokemon's actual move, but it doesn't seem to be in the PKM at all (it always gives the Pokemon's "real" moves).)

And this is fairly useless, but one thing I found in that list of tables in common_rel was the Contest stats. In the Colosseum moves table, byte 0x14 in an entry is an index into this table, defining that move's Contest stats.

Contest stats (Colosseum):

  • In: common.fsys\common_rel.fdat
  • Start: 0x14BCA8
  • Entry size: 0x08 (dec 8)
  • Entry count: 51

Offsets...

  • 0x00 -- 1 byte -- Appeal (hearts * 10)
  • 0x01 -- 1 byte -- Jamming (hearts * 10)
  • 0x02 -- 2 bytes -- 0
  • 0x04 -- 4 bytes -- Description string (ID)

Link to comment
Share on other sites

Even though it's not in the list of tables I -hacking-tutorial-part-7-Editing-Trainers-(Colosseum)&p=205678&viewfull=1#post205678'>found in Colosseum's common_rel, I noticed that the move table starts one entry earlier than you said it does above (at 0x11E010).

Sorry, my colosseum data is a bit unreliable at times since it's pretty old. Thanks for that.

This is certainly in the games. Shadow Pokemon can only use Shadow moves at first, so this "????" is a placeholder that just hides the other moves until the Pokemon has been purified enough. (I'm not exactly sure at what point that move ID gets substituted over the Pokemon's actual move, but it doesn't seem to be in the PKM at all (it always gives the Pokemon's "real" moves).)

That makes sense. I noticed the description and still didn't make the connection hahaha.

Contest stats (Colosseum):

  • In: common.fsys\common_rel.fdat
  • Start: 0x14BCA8
  • Entry size: 0x08 (dec 8)
  • Entry count: 51

Offsets...

  • 0x00 -- 1 byte -- Appeal (hearts * 10)
  • 0x01 -- 1 byte -- Jamming (hearts * 10)
  • 0x02 -- 2 bytes -- 0
  • 0x04 -- 4 bytes -- Description string (ID)

The contests stats aren't actually that 'useless' from a hacking point of view. Since this data is irrelevant it can all be replaced in order to optimise the lzss compression. Decreasing the file size is always nice.

Link to comment
Share on other sites

The contests stats aren't actually that 'useless' from a hacking point of view. Since this data is irrelevant it can all be replaced in order to optimise the lzss compression. Decreasing the file size is always nice.

Not exactly all of it. Unless you go so far as hacking the move displays and/or the code that loads the contest stats, you'll at least need to keep one entry around so you can just set the index for all the entries to 0 and it has sensible data to read.

Link to comment
Share on other sites

It occurs to me I may have misunderstood your meaning a bit. If you just meant to zero out the whole table, then that wouldn't have any problems; the game doesn't generally have any trouble if given an invalid string ID, and the appeal/jam fields are certainly fine with 0. What I initially figured--and which I now realize would bring its own problems--was that you meant to delete the table, as in, all the data that used to be after the table would now appear that much earlier. At any rate, my main worry was that if you replaced the table with some new data and weren't careful about it and ended up with the "wrong" value in the description string field, you could get some pretty weird "descriptions". But aside from that, appeal/jam seem not to have any issue with random values.

It also just occurred to me that the Contest category (Smart/etc) has to be defined too, and that turns out to be offset 0x15. Oddly, it seems there may also be something that overrides the category in a move entry, because I tried changing the category for Shadow Rush and that ???? but they persisted with no-icon or the "???" icon. (Changing 0x15 worked just as expected for Bite, though.)

Link to comment
Share on other sites

It occurs to me I may have misunderstood your meaning a bit. If you just meant to zero out the whole table, then that wouldn't have any problems; the game doesn't generally have any trouble if given an invalid string ID, and the appeal/jam fields are certainly fine with 0. What I initially figured--and which I now realize would bring its own problems--was that you meant to delete the table, as in, all the data that used to be after the table would now appear that much earlier. At any rate, my main worry was that if you replaced the table with some new data and weren't careful about it and ended up with the "wrong" value in the description string field, you could get some pretty weird "descriptions". But aside from that, appeal/jam seem not to have any issue with random values.

It also just occurred to me that the Contest category (Smart/etc) has to be defined too, and that turns out to be offset 0x15. Oddly, it seems there may also be something that overrides the category in a move entry, because I tried changing the category for Shadow Rush and that ???? but they persisted with no-icon or the "???" icon. (Changing 0x15 worked just as expected for Bite, though.)

No worries. Sorry if I wasn't clear.

The game often checks for shadow moves in the ASM and probably determines whether it should display the icon or not in the code.

For xD I guessed how the game may check for a shadow move. I'd already tried copying the exact entry for a shadow move and putting it over a regular move and that didn't make it a shadow move so I knew it wasn't in the move data table. The next obvious answer was that the game simply compared the index with 0x164. So I searched Start.dol for the value 0x164 which led me to the instruction "0x2c000164" which is "cmpwi r0,356". I found the same instruction in the RAM on dolphin in debug mode and used break points to test it. A neat feature is that you can see which functions call the function you're looking at. Finding a similar function could be helpful to you. For example, the main part of my phsyical/special split implementation was finding the function that determined the category of a move. I knew it had to check if the move was a shadow move or not so I looked at each of the functions that called the function for checking. I found the function and simply ignored the check so that it always ran the code that checks the move data rather than the move's type.

Another helpful way to find ASM functions is to see which values in the RAM are being edited by Action Replay or Gecko codes. You can then begin to look into which functions branch to and from eachother. This helped me find the shiny calculation function. Seeing a bunch of XORs and a comparison to the value '8' were a dead give away.

Unfortunately it doesn't seem that xD displays the contest data. I thought of using it to display an image of the move's status rather than contest category.

Link to comment
Share on other sites

The game often checks for shadow moves in the ASM and probably determines whether it should display the icon or not in the code.

For xD I guessed how the game may check for a shadow move. I'd already tried copying the exact entry for a shadow move and putting it over a regular move and that didn't make it a shadow move so I knew it wasn't in the move data table. The next obvious answer was that the game simply compared the index with 0x164. So I searched Start.dol for the value 0x164 which led me to the instruction "0x2c000164" which is "cmpwi r0,356". I found the same instruction in the RAM on dolphin in debug mode and used break points to test it. A neat feature is that you can see which functions call the function you're looking at. Finding a similar function could be helpful to you. For example, the main part of my phsyical/special split implementation was finding the function that determined the category of a move. I knew it had to check if the move was a shadow move or not so I looked at each of the functions that called the function for checking. I found the function and simply ignored the check so that it always ran the code that checks the move data rather than the move's type.

Another helpful way to find ASM functions is to see which values in the RAM are being edited by Action Replay or Gecko codes. You can then begin to look into which functions branch to and from eachother. This helped me find the shiny calculation function. Seeing a bunch of XORs and a comparison to the value '8' were a dead give away.

Unfortunately it doesn't seem that xD displays the contest data. I thought of using it to display an image of the move's status rather than contest category.

I probably don't really care that much if it's some assembly. I've generally been having trouble reading the assmebly to any great extent, but I may see if I can find some simpler introductions than the very technical/jargony instruction set documentations I've been trying to reference.

When you say that a nice "feature" is you can see what functions are calling what you're looking at, you don't mean that Dolphin has some "feature" that will determine that automatically, do you? Did you just mean something like you can look for instructions that jump to the start of your function (though I think finding that may be a little complicated too)?

I did use one of the AR codes just like you describe already, but with my general trouble reading the assembly, I haven't been eager to try it a lot.

Link to comment
Share on other sites

I probably don't really care that much if it's some assembly. I've generally been having trouble reading the assmebly to any great extent, but I may see if I can find some simpler introductions than the very technical/jargony instruction set documentations I've been trying to reference.

When you say that a nice "feature" is you can see what functions are calling what you're looking at, you don't mean that Dolphin has some "feature" that will determine that automatically, do you? Did you just mean something like you can look for instructions that jump to the start of your function (though I think finding that may be a little complicated too)?

I did use one of the AR codes just like you describe already, but with my general trouble reading the assembly, I haven't been eager to try it a lot.

It really it is a feature that calculates it for you. I don't know how much you know about using debug mode so I'll start from the beginning. It also shows you the code in hex and in assembly and you can place breakpoints and all that.

When in debug mode, choose the 'Symbols' option in the top menu and then 'Generate Symbol Map'. This will get dolphin to name all the functions for you and they will come up in different colours making it easy to see where each one starts and ends.

If you look at the 'code' tab. You will see 4 boxes on the very left. The second one shows the names of the functions (Dolphin automatically names them based on their offset and you can change the name to whatever you like if you figure out what it does). The third box shows the functions the current function branches to and the 4th box shows which functions branch to the current function.

You can click on any of these and it'll take you straight to that function. Also if you're looking at the code itself you can right click on a branch instruction and there's an option to follow that branch and dolphin will take you to the instruction it branches to.

I had a lot of trouble finding a good ASM tutorial as well but then I stumbled across a really good one on the super smash bros melee forums. It uses melee and Sonic adventure 2 battle as examples but it is really easy to follow and should teach you everything you need to know. There aren't any prerequisites either, so I'm sure you'll get it. This one video is all I needed to get started. Here's the link:

I hope you give it a go. It's a few hours long but well worth the time. Good luck!

Link to comment
Share on other sites

It really it is a feature that calculates it for you. I don't know how much you know about using debug mode so I'll start from the beginning. It also shows you the code in hex and in assembly and you can place breakpoints and all that.

When in debug mode, choose the 'Symbols' option in the top menu and then 'Generate Symbol Map'. This will get dolphin to name all the functions for you and they will come up in different colours making it easy to see where each one starts and ends.

If you look at the 'code' tab. You will see 4 boxes on the very left. The second one shows the names of the functions (Dolphin automatically names them based on their offset and you can change the name to whatever you like if you figure out what it does). The third box shows the functions the current function branches to and the 4th box shows which functions branch to the current function.

You can click on any of these and it'll take you straight to that function. Also if you're looking at the code itself you can right click on a branch instruction and there's an option to follow that branch and dolphin will take you to the instruction it branches to.

I had a lot of trouble finding a good ASM tutorial as well but then I stumbled across a really good one on the super smash bros melee forums. It uses melee and Sonic adventure 2 battle as examples but it is really easy to follow and should teach you everything you need to know. There aren't any prerequisites either, so I'm sure you'll get it. This one video is all I needed to get started. Here's the link:

I hope you give it a go. It's a few hours long but well worth the time. Good luck!

Well damn, I'll have to play with that feature... I haven't paid a whole lot of attention to Dolphin's menus, I've mostly only noticed the more or less obvious icons and interface stuff. Though it's also possible even if I did see that Symbols menu I may not have realized what it did.

I'll have to take a look at that video too. There's definitely a couple things I'd like to find. Thanks!

Link to comment
Share on other sites

  • 1 month later...

I did my first major tests yesterday and after noticing a few odd things with animations I'd changed I noticed that in the move data there are 2 animations. The one previously identified at bytes 0x32-0x33 but also at 0x1e-0x1f. There are cases where changing only one of them is fine but it's lengthy to explain and not worth it so as a rubric just change both of them to the animation you want. This was in xD btw. I haven't checked colosseum for this but I reckon it has 2 animations as well.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...