FF7/Battle and growth data
Contents
Kernel.bin section 3
This file contains a bunch of information about character growth and battles. Table below explains it all (credits go to Terence F. for this).
General data layout
Offset | Length | Description |
---|---|---|
0x0000 | 56 bytes | Character data: Cloud (see below) |
0x0038 | 56 bytes | Character data: Barret |
0x0070 | 56 bytes | Character data: Tifa |
0x00A8 | 56 bytes | Character data: Aeris |
0x00E0 | 56 bytes | Character data: Red XIII |
0x0118 | 56 bytes | Character data: Yuffie |
0x0150 | 56 bytes | Character data: Cait Sith |
0x0188 | 56 bytes | Character data: Vincent |
0x01C0 | 56 bytes | Character data: Cid |
0x01F8 | 12 x 1 byte | Random bonus to primary stats |
0x0204 | 12 x 1 byte | Random bonus % to HP |
0x0210 | 12 x 1 byte | Random bonus % to MP |
0x021C | 37 x 16 bytes | Primary stat curve 0 - 36 (see below) |
0x046C | 9 x 16 bytes | HP stat curve 37 - 45 (Base * 40) |
0x04FC | 9 x 16 bytes | MP stat curve 46 - 54 (Base * 2) |
0x058C | 9 x 16 bytes | EXP stat curve 55 - 63 (Gradient is quadratic, no Base) |
0x61C | 1508 bytes | Character AI data (see below) |
0xC00 | 540 bytes | FF padding |
0xE1C | 256 bytes | Random number look-up table (all numbers from 0-255 are here) |
0xF1C | 64 bytes | Scene.bin look-up table (see below) |
0xF5C | 56 bytes | Spell order from Magic menu in battles (see below) |
Character data record
Offset | Length | Function |
---|---|---|
0x00 | 1 byte | Strength Level-Up Curve |
0x01 | 1 byte | Vitality Level-Up Curve |
0x02 | 1 byte | Magic Level-Up Curve |
0x03 | 1 byte | Spirit Level-Up Curve |
0x04 | 1 byte | Dexterity Level-Up Curve |
0x05 | 1 byte | Luck Level-Up Curve |
0x06 | 1 byte | HP Level-Up Curve |
0x07 | 1 byte | MP Level-Up Curve |
0x08 | 1 byte | Experience Level-Up Curve |
0x09 | 1 byte | FF (padding) |
0x0A | 1 byte | Starting Level |
0x0B | 1 byte | FF (padding) |
0x0C | 1 byte | Limit Command 1-1 |
0x0D | 1 byte | Limit Command 1-2 |
0x0E | 1 byte | Limit Command 1-3 (UNUSED) |
0x0F | 1 byte | Limit Command 2-1 |
0x10 | 1 byte | Limit Command 2-2 |
0x11 | 1 byte | Limit Command 2-3 (UNUSED) |
0x12 | 1 byte | Limit Command 3-1 |
0x13 | 1 byte | Limit Command 3-2 |
0x14 | 1 byte | Limit Command 3-3 (UNUSED) |
0x15 | 1 byte | Limit Command 4-1 |
0x16 | 1 byte | Limit Command 4-2 (UNUSED) |
0x17 | 1 byte | Limit Command 4-3 (UNUSED) |
0x18 | 2 bytes | Kills required for Limit Level 2 |
0x1A | 2 bytes | Kills required for Limit Level 3 |
0x1C | 2 bytes | Uses required for Limit 1-2 |
0x1E | 2 bytes | Uses required for Limit 1-3 (UNUSED) |
0x20 | 2 bytes | Uses required for Limit 2-2 |
0x22 | 2 bytes | Uses required for Limit 2-3 (UNUSED) |
0x24 | 2 bytes | Uses required for Limit 3-2 |
0x26 | 2 bytes | Uses required for Limit 3-3 (UNUSED) |
0x28 | 4 bytes | HP Divisor for Limit Level 1 |
0x2C | 4 bytes | HP Divisor for Limit Level 2 |
0x30 | 4 bytes | HP Divisor for Limit Level 3 |
0x34 | 4 bytes | HP Divisor for Limit Level 4 |
Stat curve record
Each entry is 16 bytes long and contains eight pairs of Gradients and Bases (1 byte each) for eight different level groups:
2-11 12-21 22-31 32-41 42-51 52-61 62-81 82-99
The general formula for primary stats to follow is:
Stat Difference = Rnd(1..8) + Base + Floor(Gradient * [Level Attained] / 100) - Current Stat
This difference is capped at 11 and the value located at &[0x01F8 + Stat Difference] is added to that Stat.
HP and MP use a similar system, but a different formula:
HP Baseline = Base * 40 + (Level - 1) * Gradient MP Baseline = Base * 40 + [(Level - 1) * Gradient / 10] Difference = Rnd(1..8) + [100 * Baseline / Current Stat] - 100
In the above formulas, Base is a signed byte (between -128 and 127) so Base * 40 can range between -5120 and 5080.
Again, this difference is capped at 11 and the appropriate points are increased by (Base is now treated as an unsigned byte):
(&[0x204 + Difference] / 100) * Base for HP (&[0x210 + Difference] / 100) * [Level * Gradient / 10] - [(Level - 1) * Gradient / 10] for MP
where &[x] is the value located at the address of this section
The Experience level curves are 16 bytes long, although only eight bytes of each are used. Experience is calculated on a need-to-level basis. This means that the total Experience needed for each character to reach the next level is calculated and stored in memory.
Needed XP = [Mod * ((Lvl-1) ^ 2) / 10]
Where Mod is the value of the byte at the point in the curve based on the level to attain. So with a Mod of 70, to get to level 13 from level 12, a character would need:
70 * ((13-1) ^ 2) /10 70 * (144 / 10) 70 * 14.4 1008 additional XP
The savemap contains information about the needed XP to get to the next level for each character so it can be assumed that the game only performs this calculation at level up and changes the needed XP stat accordingly and compares that against the total XP the character has to determine when the next level occurs.
To calculate the total XP needed for a given level:
XP = 0 For I = 1 to Lvl-1 XP = XP + [Mod * (I ^ 2) / 10] Next I
Remember, the Mod will need to be adjusted to the character and level group each time I increments.
Character AI data
Section contains 24-byte header representing 2-bytes per script block (1 per character?). Each number is an offset from the beginning of this block to the actual AI data. Each script block follows the same AI data found in the Battle Scenes. A basic disassembly of the characters' scripts can be found here
Scene.bin Look-up file
As you may know, scene.bin file is divided into banks or sections. There are 33 total sections, and each one is 8192 long. Each section contains 5 - 16 GZipped files (scenes), based on their length. Since each section of scene.bin must be 8192 bytes, altering a scene may cause it to be necessary to place it in the next section. This look-up table contains data about the starting scene in each section:
00 0C 12 19 21 27 2D ...
Which means:
Section 1 contains scenes 0x00 - 0x0B = 12 files Section 2 contains scenes 0x0C - 0x11 = 6 files Section 3 contains scenes 0x12 - 0x18 = 7 files ... and so on.
Every time you modify scene.bin file you must also keep this table updated or you'll end with VERY random encounters (wrong battles in wrong places). You can use SceneFix program, which'll update the table for you.
Magic Order
This segment of data tells the game in what order to load the attacks into which Magic section. There are four Magic sections: Restore, Attack, Indirect, and Special. The first three can be reorganized in the battle's magic menu. When the first 56 attacks are loaded, these bytes tell the game which section and what order to be loaded in:
AAA:BBBBB AAA - Section BBBBB - Index within section of attack loaded
The Magic menu will only display sections 0 - 3 (Summons are section 4, E.Skills are section 5, etc.). The sections are then displayed sequentially in the field magic menu and in the order specified in the battle menu.
Eg: The fourth attack in Attack data is Regen. The fourth byte in this data segment is 08. This means load Regen into section 0 at position 8.
NOTES:
- If a value is repeated, that attack will override the previous listing.
- The final two bytes are NULL (0xFF) so the game moves the Attack pointer ahead to load the summon attacks.