(Merry Christmas!)
There are up to six things we have to do in order to replace an ability with a new one:
1) Spell Entry
2) Animation Entry
3) Effect Code (in C2)
4) Animation Code (in C1)
5) Text
6) Job Info
As an example, I will be replacing the command "Pray" with "Psych" and giving it to a Black Mage at JLvl 4. For simplicity, the ability will function almost exactly like the spell. The one change will be the MP cost, which will be 0.
Note: I'll be assuming people reading this will be familiar with the basics of the data format. All that information is on the site here. Please feel free to share this information.
1) Spell Entry
Many abilities in the game are actually spells that are called via code (see Part 3). In fact, the code interpreting these is for all intents and purposes identical. We could simply copy the spell data for Psych to the ability data for Pray, change the MP cost, and skip straight to editing text. In fact, for this simple change, that's pretty much what we're going to do. That won't always be the case, as I'll demonstrate with a subsequent example.
So, copy the Psych data to D1/5AE8 (where the Pray ability is located), and change the MP to 0. Easy! You'll want to note the ability offset as well, which is 21.
2) Animation Entry
We don't just want our Psych ability to act like Psych, we want it to look like it as well. Luckily, we're using an animation that already exists, so we don't actually have to do much here. However, if you wanted to add a new animation, you could do so by editing the animation data table.
We do want to know the offset of our animation though; it's 35.
3) Effect Code
All abilities call a snippet of code that sets up the animation and effect. This uses indirect addressing; there's a lookup table at C2/4A92 that is a list of addresses. This maps to the list of command abilities, with one big caveat: subtract one from the ability number to get the offset. I don't know why they skip ability number 00 (Nothing), but it does. So, Pray is ability number 21, so we want entry 0x20. Our Pray code is at C2/1169. NOTE: If you have InstructrTrepe's function offset list, several of the addresses for the commands are wrong. I've verified this in code and with breakpoints. Use the lookup table to be certain.
Here's our Pray code. I've noted the functions of each subroutine.
C2/1169: A9 21 LDA #$21
C2/116B: 20 AA 16 JSR $16AA Load Ability Parameters
C2/116E: 20 5F 17 JSR $175F Get Selection
C2/1171: 20 A9 02 JSR $02A9 Separate Enemy/Ally Targets
C2/1174: 20 C2 02 JSR $02C2 Count Targets
C2/1177: A9 21 LDA #$21
C2/1179: 20 FA 16 JSR $16FA Queue Banner
C2/117C: A9 20 LDA #$20
C2/117E: 20 E1 16 JSR $16E1 Queue Ability Animation
C2/1181: 20 1A 17 JSR $171A Get Attack Type
C2/1184: 20 35 17 JSR $1735 Increment Effect Counter
C2/1187: 4C E3 98 JMP $98E3 Run Effect
As you can see, there are three functions that take a parameter (16AA, 16FA, 16E1). We don't need to change the ability or the banner. Now, you may be thinking we need to change the input for Queue Ability Animation. It makes sense, right? Unfortunately, it's also incorrect. We'll leave it at #20.
4) Animation Code
So why exactly did we leave the input for QAA at #20? The detailed answer is a little complex, and not strictly necessary to understand for this basic example. However, that parameter actually indicates the value for a lookup table at C1/8D88, which leads to the following code:
C1/9909 20 93 9D JSR $9D93
C1/990C A9 0B LDA #$0B
C1/990E 20 EC 96 JSR $96EC
C1/9911 A2 D8 00 LDX #$00D8 Anim: Pray
C1/9914 20 9C B6 JSR $B69C Run Animation
C1/9917 7B TDC
C1/9918 4C EC 96 JMP $96EC Continue Animations
The important lines are the LDX and subroutine $B69C. All abilities call bits of code like this, which are animation handlers. For Pray, this is pretty simple. Go ahead and change that #00D8 to #0035.
5) Text
This is relatively straight-forward. Change the ability name at E0/1237; this also changes the text for the menu and the banner. Change the description at D1/776A, but make sure to keep it at 24 bytes (use padding if needed). The lookup table for description addresses starts at D1/716C.
If you went on to Part 6, then pulled up the menu, you'd notice that the job level information is still indicating Chemist L4. Interestingly, this is not text, but a byte value that indicates job and level. This data is located at C0/F739, and uses the same ability offset. Bytes 0-4 indicate the job number, and bytes 5-7 indicate the level. So we go to offset 21 at C0/F75A, which is currently set at #90. Parsing that code, it's job number 10 (Chemist) and level 4. We're going to change that to 8A (job A, level 4).
6) Job Info
If you've made it this far, you shouldn't have a problem with this next part. Calculate or lookup the offset for the job info table (38), go to the data, and change the learned ability to #21. Now you're ready to go!