View Full Version : Research: Battle Scripts

April 18th, 2010, 7:59 PM
While researching abilities, I came across something peculiar. In some abilities, a pointer to a ROM area (usually around x1d0000) was loaded, but no runnable code was present. Also, it appeared that some pointers were present, but were unaligned and as such nearly useless for referencing. The structure of that data was somewhat familiar. At first, I thought they were strings, then random data. But it looked too much like a script, although it made no sense as a regular script. So, I decided to follow up on that data.

In fact, that data was indeed a script, but not a regular one. This script was a special kind, run by a separate code, similar in much to the regular script one. Code replication was not on gamefreak's mind, as four similar routines pop up on the code (as far as I've found them). One such example is the routine at 0x08015c74
ROM:08015C74 battle_script_call ; DATA XREF: ROM:off_801BC64o
ROM:08015C74 PUSH {LR}
ROM:08015C76 LDR R0, =0x2023BC8
ROM:08015C78 LDR R0, [R0]
ROM:08015C7A CMP R0, #0
ROM:08015C7C BNE loc_8015C90
ROM:08015C7E LDR R1, =battle_script_commands
ROM:08015C80 LDR R0, =0x2023D74
ROM:08015C82 LDR R0, [R0]
ROM:08015C84 LDRB R0, [R0]
ROM:08015C86 LSL R0, R0, #2
ROM:08015C88 ADD R0, R0, R1
ROM:08015C8A LDR R0, [R0]
ROM:08015C8C BL sub_81E3BA8 ;simple bx r0
ROM:08015C90 loc_8015C90 ; CODE XREF: ROM:08015C7Cj
ROM:08015C90 POP {R0}
ROM:08015C92 BX R0

Where battle_script_commands is the location 0x0825011C where all commands are located. As far as I know, there are 248 different commands (0x00 to 0xf7) available, but I've only just started studying them. so far, it seems that basic operations are included (add, sub, mov), but some more complex (and battle related) are as well.
I will "decompile" the script for the rainy weather effect for you here, by dividing it in sections. That script is located at 0x081d927f

39 20 00 or 39 0020
10 c1 00 or 10 00c1
45 07 0a 00 00 00 00 or 45 07 0a 00000000
41 dc 92 1d 08 or 41 081d92dc

and at 081d92dc
2e db 3f 02 02 00 or 2e 02023fdb 00
2f db 3f 02 02 01 or 2f 02023fdb 01
2d db 3f 02 02 cc 3b 02 02 01 e2 92 1d 08 or 2d 02023fdb 02023bcc 01 081d92e2

Now, this is just a bunch of numbers, so to make sense of it, here's it spelled out:

pause 0x20 (only calls itself 20 times, doing nothing else)

printString 0xc1 (prints the battle message. sets the value to be print and stores a byte to tell that something needs to be print. Waits until no more characters are written on the screen to continue)


battleAnimation 0x7 0xa 0x0 (displays a certain battle animation, but a limited set of them. 0xa is the raindrop screen. 0x7 is a check, but I don't know of what. 0x0 is an address to be used for checking a byte, but I don't know what for yet)

call 081d92dc (calls the other script for execution)

exit (or not quite. see end of post)


setbyte 0x02023fdb 0x0 (sets the value at that specific address to 0)

checkform (a specific check that verifies the (cast)form of the pokemon involved.)

add 0x02023fdb 0x1 (adds the given byte (0x1) to the contents of the given address)

if (0x02023fdb 0x02023bcc) equal to 0x1 goto 0x081d92e2 (this conditional branch checks 0x1 bytes starting at each position are totaly equal. if not, jump to given address)

return (simply return from the function)

If you want to know what are the printing strings in the command, go to 0x3fdf3c and check position (number - 0xc) of that table. 0x0 to 0xc are reserved to display buffers (like your pokemon name, an attack name or a trainer name)
For the battle print address, note that this is one of (possibly) several graphical functions, so it offers little content. some will crash if tried.

01, nothing
02, disappear and pokemon enter (possibly substitute removal)
03, create substitute
04 turns you into a pokeblock, crash
05 knock off item
06 warp
07 berry item heal
08 disappearing
09 charge
0a rain
0b sun
0c sandstorm
0d hail
0e ?? (absorb-like)
0f hit
10 item up
11 wiggle a bit
12 confusion applied effect
13 awesome blast animation
14 focus energy pumping
15 health recover
16 screen darken recover
17 astonish drops
18 scary face + astonish
19 transform into enemy pokemon (front sprite)
1a turns you into a rock
1b waiting waggle
1c level up shine on your battle display
1d come back animation
1e other come back animation
1f capture pokemon in pokeball
20 turns you into a pokeball, crash.
21 switch (trainer away)

But you may ask, this is fun and all, but what good is it for?
Well, besides some abilities, almost all attacks seem to use this to display and cause effects. there is a table of pointers that is referenced by the attack effect table that seem to be responsible for the graphical part of the attacks and respective effects. So, technically, with this, we can create custom effects and display custom messages as well as change animations for attacks, allowing a greater control over battles.

But still there is much to be done. I posted 11 out of 248 different commands, and one of the ones I posted I'm not too sure it is correct ("exit" did indeed seem to exit command execution, but it loaded a special pointer and placed it in the execution box, so it may be a "return and wait" kind of command instead. Next time it activated was with an attack command, but items also seem to work). So, I'll leave this here for now, hoping someone who knows what to do with this information find it useful.

Edit: While not that many, I seem to have found several useful commands that actually explain a lot of the whys we had regarding Battle mechanics. I'll post below all commands I have found to this moment, as well as what they do (or at least part of what they do):
Edit: While not that many, I seem to have found several useful commands that actually explain a lot of the whys we had regarding Battle mechanics. I'll post below all commands I have found to this moment, as well as what they do (or at least part of what they do):
02 - Used attack display (no arguments)
This command loads the recently used attack that called it, closes the attack window and displays the message "(poke) used (attack).
04 - Critical calculator (no arguments)
This command checks the pokemon current status, items and attack effect byte to increase critical ratio, then generates a random number to represent critical. if true, a critical byte will be set in the RAM.
05 -Base damage calculator (no arguments)
This command creates the real base damage for the attack. If not set, the attack will make zero to near zero damage.
06 -Type damage calculator (no arguments)
This command calculates STAB bonus and general attack effectiveness. All type-related checks are done in this command.
09 - Battle animation display (no arguments)
This command makes more than that, but its complexity can only show us results.This code calls the attack animations according to the attack it has.
0B -Health bar decrease (side to apply)
This command decrease the health bar for the amount in the damage variable. May decrease your own, your opponents or both.
0C -Health value decrease (side to apply)
While 0B offers the graphical interface, it's 0c that does "the dirty work". So, using only 0b will result in not decreasing health, and using only 0c will leave the health bar as it was until you open a menu, or 0b is called.
0D -Critical message display (no arguments)
This command only purpose seems to be the display of the "Critical hit" message. Checks if a critical occured and displays it if so.
10 - Message display (halfword value of the message to print)
This command is the generic print-message command.
12 - Super Effective Message display (halfword time to wait after display)
This command prints the super effective or not very effective message when needed.
1A - Faint Animation display (side to apply to)
This command makes the pokemon go down in the screen, to make it disappear.
23 - Battle Ending functions (1 byte ??)
This command runs itself from 0 to 6 times. Each time, it does something different. But mainly, this code asks for battle ending, including exp calculations and display.
24 - Wild battle identifier (no arguments)
This command checks if there is a pokemon to be used next, or not. If a wild battle is in place, this code calls the last checks to end the battle
26 - ??? (1 byte to store)
Stores the given byte to the memory address before the script pointer. Used by next function
27 - jump if stored byte (word pointer to jump to)
Jumps to the given address if the earlier function stored a byte different than 0 on the loacation
28 - goto (word pointer)
Simple goto, jumps to the location given.
29,2a and 2b - Jump if (byte if mask, word pointer to where value is stored, byte, halfword or word to compare to, word destination pointer)
A set of branches, that only vary in the size of the middle argument (represented in order). 0 is jump if equal, 1 is jump if not equal, 2 is jump if higher, 3 is jump if less or equal, 4 is jump if AND of both values is not zero and 5 is jump if AND of both value is zero.
2c,2d - Jump if array (word first array, word second array, byte compare size, word pointer to go to)
Jumps if a simple, any sized, piece of data meets the condition. Any sized here means it's used for comparing areas of memory usually larger than 4 bytes, but can be used to compare two memory positions of any size.
2e - Store byte (word address, byte to store)
Stores the byte in the address.
2f - Add byte (word address, byte to add)
Adds the byte to the address' contents.
30 - Subtract byte (word address, byte to subtract)
Subtracts the byte to the address' contents.
31 - Copy Array (word first array, word second array, byte copy size)
Copies [size] bytes from the second array to the first.
32 - Add Array (word destination array, word source array, byte size, word pointer to add)
Adds the bytes pointed by the add pointer to the ones at the source array, and stores the results in the destination array.
33,34 and 35 - ORR (word address, byte, halfword or word to ORR contents with)
A set of ORR functions (flag setters), that only vary in the size of the middle argument (represented in order). ORRs value in that pointer and stores it back
36,37 and 38 - NOT (word address, byte, halfword or word to bitwise negate contents with)
A set of NOT functions, that only vary in the size of the middle argument (represented in order). Negates the value in that pointer and stores it back
39 - Pause (halfword time to wait)
This function will be called [wait] times, checking only if the time has passed. When that happens, erases wait byte and continues execution.
3A - Wait (no arguments)
This function waits for an event that has set 0x2023BC8 to occur. As it almost never is set, we can safely use it as a "nop" command to check execution proprieties
3C, 3D - return (no arguments)
This function returns to the script that called the current script. There are differences between the two, but they do mainly that.
3f - End (no arguments)
This function seems to end the execution of the script, called at battle end and after each non-lethal attack. Seems to return to normal code execution.
41 - Call (word pointer to call to)
Calls another battle script into execution, saving the old next pointer on the call stack.
45 - Animation print (byte bank, byte animation, word pointer to a value)
This function prints several battle animations, such as substitute(key above). In the end, not much is known, but it seems likely that more functions like this exist (altough 9 seems to be the one handling all that)
4c- Pokemon Data switch (byte bank)
Replaces the pokemon currently in [bank] side of the battle by a pre-selected one (your case, the one you pressed switch or used baton pass on)
4d - Pokemon Battle Data switch (byte bank)
Using the above switches the pokemon inner data, but this switch is where all battle relevant data is swapped. HP, pp, attacks, stats... Everything is recreated based on the pokemon introduced on the last command.
4e - Pokemon and Health bar display(byte bank)
The graphic representation of the two above commands, this one prints the new pokemon by switching it out and redraws the healt bar accordingly.
53 - Trainer display(byte side)
Allows for the trainer in either corner to come out into the field. What it doesn't allow is for that trainer to go away...
55 - Level up/item get song (no arguments)
Plays the mentioned sound
56 -Pokemon faint cry (byte side)
Plays the Pokemon fainting (low pitched) cry
57 -Flee (not sure, but seems like none)
Flees the scene. Not sure if it does more than that.
5c -Flash Animation (byte bank)
The flash animation that happens when you're hit.
61 -Pokemon Switch animation (byte side to switch)
Changes the pokemon according to the 4c and 4d loaded data. If applied to the rival pokemon, the pokeball bar always appears.
91 -Give money (none)
Gives the halfword worth of money deposited at 0x02023E7E and displays the "obtained X [poke]" message from PayDay use. The money is really added to the normal ammount
EF - Pokemon capture (none)
This is the code responsible for capturing a pokemon. This code will calculate the rates of capture based on the ball used (stored at 0x2023D68). If the item stored is null or invalid (over 0xc), the catch rate is 0.

I'll return with more as I find them

Shiny Quagsire
April 19th, 2010, 5:57 AM
So with this, we could make a custom tutorial battle or something? Cool! :)

April 20th, 2010, 6:58 PM
So I guess the only way to test this is by studying the format, then trying to replicate it with different command sequences.

This is the first time I regret moving to Linux, I'll have to setup a slave windows-box and try some of this.

Full Metal
April 21st, 2010, 4:38 AM
Have you found the command for removing HP?
I believe that would be essential to any new moves, and will likely be in most of them.

April 30th, 2012, 8:02 PM
Been a while, huh? I'll be really busy the next month, so I won't be here long. I'll post the research I have so far in this field.
I have finished documenting all of the Attack effects, and the results are a bit disappointing. Many commands are very specific for a single attack or effect, many being simple setters. I'll present the results.
Fun fact: It took me about 1 month on-off time to document the workings of 75% of the codes, but 2 1/2 months to put it in a readeable TXT format.

Note that this is not yet a complete research. Hopefully, more will be added when found.
I will divide this in sections, starting with the battle RAM locations that have been studied, and then going then into a summary of the available (found) commands.

For those who are interested in only making new scripts, the summary of the commands should be enough (second spoiler tag). The RAM section is important to understand the workings of the engine and battle in general, as well as what changes are needed to simulate other effects.

RAM Structures
Starting the RAM locations section, we have the structures for the pokemon that are out. Each of these structures is replicated four times, one for each pokemon that can be out, following the order "your pokemon", "enemy pokemon", "your second pokemon", "enemy second pokemon". This structures are always present, but in single battles, the last two are not initialized nor used.

The first structure is the Pokemon individual battle structure, with a size of 0x58 (88) bytes, that keeps most information used in battle. In fact, the actual pokemon party data is only accessed to update certain changes in the data, when data is needed on other party members (like beat up or assist) or when switches are involved (baton pass, or the "pokemon" and item tabs).

We will call this structure the "Battle Data" for short. Here the configuration:

Battle Data
0x0 -- Species -- The pokemon species.

Base Stats
0x2 -- Attack -- The pokemon Attack base value
0x4 -- Defence -- The pokemon Defense base value
0x6 -- Speed -- The pokemon Speed base value
0x8 -- S.Atk -- The pokemon Special Attack value
0xA -- S.Def -- The pokemon Special Defence value

0xc -- Slot 1 -- The Attack ID present on slot 1
0xe -- Slot 2 -- The Attack ID present on slot 2
0x10-- Slot 3 -- The Attack ID present on slot 3
0x12-- Slot 4 -- The Attack ID present on slot 4

0x14 -- IVs -- Stored in a single word, same as the encrypted version in the party data. Values are shown later, for convenience

Stat Buffs
Stat buffs are the values manipulated by attacks such as Growl and Harden, that change the final attack value, but are cleared by switching out or at battle end.
The base value is always 6, 0xc (12) is the maximum value permited by the game.

0x18-- ?? -- Not find in use. Logic would say this would be a "HP buff"
0x19-- Atk -- Attack stat modifier.
0x1a-- Def -- Defence stat modifier
0x1b-- Spd -- Speed stat modifier
0x1c-- S.Atk -- Special Attack stat modifier
0x1d-- S.Def -- Special Defense stat modifier
0x1e-- Acc -- Accuracy stat modifier
0x1f-- Evasion -- Evasion stat modifier

0x20-- Ability -- Pokemon's ability ID
0x21-- Type1 -- Pokemon's first type
0x22-- Type2 -- Pokemon's second type
0x23-- ??? -- No information found

Attack PP
0x24-- Slot 1 -- The Attack PP on slot 1
0x25-- Slot 2 -- The Attack PP on slot 2
0x26-- Slot 3 -- The Attack PP on slot 3
0x27-- Slot 4 -- The Attack PP on slot 4

0x28-- curr HP -- The Actual HP the pokemon has
0x2a-- Level -- The pokemon level
0x2b-- Happiness-- The pokemon current happiness level
0x2c-- Max HP -- The Maximum HP of the pokemon
0x2e-- Held Item-- The current item this pokemon is holding.

0x30-- Name -- The pokemon's name (11 bytes)
0x3b-- ??? -- litte information. Used in sketch
0x3c-- Trainer -- The trainer name
0x44-- ?? -- Word. No Information
0x48-- PID -- The pokemon personality id, as shown in the party first slot

0x4c-- Status -- The first set of pokemon status flags. These are kept post battle. Structure shown later.
0x50-- Status 2 -- Second set. This one requires a detailed explantion. See after this table.
0x54-- OTID -- The trainer ID for this pokemon.
This structure is very important, as most pokemon specific data can be found easily here. Most interesting data is present here and can be altered at will, making editing pokemon during battle easy, and making changes that are not permanent confined to the battle screen.
It can be located starting at 0x02023be4, with all four following each other.

Another pokemon set of status is kept separately. That data is a set of flags for other effects like leech seed and ingrain. starting at 02023DFC, one word for each pokemon out.

Another pokemon structure is the one that keeps miscelaneous information for attacks such as encore and disable. This structure shall be called "Disable struct", for it was the first of the effects documented in it.
This structure still has some unknowns in it, as it is somewhat random in its contents. So, lots of bytes might actually be halfwords, only not discovered yet
Disable Struct
0x0 to 0x4 -- ???

Atk indexes
0x4 -- Disabled attack -- The disabled attack Index. Disable stores the attack ID, so only one attack can be disabled.
0x6 -- Encore attack -- The ID of the attack to be repeated in encore.
0x8 -- Protect-endure effect -- 1 if protect or endure are active
0x9 -- Stockpiled counter -- Counts the number of times stockpile was used
0xa -- ???

0xb -- Disable timer -- Time left on disable. 0x10 means until switch or battle end. 0xf to 0x0 means number of turns (up to 15)
0xc, 0xd -- ??
0xe -- encore timer -- Time left on encore. same structure as disable timer
0xf -- perish timer -- Time left on perish song faint count.
0x10-- fury cutter counter -- keeps the number of sucessful fury cutter uses. cap is imposed by the command that sets it.
0x11-- rollout timer -- Counts down from 5 to 0, limiting the number of times rollout can be used. difference gives the current power
0x12-- charge timer -- count down from 2, counting with turn it was set. If set to larger numbers, it will allow more than one turn of boosted electric power
0x13-- taunt timer -- turns until taunt looses effect. it will not decrease on the turn it was set
0x14-- ??

0x15-- always hit -- does not miss once when this is set
0x16-- battle start -- timer that counts down from the start of first turn. Only 1 on first turn, used by fake out.
0x17 -- ??
0x18 -- Truant counter -- 1 when is the slack turn
0x19 to 0x1b -- ??
This structure is located starting at 0x02023e0c

The last of the structures for individual pokemon is the structure related to damging moves. This structure will be called "Protect struct" for now, as it was first really discovered in the protect-endure command. It is largely unknown.
It has 0x10 (16) bytes in size, and only three entries are known.
Protect struct
0x1 -- Protect_flags -- Flags that set a number of status, including protect
0x4 -- Phys_damage -- The amount of physical damage received this turn
0x6 -- Spc_damage -- The amount of special damage received this turn
These structures are located starting at 0x02023e8c.

And that's it for individual pokemon structures. Two other structures are kept to check on for party affecting effects, such as reflect, even if one is just an halfword.

The halfword located at 0x02023dde will be called halver_marker, as the first flags found for it were the reflect and light screen ones.

Right after it, at 0x02023de4 is located the structure that keeps the timers for party-affecting effects, such as the ones mentioned above. This structure will be called "Party timers",
Party timers
0x0 -- reflect timer -- Turns left on reflect effect. starts at 5
0x1 -- ??
0x2 -- lightscreen timer -- Turns left on lightscreen effect.
0x3 to 0x5 - ???
0x6 -- safeguard timer -- Turns left on safeguard effect.
0x7 -- ???
0x8 -- Follow me timer -- turns left where the foe must target someone
0x9 -- follow me target-- the forced target's slot.
0xa -- spike_setter -- 1 if spikes are set. must be set with the flag in the halver flags to work
0xb -- ???

These are the structures found that are related to the attack functioning.
The data found on other battle essential data will be spoken about later.

First, the flags indicated on the several structures are indicated below for
each field. Starting with the Battle data:
(mask -> effect)
0x0000001f --> hp
0x000003e0 --> atk
0x00007c00 --> def
0x000f8000 --> spd
0x01f00000 --> s.atk
0x03e00000 --> s.def
0x00000007 -> Sleep (up to 7 turns)
0x00000008 -> poison
0x00000010 -> burn
0x00000020 -> freeze
0x00000040 -> paralyze
0x00000080 -> badly poisoned
Status 2
0x00000007 -> confusion: 7 turns max, decreases each turn before use. snaps out when 1->0)
0x00000008 -> flinching
0x00000070 -> uproar
0x00000f00 -> charging energy (bide) when 1, spit all energy. 3 total, as each flag is a different state

0x00001000 -> multiple attack over several turns.
This one is very important, as it is used by any attack that has two turns.
From Rollout to dig, solarbeam to petal dance, any attack that forces the user to use it a second turn (skip attack selection) sets this flag.
The attack must then know how to deal with it, and unset it when time is up.

0x0000e000 -> multiple attack (warp) target by up to 7 turns.
This is the target's side, so its the timer for the one suffering from the attack.
0x000f0000 -> attraction, infatuation.
The bit indicates the slot of who is the target.
1 is your pokemon,2 is opponent, 3rd bit is your second out pokemon, 4th is your opponent 2nd pokemon out.
ex: 0x000a0000 means the pokemon is in love with both of your opponent pokemon. The one showed is always the lowerst one. It is possible to be in love with oneself.

0x00100000 -> plus critical hit chance (focus energy)
0x00200000 -> transformed
This means that this pokemon used transform, and is now a copy of
another pokemon. Some effects are canceled by this attack (such as skectch effect)

0x00400000 -> needs recharge (hyper beam case)
0x00800000 -> atk up if hit (rage effect)
0x01000000 -> substitute
Lots of attack scripts check for this condition before acting. Status effects do not affect substituted pokemon.

0x02000000 -> opponent faints if you faint (destiny bond)
0x04000000 -> prevent escape
0x08000000 -> nightmares
0x10000000 -> cursed (ghost curse effect)
0x20000000 -> next attack will hit (foresight)
0x40000000 -> defence curl used
Special (status) flags
0x00000001 --> ??
0x00000002 --> ??
0x00000004 --> leech seed affected
0x00000010 --> always hit
0x00000020 --> perish song affected
0x00000040 --> on air (fly, bounce)
0x00000080 --> underground (dig)
0x00000100 --> minimized
0x00000200 --> charged up
0x00000400 --> rooted
0x00000800 --> sleep this turn(yawn)
0x00001000 --> sleep in one turn(yawn)
0x00002000 --> cannot use attacks from target(imprision)
0x00004000 --> foe loses all pp on last used atk if user faints (grudge)
0x00010000 --> elec attacks cause half damage (mud sport)
0x00020000 --> fire attacks cause half damage (water sport)
0x00040000 --> underwater (dive)
Protect structure
0x1 --> protect on
0x2 --> endure on
0x8 --> helping hand on
0x10 --> magic coat
0x20 --> snatch on
Halver halfword
0x01 --> reflect on
0x02 --> light screen on
0x10 --> spikes in place
0x20 --> safeguard on
This ends the description of the main pokemon data for the battle, the one that directly affects the pokemon on the field.

Next up, we have Battle properties.

0x02022b4c keeps a word containing the flags that tell you the type of battle you are in.
Battle Type
0x00000001 --> double battle
0x00000002 --> wireless
0x00000004 --> wild battle
0x00000008 --> trainer
0x00000010 --> oak tutorial
0x00000020 --> ??
0x00000040 --> ??
0x00000080 --> safari bit
0x00000100 --> trainer tower ?
0x00000400 --> old man
0x00000800 --> trainer tower?
0x00008000 --> ghost byte
0x00010000 --> Poke Dude
0x00040000 --> ?? (probably secret base battle)
Many more types are missing. Some are unconfirmed.

Below this word is the Terrain type byte. This byte changes some graphics in the battle setting, but most importantly, it allows attacks such as secret power to change its type according to setting.
Terrain Byte
0x0 --> long grass (very tall grass)
0x1 --> tall grass
0x2 --> sand
0x3 --> underwater
0x4 --> sea
0x5 --> lake/pond
0x6 --> rock
0x7 --> cave
0x8 --> inside building
0x9 --> wireless/ no terrain
Other important pair of addresses are the weather locations.
0x02023F48 keeps the number of turns to be affected by the weather, up to 255 turns.
02023F1c keeps the actual weather. It is accessed has a Halfword, but only the lower byte was seen used. The flags are as follows.
Weather Flags
0x0001 --> rain
0x0002 --> downpour
0x0004 --> permanent rain
0x0008 --> sandstorm
0x0010 --> permanent sandstorm
0x0020 --> sunny
0x0040 --> permanent sunny day
0x0080 --> hail
Permanent means the timer is not decreased. Hail has no permanent version.

Other important locations are the ones where all battle script metadata is
0x02023FE8 --Allocated memory address-- Keeps a pointer to an allocated memory location that keeps lots of temporary data, including attack to be considered and type of that attack. (type is alloc'd+0x13)
02023BCC -- Number of pokemon out in the field. 2 if single battle, 4 if double battle. used for many things, including loops.
02023d4a -- Previous attack ID (most times)
02023d4c -- Current attack ID
02023D4E -- Switch attack ID (for metronome or mimic)

02023d50 -- Attack damage -- keeps the damage that is going to be caused when the damage causer is called.

02023D54 -- Start atk damage -- The value first placed in attack damage
02023D58, 5c,60,64 -- Acumulated damage Reset by bide, and then used to make the damage for the final attack.
02023D68 -- knocked off item -- Item removed by knock off for the player.

Battle banks are used to a number of things, but prehaps the most important is to know who to affect. There are a large number of them, but the ones that are most used are the first and second, that keep the user and targer pokemon.

02023D6B -- User Bank -- The slot of the pokemon using the attack
02023D6C -- Target Bank -- The slot of the pokemon targeted by the attack. Attacks that target the user use the above bank,not this one for calculations and checks.

02023D6D -- User partner -- the partner pokemon (if exists) of the user
02023d6E -- Target partner -- the partner of the target pokemon.

02023FDB -- bank 0a -- the last bank, not much is knonw about it. used in some places, like perish song setter.
Continuing with other important locations
02023d70 -- Hit Flags -- One flag for each pokemon to be hit by a multihit attack
ex: 0xf means hit all, 0xc means all at enemy side (even if they launched the attack)

02023d71 -- Critical marker -- 1 if not critical, 2 if critical hit. calcuated by command 4
02023d72 -- loop counter -- Used by attacks that loop over themselves, such as multi-hit (2-5 times) or all pokemon on screen (earthquake).
02023d74 -- Blt_script_exe_pointer
The current pointer to the execution of the battle script. Changing it is a jump

02023F48 -- Weather turn counter
Keeps how long the current weather is going to remain on.
Whole byte is used for counting, so 50 turns of rain would be possible.

02023f98 -- Last attack ID
Four of them, 2 bytes each, they keep the attacks used by the out pokemon in the previous turn. Used, for instance, in the repeating and charge attacks

02023DCC -- Outcome -- Calculated by first commands, it tells the outcome of an attack. Key:
0x01 -> missed
0x02 ->super effective
0x04->not very effective
0x08 -> not affected
0x10 ->one hit ko
0x20 -> failed
0x40 ->endured
0x80 -> hanged on using item
02023dd0 -- Hit marker -- This is set by the scripts, to say the target is
affected by the move even when it could not be hit.
0x00200 --> stops command 2 from printing the "x used A" script
0x00400 --> stops command 2 from printing the "x used A"
set by command 2 itself

0x02000 --> makes it affect status even if safeguarded
0x10000 --> makes it affect flying targets
0x20000 --> makes it affect underground targets[\code]
02023E7E -- Payday amount -- money to be awarded at the end of the battle

02023e85 -- Effect chooser
Very important byte, that is where the game will check for effects to be applied by the attack, such as status and stat changes. Most attacks that use effect+hit do so by setting this byte and jumping to the
normal attack script.
[code]0x1 -> Sleep
0x2 -> poison
0x3 -> burn
0x4 -> freeze
0x5 -> paralyze
0x6 -> badly poison
0x07 -> Confusion
0x08 -> Flinch
0x09 -> Tri Attack
0x0a -> uproar start
0x0b -> payday
0x0c -> set Repeating attack (0x1000 flag)
0x0d -> wrap
0x0e -> recoil
0x0f to 0x15 -> raise stat by 1 (same order as battle data)
0x16 to 0x1c -> lower stat by 1
0x1d -> recharge needed set
0x1e -> rage set
0x1f -> steal Item
0x20 -> prevent escape
0x21 -> nightmare
0x22 -> ancientpower raise
0x23 -> rapid spin
0x24 -> remove prlz if paralized
0x25 -> superpower
0x26 -> recoil and paralyze
0x27 to 0x2d -> raise stat by 2
0x2e to 0x34 -> lower stat by 2
0x35 -> ??
0x36 -> knock off
0x37 to 0x39 --> None
0x3a -> reduce 2 sp Attack (overheat)

02023e87 -- Multistring chooser
Another important byte, it chooses which string the multistring print command will use from the list. Many commands use it as a way to communicate the outcome

02023e8a -- End byte -- Ends the battle when set to C
02023FD2 -- Attack multiplier
Another useful one to, this will multiply the resulting damage by the value here set (usually 2 or 3).

02023FDE -- Stat change byte
Read by one command (89), it is used to set the stat of your choosing to a bigger or smaller value.
0x1-0x8 (low bits) are the stat to change
0x10-0x70 are the value to increase or decrease by
0x80 is the decrease bit
so, example, A4 is decrease by two the special attack stat. (0x80 + 0x20 + 0x4).
The order of the bits is the same as the one in the battle structure.

02023FF4 -- pointer to the return stack for battle scripts

Those are the important battle RAM values that were found and explained.
They are needed to understand what the game does, and how to simulate it with basic commands.

Command Listing

This section will only speak of the form of usage for the various commands.
Most complex commands will not be spoken of in detail
<Command index> <Argument 1> ... <Argument n> -- description
Where each argument is either its size (byte, word...) or a known type (Battle
banks, referenced as "bank"). flags (like in IF) will be reported there as well.

Too complex to name, this command is used everywhere.
It checks for most attack canceling status, such as freeze, fainting, and others
Needed to maintain consistency with normal battle functioning.

1 (Fail address) (hword)
The accuracy checker, responsible for checking if an attack hits or misses.
last hword is either 0 or ffff, but the difference is still not totally clear to
me. Needs more research

Prints the "[Poke] used [attack]" string. may be blocked by setting the Hit
Marker to |0x600

3 - PP reducer
Reduces pp by one (or two if pressure is present)

4 - Critical calculator
Calculates critical chances. Attacks with higher critical chance are dealt here statically (hardcoded razor leaf effect byte,for instance)

under research. most deal with actual damage calculations, such as type, special/physical split, etc

9 - Play battle animation
Plays the attack animation, if allowed. Not completely studied

a - Wait for battle animation
waits for the end of the attack animation, if started.

b - HP bar update
modifies the HP bar by the amount to be removed (in the attack section)

c - HP update
modifies the actual hp value. also responsible for the substitute break

d - Print critical message
If critical happened, here is the print for it.

Needs further research

f - Print result message
Things like super/not effective, or one-hit ko, are loaded for printing here.

10 (HWord) - Print String
Prints a string to the box, from the given ID. Strings are from a table.

11 (hword)
Looks identical to 10. needs further research

12 (hword) - Wait for text
Waits for Hword calls of this command, usually after text.
Typical value is 40, for most attacks.

13 (Word) - Print from table
Prints the selected string from a table (string in ID format).
The entry to be selected depends on the contents of 02023E87 (multi-string selector byte)

14 (word)
Looks identical to 13. Needs further research

15 - Set Effect with chance
Affects the target with an added effect if the chances (from the effect%)
come true. Effect must be loaded in the effect byte (02023E85)

16 - Set Effect
Affects the target with a given effect

17 - Set Effect
Same as 16, but changes target with user (so user is affected)

18 (bank)- Clear status
Clears the status from the targeted bank pokemon. Status to be removed is set at the effect byte (02023E85). Same key as 15,16 and 17 for the byte.

19 (byte) (byte) (address)
needs further research. deals with fainting.

1a (bank)
needs further research

1b (bank)
needs further research

1c (bank) (word) (address) - Jump if Status
Jumps to the given address if the pokemon at that bank has at least one of the given status bits set.
Second word is the bit mask for the Status flags to check.
example: 0x88 in the mask makes this jump if the user is poisoned or badly poisoned

1d (bank) (word) (address) - Jump if Secondary Status
Jumps to the given address if the pokemon at that bank has at least one of the given secondary bits set.
Second word is the bit mask for the Secondary status (0x50 in the battle structure)
example: 0x1007 checks if the banked pokemon is either confused or trapped in an attack (such as trash or rollout)

1e (bank) (ability) (address) - Jump if ability
Jumps to the given address if the banked pokemon has the given ability.
example: 1d 0x1 0x6 0x[address] Would jump to address if the user had Damp as ability.

1f (bank) (hword) (address) - Jump if Halver marker set
Jumps to the given address if the banked pokemon's party is under the effect of the selected flags.
Second word is a mask with the same key as the Halver marker halfword
example: 0x3 would jump if the party is under reflect or light screen effect

20 (bank) (if Flag) (byte quantitiy) (byte stat) (address) - Jump if stat
Jumps to a given address if the stat requested is (if flag) related to the banked pokemonif --> matches
0 --> equal
1 --> not equal
2 --> stat less than given
3 --> stat higher than given
4 --> any bit in common
5 --> no bits in common
stats are numbered as in the battle structure. stat ??? (0) is accessible

21 (bank) (word) (if set)(address) - Jump if Special status Flag
Jumps to the given address if the banked pokemon has the given special flag set.
Second word is a mask with the same key as the Special Status Flags
example: 0x400c0 would jump if pokemon is underground, underwater or on the air (flying,
if set is 0 for jump if any set, and 1 for jump if none set

22 (bank) (type) (address) - Jump if Type equals
Jumps it the given type is present in the banked pokemon
example: 22 00 0a [address] jumps to address if the pokemon is currently fire-typed

23 (bank)
24 (address)
need further research

Is a cleanup command that clears most attack specific, battle related values.
It is used by beat up to set up the next beating turn.
Needs further research.

26 (byte) - Store Looping counter
Sets the value of the loop counter (02023D72) to the given byte.
Loops are user created.

27 (address) - Decrease Loop
Decrease the loop counter, and jumps to the "looping" address given, if the counter is still not 0.

28 (address) - Jump / Goto
Jumps to the given address.

29 (if flag) (word) (byte) (address) - jump if byte
Jumps if the byte stored at [word] is [flag] to byte.
flags are the same as command 20 (jump if stat)
2a (if flag) (word) (hword) (address) - jump if hword
Same as 29, only checking a halfword
2b (if flag) (word) (word) (address) - jump if word
Same as 29, only checking a word

2c (word1) (word2) (byte) (address) - Jump if array equal
Word1,2 are pointers to memory, byte is a size.
Jumps to given address if the contents of the two words(pointers) are equal.
Used by the engine to check pretty much all comparisons between variables, as it uses the size =1/2/4 to check for byte/hword/word equals

2d (word1) (word2) (byte) (address) - Jump if array not equal
Same as 2c, only it now jumps when at least one byte of content is different.

2e (word) (byte) - Set byte
Sets the byte at (word) to the given byte.

2f (word) (byte) - Add byte
Adds the byte to the contents of the (word) address.

30 (word) (byte) - Subtract byte
Subtracts the given byte to the contents of (word) address.

31 (word1)(word2)(byte) - Copy array
Copies the array from the word2 address to the word1 address.
using size = 1/2/4 is how the game copies bytes/hwords/words

32 (word1) (word2) (word3) (byte)
Needs more research. Seems to be a "copy array with offset" function
Word3 + Word2 = source address, word1 = destination address.

33 (word) (byte) - OR byte
Performs an OR between the given byte and the contents of (Word), and stores it in (word)
34 (word) (hword) - OR hword
Same as 33, only dealing with Hwords
35 (word) (word) - OR word
same as 33, only dealing with words

36 (word) (byte) - Clear byte bit
Performs a bit clear (BIC) between the contents of (Word) and byte, and stores the result in (word).
Useful to clear flags from memory addresses.

37 (word) (hword) - Clear bit hword
Same as 36, only dealing with Hwords

38 (word) (word) - Clear bit word
same as 36, only dealing with words

39 (hword) - Pause
Pretty similar to 12, only this one is targeted to broader range.
12 is usually after text, this one is usually after animations.

3a - Wait
Waits for 02023BC8 to be zero before continuing.

needs further research

3c - return
Returns from script call.

3d - end
Ends the script.

3e - end with no outcome cleanup
Same as 3d, but does not erase 02023DCC

needs further research. Resets game when used.

40 (address)
needs further research.

41 (address) - Call
Calls a script from given address.

42 (bank) (byte) (address)
Another jump if type. No idea why there are two of them, but both are used.

43 (ability) (address) - Jump if Ability is present
Checks everyone for the ability, and if someone has it, jumps to given address

Small function, but needs further research. Sets a one in the allocated memory, but why...

45 (bank) (byte) (word) - Play specific animation
This command plays animations. More research is required.
here are the known animations with this command
01, nothing
02, disappear and pokemon enter (possibly substitute removal)
03, create substitute
04 turns you into a pokeblock, crash
05 knock off item
06 warp
07 berry item heal
08 disappearing
09 charge
0a rain
0b sun
0c sandstorm
0d hail
0e ?? (absorb-like)
0f hit
10 item up
11 wiggle a bit
12 confusion applied effect
13 awesome blast animation
14 focus energy pumping
15 health recover
16 screen darken recover
17 astonish drops
18 scary face + astonish
19 transform into enemy pokemon (front sprite)
1a turns you into a rock
1b waiting waggle
1c level up shine on your battle display
1d come back animation
1e other come back animation
1f capture pokemon in pokeball
20 turns you into a pokeball, crash.
21 switch (trainer away)
needs further research

needs further research

48 (bank) (byte1) (byte2) - Print stat animation
where byte1 is the color to print (usually associated with stat, but can be any) and byte2 needs more research, but when &1==1, plays the stat loss sound, and &1==0 plays the stat gain sound.

49 (byte) (byte)
needs further research

It's an alternate attack damage calculator, used for several non-damaging attacks such as counter and mirror coat, but is also used by rollout and fury cutter.
Basically, an alternative to the main damage calculators (5,6,7) for attacks that don't rely solely (or at all) on base power for total damage done.
Needs more research (to match with the main ones)

needs further research

4c (bank), 4d (bank), 4e (bank) (byte)
This commands are used by the game when switching is involved.
The last one (4e) is responsible for updating the pokemon bar.
Most of the work of switching is done elsewere, and is called by an unknown routine with unknown parameters. This mechanic needs lots of research before being useful

4f (bank) (address) - Jump if cannot switch
Jumps to given address if the pokemon indicated by the bank cannot switch or flee.
50 - Open party switch screen

From here on, up until command 0x77, most commands are undocumented, or severely lacking.
The ones that are more or less documented are presented here.

63 (byte) - Attack switch
Switches the banked pokemon used attack with the one set at 02023D4E.
Jumps to the start of that attack effect.

77 - Set protect/endure
One of the first (of many) that are fixed to the attack (or effect) number.
Sets protect if the attack ID is the protect or detect ones.
Sets Endure if the attack ID is the endure one.
Fails if it's neither.

78 - Faint if not Damp
Faints the pokemon if the foe's ability is not damp.
Jumps to an "Ability prevented attack" script if damp is present
Used to faint in Explosion and Selfdestruct.

79 - Erase User HP
Sets the user HP to 0 in memory. Does not affect graphics

7a (address) -Jump while target is valid
Used to loop over all out pokemon, it increments the target pokemon by one and jumps to the given address while the target pokemon is smaller than the number out (2 for single battles, 4 for double battles)
02023D6C is the Target bank. Usually, the target is set to 0, then an execution happens, then this command is called.
To avoid the user, compare the content of Target bank with the content of User bank, and jump straight to the increment if true.
Attacks such as earthquake (that affect all pokemon) use this command to iterate.

7b (address) (byte) - Set Damage as Restore half HP
Sets attack damage as half max target hp. If byte == 1, target is forced as the user.
Does not restore the HP, or alter the graphics. Only sets the recovery amount.
Used in softboiled and milk drink.

7c - Jump to last used attack effect
It only continues forward if no attack was present before.
Attack is fetched from allocated memory + 0x98

7d - Set rain
Sets rain for 5 turns. Also places 1 in the selector multistring (started to rain choice in the strings used by default)

7e - Set reflect
Sets reflect for the user's party, for 5 turns

7f - Set seeded
Sets the leech seed flag on the attack's target

80 (byte)
Manipulates very simply the attack damage value.
0 is negate (damage becomes heal, heal becomes damage)
1 is division by two
2 is multiplication by two

81 (address) - Set rest
If the pokemon HP is full, jumps to the given "fail" address.
Else, sets the damage to -MaxHP and puts the pokemon to sleep for 3 turns.
Places 0 in the multistring variable if it fell asleep, 1 if it was already

82 (address) - Jump if not first turn
Jumps to given address if not the first turn, that is, that the turn counter
(disable structure + 0x16) has reached 0.

83 - Nop

84 (address) - Jump if can't Sleep
Jumps if the target cannot fall asleep.
Causes may be uproar, insomnia or vital spirit.

85 - Stockpile
If the user's stockpile counter is less than 3, adds to the counter and buffers that number.
Else, sets the fail in the result byte (0x02023DCC) and 1 in the multistring chooser.
86 (address) - Stockpile to base damage
Sets the current damage (0x02023d50) to the value determined by the stockpile counter.
Jumps to the address if the stockpile counter is empty.
Resets the counter if sucessful
87 (address) - Stockpile to health recovery
Sets the damage to -(maxHealth >> (stockpileCounter-1))
Jumps to the address if the stockpile counter is empty.
Resets the counter if sucessful

88 - Negative Damage
Takes the base damage and sets the current damage as its negative value

89 (byte) (address) - Change Stats
where byte & 1 == 1 means target is the user, &0x40 means it can't fail
Changes the given stat of the pokemon by +-7 max.
It chooses the target stat and amount by looking at the status byte (02023FDE)
Ex: byte as 0x21 would be up attack by 2, while 0x92 would be decrease by 1

8a - Normalize all stats
Simply places all stats to 6 (default medium value) for every pokemon out. Used by haze.

8b - Start accumulating damage (Set bide)
Sets the bide flags and starts storing damage dealt to the user in its designed location.

8c - Confuse if repeating attack ended
Used by trash and petal dance. sets the Status byte to confusion if the attack's repeat counter is 0.

8d (byte)- Set loop counter
if byte == 0, sets it to a random value between 2 and 5, else set to given byte.
Used by multi-hit attacks like doubleslap.

neeeds more research. used by beat up to reset some values, but what do they do?

8f (address) - Force random switch
Used by roar, this makes the pokemon out get switched with another. if in a wild battle, makes the battle end.
address is the jump if fail address.

90 (address)- Change Type to attack
Changes the user's types to the type of one of the enemy's attacks.
Both of the user's types are changed to that new value.
jumps to address if failed.
used by conversion

91 - give money
Gives the player the amount of money present in the money variable (02023E7E)
Called from the end script of the battle.
needs more research.

92 - Set light screen
sets the light screen effect on the user's party
Also stores 3 or 4 in the multistring choice.

93 (address)
needs more research.
used by one hit ko attacks, seems to do more than that.

94 - Get Half target HP
Gets the current target HP, halves it and stores it as the damage in the damage address.

95 - Set sandstorm
Sets a sandstorm for 5 turns.

96 - Weather damage
sets the damage caused by a certain weather (checks for hail and sandstorm) at the damage address.
This one is interesting not for being called, but for changing weather damage patterns, and effectiveness against pokemon types.

97 (address)- Try and infatuate
Tries to cause infatuation on the target pokemon, using the user as the infatuator.
How infatuation works is explained in the status 2 word.
If it fails, jumps to given address.

98 (byte, some bank)
needs more research. Seems related to printing the status (pzn,slp, etc)

99 - Set stat change prevention
Sets the stat change prevention byte for 5 turn.
Used by Mist.

9a - Set critical bit
Sets the user's critical chance increased bit
(focus energy)

9b - Transform
Data execution of transformation. Copies attacks and places their PP at
max 5 pp, change types and sets the Transform bit.

9c - Set substitute
Sets the subtitute bit and sets the substitute health to 1/4 of the user's health.
No graphics in this code.
also sets the attack damage to 1/4 hp

9d (address) - Copy attack
Sets the attack slot with the attack last used by the target (mimic).
Not permanent, and there are a list of attacks that cannot be copied at 082507E8.
Cannot be used while transformed.
Jumps to fail address if it cannot copy the attack.

9e - Jump to random attack
Metronome's attack chooser, it never continues forward, always jumping to a new attack.

9f - Level to Damage
Sets the current damage to the level of the user. (ex: Night shade)

a0 - Psywave Damage calculator
Sets attack to (0.5 to 1.5)*Level to 3/2*Level (randomly decided)

a1 (address) - Counter damage calculator
Calculates the damage based on the last attack, if it was physical.
Physical damage is stored on the protect structure + 0x4.
Jumps if fails to hit (no physical attack sufffered)

a2 (address) - Mirror coat damage calculator
Calculates the damage based on the last attack, if it was special
Special damage is stored on the protect structure + 0x6.
Jumps if fails to hit (no special attack sufffered)

a3 (address) - Disable last used attack
Copies the last attack ID to the Disable structure Disabled Attack ID slot (+0x4) and stores 5 turns in the disable timer slot (+0xb).
If 0x10 turns were set, it would be a permanent disable.
jumps to address if it fails. Fails when an attack was already in the disable slot, when the attack is not valid (struggle or "-"), attack no longer exists, or when target attack has 0 PP.

a4 (address) - Set Encore
Places the last used attack on the encore ID (+0x6) in the Disable Structure, and sets the timer (+0xe) to 5.
As with Disable, setting the timer with 0x10 would make the encore'd attack repeat forever.
Jumps when an attack is already in that slot, or the attack cannot be encored (like encore and mirror move).

a5 (address) - Pain split damage calculation
Calculates the Average of both Current HP, then calculates the damage needed to reach it on all involved. The damages are then stored on the attack damage address.
The damage to your pokemon is stored directly on the attack damage, but the target HP is stored at 02023fc4.
Jumps when fails to hit, due to Substitute.

a6 (address) - Set type to random resistance
Sets the user type to a random type that is resistant (less than 5 multiplier) to the last used attack (conversion 2 effect)
Jumps to the address if it fails to find one, or the attack ID or Type is invalid.
(on a sidenote, this code is awful. It does Total Random 999 times until it finds a resistance, and if not found, grabs the first one it can find. A type with no resistances or nullifications would fail after quite a lot of time running.)

a7 - Set always hit flag
Sets flag 0x10 (certain hit on next turn) on the special status flags, and stores the pokemon slot that will be affected at Disable structure + 0x15.
This flag becomes 0x8 in the turn it takes effect, and 0 after that.

a8 (address) - Copy move permanently
It works on everything that stores itself in the last used attack buffer but
Sketch (the user attack) and struggle (and no move itself).
It will only copy if the move does not already exist. The move is stored in the battle ram, and is stored permanently after the battle, in other code.
Jumps if the move passed cannot be copied.

a9 (address) - Select random move from pokemon.
Selects attack from the user's attack slot randomly, and stores the new attack at 0x02023D4E. Used by sleep talk.
Jumps if successful in finding a new move to use.

aa - Set Destiny Bond
Sets the Destiny Bond flag, that if active and someone KO's the flag holder, it also faints

Needs further research. Used by OHKO moves

ac - HP to Power (flail code)
Selects attack based on the division between current HP and Max HP and places it at 02023F50 (a total attack power).
Used by flail and Water Spout.
Multiplies HP by 50 first, then divides by MaxHP. Result is between 0 and 50.
Choices of ratios can be seen at 0x08250810, in the format (ratio*50, power)

ad (address) - Reduce random PP
Reduces the pp of the target's last used attack by 1 to 3 PP points.
Also buffers the needed information to print the result.
Jumps if the attack is invalid or has 0 PP already.

ae - Clear status if not soundrpoof
Clears all main status (slp, brn, ...) from the the target if target is not immune to sound
Seemingly locked to Heal bell attack ID, but has other effect if not that attack.

af (address) - Curse target
Sets the curse status if the target is not already cursed. Also sets damage (3D50) to half the user's HP.
Jumps if fails (target already cursed)

b0 (address) - Set spikes
Sets the spikes as set in the party timers structure. Unlike other items in that structure,
spikes is only a byte-flag, and not a count down timer.
Jumps to address if it fails to set spikes for that party.

b1 - Set foresight
Sets the foresight flag.

b2 (address) - Set Perish song
For every pokemon out, sets the counter for perish song (disableStruct + 0xf) to 3 turns and the affected flag in the special flags (0x20), if they are not immune to sound.
Jumps to address if fails.

b3 - Rollout power calculation
If rollout is not set, sets the timer (disableStruct+0x11) to 5 turns (rollout max timer) and the repeating attack flag (0x1000) in the status 2.
Then, calculates rollout power by formula "power = baseRollout * (5-turn_counter)" and sets it to attack damage.
Warning: jumps to default "but it failed" message if the attack would miss.

b4 (bank) (address) - Jump if confused and Attack maxed
If the bank pokemon is both confused and attack >= c, jumps to given address.

b5 - Fury Cutter calculator
First, increases the counter at disableStruct+0x10.
Then, multiplies the base attack by 2^counterValue (max 2^5 = 32) and stores it in the total damage counter.
If it misses, resets the counter and jumps to the default falure message.

b6 - Happiness Attack calculator
Calculates attack based on happiness (or lack of it).
Any attack that is not "return" will cause attack to be based on lack of happiness.
If return, attack is greater with more happiness.

b7 - Present damage calculator
Damage is created randomly. Values larger than 0xcb (from the random byte) will cause recovery by 1/4 target's max HP.
Lesss than 0x65, base damage is 40, 0x65 to 0xb0 is 80, 0xb1 to 0xcb is 120.
All is stored in the attack damage, in the appropriate format.

b8 - Set safeguard
Sets the status preventing byte in the halver bytes, and a 5 turn timer at party timers+6
Also sets the result (failed or not) in the multichoice byte (0 if already set, 5 if successful(same as no. of turns)).

b9 - Magnitude calculator
Randomly selects a number between 0 and 99, and chooses magnitude number based on it.
It buffers the selected number to a string and places it in one of the string buffers

ba (address)
Needs more research.

bb - Set sunny
Sets sunny weather with 5 turns duration (counter = 5)
Also sets the Multistring chooser to 2 if fails (fail message),and to 5 if succeeds.

bc (address) - Max Attack, halve HP
Sets the damage to half of max HP, and sets Attack stat to 0xc(max) directly
Jumps to address if either currentHP < MaxHP/2 or attack is already maxed.

bd (address) - Copy foe's stats
Copies the target's stats to the user. Address is not used, but consumed.

be - Break free
Used by the break free section of the status applier (rapid spin).
Erases the 0xe000 mask bits from the second status flags, then buffers the attack and prepares the message print.

bf - Set curled
Sets the status 2 flag that tells defence curl was used. This then tells attacks
that used round shape (ice ball, rollout) to double damage.

c0 - Recover health based on sunny
Stores -2/3(if sunny), -1/2(if normal) or -1/4(other weather) maxHP in the attack damage.
Jumps if hp full to fail
Synthesis, morning sun and moonlight all use this command.

c1 - Hidden Power Calculator
Calculates type and damage based on hidden power formula.
Attack type is stored as a byte in [AllocatedAddress]+0x13

c2 - Select next target
Used by attacks that hit all on the field, selects the target of the attack if they are not the user and have the hit flags set

c3 (address) - Set future attack
Essentialy, it sets the future attack data (such as damage and type), but does a lot more than just that. Needs more research.
Jumps if it fails to set (already present)

c4 (address1)(address2) - Beat up attack calculator
Calculates attack based on loop iteration over party.
Jump if target fainted to address1, Jump if it misses or fails to address2.
needs more research.

c5 - Hide Attack prepare
Sets Flying flag if Bounce or Fly, underground if Dig, Underwater for Dive.
Hardwired to the attacks it serves. other attacks do nothing.
c6 - Unhide
Reverse of c5. Clears Fly, underground or underwater flags (depending on case).
Also hardwired to their attacks, and also does nothing if not one of them.

c7 - Set Minimize
Sets flag 0x100 of special flags, that tell if stomp should do double damage.

c8 - Set hail
Sets the weather to hail, and the weather timer to 5.
Multichoice is set to 2 if fails, or 5 if success.

c9 (address)
Sets attack damage to current user's health, if the attack or special
attack of the target can go down.
Jumps if they cannot, and 0x02023E82+6 is not 1.

ca - Set forced Target
Sets the forced target's bank in the party timer, as well as the time for effect
(9 and 8 respectively)

cb - Set charge
Sets charge (special flags | 0x200) and its timer (disable struct + 0x12 = 22).
Effect Lasts only one turn.

cc - Call attack based on Terrain
Calls one if the attacks from 0x0825081C, based on the terrain (02022B50).
It's a call, so your attack script would resume after the jump.

cd (address) - Cure if Burned, paralized or Poisoned
Deletes the status flags if there any of the above present.
Jumps to address otherwise.

ce (address) - Set Torment
Sets the status2 bit 31 flag, that prevents the same attack from being used twice in a row.
Jumps if already set.

cf (address) - Jump if not Damaged
Jumps to given address if no special or physical damage happened that turn.

d0 (address) - Set taunt
Sets the flag that prevents non-damaging moves from being selected for two turns.
Sets timer at disable struct + 0x13 to 0x22
Jumps if already set.

d1 (address)
Sets the byte used in Helping hand. Needs further research.

d2 (address) - Swap Items
Swaps the user's and target's items. Lots of checks happen here to prevent abuse in battle tower scenarios.
Jumps if fails to swap (for many reasons, such as wireless battle, or no items.)

d3 (address) - Copy ability
Copies the ability from the target to the user.
Jumps to address if ability is null OR WonderGuard.

d4 (byte) (address)
needs further research

d5 (address) - Set roots
Sets roots (special flags 0x400), for recovery every turn and prevent switching.
Jumps if already set

d6 - Double attack if damaged
Sets the attack multiplier to 2 if either physical or special damage was received previous turn.

d7 (address) - Set yawn
Jumps if failed, if yawn was set, or any other status was set.

d8 (address) - Set Attack to Health difference
Sets user's attack to the value of targetHP - UserHP
jumps if result is negative or zero.

d9 - Attack Times health Ratio
Multiplies the base attack by User's currHP, and divides it by MaxHP.
Used in attacks that grow weaker with hp decrease.

da (address)- Ability swap
Swaps abilities between target and user, if one is null or wonderguard, Jumps to address (failed)

db (address) - Set Seal on attack
Sets the "seals attacks knonw by the user" flag.
Jumps to address if that flag is already set.
Used by imprision.
the flag is set on the user, and the target must test it when using the attack. if the same as that one, fails.

dc (address) - Set Grudge
Sets the "if fainted, take all PP" flag on the user.
Jumps to address if already set.

dd - Attack Based on Weight calculator
Gets opponent's weight, and uses it to select an entry from the low kick table (08250830), that has entries <maxWeight, power>.
If the weight is less than maxWeight, then attack base is power.

de (address) - Assist attack select
Selects the attack ID to be used by assist.
Jumps if no valid attack is found
Needs more research.

df (address) - Set Magic Coat
Sets the Magic Coat timer in the party timers, as well as the magic coat flag
Jumps if failed.

e0 (address) - Set Steal Stat Change
Sets the "steal foe stat change" flag (Snatch)
Jumps to address if user is going last

e1 (address)
needs further research

e2 (bank) - Clear status + ?
Clears the status of the banked pokemon, but does something else as well.
needs further research.

e3 (bank) (address) - Jump if fainted
Jumps if banked pokemon has 0 HP

e4 - Set Effect based on Terrain
Sets the status effect byte based on the terrain it runs in.
Does not use a real "effect byte table", but rather a table with
branch locations that contain only "ldr R1, 0x02023E82; mov R0, 2"

e5 - Pickup Item Calculation
Calculates the items to get with pickup.

A Form change setter. Needs further research
Another form setter, this one Causes form switch and calls the appropriate script.needs further research

e8 (address) Set Type-based halvers
Reduces fire based attack by half if effect ID is not C9. If C9, Reduces Electric based attacks by half.
Set in Special flags 0x30000, meaning not modifiable for other attack types this way.
Jumps if fails if already set

e9 - Set Attack Type by Weather
If weather is present, changes type based on it (sunny = fire, rainy = water, etc.)
Done by an cmp chain, so repointing needed to change it.

ea (Address) - Recycle
Recovers used item if it exists, and was not knocked off.
Jumps if no item was used, or was knocked off.

eb (Address) - Set type to terrain
Sets the user's type to the one determined by the terrain type table (08250888)
Jumps if the user is already one of those types.

ec (address)
Needs further research

needs further research

ee - Break Reflect/LightScreen
Zeroes the timers of Reflect and LightScreen

Following code is location specific. most won't work without the
specific conditions being met. All Need further research
ef - Pokeball catch
Capture mechanics are all here.

f0, f1(word)

After used , it shows the pokedex if the pokemon was not yet captured

The nickname pokemon screen shows after used.
End Location-Specific code

f4 - Subtract HP
Simply takes AttackDamage from User's HP

f5 - Remove Status
Simply zeroes the status bytes

f6, f7
Both are quitting instructions, but f7 places the number of pokemon out in 2023BE2

With this, I conclude the Script Code description.

March 15th, 2016, 8:23 PM
This is a lot of information for me, I´m working in some project but I have a issue with bugs in the battles, and I think this info can help me, but Im not an expert so I ask you:
I have 2 bugs in battles
No. 1. It rains in all battles
No. 2. When I shift pokemon during th battle, they get some bad status like poison or sleep, randomly

How can I fix that with your info?

March 15th, 2016, 8:34 PM
This is a lot of information for me, I´m working in some project but I have a issue with bugs in the battles, and I think this info can help me, but Im not an expert so I ask you:
I have 2 bugs in battles
No. 1. It rains in all battles
No. 2. When I shift pokemon during th battle, they get some bad status like poison or sleep, randomly

How can I fix that with your info?If you don't know how battle data works, the better way to solve something like this is to look through your backups for the most recent file without the bug, use something like the HxD compare feature to find where the differences are between the broken and non-broken ROM, then look at what those changes did/make sure you did what you intended.