If you are still using the old URL (datacrystal.romhacking.net), please update your bookmarks! The old URL may stop working soon.
The current URL is datacrystal.tcrf.net.
The current URL is datacrystal.tcrf.net.
Breath of Fire II/ROM map: Difference between revisions
Jump to navigation
Jump to search
Justin3009 (talk | contribs) |
(Added Shaman data and explanation) |
||
(33 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
{{rommap|game=Breath of Fire II}} | |||
The following ROM data was obtained from an old Gamefaqs thread ([http://www.gamefaqs.com/boards/563530-breath-of-fire-ii/62767121 link]) by a user called StarryKnights. | The following ROM data was obtained from an old Gamefaqs thread ([http://www.gamefaqs.com/boards/563530-breath-of-fire-ii/62767121 link]) by a user called StarryKnights. | ||
Line 22: | Line 24: | ||
08 - Bleu | 08 - Bleu | ||
09 - Kid Ryu | 09 - Kid Ryu | ||
0A - Kid | 0A - Kid Bow (Zombie in battle) | ||
08: Initial level | |||
09-10: Unused (Current health) | |||
11-12: Initial Max HP | 11-12: Initial Max HP | ||
13-14: Unused (Current AP) | 13-14: Unused (Current AP) | ||
Line 51: | Line 53: | ||
50-64: Unused | 50-64: Unused | ||
Starting PC Stats tables | |||
---- | |||
x00:087C - Ryu Starting Stats (UNUSED! Kid Ryu is what the states are based off of.) | |||
x00:08BC - Bow Starting Stats (UNUSED! Kid Bow is what the states are based off of.) | |||
x00:08FC - Rand Starting Stats | |||
x00:093C - Katt Starting Stats | |||
x00:097C - Nina Starting Stats | |||
x00:09BC - Jean Starting Stats | |||
x00:09FC - Sten Starting Stats | |||
x00:0A3C - Spar Starting Stats | |||
x00:0A7C - Deis Starting Stats | |||
x00:0ABC - Kid Ryu Starting Stats (Carries over to Adult Ryu) | |||
x00:0AFC - Kid Bow Starting Stats (Carries over to Adult Bow) | |||
x00:0B3C - Bow Starting Stats (Character Intro) [UNUSED IN ENGLISH] | |||
x00:0B7C - Rand Starting Stats (Character Intro) [UNUSED IN ENGLISH] | |||
x00:0BBC - Katt Starting Stats (Character Intro) [UNUSED IN ENGLISH] | |||
x00:0BFC - Nina Starting Stats (Character Intro) [UNUSED IN ENGLISH] | |||
x00:0C3C - Jean Starting Stats (Character Intro) [UNUSED IN ENGLISH] | |||
x00:0C7C - Sten Starting Stats (Character Intro) [UNUSED IN ENGLISH] | |||
x00:0CBC - Spar Starting Stats (Character Intro) [UNUSED IN ENGLISH] | |||
x00:0CFC - Ryu Starting Stats (Character Intro) [UNUSED IN ENGLISH] | |||
Starting Spells (All values here start with "A9 xx". Edit the "xx" portion only!) | |||
---- | |||
Rand: | |||
x00:04F7 ;Cure1 | |||
x00:04FD ;CurePSN | |||
x00:0503 ;Set spell learn flag | |||
Nina: | |||
x00:0509 ;Tornado | |||
x00:050F ;Thunder | |||
x00:0515 ;Cold | |||
x00:051B ;Spark | |||
x00:0521 ;Set spell learn flag | |||
Jean: | |||
x00:0527 ;Ag-Up | |||
x00:052D ;Set spell learn flag | |||
Sten: | |||
x00:0533 ;Spark | |||
x00:0539 ;Set spell learn flag | |||
Spar: | |||
x00:053F ;Cold | |||
x00:0545 ;Cure1 | |||
x00:054B ;Ag-Down | |||
x00:0551 ;Pwr. Down | |||
x00:0557 ;Def. Down | |||
x00:055D ;Hush | |||
x00:0563 ;Ag-Up | |||
x00:0569 ;Set spell learn flag | |||
Deis: | |||
x00:056F ;Sonic Boom | |||
x00:0575 ;Bomb | |||
x00:057B ;Flame | |||
x00:0581 ;Freeze | |||
x00:0587 ;Death | |||
x00:058D ;Ag-Down | |||
x00:0593 ;Pwr. Down | |||
x00:0599 ;Def. Down | |||
x00:059F ;Ag-Up | |||
x00:05A5 ;Def-Up | |||
x00:05AB ;Atk-Up | |||
x00:05B1 ;Sap | |||
x00:05B7 ;Drain | |||
x00:05BD ;Exit | |||
x00:05C3 ;Warp | |||
x00:05C9 ;Set spell learn flag | |||
x00:05CB | |||
</pre> | </pre> | ||
< | |||
==Othello== | |||
<pre> | |||
For Othello, the game when you have the carpenter with the log houses on stilts, the items available are hard coded with instructions. | |||
The first 4 items are available from the husband, the second four are available from the wife. | |||
You can change which items you win by altering the following values: | |||
Weapon 1: Item is 0x009220, Quantity is 0x0x00921D, original is TigerSD, 0xA6 | |||
Weapon 2: Item is 0x009255, Quantity is 0x0x009252, original is LopOffWP, 0xAE | |||
Weapon 3: Item is 0x009278, Quantity is 0x0x009275, original is IceBW, 0x82 | |||
Armor 1: Item is 0x00929B, Quantity is 0x0x009598, original is ShinyHT, 0xF1 | |||
Weapon 4: Item is 0x0095E1, Quantity is 0x0x0095DE, original is KingOfDR, 0x7C | |||
Weapon 5: Item is 0x009616, Quantity is 0x0x009613, original is ThundrST, 0x89 | |||
Armor 2: Item is 0x009639, Quantity is 0x0x009636, original is RainbwRB, 0xDA | |||
Armor 3: Item is 0x00965C, Quantity is 0x0x009659, original is GiantSH, 0xEB | |||
Do not alter other code in this section or you may lock the game. | |||
For weapons, the Quantity must be set to 0x11 | |||
For armors, the Quantity must be set to 0x21 | |||
If changing to Etc, set the Quantity to 0x01 | |||
Changing these values will not alter the choice when deciding which item to take when available. | |||
i.e. If you change the TigerSD to DragonAR, it will still show Weapon 1 and will show as a sword on the table. | |||
</pre> | |||
==Stat gain tables== | ==Stat gain tables== | ||
Line 62: | Line 161: | ||
Stat Gain Tables: | Stat Gain Tables: | ||
---- | ---- | ||
These cover levels 2-99 for every single character. | |||
Hex offset (HiROM Address) | Hex offset (HiROM Address) | ||
x0571B0 - x055DF0 ($C5:71B0 - $C5:5DF0) | |||
4 bytes, split into 8 half-bytes in this order with a max increase of '15 (F)' per stat: | 4 bytes, split into 8 half-bytes in this order with a max increase of '15 (F)' per stat: | ||
Line 74: | Line 175: | ||
Almost every character seems to have extra level gains for levels they don't join at. These are not used at all due to the initial data. | Almost every character seems to have extra level gains for levels they don't join at. These are not used at all due to the initial data. | ||
Also, it seems Bleu's stats uses the Monster Table as her level up data so she doesn't have her 'own' to modify without some serious stat table moving. | Also, it seems Bleu's stats uses the Monster Table as her level up data so she doesn't have her 'own' to modify without some serious stat table moving. | ||
x0571B0 - x057338: Ryu Stat Gain | |||
x057338 - x0574C0: Bow Stat Gain | |||
x0574C0 - x057648: Rand Stat Gain | |||
x057648 - x0577D0: Katt Stat Gain | |||
x0577D0 - x057958: Nina Stat Gain | |||
x057958 - x057AE0: Jean Stat Gain | |||
x057AE0 - x057C68: Sten Stat Gain | |||
x057C68 - x057DF0: Spar Stat Gain | |||
x057DF0 - x057F78: Bleu Stat Gain [THIS IS THE MONSTER ENTRY TABLE! DO NOT MODIFY THIS! This is how the original game does it as Bleu was haphazardly put in!] | |||
Guts gain upon level is consistently the same for every level up. Each PC's gain starts at: | Guts gain upon level is consistently the same for every level up. Each PC's gain starts at: | ||
x018FE5 ($818FE5) | |||
</pre> | |||
==Spell gains table== | |||
<pre> | |||
Pointers: 5AA00-5AA011 | |||
5AA12-5AADE | |||
Pairs of bytes. First is for level the spell is gained on, the second is the spell gained. 00 terminates. | |||
</pre> | </pre> | ||
==Enemy information== | ==Enemy information== | ||
<pre> | <pre> | ||
Enemy | Enemy Stats: | ||
---- | |||
x05:9000 - 05:A8FF (C5:9000 - C5:A8FF) | |||
Byte Listing | |||
---- | |||
01-08: Enemy Name | |||
09-10: Max HP | |||
11-12: Max AP | |||
13: Luck | |||
14-15: Attack | |||
16-17: Defense | |||
18-19: Agility | |||
20: ???, copied to monster RAM + 0x68 | |||
21-22: Experience | |||
23-24: Zenny | |||
25: Item set | |||
26: ???, Copied to monster RAM 0x5D | |||
27: Drop Rate. It is also used as another monster stat @ monster RAM + 0x50 | |||
28: ???, copied to monster RAM 0x52 | |||
29: ???, copied to monster RAM 0x51 | |||
30: ???, copied to monster RAM 0x54 | |||
31-32: ??? | |||
Enemy Battle Backgrounds: | |||
---- | |||
x055561 - 0x05----: Battle backgrounds for enemy groups? [Must use values 00 or BB+] [This has not fully been deciphered.] | |||
</pre> | |||
For detailed information on how drop rates and item sets work, check out Ben Siron's handbook that explains many of the game's mechanics: [http://www.gamefaqs.com/snes/563530-breath-of-fire-ii/faqs/5436 link] | |||
==Spell Info Table== | |||
<pre> | |||
584F0-58A20 | |||
Each spell is 16 bytes long | |||
Bytes 1-8: Spell Name. | |||
Bytes 9 and 10: Spell cost. | |||
Bytes 11 and 12: These are tricky, the first 15 bits are used for a description pointer, and the | |||
most significant bit appears to be used on spells with beneficial effects(Cure, Antdt, Renew, Etc). | |||
Byte 13: Spell element. These elements are set by bits and are, in order: Ability down, fire, lightning, | |||
ice/water, wind, unknown/unused, earth, physical/non-elemental. | |||
Byte 14: Targeting and special switches. | |||
Bit 1: Unknown. used only on the spell 8.0. | |||
Bit 2: By default, will cast on opposing party. | |||
Bit 3: Unknown. Used on Dispell, Recover, IdiotLzr, Hunt, and Whodini. | |||
Bit 4: Usable outside of battle. | |||
Bit 5: Usable during battle. | |||
Bit 6: Auto-confirm spell. This is more used more for spells that target an entire party. | |||
Bit 7: Auto target opposing party. | |||
Bit 8: Sets the spell to show green numbers. This will not make a spell heal, but will cause 0 damage, | |||
and shows green numbers. | |||
Byte 15: Other switches. Most of this byte has unknown usages, but these are known effects. | |||
Bits 1-4: These bits have an unknown effect. | |||
Bit 5: used as a trigger effect, used specifically on G.Drgn when it's first learned and Anfini during Deathevn. | |||
Bit 6: unknown, but is used in various spells | |||
Bit 7: set to consume all of the users AP and is only used in Ryu's dragon spells. This also changes the | |||
animation Ryu uses when casting, and will crash if it is changed. This does not change how much AP is actually | |||
used when casting the spell. | |||
Bit 8: set when the spell requires a check against the characters mood. | |||
Byte 16: When a spell requires a mood check, this is the value a characters mood must be before using. | |||
</pre> | |||
==Item Info Table== | |||
<pre> | |||
0x070000-0x70FFF | |||
Byte Listing | |||
---- | |||
01-08: Item name | |||
09-10: Item cost | |||
11-12: Item description pointer, and similar to spell's description, the most significant bit is set for beneficial effects, when an item can be used as such. | |||
13: Targeting and special switches. these switches appear to be exactly the same as said byte in the spells | |||
14: Who can equip this item, if possible. each bit represents different characters with Nina and Bleu sharing bits. | |||
15: Attack power for weapons, and defense power for armor. | |||
16: This has a number of uses depending on what item it is being used for. | |||
For unequippable items and weapons, it appears to identify what spells are cast when an item is used. | |||
For armors, the least significant 6 bits are used for armor weight, which allows for a max weight of 63. | |||
For values 0x00 to 0x3F, items get equipped into the armor slot with a weight assigned by the bit. | |||
For values 0x40 to 0x7F, items get equipped into the shield slot. | |||
For values 0x80 to 0xBF, items get equipped into the helmet slot. | |||
For values 0xC0 to 0xFF, items becomes unequippable. | |||
</pre> | |||
==Experience Tables== | |||
<pre> | |||
56680-571AF | |||
Each level is 3 bytes each and starts at level 2. | |||
All characters have individual experience tables except for Bleu, who shares Nina's table. | |||
Each character table is 294 bytes long (98 levels * 3 bytes each). | |||
The experience tables for individual characters are in the same order as the are in the | |||
ROM character information, so Ryu first, then Bow, Rand, Katt, Nina/Bleu, Jean, Sten, and Spar. | |||
</pre> | |||
==Cooking data== | |||
<pre> | |||
3F95E-3FA5F | |||
This is at least two table used when cooking for item values and to determine which recipe you will cook. | |||
The first portion from 0x3F95E to 0x3F997 are used to determine what the recipe will yield | |||
The second portion from 3F998 to 3FA0B are recipe look ups, and also used to determine how much an item adds to these values. | |||
When you select an item, it's value is lookup in this table, which has not been fully studied yet. | |||
When you have a recipe and select to cook, the table is looked through backwards from high to low. | |||
Each recipe contains 4 values and is checked for the current recipe values. | |||
When a recipe is found, a second check is done from the front of this section forward. | |||
When an item in this lookup is found, that slot is recorded, which is the item you will result in, with a chance of Charcoal. | |||
Technical Explanation: | |||
Cooking data is read from C3:F998 + X, X starts at 0x70 - 1, which is 0x6F (This is how it's actually dont in code) | |||
This will point to C3:FA07 | |||
Each data is 4 bytes long | |||
These values are compared to 7E:1CCD through 7E:1CD0, FA07 to 1CD0, FA06 to 1CDF, etc. | |||
If the ROM values are higher than the RAM, the next set is selected and checked, so in this case, failure will go to C3:FA03 no metter which byte. | |||
If ONLY ONE of the bytes is 0 value, the check is failed to the next set. | |||
If BOTH bytes are 0, the check passes and the next byte in this set is checked. | |||
If all 4 bytes pass the check, then this is the recipe that will be selected. | |||
This byte is LSR twice, effectively dividing by 4. | |||
This byte is then used against the table at C3:F95E + X, X starts at 1, which points to C3:F95F | |||
This table at C3:59FE is 0x39 long ending at C3:F997, though there is no actual check against this. | |||
After this point is the actual recipe data | |||
Each value is read incrementally until the value from the last result is matched, this index is recorded and will be the resulting item. | |||
As an example, when we cook 2 Frizbee, we get values 0x20, 0x0, 0x20, 0x10 for our RAM at 7E:1CCD through 7E:1CD0 respectively. | |||
This is checked against the table from C3:FA07 down. | |||
C3:FA07 is 0x40, which is higher than 7E:1CD0, so the check is failed. | |||
At C3:F9D7 the third bytes value in RAM, 7E:1CCE, is GREATER THEN THE ROM value, 0, but as both bytes need to be 0, this check is failed | |||
The check passes at C3:F9DB, which the values in the ROM are less than or equal to the RAM values, and the 0 bytes match up in RAM and ROM, 7E:1CCF vs C3:F9DA | |||
The resulting value is 0x40, which is ASL twice to 0x10. | |||
We then pass through the table from C3:F95F until we read the value 0x10, which happens to be the 16th value (0x10) | |||
This will be the resulting item index from the item list from C7:0000, which is a Dinker | |||
Finding out what items recipe values are is somewhat easier and uses the same tables. | |||
When selecting an item, you go to the X index from C3:F96E, read this value and LSR twice to multiply the value by 4. | |||
This index is added to C3:F998, which points to the base of the recipe values. | |||
These values are then added to RAM sequentially to give the new recipe value. | |||
As an example, when adding a F.Spice, we take the item slot of the item, 0x16 and read from C3:F9DE + 0x14, which would be C3:F972 | |||
This gives us the value of 0x0B, which we LSR twice into 0x2C | |||
Now add this value to C3:F998 which results in C3:F9C4, and add the 4 byte set to RAM, which would give us 0x00, 0x08, 0x10, 0x10, for 7E:1CCD through 7E:1CD0, respectively | |||
</pre> | |||
==Shop data== | |||
<pre> | |||
3FA60-3FBBF | |||
Shops use item slot numbers for what items to sell and is terminated by a value of 00. | |||
The ROM uses 3FA60 when referencing the shop data, but the data appears to start around 3FAC9 | |||
and appears to mostly be in numerical order, by item slot number. | |||
</pre> | |||
==Game Script== | |||
<pre> | |||
The game script starts at 290000 and continues to 2CADA4, but this data uses simple compression. | |||
with it's data starting at 22D000 through 22D531, and the actual pointer data starting at 22DE00. | |||
22DDF2 through 22DDF7 contain values of when to switch banks, 2 bytes each. | |||
The data itself is mostly ASCII coding, with some special formatting. | |||
</pre> | |||
==Music Data== | |||
<pre> | |||
Some data may be missing but these offsets are noted for setting music. (BacuraFF) | |||
x00AF80 - x00B0B3 - Indoor Map Music | |||
x00C0F0 - x00C13D - Event/Boss Battle Music | |||
Each seem to be one byte each. | |||
Some events forcefully change music and that is not included. | |||
</pre> | |||
==Monster Formation Data== | |||
<pre> | |||
Defines what enemies are in and how they are displayed on screen. Some of this data also interferes with the level up data. | |||
Formation Data: | |||
---- | |||
x05:7DF0 - 0x5:84EF | |||
Bytes (7 each) | |||
---- | |||
01: Enemy formation - Doesn't appear to do anything except move enemies around the screen | |||
02 - 07: Enemy pointer | |||
</pre> | |||
==Overworld mob formation pointers== | |||
<pre> | |||
Defines which enemies can be run into from your location on the overworld | |||
Map Data: | |||
---- | |||
x05:5460 - x5:5550 | |||
Note: Max value on overworld is naturally 0x3F | |||
</pre> | |||
==Map Portal Data== | |||
<pre> | |||
Defines where a portal is, and where it takes you, and some special switches | |||
Portal Data: | |||
---- | |||
x05:1800 - x05:48F4? (Might be shorter) | |||
Bytes (variable bytes) | |||
---- | |||
01: Which map these portals belong to | |||
02: How many portals are in this map | |||
Each portal is 7 bytes as | |||
01: Source X map position | |||
02: Source Y map position | |||
03: Destination X map position | |||
04: Destination Y map position | |||
05: Destination map pointer | |||
06: Special switches/values used for loading | |||
07: More switches/values | |||
</pre> | |||
==Shamans== | |||
<pre> | |||
x05:8A30 - x05:8A60 - Used as an index to pull from the Shaman pair table | |||
x05:8A61 - x05:8B08 - This is used to index where to pull the shaman bonuses | |||
x05:8B09 - ? - This is a table grouped into 8 values used to grant stat bonuses based on Shaman forms. | |||
x01:837A - x01:838F - Used to write to the "List" in the uniting menu when forms are successful. | |||
How it works: | |||
The function begins at x03:E2C8. | |||
It first checks if Bleu was selected for uniting, and fails if she was. | |||
Next it resets any shaman bonuses with the corresponding character in RAM i.e. if it was Bow, it would set all of 7E:5550 to 00. | |||
It then recalculates all equipment for the character, Off from weapons, Def from armor, etc. including bonuses. | |||
Then, it checks if either the holy (Seny) or devil (Shin) shamans were used. | |||
If Seny was used, the characters status is OR'd with 0x04. | |||
If Shin was used, the characters status is OR'd with 0x02. | |||
Although these bytes are changed, it doesn't appear to have any effect and is reset shortly thereafter by other functions. | |||
Now the meat: | |||
Each shaman has a corresponding byte associated, Sana is 00, Seso is 01, Spoo is 02, Solo is 03, Seny is 04, and Shin is 05. | |||
This is the same as the order they show in the menu when all are present. | |||
When only one is picked, it is used as the index, when both are picked, the values are bit OR against each other. | |||
By default, the first shaman picked is always 0x00, and the second Shaman is 0xFF. It is checked for negative value when calculating. | |||
This value is added to address x05:8A30 - 1 to get the pair index address. | |||
Then, take the character value (x7E:1CAC) and multiply by 0x15, add the pair index address, and add to x05:8A61. | |||
If a 0 is pulled from this index, the pairing fails. Even if hacked to cheat this system, no bonuses are given for a 0 index. | |||
This value is then multiplied by x08 and added to x05:8B09, this is what we will use to find the stat bonus you get from a combination. | |||
You go through the next 8 values and multiply by your raw stat corresponding to this number in order of Str, Stmna, Agil, Wis, Luck, AP. | |||
So the first value is multiplies against strength, the high byte is then used and added to your raw strength for offense, the second is against stamina, etc. | |||
These bonuses are written to x7E:5540 + (Character value * x10), the character value can be found at the base of the character + x06. | |||
For this, Bow is x01, Rand is x02, etc. These are always in the same order, regardless of character order in RAM. | |||
Luck is not written, this appears to be a glitch, as the game does not use an index to confirm all stats are written and appears to exit early. | |||
</pre> | </pre> | ||
==RNG== | |||
== | |||
<pre> | <pre> | ||
The random number generator (RNG) is used in the game anywhere variance is required | |||
Here it is, disassembled in it's glory, and how it works: | |||
;Random Number Generator. Entry point is JSL | |||
$C0/648B 08 PHP | |||
$C0/648C C2 20 REP #$20 | |||
$C0/648E AD D6 00 LDA $00D6 [$81:00D6] | |||
$C0/6491 0A ASL A | |||
$C0/6492 0A ASL A | |||
$C0/6493 18 CLC | |||
$C0/6494 6D D6 00 ADC $00D6 [$81:00D6] | |||
$C0/6497 EB XBA | |||
$C0/6498 E2 20 SEP #$20 | |||
$C0/649A 8D D7 00 STA $00D7 [$81:00D7] | |||
$C0/649D 18 CLC | |||
$C0/649E 6D D6 00 ADC $00D6 [$81:00D6] | |||
$C0/64A1 8D D6 00 STA $00D6 [$81:00D6] | |||
$C0/64A4 28 PLP | |||
$C0/64A5 6B RTL | |||
What it does (just the math): | |||
Load 7E00D6 | |||
Multiply by 5 | |||
Switch high and low bits | |||
Set 8-bit register | |||
Store into 7E00D7(High Byte of D6) | |||
Add original D6 (Low byte only) | |||
The function then reads/mutates A for the result | |||
</pre> | </pre> | ||
{{Internal Data|game=Breath of Fire II}} |
Latest revision as of 03:18, 21 November 2024
The following article is a ROM map for Breath of Fire II.
The following ROM data was obtained from an old Gamefaqs thread (link) by a user called StarryKnights.
Characters starting information
Initial data for the game's characters. Information block starts at x00:087C ($C0:087C) and ends at x00:0D3B ($C0:0D3B) (Assuming no header). Each entry is 64 bytes long. This data follows the RAM PC data setup from the RAM map, though, much of this start up data goes unused. Layout: 01-04: Character Name 05: Unused (In-game compared to RAM, setting this value to 20 would make the PC sprite into Valerie) 06: Unused (PC Status) 07: Character's PC Number 00 - Ryu 01 - Bow 02 - Rand 03 - Katt 04 - Nina 05 - Jean 06 - Sten 07 - Spar 08 - Bleu 09 - Kid Ryu 0A - Kid Bow (Zombie in battle) 08: Initial level 09-10: Unused (Current health) 11-12: Initial Max HP 13-14: Unused (Current AP) 15-16: Initial Max AP 17: Shaman Form 18: Initial Strength 19: Initial Stamina 20-21: Initial Agility 22: Initial Condition 23-24: Initial Weapon (Value 11 tells the game that you have a weapon equipped) 25-26: Initial Shield (Value 21 tells the game that you have a piece of armor equipped) 27-28: Initial Armor (Value 21 tells the game that you have a piece of armor equipped) 29-30: Initial Helmet(Value 21 tells the game that you have a piece of armor equipped) 31-32: Initial Accessory 1 (Although set to 00 00 on most characters, this is bugged as you're not supposed to be able to unequip 'nothing') 33-34: Initial Accessory 2 (Although set to 00 00 on most characters, this is bugged as you're not supposed to be able to unequip 'nothing') 35-36: Unused (Current Attack) 37-38: Unused (Current Defense) 39-40: Unused (Current Vigor) 41: Unused (Current Wisdom) 42-43: Unused (Current Luck) 44: Initial Guts 45: Initial Wisdom Base 46: Initial Luck Base 47-49: Initial EXP 50-64: Unused Starting PC Stats tables ---- x00:087C - Ryu Starting Stats (UNUSED! Kid Ryu is what the states are based off of.) x00:08BC - Bow Starting Stats (UNUSED! Kid Bow is what the states are based off of.) x00:08FC - Rand Starting Stats x00:093C - Katt Starting Stats x00:097C - Nina Starting Stats x00:09BC - Jean Starting Stats x00:09FC - Sten Starting Stats x00:0A3C - Spar Starting Stats x00:0A7C - Deis Starting Stats x00:0ABC - Kid Ryu Starting Stats (Carries over to Adult Ryu) x00:0AFC - Kid Bow Starting Stats (Carries over to Adult Bow) x00:0B3C - Bow Starting Stats (Character Intro) [UNUSED IN ENGLISH] x00:0B7C - Rand Starting Stats (Character Intro) [UNUSED IN ENGLISH] x00:0BBC - Katt Starting Stats (Character Intro) [UNUSED IN ENGLISH] x00:0BFC - Nina Starting Stats (Character Intro) [UNUSED IN ENGLISH] x00:0C3C - Jean Starting Stats (Character Intro) [UNUSED IN ENGLISH] x00:0C7C - Sten Starting Stats (Character Intro) [UNUSED IN ENGLISH] x00:0CBC - Spar Starting Stats (Character Intro) [UNUSED IN ENGLISH] x00:0CFC - Ryu Starting Stats (Character Intro) [UNUSED IN ENGLISH] Starting Spells (All values here start with "A9 xx". Edit the "xx" portion only!) ---- Rand: x00:04F7 ;Cure1 x00:04FD ;CurePSN x00:0503 ;Set spell learn flag Nina: x00:0509 ;Tornado x00:050F ;Thunder x00:0515 ;Cold x00:051B ;Spark x00:0521 ;Set spell learn flag Jean: x00:0527 ;Ag-Up x00:052D ;Set spell learn flag Sten: x00:0533 ;Spark x00:0539 ;Set spell learn flag Spar: x00:053F ;Cold x00:0545 ;Cure1 x00:054B ;Ag-Down x00:0551 ;Pwr. Down x00:0557 ;Def. Down x00:055D ;Hush x00:0563 ;Ag-Up x00:0569 ;Set spell learn flag Deis: x00:056F ;Sonic Boom x00:0575 ;Bomb x00:057B ;Flame x00:0581 ;Freeze x00:0587 ;Death x00:058D ;Ag-Down x00:0593 ;Pwr. Down x00:0599 ;Def. Down x00:059F ;Ag-Up x00:05A5 ;Def-Up x00:05AB ;Atk-Up x00:05B1 ;Sap x00:05B7 ;Drain x00:05BD ;Exit x00:05C3 ;Warp x00:05C9 ;Set spell learn flag x00:05CB
Othello
For Othello, the game when you have the carpenter with the log houses on stilts, the items available are hard coded with instructions. The first 4 items are available from the husband, the second four are available from the wife. You can change which items you win by altering the following values: Weapon 1: Item is 0x009220, Quantity is 0x0x00921D, original is TigerSD, 0xA6 Weapon 2: Item is 0x009255, Quantity is 0x0x009252, original is LopOffWP, 0xAE Weapon 3: Item is 0x009278, Quantity is 0x0x009275, original is IceBW, 0x82 Armor 1: Item is 0x00929B, Quantity is 0x0x009598, original is ShinyHT, 0xF1 Weapon 4: Item is 0x0095E1, Quantity is 0x0x0095DE, original is KingOfDR, 0x7C Weapon 5: Item is 0x009616, Quantity is 0x0x009613, original is ThundrST, 0x89 Armor 2: Item is 0x009639, Quantity is 0x0x009636, original is RainbwRB, 0xDA Armor 3: Item is 0x00965C, Quantity is 0x0x009659, original is GiantSH, 0xEB Do not alter other code in this section or you may lock the game. For weapons, the Quantity must be set to 0x11 For armors, the Quantity must be set to 0x21 If changing to Etc, set the Quantity to 0x01 Changing these values will not alter the choice when deciding which item to take when available. i.e. If you change the TigerSD to DragonAR, it will still show Weapon 1 and will show as a sword on the table.
Stat gain tables
Stat Gain Tables: ---- These cover levels 2-99 for every single character. Hex offset (HiROM Address) x0571B0 - x055DF0 ($C5:71B0 - $C5:5DF0) 4 bytes, split into 8 half-bytes in this order with a max increase of '15 (F)' per stat: Byte 1: HP, AP Byte 2: Strength, Stamina Byte 3: Unused, Agility Byte 4: Wisdom, Luck Almost every character seems to have extra level gains for levels they don't join at. These are not used at all due to the initial data. Also, it seems Bleu's stats uses the Monster Table as her level up data so she doesn't have her 'own' to modify without some serious stat table moving. x0571B0 - x057338: Ryu Stat Gain x057338 - x0574C0: Bow Stat Gain x0574C0 - x057648: Rand Stat Gain x057648 - x0577D0: Katt Stat Gain x0577D0 - x057958: Nina Stat Gain x057958 - x057AE0: Jean Stat Gain x057AE0 - x057C68: Sten Stat Gain x057C68 - x057DF0: Spar Stat Gain x057DF0 - x057F78: Bleu Stat Gain [THIS IS THE MONSTER ENTRY TABLE! DO NOT MODIFY THIS! This is how the original game does it as Bleu was haphazardly put in!] Guts gain upon level is consistently the same for every level up. Each PC's gain starts at: x018FE5 ($818FE5)
Spell gains table
Pointers: 5AA00-5AA011 5AA12-5AADE Pairs of bytes. First is for level the spell is gained on, the second is the spell gained. 00 terminates.
Enemy information
Enemy Stats: ---- x05:9000 - 05:A8FF (C5:9000 - C5:A8FF) Byte Listing ---- 01-08: Enemy Name 09-10: Max HP 11-12: Max AP 13: Luck 14-15: Attack 16-17: Defense 18-19: Agility 20: ???, copied to monster RAM + 0x68 21-22: Experience 23-24: Zenny 25: Item set 26: ???, Copied to monster RAM 0x5D 27: Drop Rate. It is also used as another monster stat @ monster RAM + 0x50 28: ???, copied to monster RAM 0x52 29: ???, copied to monster RAM 0x51 30: ???, copied to monster RAM 0x54 31-32: ??? Enemy Battle Backgrounds: ---- x055561 - 0x05----: Battle backgrounds for enemy groups? [Must use values 00 or BB+] [This has not fully been deciphered.]
For detailed information on how drop rates and item sets work, check out Ben Siron's handbook that explains many of the game's mechanics: link
Spell Info Table
584F0-58A20 Each spell is 16 bytes long Bytes 1-8: Spell Name. Bytes 9 and 10: Spell cost. Bytes 11 and 12: These are tricky, the first 15 bits are used for a description pointer, and the most significant bit appears to be used on spells with beneficial effects(Cure, Antdt, Renew, Etc). Byte 13: Spell element. These elements are set by bits and are, in order: Ability down, fire, lightning, ice/water, wind, unknown/unused, earth, physical/non-elemental. Byte 14: Targeting and special switches. Bit 1: Unknown. used only on the spell 8.0. Bit 2: By default, will cast on opposing party. Bit 3: Unknown. Used on Dispell, Recover, IdiotLzr, Hunt, and Whodini. Bit 4: Usable outside of battle. Bit 5: Usable during battle. Bit 6: Auto-confirm spell. This is more used more for spells that target an entire party. Bit 7: Auto target opposing party. Bit 8: Sets the spell to show green numbers. This will not make a spell heal, but will cause 0 damage, and shows green numbers. Byte 15: Other switches. Most of this byte has unknown usages, but these are known effects. Bits 1-4: These bits have an unknown effect. Bit 5: used as a trigger effect, used specifically on G.Drgn when it's first learned and Anfini during Deathevn. Bit 6: unknown, but is used in various spells Bit 7: set to consume all of the users AP and is only used in Ryu's dragon spells. This also changes the animation Ryu uses when casting, and will crash if it is changed. This does not change how much AP is actually used when casting the spell. Bit 8: set when the spell requires a check against the characters mood. Byte 16: When a spell requires a mood check, this is the value a characters mood must be before using.
Item Info Table
0x070000-0x70FFF Byte Listing ---- 01-08: Item name 09-10: Item cost 11-12: Item description pointer, and similar to spell's description, the most significant bit is set for beneficial effects, when an item can be used as such. 13: Targeting and special switches. these switches appear to be exactly the same as said byte in the spells 14: Who can equip this item, if possible. each bit represents different characters with Nina and Bleu sharing bits. 15: Attack power for weapons, and defense power for armor. 16: This has a number of uses depending on what item it is being used for. For unequippable items and weapons, it appears to identify what spells are cast when an item is used. For armors, the least significant 6 bits are used for armor weight, which allows for a max weight of 63. For values 0x00 to 0x3F, items get equipped into the armor slot with a weight assigned by the bit. For values 0x40 to 0x7F, items get equipped into the shield slot. For values 0x80 to 0xBF, items get equipped into the helmet slot. For values 0xC0 to 0xFF, items becomes unequippable.
Experience Tables
56680-571AF Each level is 3 bytes each and starts at level 2. All characters have individual experience tables except for Bleu, who shares Nina's table. Each character table is 294 bytes long (98 levels * 3 bytes each). The experience tables for individual characters are in the same order as the are in the ROM character information, so Ryu first, then Bow, Rand, Katt, Nina/Bleu, Jean, Sten, and Spar.
Cooking data
3F95E-3FA5F This is at least two table used when cooking for item values and to determine which recipe you will cook. The first portion from 0x3F95E to 0x3F997 are used to determine what the recipe will yield The second portion from 3F998 to 3FA0B are recipe look ups, and also used to determine how much an item adds to these values. When you select an item, it's value is lookup in this table, which has not been fully studied yet. When you have a recipe and select to cook, the table is looked through backwards from high to low. Each recipe contains 4 values and is checked for the current recipe values. When a recipe is found, a second check is done from the front of this section forward. When an item in this lookup is found, that slot is recorded, which is the item you will result in, with a chance of Charcoal. Technical Explanation: Cooking data is read from C3:F998 + X, X starts at 0x70 - 1, which is 0x6F (This is how it's actually dont in code) This will point to C3:FA07 Each data is 4 bytes long These values are compared to 7E:1CCD through 7E:1CD0, FA07 to 1CD0, FA06 to 1CDF, etc. If the ROM values are higher than the RAM, the next set is selected and checked, so in this case, failure will go to C3:FA03 no metter which byte. If ONLY ONE of the bytes is 0 value, the check is failed to the next set. If BOTH bytes are 0, the check passes and the next byte in this set is checked. If all 4 bytes pass the check, then this is the recipe that will be selected. This byte is LSR twice, effectively dividing by 4. This byte is then used against the table at C3:F95E + X, X starts at 1, which points to C3:F95F This table at C3:59FE is 0x39 long ending at C3:F997, though there is no actual check against this. After this point is the actual recipe data Each value is read incrementally until the value from the last result is matched, this index is recorded and will be the resulting item. As an example, when we cook 2 Frizbee, we get values 0x20, 0x0, 0x20, 0x10 for our RAM at 7E:1CCD through 7E:1CD0 respectively. This is checked against the table from C3:FA07 down. C3:FA07 is 0x40, which is higher than 7E:1CD0, so the check is failed. At C3:F9D7 the third bytes value in RAM, 7E:1CCE, is GREATER THEN THE ROM value, 0, but as both bytes need to be 0, this check is failed The check passes at C3:F9DB, which the values in the ROM are less than or equal to the RAM values, and the 0 bytes match up in RAM and ROM, 7E:1CCF vs C3:F9DA The resulting value is 0x40, which is ASL twice to 0x10. We then pass through the table from C3:F95F until we read the value 0x10, which happens to be the 16th value (0x10) This will be the resulting item index from the item list from C7:0000, which is a Dinker Finding out what items recipe values are is somewhat easier and uses the same tables. When selecting an item, you go to the X index from C3:F96E, read this value and LSR twice to multiply the value by 4. This index is added to C3:F998, which points to the base of the recipe values. These values are then added to RAM sequentially to give the new recipe value. As an example, when adding a F.Spice, we take the item slot of the item, 0x16 and read from C3:F9DE + 0x14, which would be C3:F972 This gives us the value of 0x0B, which we LSR twice into 0x2C Now add this value to C3:F998 which results in C3:F9C4, and add the 4 byte set to RAM, which would give us 0x00, 0x08, 0x10, 0x10, for 7E:1CCD through 7E:1CD0, respectively
Shop data
3FA60-3FBBF Shops use item slot numbers for what items to sell and is terminated by a value of 00. The ROM uses 3FA60 when referencing the shop data, but the data appears to start around 3FAC9 and appears to mostly be in numerical order, by item slot number.
Game Script
The game script starts at 290000 and continues to 2CADA4, but this data uses simple compression. with it's data starting at 22D000 through 22D531, and the actual pointer data starting at 22DE00. 22DDF2 through 22DDF7 contain values of when to switch banks, 2 bytes each. The data itself is mostly ASCII coding, with some special formatting.
Music Data
Some data may be missing but these offsets are noted for setting music. (BacuraFF) x00AF80 - x00B0B3 - Indoor Map Music x00C0F0 - x00C13D - Event/Boss Battle Music Each seem to be one byte each. Some events forcefully change music and that is not included.
Monster Formation Data
Defines what enemies are in and how they are displayed on screen. Some of this data also interferes with the level up data. Formation Data: ---- x05:7DF0 - 0x5:84EF Bytes (7 each) ---- 01: Enemy formation - Doesn't appear to do anything except move enemies around the screen 02 - 07: Enemy pointer
Overworld mob formation pointers
Defines which enemies can be run into from your location on the overworld Map Data: ---- x05:5460 - x5:5550 Note: Max value on overworld is naturally 0x3F
Map Portal Data
Defines where a portal is, and where it takes you, and some special switches Portal Data: ---- x05:1800 - x05:48F4? (Might be shorter) Bytes (variable bytes) ---- 01: Which map these portals belong to 02: How many portals are in this map Each portal is 7 bytes as 01: Source X map position 02: Source Y map position 03: Destination X map position 04: Destination Y map position 05: Destination map pointer 06: Special switches/values used for loading 07: More switches/values
Shamans
x05:8A30 - x05:8A60 - Used as an index to pull from the Shaman pair table x05:8A61 - x05:8B08 - This is used to index where to pull the shaman bonuses x05:8B09 - ? - This is a table grouped into 8 values used to grant stat bonuses based on Shaman forms. x01:837A - x01:838F - Used to write to the "List" in the uniting menu when forms are successful. How it works: The function begins at x03:E2C8. It first checks if Bleu was selected for uniting, and fails if she was. Next it resets any shaman bonuses with the corresponding character in RAM i.e. if it was Bow, it would set all of 7E:5550 to 00. It then recalculates all equipment for the character, Off from weapons, Def from armor, etc. including bonuses. Then, it checks if either the holy (Seny) or devil (Shin) shamans were used. If Seny was used, the characters status is OR'd with 0x04. If Shin was used, the characters status is OR'd with 0x02. Although these bytes are changed, it doesn't appear to have any effect and is reset shortly thereafter by other functions. Now the meat: Each shaman has a corresponding byte associated, Sana is 00, Seso is 01, Spoo is 02, Solo is 03, Seny is 04, and Shin is 05. This is the same as the order they show in the menu when all are present. When only one is picked, it is used as the index, when both are picked, the values are bit OR against each other. By default, the first shaman picked is always 0x00, and the second Shaman is 0xFF. It is checked for negative value when calculating. This value is added to address x05:8A30 - 1 to get the pair index address. Then, take the character value (x7E:1CAC) and multiply by 0x15, add the pair index address, and add to x05:8A61. If a 0 is pulled from this index, the pairing fails. Even if hacked to cheat this system, no bonuses are given for a 0 index. This value is then multiplied by x08 and added to x05:8B09, this is what we will use to find the stat bonus you get from a combination. You go through the next 8 values and multiply by your raw stat corresponding to this number in order of Str, Stmna, Agil, Wis, Luck, AP. So the first value is multiplies against strength, the high byte is then used and added to your raw strength for offense, the second is against stamina, etc. These bonuses are written to x7E:5540 + (Character value * x10), the character value can be found at the base of the character + x06. For this, Bow is x01, Rand is x02, etc. These are always in the same order, regardless of character order in RAM. Luck is not written, this appears to be a glitch, as the game does not use an index to confirm all stats are written and appears to exit early.
RNG
The random number generator (RNG) is used in the game anywhere variance is required Here it is, disassembled in it's glory, and how it works: ;Random Number Generator. Entry point is JSL $C0/648B 08 PHP $C0/648C C2 20 REP #$20 $C0/648E AD D6 00 LDA $00D6 [$81:00D6] $C0/6491 0A ASL A $C0/6492 0A ASL A $C0/6493 18 CLC $C0/6494 6D D6 00 ADC $00D6 [$81:00D6] $C0/6497 EB XBA $C0/6498 E2 20 SEP #$20 $C0/649A 8D D7 00 STA $00D7 [$81:00D7] $C0/649D 18 CLC $C0/649E 6D D6 00 ADC $00D6 [$81:00D6] $C0/64A1 8D D6 00 STA $00D6 [$81:00D6] $C0/64A4 28 PLP $C0/64A5 6B RTL What it does (just the math): Load 7E00D6 Multiply by 5 Switch high and low bits Set 8-bit register Store into 7E00D7(High Byte of D6) Add original D6 (Low byte only) The function then reads/mutates A for the result
Internal Data for Breath of Fire II
| |
---|---|