JPAN

pokemon rom researcher

Seen July 2nd, 2016
Posted August 31st, 2015
104 posts
10.5 Years
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
Spoiler:
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
 
Attacks
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
 
IVs
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)
IVs
0x0000001f --> hp
0x000003e0 --> atk
0x00007c00 --> def
0x000f8000 --> spd
0x01f00000 --> s.atk
0x03e00000 --> s.def
Status
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
stored.
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.

Banks
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.
[code]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.
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
Spoiler:

This section will only speak of the form of usage for the various commands.
Most complex commands will not be spoken of in detail
Structure:
<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.

0
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

2
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)

5
6
7
8
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.

e
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 pokemon
if --> 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,
bounce)
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

25
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.

3b
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

3f
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

44
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)
46
needs further research

47
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

4a
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)

4b
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
asleep

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.

8e
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

ab
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.

e6
A Form change setter. Needs further research
e7
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

ed
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)

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

f3
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.
Here are the links for my work


Currently working on:
Battle Script Documentation
Another large project