Male
Seen January 28th, 2018
Posted December 6th, 2015
736 posts
14.3 Years
Hello, Jambo51 here again, and I'm here today to ask and hopefully answer the following statement:

How do we add the new moves to our beloved Generation 3 ROMs?

The answers I will provide will be for BPRE 1.0 (aka FR US 1.0), but they will also be applicable to Ruby and Emerald with a bit of thinking and some reading of ini files.

PLEASE NOTE: You can only successfully add attacks which actually do damage at this time. Status inflicting moves (whether purely status or damage and status inflicting) are a no go for now.

What's needed:
A Hex Editor
Pokémon Game Editor by Gamer2020, it perfectly supports the extended data!
Some knowledge of how the INI for PGE works
A Brain
Some PATIENCE

So, there are 2 different ways to add the new moves. The first, in the spoiler below, only supports up to 511 moves (there are a total of 559 in generation 5), but keeps support for the standard style of moveset used in generation 3.

Spoiler:
This is so easy to do, it's not even funny.
All you need to do is repoint the attack table and the attack names array, and add the extra attacks.
How easy is that!?!

In all seriousness, you want to navigate to 0x250C04 and select 4260 bytes of data, then copy it to some aligned free space in your rom, and then repoint all references to that table. This is the silly part, there are ALSO pointers to 0x250C08 in the ROM which must also be repointed, which are used when writing the new moves' PP onto your Pokémon's data. Obviously, when repointing the PP part, you add 4 to the location you replaced 0x250C04 with. Ie, if you replaced 0x2504C04 with 0x960000, then you'd replace 0x250C08 with 0x960004.

Now, navigate back to 0x250C04 and copy (12 * number of new attacks) worth of data. This should ensure that the new attacks you add inherit some sensible data which PGE can work with.

Then navigate to 0x247094, and copy 4615 bytes and paste it into free space, then repoint as necessary.

Go back to 0x247094 and now copy (13 * number of new attacks) worth of attack names. Again, this will ensure that PGE will inherit names it can work with.

Next, navigate to 0x1C68F4, and copy 1420 bytes, and paste them into free space in the ROM, making sure the pointer is THUMB aligned. That is, ends with a 0, 4, 8 or C.

Then, go back to 0x1C68F4 and copy (4 * number of new attacks) bytes of data, and paste it into the area after the already copied data. So for example, if you repointed to 0x9F0000, you would paste this latest data starting at 0x9F058C.

Finally, repoint the pointer to 0x1C68F4 to your new data. This will allow the new moves to have animations. As of now, they will simply inherit the animations of the first however many attacks you added. Ie, Attack 355 will have Attack 0's animation (Attack 0 shares Pound's animation, so don't worry about that little problem), and so on and so forth.

Then, update PGE's ini to add support in the tool for the new moves.
You simply need to change the pointer to the attack data table to the location you repointed your data to, and update the number of attacks parameter so that it accounts for all your nice, shiny new attacks.

That is change:
NumberOfAttacks=354
AttackData=&H250C04
AttackNames=&H247094
to:
NumberOfAttacks=[Number of attacks]
AttackData=&[Location of repointed attack data table]
AttackNames=&[Location of repointed attack name array]
Then, using PGE, simply modify the attacks after Psycho Blast to comply with the base stats of the moves you want to use.

Now, for the effects, see the post further down this page where I give a worked example of how to do Flare Blitz's effect to work out how to create custom effects. You will need to repoint the table as well, I give the offset of the table in that post.

Please note, the new attacks will have blank names at this stage if you correctly repointed. So make sure you don't put anything else into that area of the ROM until you've finished at least marking out where the names will end.

You can easily update the movesets to include these new moves without any further hassle.

Finally, overwrite the bytes at 0xD75FC with 00 00 00 00 00 00 to disable the only limiter in the ROM. If you do not edit this, rather than saying "Bulbasaur used VenoShock!", it will say "Bulbasaur used a POISON move!"

From here, your new attacks should work (almost - wrong animations) perfectly.


And this is how to add more than 511 moves. Please note, this is substantially more difficult and awkward than the above method, and requires you to redo every single moveset in the game.

Spoiler:
Firstly, do exactly what is above. Everything which follows is based on the simple foundation of what is above. *Waits*
Done that? Good.

Now we must insert some ASM routines to rewrite how the movesets are read.

So, insert the following routine:
.text
.align 2
.thumb
.thumb_func
.global newmovesetstyle
main:
 mov r1, r9
 lsl r1, r1, #0x2
 ldr r0, table
 add r0, r0, r1
 ldr r0, [r0, #0x0]
 ldr r6, there
 add r6, #0x6
 ldrb r7, [r6, #0x0]
loop: lsl r1, r7, #0x1
 add r1, r1, r7
 add r3, r0, r1
 ldrb r1, [r3, #0x2]
 mov r4, r10
 cmp r4, r1
 beq learn
 cmp r1, #0xFF
 beq exit
 add r7, #0x1
 b loop
learn: ldr r2, there
 add r7, #0x1
 strb r7, [r6, #0x0]
 ldrb r1, [r3, #0x1]
 lsl r1, r1, #0x8
 ldrb r0, [r3, #0x0]
 orr r0, r1
 strh r0, [r2, #0x0]
 ldr r1, return
 bx r1
exit: ldr r0, return2
 bx r0
.align
return:  .word 0x0803EB65
return2: .word 0x0803EB73
table:  .word 0x08FFFFFF   /*Replace with your table's location/*
there:  .word 0x02024022
Change 0x3EB20 to 18 49 08 47. Then navigate to 0x3EB84 and change it to XX XX XX 08, where the XX XX XX stands for the pointer to your new routine plus 1.

The table I reference in here is the moveset table. So change your 0x8FFFFFF to point to it. This applies to all 3 routines here, so make sure you change them all.

This only fixes the PLAYER's learnsets, so you now need to insert this next routine:

.text
.align 2
.thumb
.thumb_func
.global newmovesetstyle2
main:
 ldrb r1, [r0, #0x2]
 mov r2, #0xFF
 cmp r1, r2
 beq exit2
 mov r9, r2
 mov r3, #0x0
loop: lsl r0, r3, #0x1
 add r0, r0, r3
 ldr r1, movesettable
 add r1, r1, r6
 ldr r1, [r1, #0x0]
 add r7, r0, r1
 ldrb r0, [r7, #0x2]
 mov r4, r10
 cmp r0, r4
 bgt exit2
 ldrb r1, [r7, #0x1]
 ldrb r0, [r7, #0x0]
 lsl r1, r1, #0x8
 orr r1, r0
 mov r0, r8
 str r3, [sp, #0x0]
 bl branchone
 mov r5, r9
 ldr r3, [sp, #0x0]
 cmp r0, r9
 bne exit
 mov r0, r8
 add r1, r4, #0x0
 bl branchtwo
 ldr r3, [sp, #0x0]
exit: add r3, #0x1
 lsl r1, r3, #0x1
 add r1, r1, r3
 add r0, r7, r1
 ldrb r0, [r0, #0x2]
 cmp r0, r5
 bne loop
exit2: add sp, #0x4
 pop {r3-r5}
 mov r8, r3
 mov r9, r4
 mov r10, r5
 pop {r4-r7}
 pop {r0}
 bx r0
branchone: push {r4-r7,lr}
 add sp, #-0x4
 ldr r7, gothere
 bx r7
branchtwo: push {r4-r7}
 ldr r7, gothere2
 bx r7
.align
gothere: .word 0x0803E8B5
gothere2: .word 0x0803EC43
movesettable: .word 0x08FFFFFF
Change 0x3EA10 to 00 49 08 47 XX XX XX 08 where the XX XX XX stands for the pointer to your new routine plus 1.

This will fix the moveset loading to it can now support up to 0xFFFF moves (instead of 0x1FF).

Finally, in order for the Move Relearner to work with the new system, insert this routine in your ROM:

 .text
.align 2
.thumb
.thumb_func
.global newmovesetstyle
main:
 lsl r2, r5, #0x1
 add r2, r2, r5
 ldr r1, [sp, #0x10]
 add r0, r2, r1
 ldrb r0, [r0, #0x2]
 ldr r1, [sp, #0xC]
 add r7, r2, #0x0
 add r5, #0x1
 mov r12, r5
 cmp r0, r1
 bgt later
 mov r4, #0x0
 cmp r1, r0
 beq later2
 mov r4, #0x1
 neg r4, r4
 ldr r0, [sp, #0x14]
 ldr r1, table
 add r6, r0, r1
 mov r3, sp
 sub r3, #0x2
 add r5, r7, #0x0
there: add r3, #0x2
 add r4, #0x1
 cmp r4, #0x3
 bgt later2
 ldr r0, [r6, #0x0]
 add r0, r5, r0
 ldrb r2, [r0, #0x0]
 ldrb r0, [r0, #0x1]
 lsl r0, r0, #0x8
 orr r0, r2
 ldrh r2, [r3, #0x0]
 cmp r0, r2
 bne there
later2: cmp r4, #0x4
 bne later
 mov r4, #0x0
 cmp r4, r10
 bge later3
 mov r1, r9
 ldr r0, [r1, #0x0]
 add r0, r7, r0
 ldrb r2, [r0, #0x0]
 ldrb r1, [r0, #0x1]
 lsl r1, r1, #0x8
 orr r1, r2
 ldr r0, [sp, #0x8]
 ldrh r2, [r0, #0x0]
 cmp r1, r2
 beq later3
 ldr r1, [sp, #0x14]
 ldr r2, table
 add r6, r1, r2
 ldr r3, [sp, #0x8]
 add r5, r7, #0x0
there2: add r3, #0x2
 add r4, #0x1
 cmp r4, r10
 bge later3
 ldr r0, [r6, #0x0]
 add r0, r5, r0
 ldrb r2, [r0, #0x0]
 ldrb r0, [r0, #0x1]
 lsl r0, r0, #0x8
 orr r0, r2
 ldrh r2, [r3, #0x0]
 cmp r0, r2
 bne there2
later3: cmp r4, r10
 bne later
 mov r0, r10
 add r0, #0x1
 mov r10, r0
 lsl r2, r4, #0x1
 ldr r1, [sp, #0x8]
 add r2, r2, r1
 mov r4, r9
 ldr r0, [r4, #0x0]
 add r0, r7, r0
 ldrb r1, [r0, #0x0]
 ldrb r0, [r0, #0x1]
 lsl r0, r0, #0x8
 orr r0, r1
 strh r0, [r2, #0x0]
later: mov r5, r12
 mov r1, r9
 ldr r0, [r1, #0x0]
 lsl r1, r5, #0x1
 add r1, r1, r5
 add r1, r1, r0
 ldrb r0, [r1, #0x2]
 cmp r0, #0xFF
 bne main
 mov r0, r10
 add sp, #0x18
 pop {r3-r5}
 mov r8, r3
 mov r9, r4
 mov r10, r5
 pop {r4-r7}
 pop {r1}
 bx r1
.align
table: .word 0x08FFFFFF
Change 0x43CE8 to 00 4A 10 47 XX XX XX 08 where the XX XX XX stands for the pointer to your new routine plus 1.

In PGE, you now need to open up the settings drop-down menu, and select "Use Jambo's Moveset hack" to support the new moveset style.

It is good practise (and will help avoid crashes) to repoint all your movesets to free space and start fresh with the new movesets.

Hey, I never said it would be easy!

Bear in mind, the same rules apply here as before. No status inflicting moves will work, so don't try them.

And you are done!

NOTE: For any intrepid people who wish to use the new moveset style without using PGE (I wouldn't advise it!), this is a short explanation of how they now work:

The new movesets are collections of 3 bytes each which are set up thus:
[MOVE - Half-Word - Reverse Hex] [Level - Byte]
So if I wanted my Pokémon's moveset to contain Pound at level 52, it would be:
01 00 34
To end the moveset, you put:
00 00 FF


So far, I'm betting you're wondering why I decided to post this in R&D when it's clearly a tutorial, right?

Wrong! It's just a necessary evil before we can discuss the REAL thing I want to research!

What I want us to research is the ANIMATIONS and BATTLE SCRIPTS associated with the moves and how we can extend both of the above so that we can create new moves which truly imitate their "real" counterparts.

So, does anyone have any pertinent information (above and beyond what we already know) about either subject mentioned above?

FWIW, this is (AFAIK) our best understanding of Battle Scripts.

EDIT: Since I posted this, I found the table which controls animations and was able to make a new move use an existing animation. Based on what I saw, I suspect that the game uses an "Animation Script" in the same vein as the "Battle Scripts". A specially set aside set of commands specifically used for creating move animations.
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!

Gamer2020

Accept no Imitations!

Male
Distant Land
Seen July 31st, 2023
Posted January 9th, 2021
1,062 posts
15.3 Years
What I want us to research is the ANIMATIONS and BATTLE SCRIPTS associated with the moves and how we can extend both of the above so that we can create new moves which truly imitate their "real" counterparts.

So, does anyone have any pertinent information about either of the above(above and beyond what we already know) about either subject mentioned above?

FWIW, [a href="http://www.pokecommunity.com/showpost.php?p=5731099&postcount=1]this is (AFAIK) our best understanding of Battle Scripts.[/a]
I would just like to add that I do have a very basic working Battle Script decompiler. I will be adding a battle script editor to PGE when I have documentation on all the commands so any help on this subject will actually help everyone.
I don't use this site since the whole pedophile incident. (And honestly didn't really use it before that.)

You can find me on gamer2020.net
Male
Seen August 13th, 2021
Posted August 3rd, 2013
42 posts
12.8 Years
http://www.youtube.com/watch?v=jbQP4--Z0Vg&feature=player_detailpage#t=118s

Here is a link to a video from Vega. The move Aerodactyl is using is indeed Brave Bird (I checked the Japanese characters on Bulbapedia). Animation and Effect are functional, though I'm not sure if this an animation that the game already used

marcc5m

what

Age 27
Male
Scotland
Seen 3 Weeks Ago
Posted February 17th, 2023
1,115 posts
12.7 Years
http://www.youtube.com/watch?v=jbQP4--Z0Vg&feature=player_detailpage#t=118s

Here is a link to a video from Vega. The move Aerodactyl is using is indeed Brave Bird (I checked the Japanese characters on Bulbapedia). Animation and Effect are functional, though I'm not sure if this an animation that the game already used
Brave Bird and Sky attack use the same animation.
Male
Seen January 28th, 2018
Posted December 6th, 2015
736 posts
14.3 Years
The battle script commands aren't specifically designed only to work with a certain attack. They are (generally) a bunch of commands, which, when put together, produce the effect of the attack in question.
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Male
Seen January 28th, 2018
Posted December 6th, 2015
736 posts
14.3 Years
Yes. You can edit existing data, although there's little point. If you read the main post, you'll see that you can just add 1 extra attack onto the end of the table, instead of overwriting.

What we CAN'T do at this stage is change the EFFECTS of the attack. That is, we can't make it lower/raise stats, cause status ailments etc. This is because we don't understand the battle scripts well enough to use them to create new effects yet.

Yes, you can indeed use existing animations, and with great ease. I found the animation table in the ROM and it was linked to what I believe are Animation Scripts. All you would need to do would be point your new attack to that animation, and it would use it. I actually copied the existing table into the new slots for the expansion I've done thus far.
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Male
Seen August 13th, 2021
Posted August 3rd, 2013
42 posts
12.8 Years
Well, there are many attacks that are exact duplicates of each other in terms of effect, such as Withdraw/Defense Curl/Harden (aside from the added effect of Rollout). I was looking to take these duplicates and replace them with attacks from later Generations. Obviously, being able to add them without replacing is the goal, but I'd rather have a few fully functional new attacks now than sacrifice animations for attacks that just do damage.
Male
Seen January 28th, 2018
Posted December 6th, 2015
736 posts
14.3 Years
Well, there are many attacks that are exact duplicates of each other in terms of effect, such as Withdraw/Defense Curl/Harden (aside from the added effect of Rollout). I was looking to take these duplicates and replace them with attacks from later Generations. Obviously, being able to add them without replacing is the goal, but I'd rather have a few fully functional new attacks now than sacrifice animations for attacks that just do damage.
I've worked out how to use existing animations for now actually. I don't have anything noted down though, so I'll need to look it up again.
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Male
Seen May 26th, 2023
Posted September 19th, 2022
1,323 posts
16.4 Years
This might help with adding new moves, but here's a list of all effect numbers:
Spoiler:

0 = no added effect
1 = puts target to sleep
2 = posion the target
3 = abosrbs half the damage inflicted (Absorb, Mega Drain, etc.)
4 = burn the target
5 = freeze the target
6 = paralyze the target
7 = Selfdestruct, Explosion
8 = takes 1/2 of damage inflicted on sleeping foe (Dream Eater)
9 = Mirror Move
10 = raises user's Attack
11 = raises user's Defense
12 = raises user's Speed
13 = raises user's Special Attack
14 = raises user's Special Defense
16 = raises user's evasion
17 = never misses
18 = lowers opponent's Attack
19 = lowers opponent's Defense
20 = lowers opponent's Speed
21 = lowers opponent's Special Attack
22 = lowers opponent's Special Defense
23 = lowers opponent's Accuracy
24 = lowers opponent's evasion
25 = Haze (there's many effects associated exclusively with this move)
26 = Bide
27 = Thrash/Petal Dance/Outrage
28 = Whirlwind/Roar effect
29 = happens 2-5 times
30 = Conversion
31 = may cause flinching
32 = Recover 1/2 of maximum HP
33 = badly poisons foe
34 = Pay Day
35 = Light Screen
36 = may freeze, paralyze, or burn
37 = Rest
38 = 1-hit KO
39 = takes 2 turns + high critical hit ratio (Razor Wind)
40 = always cuts half of foe's current HP
41 = always do 40 HP damage (Dragon Rage)
42 = Bind/Fire Spin/Clamp/Whirlpool effect
43 = high critical hit ratio
44 = hits twice (Double Kick)
45 = if miss, then user receives 1/8 of damage it would have dealt (Jump Kick)
46 = stops stat changes (Mist)
47 = raises user's critical-hit ratio
48 = recoil damage, 1/4 of damage (Take Down)
49 = Confuse target
50 = sharply raises users Attack
51 = sharply raises users Defense
52 = sharply raises users Speed
53 = sharply raises users Special Attack
54 = sharply raises users Special Defense
57 = Transform
58 = sharply reduces foe's Attack
59 = sharply reduces foe's Defense
60 = sharply reduces foe's Speed
61 = sharply reduces foe's Special Attack
62 = sharply reduces fow's Special Defense
65 = Reflect
66 = poisons the target (again, for some reason)
67 = paralyzes the target (again, for some reason)
68 = lower opponent's Attack
69 = lower opponent's Defense
70 = lower opponent's Speed
71 = lower opponent's Special Attack
72 = lower opponent's Special Defense
73 = lower opponent's accuracy
75 = takes 2 turns, may cause opponent to flinch
76 = may Confuse target
77 = hits twice, may poison opponent (Twineedle)
78 = never misses, but attacks second
79 = Substitute
80 = immobile next turn (Hyper Beam)
81 = raises user's Attack every time is hit (Rage)
82 = Mimic
83 = Metronome
84 = steals opponent HP every turn (Leech Seed)
85 = Splash
86 = Disable
87 = damage is equal to user's level (Seismic Toss/Night Shade)
88 = amount of damage done varies (Psywave)
89 = Counter
90 = Encore
91 = Pain Split
92 = can only use this attack if user is asleep (Snore)
93 = Conversion 2
94 = next move after will not miss (Mind Reader)
95 = Sketch
97 = Sleep Talk
98 = Destiny Bond
99 = inflicts more damage if user has less HP (Flail, Reversal)
100 = Spite (cuts opponent's PP)
101 = False Swipe (will never make opponent faint)
102 = heals all status problems
103 = always attacks first
104 = attacks 3 times, gets stronger each time (Triple Kick)
105 = steal foe's held item
106 = prevents foe from fleeing/switching
107 = inflicts 1/4 damage on sleeping foe (Nightmare)
108 = raises user's evasion, receives double damage from Stomp
109 = Curse
111 = Protect/Detect
112 = Spikes
113 = Foresight
114 = Perish Song
115 = Sandstorm
116 = Endure
117 = Rollout/Ice Ball
118 = Swagger
119 = Fury Cutter
120 = Attract
121 = higher attack power if Pokemon happiness is higher
122 = Present
123 = higher attack power if Pokemon happiness is lower
124 = prevents all status problems from user
125 = thaw out if frozen, may burn target (Flame Wheel/Sacred Fire)
126 = Magnitude
127 = Baton Pass
128 = Pursuit
129 = Rapid Spin (removes Fire Spin, Whirlpool, etc.)
130 = always do 20 HP damage (SonicBoom)
132 = Morning Sun
133 = Synthesis
134 = Moonlight
135 = Hidden Power
136 = Rain Dance
137 = Sunny Day
138 = 10% chance of raising user's Defense (Steel Wing)
139 = may raise user's Attack (Metal Claw)
140 = may raise user's Attack, Defense, Speed, Special Attack, and Special Defense
142 = maximizes Attack, HP is cut in half (Belly Drum)
143 = Psych Up
144 = Mirror Coat (special version of Counter)
145 = takes 2 turns, raises user's Defense (Skull Bash)
146 = may flinch opponent, double the damage if opponent uses Fly or Bounce
147 = does double the damage if opponent is using Dig
148 = Future Sight
149 = does double the damage is opponent is using Fly or Bounce
150 = may cause flinching + attack power is doubled if opponent used Minimize
151 = takes 2 turns, unless Sunny Day is in effect. Only 1/2 the damage if Rain Dance, Sandstorm, or Hail
152 = Thunder (there's many effects associated exclusively with this move)
153 = Teleport
154 = Beat Up
155 = takes 2 turns
156 = raises user's Defense, power of Rollout and Ice Ball is now doubled
157 = Softboiled/Milk Drink (Recover, but usable out of battle)
158 = Attacks first, causes flinching (Fake Out)
159 = Prevents sleep, attacks for 2-5 turns (Uproar)
160 = Stockpile
161 = Spit Up
162 = Swallow
164 = Hail
165 = Torment
166 = Confuses foe, but raises foe's Special Attack
167 = Burns the foe, but doesn't affect Fire types
168 = Memento
169 = Boosts Attack when burned, paralyzed, or poisoned
170 = takes 2 turns, but if hit user flinches (Focus Punch)
171 = Stronger against paralyzed foes, but heals the paralysis (SmellingSalt)
172 = Makes foes attack only the user (Follow Me)
173 = Nature Power
174 = Next electric move used is now stronger (Charge)
175 = Taunt
176 = Helping Hand
177 = Trades held items with foe
178 = copies opponent's special ability
179 = Wish
180 = attacks randomly with one of partner's moves (Assist)
181 = Ingrain
182 = lowers user's Attack and Defense
183 = Magic Coat
184 = Recycle
185 = double the damage if user was hurt by opponent in the same turn
186 = destroyes Light Screen and Reflect (Brick Break)
187 = Yawn
188 = opponent loses held item (Knock Off)
189 = Endeavor
190 = the higher user's HP, the more damage
191 = user swaps abilities with opponenet (Skill Swap)
192 = Imprison
193 = Refresh
194 = Grudge
195 = Snatch
196 = more damage on heavier foes (Low Kick)
197 = Secret Power
198 = recoil damage, 1/3 of damage (Double-Edge)
199 = confuses all Pokemon on the scene (Teeter Dance)
200 = high critical hit ratio + may cause burn (Blaze Kick)
201 = Mud Sport
202 = damage + badly poison target
203 = type and power depends on weather (Weather Ball)
204 = sharply lowers Special Attack after use (Overheat)
205 = lower's opponent's Attack and Defense (Tickle)
206 = raises user's Defense and Special Defense (Cosmic Power)
207 = can hit an opponent using Fly or Bounce (Sky Uppercut)
208 = raises user's Attack and Defense (Bulk Up)
209 = high critical hit ratio + poison
210 = Water Sport
211 = raises user's Special Attack and Special Defense (Calm Mind)
212 = raises user's Attack and Speed (Dragon Dance)
213 = Camouflage

Note that there are some (well hardly any) numbers that are missing, and that's only because no attack uses the effect number.
Male
Seen January 28th, 2018
Posted December 6th, 2015
736 posts
14.3 Years
This could (in fact) be very helpful, as I can use it to track down what battle script command does what. The only difference now is that I won't be doing it blindly. So thank you. You may possibly have saved me a huge amount of time.
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Male
Seen May 26th, 2023
Posted September 19th, 2022
1,323 posts
16.4 Years
This could (in fact) be very helpful, as I can use it to track down what battle script command does what. The only difference now is that I won't be doing it blindly. So thank you. You may possibly have saved me a huge amount of time.
You're welcome lol, I guess it also helps that some moves have exclusive effects, such as Thunder. I would imagine that if you were to do Fusion Bolt on a Gen III game, it would look like Fly + Thunder.

Also here's a Japanese rom hack that has plenty of Gen IV moves incorporated, perhaps it could help give you ideas for animations:
http://www.youtube.com/watch?v=XGpqbjA-aow&feature=related

(I can read Japanese, so here's where you can see the new moves)
0:33 - Focus Blast
1:07 - Gunk Shot
1:58 - Energy Ball
2:15 - Aqua Jet
3:39 - a custom attack using katakana to spell out, "Hurricane", which is kinda odd because Hurricane's japanese name is Boufou, not Harikeen
4:54 - Hammer Arm


EDIT: Since I posted this, I found the table which controls animations and was able to make a new move use an existing animation. Based on what I saw, I suspect that the game uses an "Animation Script" in the same vein as the "Battle Scripts". A specially set aside set of commands specifically used for creating move animations.
EDIT: Um... is there any reason why you didn't tell us the offset of the animation table? If you force everyone to find it themselves, it's gonna be a lot harder for people to help with the research.

Gamer2020

Accept no Imitations!

Male
Distant Land
Seen July 31st, 2023
Posted January 9th, 2021
1,062 posts
15.3 Years
Finally, overwrite the bytes at 0xD75FC with 00 00 00 00 00 00 to disable the only limiter in the ROM. If you do not edit this, rather than saying "Bulbasaur used VenoShock!", it will say "Bulbasaur used a POISON move!"
I had a couple of free minutes so I did a little tinkering. I think that the location for this in Emerald should be 0x14E504. I will find the locations of other stuff when I get a chance.
I don't use this site since the whole pedophile incident. (And honestly didn't really use it before that.)

You can find me on gamer2020.net
Male
Seen January 28th, 2018
Posted December 6th, 2015
736 posts
14.3 Years
EDIT: Um... is there any reason why you didn't tell us the offset of the animation table? If you force everyone to find it themselves, it's gonna be a lot harder for people to help with the research.
There's no reason per sé, I just forgot to post it what with my exams and everything.
The table (in FR) is at 0x1C68F4. It starts with move 0x0 (an invalid move - left in as an error handler) and carries on in order of the moves in the game.

This is a table of pointers to animation scripts. Somehow they link together from the script to animation on screen, though i've not worked it out yet.
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!

colcolstyles

Yours truly

Male
The Bay Area
Seen May 18th, 2019
Posted August 13th, 2012
1,588 posts
15.3 Years
EDIT: Since I posted this, I found the table which controls animations and was able to make a new move use an existing animation. Based on what I saw, I suspect that the game uses an "Animation Script" in the same vein as the "Battle Scripts". A specially set aside set of commands specifically used for creating move animations.
Yeah, I've been doing some research and that seems to be the case. In Emerald, the table of animation scripts is at 0x2c8d6c and the table of animation commands is at 0x525e98. I only just started so I don't know what the majority of the commands do but (and these are just educated guesses) 0x00 loads graphics, 0x02 starts an animation, and 0x05 waits for all current 0x02 animations to finish before continuing the script execution. It seems like all the interesting stuff will be located inside 0x02. I'll take a look at it when I get the chance.

I had a couple of free minutes so I did a little tinkering. I think that the location for this in Emerald should be 0x14E504. I will find the locations of other stuff when I get a chance.
Yeah, that's where the limiter is. I changed the byte at 0x14e50b to 0xe0 which changes the 'bls' instruction to a 'b' instruction.

Brother of Vrai

DoesntKnowHowToPlay

Tiny Umbrella with Lots and Lots of Good

Seen February 18th, 2023
Posted February 3rd, 2023
264 posts
11.7 Years
I've been messing around with these a bit, and thought I'd post some of the stuff I found. All of this is for FR, although I assume it'll be similar for other versions. It's also a bit rambly and unprofessional, as I haven't spent too much time investigating these, for which I apologize.

0x00 loads image data, and seems to always take 2 bytes as an argument.

As colcolstyles said, 0x2 seems to execute animations while 0x5 waits for them to finish before continuing.

0x08 terminates execution.
Jump functions seem to exist, but since they go to other places in the ROM this means scripts always seem to end in 08 (although an 08 is not always a terminator).

0x19 does something with sounds.

14 17 16 03 2D B8 0B 08 05 04 00 XX 00 YY 00 00 FF FF starts the Silver Wind background. XX determines how fast the background scrolls horizontally, while YY determines how fast it scrolls vertically. These default to FA and 00, and should probably be left as such. The FFs at the end, if changed, cause the background to continue scrolling after execution.

This script:
Spoiler:

14 17 16 03 2D B8 0B 08 05 04 00 FA 00 00 00 00 FF FF
Stuff
04 00 03 F9 A7 0B 08 0A 05 01 00 00 00 04 00 04 00 00 00 17 04 00 04 00 04 06 04 00 04 00 05 19 7E 00 3F 0B 03 04 00 15 16 03 3D A8 0B 08 0A 05 01 00 00 00 04 00 00 00 00 00 10 07 FF FF 17 08

Starts the silver wind animation, executes whatever is in Stuff, and then stops the Silver Wind animation. There may be a few commands that aren't needed in there, but I was able to create animations for Quiver Dance and X-Scissor.
Male
Seen January 28th, 2018
Posted December 6th, 2015
736 posts
14.3 Years
Ok - This is what I have managed to come up with over the last few weeks/months.

Once I stopped getting caught up in understanding what each and every command actually does, and started looking at the bigger picture, I realised that there are groups of commands which, when executed together, produce the effect we are looking for. If we were ever to create a compiler for battle scripts - I would term these as "super commands".

So, without further ado - the combination of commands which activates the stat changing effects:

Spoiler:

48 [Side - Byte] [Colour - Byte] [Unknown - Byte] // Stat Change Animation
2E [RAM Pointer - Always 0x02023FDE for this! - Word] [Effect - Byte] // Stores what effect to execute
89 [Side - Byte] [ROM Pointer - Script to execute if failed (I think)] // Actually changes the stat, based on what you stored into 02023FDE above.
12 40 00 // Puts [stat] fell/rose onto screen, and delays for a little over a second.


Obviously, these differing bytes will all need quantified. I'll start at the top:

Command 48:
Spoiler:
As far as I can tell, this is simply one of many animation commands, but this one is specifically set aside for the stat changing animations.

Side - Can be either 0 or 1. 0 is the opponent, and 1 is the user.

Colours - These are weird. There are only 3 colours however, so I've taken to using 3 numbers.
0x2 - Red (Attack and Special Attack)
0x3 - Blue (Everything else)
0x4 - Green (Defense and Special Defense)

Unknown Byte - This may control the direction of the animation, though I'm not sure.
0x9 - Down
0x0 - Up


Command 2E (storebyte):
Spoiler:
This command stores a given byte into the RAM address given to the command.

RAM Address - It can obviously be different for different effects, but most effects store a byte into the RAM Address 0x02023FDE.

Effect to Trigger - This is gonna be a fairly long list!
Spoiler:
Note: There are far more effects than this, but I don't have a list of them to hand.

Raising One Level:
0x11 - Attack
0x12 - Defense
0x13 - Speed
0x14 - Special Attack
0x15 - Special Defense
0x16 - Accuracy
0x17 - Evasion

Raising Two Levels:
0x21 - Attack
0x22 - Defense
0x23 - Speed
0x24 - Special Attack
0x25 - Special Defense
0x26 - Accuracy
0x27 - Evasion

Lowering One Level:
0x91 - Attack
0x92 - Defense
0x93 - Speed
0x94 - Special Attack
0x95 - Special Defense
0x96 - Accuracy
0x97 - Evasion

Lowering Two Levels:
0xA1 - Attack
0xA2 - Defense
0xA3 - Speed
0xA4 - Special Attack
0xA5 - Special Defense
0xA6 - Accuracy
0xA7 - Evasion



Command 89 (executestatchange):
Spoiler:
Executes the effect stored at 0x02023FDE.

Side - It's actually more than this, but I wasn't able to work out what exactly. It definitely controls side as well, however.

0xC1 - User
0x41 - Opponent

Script Pointer - A pointer to a battle script to branch to. Not entirely sure if this is for failure, but I suspect it is since the ROM continues execution of the existing script if the stat change succeeds.


Command 12 (showstatus):
Spoiler:
Prints the result of the changed stat to screen. Takes a frame delay as a parameter. This seems to work out in the background (possibly by reading 0x02023FDE) what effect was executed.

40 00 - 0x40 - 64 frame delay. At GBA's running speed. That is almost exactly 1 second of delay.


Fantastic - So far I've only talked about changing stats. What about burning, poisoning or damaging the foe? Well, these require yet more different commands!

Spoiler:
So, we want to create a basic attack that does damage. This is how it's structured (all numbers are in hex):
Spoiler:
00 01 5E 69 1D 08 00 00 02 03 04 05 06 07 09 0A 0E 5C 00 3A 0B 00 0C 00 0D 12 40 00 0F 12 40 00 15 19 00 00 00 00 00 00 2E D8 3F 02 02 00 49 00 00 3D


See why I put it in a spoiler? The thing is, if you search for this string in your BPRE ROM, you will find it already exists, so why do we need to know about it at all? Why not just directly call that existing script? The answer is because a lot of the new moves use combinations of existing effects. This is something we cannot achieve simply by using the existing scripts. However, what we CAN do, and I advise you should do, is branch back to this script at the earlist available opportunity, after executing your effects.

Now, the most important part of that script for our purposes is towards the end. The 0x15 byte is the byte which takes care of any added effects that the attack may have. It reads from 0x02023E85 to find what effect it should execute. So why did I bother showing you what's above, I hear you asking.

The stuff that is above isn't reliant on a branch back to this code! You can simply end the execution of the effect(s) by using the return command (0x3C or 0x3D).
It basically comes down to this: If your attack does damage - use this new way, if it doesn't, use the older way from above.

I'll try to explain this with an example: Let's say we want to have Flare Blitz. Flare Blitz does damage, causes recoil AND can cause a burn. This is a combination of 2 existing effects, but because it has to do damage as well, we can't simply use the stat changing method. What do we do?

Firstly, we take care of the damage part of the attack. This is the section of the huge script from above that is in italics. All that nonsense takes care of causing damage to the opponent. So we need that:

Current Code for Flare Blitz:
00 01 5E 69 1D 08 00 00 02 03 04 05 06 07 09 0A 0E 5C 00 3A 0B 00 0C 00 0D 12 40 00 0F 12 40 00
Excellent. Our attack would now do damage, carry an animation and all that good stuff.
Now, what effect gets executed next for Flare Blitz? Well - The recoil effect, of course! So, how to we go about finding how to use this effect?

The recoil effect we want is already in the ROM, however, we cannot simply call that one, because the game wouldn't then go on to execute the burn effect. What we need to do is take the relevant part of the recoil effect and insert it into our script, then execute it.

So, knowing that the recoil effect we want is number 198 (the same recoil effect as Double-Edge for anyone wondering where I pulled that number from), we can find the corresponding script easily enough. The table of effects starts at 0x1D65A8 in BPRE. So, we find the 198th entry in that table, and go to the script's location. What we see is what byte is stored, and to where, to execute the recoil effect. So we copy the storebyte command (2E) and all it's parameters to gain the effect.

Current Code:
00 01 5E 69 1D 08 00 00 02 03 04 05 06 07 09 0A 0E 5C 00 3A 0B 00 0C 00 0D 12 40 00 0F 12 40 00 2E 85 3E 02 02 E6
Now we must execute the effect. Well, that's easy. Command 0x15 executes effects, so we simply add a 15 to the script.

Current Code:
00 01 5E 69 1D 08 00 00 02 03 04 05 06 07 09 0A 0E 5C 00 3A 0B 00 0C 00 0D 12 40 00 0F 12 40 00 2E 85 3E 02 02 E6 15
Excellent - but so far, we've only added 1 of the 2 effects, and it's taken a lot of work! Thankfully, from here on out, it gets easier, as for each effect, you simply repeat the cycle of store and execute until completion. So we want to add the burn effect now. The burn effect byte is 0x3, so we now stick a storebyte for that byte into the end of the script, as well as an execute effect command.

Current Code:
00 01 5E 69 1D 08 00 00 02 03 04 05 06 07 09 0A 0E 5C 00 3A 0B 00 0C 00 0D 12 40 00 0F 12 40 00 2E 85 3E 02 02 E6 15 2E 85 3E 02 02 03 15
Now, that's all of the effects which can be added for this attack directly (the defrosting is handled passively elsewhere), so now what do we do?
Ah yes, as per what I said earlier, we should return to the original script as soon as possible. So now we simply put a Goto command onto the end of the script, returning back to normal execution.

Flare Blitz Code:
00 01 5E 69 1D 08 00 00 02 03 04 05 06 07 09 0A 0E 5C 00 3A 0B 00 0C 00 0D 12 40 00 0F 12 40 00 2E 85 3E 02 02 E6 15 2E 85 3E 02 02 03 15 28 47 69 1D 08
There we have it! One functional Flare Blitz effect.The recoil will ALWAYS happen, so you don't need to worry about clashes between the recoil and the CHANCE of burning, but if you have 2 effects such as flinch and burning which both rely on chance, they both must share the same chance of happening. This is simply a limiation of the code's design. It is possible for BOTH effects to happen at the same time, so you can't have a chance for poison combined with a chance for paralysis (for example).


Feel free to test out and use this battle script! Using this methodology, it is possible to combine any existing effects in the BPRE 1.0 ROM, which makes the vast majority of Gen 4's (and a fair number of Gen 5's) moves possible on Gen 3 ROMs, animations notwithstanding. A short health warning, all the pointers I include in this post apply specifically to BPRE. However, this string of commands:
Spoiler:
02 03 04 05 06 07 09 0A 0E 5C 00 3A 0B 00 0C 00 0D 12 40 00 0F 12 40 00 15 19


should appear in all of the Gen 3 ROMs.
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!

redriders180

Mastermind of Pokemon Glazed

Male
Path of Victory, Tunod
Seen December 17th, 2016
Posted November 17th, 2015
314 posts
13.3 Years
Post
This is really neat...now I can put new moves in my game? I just have one question...making this script makes plenty of sense, but what exactly do I do with it? Forgive me for sounding noobish, but I can't find an offset, or a way to find an offset, anywhere :(. I just did the tutorial you posted in the OP, so I really hope this new revelation is supported by that...

Speaking of which, is said tutorial updated? I'm confused, since before, it was "make sure effect byte is set to zero". Is this still true? Basically, I don't understand what we can and can't do.


I think I'm done with ROM hacking. I'll still pop in and visit, though.


DoesntKnowHowToPlay

Tiny Umbrella with Lots and Lots of Good

Seen February 18th, 2023
Posted February 3rd, 2023
264 posts
11.7 Years
In FR, the battle script pointer table is at 0x1D6926. If you want to add a new move effect, you'll need to repoint one of the pointers there to your new battle script, and make sure your new moves are using that effect. There are a number of "holes" in the table, such as at #12 (which would be, going by the pattern, an effect that gives +1 to the user's speed), but if you use those the AI probably won't interpret them correctly (or at all).

Also, thank you very much for that very helpful post Jambo. I wouldn't have been able to find the table at all without your attack script.

redriders180

Mastermind of Pokemon Glazed

Male
Path of Victory, Tunod
Seen December 17th, 2016
Posted November 17th, 2015
314 posts
13.3 Years
In FR, the battle script pointer table is at 0x1D6926. If you want to add a new move effect, you'll need to repoint one of the pointers there to your new battle script, and make sure your new moves are using that effect. There are a number of "holes" in the table, such as at #12 (which would be, going by the pattern, an effect that gives +1 to the user's speed), but if you use those the AI probably won't interpret them correctly (or at all).

Also, thank you very much for that very helpful post Jambo. I wouldn't have been able to find the table at all without your attack script.
But is it possible to expand the battle script pointer table as well? For instance, it only goes up to 213 right now, surely it can go to 255?


I think I'm done with ROM hacking. I'll still pop in and visit, though.


Male
Seen January 28th, 2018
Posted December 6th, 2015
736 posts
14.3 Years
i think in this script it also need something to do when the opponent use "protect"
No, we don't. It's all handled by the damage part of the script. Quite clever, isn't it?

Also, thank you very much for that very helpful post Jambo. I wouldn't have been able to find the table at all without your attack script.
You're welcome, although the pointer you posted isn't the pointer table to the battle scripts, it's the actual basic damage script itself, lol!

I actually gave the location in my post, so use that instead. The great thing is that all text and delays and such are ALL handled by the script, so it makes adding new attacks much easier! :)
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!