data/claims/ff4-tables.yamlFinal Fantasy IV's data tables (everything8215's ff4 disassembly, Final Fantasy II 1.1 (U))
Game: Final Fantasy IV.
Each of the 224 monsters has a property block that starts with its level (the top bit marks a boss), its HP, three indexes into a table of three-byte triples (a multiplier, a rate, and a value) for its attack, defense, and magic defense, an index into a table of agility ranges, and a byte whose low six bits pick its item set and top two bits its drop odds; experience and gil sit in tables of two bytes per monster. When a battle starts, the game copies the level, sets current and maximum HP to the HP, sets MP to the HP divided by 16, rolls agility between the range's two values, and copies the attack triple; for defense and magic defense it stores the rate byte and then the value at the same address, so the value overwrites the rate. HP runs from 1 (Shadow) to 65,500 (Golbez) and experience up to 65,000 (Mind); 64 monsters have the boss bit. ff4-tables/monsters
vanilla/ff4-en-rip.json#L6272-L6370"monsterProperties": {
"type": "array",
"name": "Monster Properties",
"range": "0x0EA860-0x0EB438",
"arrayLength": 224,
"asmSymbol": "MonsterProp",
"file": "battle/data/monster_prop_en.asm",
"assembly": {
"type": "assembly",
"name": "Monster %i",
"format": "ff4-monster",
"assembly": {
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L4893-L5152"monsterAttackDefense": {
"type": "array",
"name": "Monster Attack/Defense Properties",
"range": "0x0EA380-0x0EA61F",
"arrayLength": 224,
"itemLength": 3,
"asmSymbol": "MonsterStats",
"file": "battle/data/monster_stats.asm",
"assembly": {
"type": "assembly",
"name": "Monster Attack/Defense %i",
"assembly": {
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L4798-L4892"monsterAgility": {
"type": "array",
"name": "Monster Agility Properties",
"range": "0x0EA620-0x0EA69F",
"arrayLength": 64,
"itemLength": 2,
"asmSymbol": "MonsterAgility",
"file": "battle/data/monster_agility_en.asm",
"assembly": {
"type": "assembly",
"name": "Monster Agility %i",
"assembly": {
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L5660-L5674"monsterExperience": {
"type": "array",
"name": "Monster Experience",
"range": "0x0EA1C0-0x0EA37F",
"arrayLength": 224,
"itemLength": 2,
"asmSymbol": "MonsterXP",
"file": "battle/data/monster_xp_en.asm",
"assembly": {
"type": "property",
"name": "Experience",
"length": 2,
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L5675-L5689"monsterGP": {
"type": "array",
"name": "Monster GP",
"range": "0x0EA000-0x0EA1BF",
"arrayLength": 224,
"itemLength": 2,
"asmSymbol": "MonsterGil",
"file": "battle/data/monster_gil_en.asm",
"assembly": {
"type": "property",
"name": "GP",
"length": 2,
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L6196-L6224"monsterName": {
"type": "array",
"name": "Monster Name",
"range": "0x0E9800-0x0E9EFF",
"arrayLength": 224,
"itemLength": 8,
"asmSymbol": "MonsterName",
"file": "battle/text/monster_name_en.asm",
"assembly": {
"type": "text",
"name": "Name",
"encoding": "fixedLength",
…Final Fantasy II (USA) (Rev 1) · 0x726a0-0x73438 — $0E:A6A0: the monster property pointers (224 words) and the property blocksFinal Fantasy II (USA) (Rev 1) · 0x71800-0x71eff — $0E:9800: the monsters' names, 8 bytes eachFinal Fantasy II (USA) (Rev 1) · 0x72000-0x7267f — $0E:A000: gil, experience (2 bytes per monster each), the 224 attack and defense triples, and the 64 agility rangesFinal Fantasy IV Disassembly · battle/init.asm#L819-L938InitMonster:
@8fca: lda $b9
sta $35a0
asl
clc
adc #$0a
tax
lda #$40 ; enable action timer
sta $29eb,x
longa
lda $bb
asl
…Final Fantasy IV Disassembly · battle/init.asm#L1368-L1380LoadMonsterStat:
@9489: phx
sta $df
lda #3
sta $e1
jsr Mult8
ldx $e3
ldy #$0080
@9498: lda f:MonsterStats,x
sta $289c,y
inx
iny
…Final Fantasy IV Disassembly · battle/battle.asm#L734-L739Lsr_5: lsr
Lsr_4: lsr
Lsr_3: lsr
Lsr_2: lsr
lsr
rtsFinal Fantasy IV Disassembly · notes/ff4j-sfc-ram-map.txt#L712-L715| | +$1007 current hp |
| | +$1009 max hp |
| | +$100B current mp |
| | +$100D max mp |Final Fantasy IV Disassembly · notes/ff4j-sfc-ram-map.txt#L1247-L1247| | $2000-$203F same as $1000-$103F |Final Fantasy IV Disassembly · battle/battle.asm#L546-L578; [ random (x..a) ]
RandXA:
@8379: shorti
stx $96
cpx #$ff
bne @8383
bra @83b6
@8383: cmp #$00
beq @83b6
cmp $96
beq @83b6
ldx $97
…Checked by claude, 2026-10-28 — compared each monster's level, HP, attack value, item byte, experience and gil in the decoded rows with the ROM bytes (the property block found through its pointer), and read the battle-start code that loads themRevised after a check by a second AI model, 2026-10-28.Rows come from the repo's rip tool, which decodes the ROM's variable-length property blocks; names are the ROM's text. The rate byte columns hold what the table stores; the battle-start code overwrites it with the value as the statement says. MP is not in the table. Drop odds are computed in ff4-tables/steals-drops.
The 64 item sets hold four items each, and each monster's item byte picks a set and its drop odds. After a won battle each defeated monster's top two bits decide whether it drops an item: 11 always, 01 when a random number from 0 to 98 is under 5, 10 when it is under 25, 00 never. That number is a byte of the 256-byte random table modulo 99, and the table holds each byte value once, so the odds are 15 and 75 in 256 (computed). A drop takes the set's first item when a random byte is under $80, the second under $D0, the third under $FC, and otherwise the fourth: 128, 80, 44, and 4 in 256 (computed). A battle keeps at most 8 drops. A successful steal takes the set's first item, ten at a time for items $54 to $60, and ends without one when both odds bits are set. 84 monsters never drop, 135 have the 15-in-256 odds, 1 the 75-in-256, and 4 always drop; sets 27, 45, 61 belong to no monster. ff4-tables/steals-drops
vanilla/ff4-en-rip.json#L6087-L6195"monsterItems": {
"type": "array",
"name": "Monster Items",
"range": "0x0E9F00-0x0E9FFF",
"arrayLength": 64,
"itemLength": 4,
"asmSymbol": "MonsterItems",
"file": "battle/data/monster_items_en.asm",
"assembly": {
"type": "assembly",
"name": "Monster Items %i",
"assembly": {
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L6272-L6370"monsterProperties": {
"type": "array",
"name": "Monster Properties",
"range": "0x0EA860-0x0EB438",
"arrayLength": 224,
"asmSymbol": "MonsterProp",
"file": "battle/data/monster_prop_en.asm",
"assembly": {
"type": "assembly",
"name": "Monster %i",
"format": "ff4-monster",
"assembly": {
…Final Fantasy II (USA) (Rev 1) · 0x71f00-0x71fff — $0E:9F00: the 64 item sets, 4 item numbers eachFinal Fantasy II (USA) (Rev 1) · 0xa6e00-0xa6eff — $14:EE00: the 256-byte random table; each value 0-255 appears onceFinal Fantasy IV Disassembly · battle/win.asm#L64-L118lda $358e,x
sta $b3
lda $358e,x
and #$c0
cmp #$c0
beq @ed0f
cmp #$40
bne @ed00
lda #$05
bra @ed06
@ed00: cmp #$80
bne @ed5f
…Final Fantasy IV Disassembly · battle/cmd.asm#L76-L156; [ battle command $17: steal (sneak) ]
; steal rate is (attacker level + 50) - (monster level + 10)
; so 40% if attacker and monster are at the same level
; after a failed steal, there is a (monster level + 10) chance
; that edge takes damage of (max hp) / 16
Cmd_17:
@e1cf: lda #$17
sta $34c8 ; set command name
lda #$10
sta $34c7 ; show command name
lda #$f8 ; display text
sta $33c6
…Final Fantasy IV Disassembly · battle/battle.asm#L937-L951Rand99:
@858b: clr_ax
lda #98
jsr RandXA
rts
; ------------------------------------------------------------------------------
; [ random (0..255) ]
Rand:
@8593: clr_ax
lda #$ff
jsr RandXA
rtsFinal Fantasy IV Disassembly · battle/battle.asm#L638-L662Div16:
@8407: longa
stz $3949
stz $394b
lda $3945
beq @843f
lda $3947
beq @843f
clc
ldx #$0010
@841d: rol $3945
rol $394b
…Final Fantasy IV Disassembly · battle/battle.asm#L219-L223InitBattle:
@808a: jsr InitHWRegs
ldx #$00ff
@8090: lda f:RNGTbl,x ; copy rng table to buffer
sta $1900,xFinal Fantasy IV Disassembly · battle/battle.asm#L546-L578; [ random (x..a) ]
RandXA:
@8379: shorti
stx $96
cpx #$ff
bne @8383
bra @83b6
@8383: cmp #$00
beq @83b6
cmp $96
beq @83b6
ldx $97
…Checked by claude, 2026-10-28 — matched every set's four item numbers with the ROM's 256 bytes at $0E:9F00, counted the random table's distinct values (256), and counted the bytes whose value modulo 99 is under 5 (15) and under 25 (75)Revised after a check by a second AI model, 2026-10-28.In the ROM's item names, $54 to $5F are Iron to Artemis; $60 has no name. Set 0 holds four empty slots for monsters that never drop. Item names drop their icon, so names repeat (arrows and armor share some).
The price table has a byte for each of the 256 items: with the top bit clear the price is the byte times 10, with it set the low seven bits times 1,000 (the shop code multiplies them by 250 and then by 4). Prices run up to 125,000 (Dummy); 21 items cost 0, two of them unnamed. ff4-tables/item-prices
vanilla/ff4-en-rip.json#L2806-L3011"itemProperties": {
"type": "array",
"name": "Item Price",
"range": "0x0FA450-0x0FA54F",
"arrayLength": 256,
"itemLength": 1,
"asmSymbol": "ItemPrice",
"file": "menu/data/item_price_en.asm",
"stringTable": "itemNames",
"assembly": {
"type": "assembly",
"name": "Item %i",
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L2725-L2805"itemNames": {
"type": "array",
"name": "Item Names",
"range": "0x0F8000-0x0F88FF",
"arrayLength": 256,
"itemLength": 9,
"asmSymbol": "ItemName",
"file": "btlgfx/text/item_name_en.asm",
"assembly": {
"type": "assembly",
"name": "Item Name %i",
"assembly": {
…Final Fantasy II (USA) (Rev 1) · 0x7a450-0x7a54f — $0F:A450: the item prices, a byte eachFinal Fantasy II (USA) (Rev 1) · 0x78000-0x7906f — $0F:8000: the item names, 9 bytes each (an icon and 8 letters)Final Fantasy IV Disassembly · menu/shop.asm#L316-L343@c4d8: sta $5d
sta ($51)
jsr IncShopPtr
phy
jsr Tax16
lda f:ItemPrice,x ; item prices
bpl @c533
; 1000x price multiplier
and #$7f
sta f:hWRMPYA
lda #$fa ; multiply by 250
sta f:hWRMPYB
…Final Fantasy IV Disassembly · menu/shop.asm#L343-L347rol $47
rol $45
rol $46
rol $47
ldx $45Final Fantasy IV Disassembly · menu/shop.asm#L359-L361@c533: sta f:hWRMPYA
lda #$0a ; multiply by 10
sta f:hWRMPYBChecked by claude, 2026-10-28 — computed every price from the ROM's 256 bytes at $0F:A450 by the shop code's two branchesRevised after a check by a second AI model, 2026-10-28.Item names are the ROM's text without the icon that precedes each.
Each of the 48 shops lists up to 8 items, ended by $FF; the shop menu reads the list at the shop number times 8 and each item's price from the price table (ff4-tables/item-prices). The shops sell from 1 to 8 items. ff4-tables/shops
vanilla/ff4-en-rip.json#L7135-L7243"shopProperties": {
"type": "array",
"name": "Shop Properties",
"range": "0x13A300-0x13A47F",
"arrayLength": 48,
"itemLength": 8,
"asmSymbol": "ShopProp",
"file": "menu/data/shop_prop_en.asm",
"assembly": {
"type": "assembly",
"name": "Shop %i",
"assembly": {
…Final Fantasy II (USA) (Rev 1) · 0x9a300-0x9a47f — $13:A300: the 48 shop lists, 8 bytes eachFinal Fantasy IV Disassembly · menu/shop.asm#L290-L321LoadShopList:
@c4a0: ldx $41 ; zero
stx $1a78
stx $1a7a
stx $1a7c
stx $1a7e
jsr SelectBG4
ldx #$1b55
stx $51
lda #$00
xba
lda $1a00
…The price table has a byte for each of the 256 items: with the top bit clear the price is the byte times 10, with it set the low seven bits times 1,000 (the shop code multiplies them by 250 and then by 4). Prices run up to 125,000 (Dummy); 21 items cost 0, two of them unnamed. CodeChecked by claude, 2026-10-28 — matched every shop's 8 bytes with the ROM at $13:A300 and read the menu's list loopChecked by a second AI model, 2026-10-28.Which town or event opens each shop is not traced here (event command $ED takes the shop number).
18 party slots point into 13 level-up tables (Tellah's serves three slots; Kain's, Rydia's, Rosa's, and Yang's two each), each 5 bytes per level from the character's starting level to 69, then 8 stat bytes. When the game checks a character after a battle it adds the entry's experience, a 19-bit number, to the experience at the last level, and gains a level while the character's experience reaches that sum, checking again after each level, up to level 99. The first byte's top five bits pick which of strength, agility, stamina, intellect, and spirit change and its low three bits by how much (+0 to +6, or 7 for −1), kept from 1 to 99. HP rises by the second byte plus a random 0 to an eighth of it, up to 9,999, and MP by the third byte's low five bits plus a random 0 to an eighth of that, up to 999. From level 70 on, the level-69 entry serves, with its first byte replaced by one of the 8 stat bytes at random. The rows are 832 entries. ff4-tables/level-ups
vanilla/ff4-en-rip.json#L1321-L1343"LevelUpProp": {
"type": "array",
"name": "Character Level Progression",
"range": "0x0FB528-0x0FC3C7",
"arrayLength": 13,
"asmSymbol": "LevelUpProp",
"file": "battle/data/level_up_prop.asm",
"itemRanges": [
"0x0FB528-0x0FB65B",
"0x0FB65C-0x0FB78F",
"0x0FB790-0x0FB8F0",
"0x0FB8F1-0x0FB9F2",
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L1344-L1417"LevelUpPropLow": {
"type": "array",
"arrayLength": 13,
"assembly": {
"type": "array",
"itemLength": 5,
"assembly": {
"type": "assembly",
"name": "Level Up Properties %i",
"assembly": {
"exp": {
"type": "property",
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L1418-L1467"LevelUpPropHigh": {
"type": "array",
"arrayLength": 13,
"assembly": {
"type": "array",
"arrayLength": 8,
"itemLength": 1,
"assembly": {
"type": "assembly",
"name": "High Level Random Stats %i",
"assembly": {
"statMod": {
…Final Fantasy II (USA) (Rev 1) · 0x7b500-0x7c3c7 — $0F:B500: 18 pointers (each offset back by the character's starting level) and the 13 tablesFinal Fantasy IV Disassembly · battle/battle_data.asm#L43-L76.define DK_KNIGHT_INIT_LVL 10
.define KAIN_INIT_LVL 10
.define RYDIA_INIT_LVL 1
.define TELLAH_INIT_LVL 20
.define EDWARD_INIT_LVL 5
.define ROSA_INIT_LVL 10
.define YANG_INIT_LVL 10
.define PALOM_INIT_LVL 10
.define POROM_INIT_LVL 10
.define PALADIN_INIT_LVL 1
.define CID_INIT_LVL 20
.define EDGE_INIT_LVL 25
…Final Fantasy IV Disassembly · battle/win.asm#L294-L401@ef06: ldx $a6
lda $1000,x
and #$1f
dec
asl
tax
lda f:LevelUpPropPtrs,x
sta $80
lda f:LevelUpPropPtrs+1,x
sta $81
lda #^LevelUpPropPtrs
sta $82
…Final Fantasy IV Disassembly · notes/ff4j-sfc-ram-map.txt#L764-L764| | ++$1037 experience |Final Fantasy IV Disassembly · notes/ff4j-sfc-ram-map.txt#L772-L772| | ++$103D experience at last level |Final Fantasy IV Disassembly · battle/win.asm#L431-L476LevelUp:
@f02e: lda $289c
and #$07
sta $af
longa
lda $a6
adc #$000f
tax
shorta0
ldy #$0005
@f043: asl $289c
bcc @f06b
…Final Fantasy IV Disassembly · battle/win.asm#L511-L537LevelUpHPMP:
@f0cd: sta $b5
stz $b6
longa
clc
lda $a6
adc $b5
sta $b5
shorta0
clr_ax
lda $b1
jsr Lsr_3
…Checked by claude, 2026-10-28 — decoded each table from the ROM at $0F:B528 and matched it with the rip's rows, and checked that each of the 18 pointers plus (starting level − 1) × 5 lands on its table's first byteRevised after a check by a second AI model, 2026-10-28.A row gives what reaching the next level from that level adds. Class names are the ROM's (each table's character in parentheses). The stat names are ours, in the order of the five stat bytes the code walks.
Each of 512 map numbers has an encounter-rate byte and a battle-group byte; 109 maps have a nonzero rate. On those maps each check for a battle starts one when a random byte (a table byte plus a running offset) is under the rate, so the rate is the chance in 256 for a uniform byte (computed); a second random byte picks one of the group's 8 battles, the first four 43 in 256 each, the next two 32, then 16 and 4 (computed from the code's cutoffs $2B, $56, $81, $AC, $CC, $EC, $FC). Maps 256 and up take battles numbered from 256. ff4-tables/map-encounters
vanilla/ff4-en-rip.json#L3115-L3131"mapBattleProbability": {
"type": "array",
"name": "Map Battle Probability",
"range": "0x0EC342-0x0EC541",
"arrayLength": 512,
"itemLength": 1,
"asmSymbol": "SubBattleRate",
"file": "field/data/sub_battle_rate.asm",
"assembly": {
"type": "property",
"name": "Battle Probability",
"min": 1,
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L3100-L3114"mapBattle": {
"type": "array",
"name": "Map Battle",
"range": "0x0EC596-0x0EC795",
"arrayLength": 512,
"itemLength": 1,
"asmSymbol": "SubBattleGrp",
"file": "field/data/sub_battle_grp.asm",
"assembly": {
"type": "property",
"name": "Battle Group",
"link": "battleGroup[%i]",
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L744-L895"battleGroup": {
"type": "array",
"name": "Battle Group",
"range": "0x0EC816-0x0ECA95",
"arrayLength": 80,
"itemLength": 8,
"asmSymbol": "SubBattles",
"file": "field/data/sub_battles.asm",
"assembly": {
"type": "assembly",
"name": "Battle Group %i",
"assembly": {
…Final Fantasy II (USA) (Rev 1) · 0x74342-0x74a95 — $0E:C342: the map rates (512), the map groups (512), the world groups (16 × 8) and the map battle groups (80 × 8)Final Fantasy II (USA) (Rev 1) · 0x70000-0x70fff — $0E:8000: the 512 battles' properties (the monsters named in the cells)Final Fantasy IV Disassembly · field/rand_battle.asm#L202-L230; sub-map
@8c53: lda $1702
sta $3d
lda $1701
beq @8c5f
lda #$01
@8c5f: sta $3e
ldx $3d
lda f:SubBattleRate,x
beq @8c7e
sta $06
lda $c0
…Final Fantasy IV Disassembly · field/rand_battle.asm#L230-L235@8c91: ldx $3d
lda $0ec596,x
jsr ChooseRandBattle
ldx $3d
lda f:SubBattles,x
sta $1800Final Fantasy IV Disassembly · field/rand_battle.asm#L290-L348; [ choose random battle ]
; battle probabilities
; 0: 43/256 (16.8%)
; 1: 43/256 (16.8%)
; 2: 43/256 (16.8%)
; 3: 43/256 (16.8%)
; 4: 32/256 (12.5%)
; 5: 32/256 (12.5%)
; 6: 16/256 (6.25%)
; 7: 4/256 (1.56%)
ChooseRandBattle:
@8cf0: sta $3d
…Final Fantasy IV Disassembly · field/rand_battle.asm#L253-L257UpdateBattleParams:
@8cb5: lda $1701
beq @8cbc
lda #$01 ; set msb of battle id
@8cbc: sta $1801Checked by claude, 2026-10-28 — matched all 512 rates and groups and the 80 groups' battles with the ROM, and read the sub-map branch and the battle choiceChecked by a second AI model, 2026-10-28.Map titles are the ROM's; many floors share a title such as 1F. A battle cell gives its number and its monsters (count of each).
On the overworld the battle rate comes from an 8 × 8 grid of 32 × 32-tile areas, 10, 8, or 7 in 256, and the battle group from a matching grid of groups 0 to 6; the underground has a rate of 8 and a 4 × 4 grid of groups 7, 8, and 10, and the moon a rate of 8 and four quarters, all group 9. Each group lists 8 battles picked with the same odds as on maps (ff4-tables/map-encounters); underground and moon battles are numbered from 256. Groups 11 to 15 hold only battle 0 eight times and are in no grid, so they are never used. ff4-tables/world-encounters
field/rand_battle.asm#L19-L37OverworldBattleRate:
.byte 10,10,10, 8, 8,10,10,10
.byte 10,10,10, 8, 8,10,10,10
.byte 10,10,10, 8, 8,10,10,10
.byte 10,10, 7, 8, 8, 8,10,10
.byte 8, 8, 7, 7, 8, 8,10,10
.byte 8, 8, 7, 7, 8,10,10,10
.byte 8, 8, 8, 8, 8,10,10,10
.byte 8, 8, 8, 8, 8,10,10,10
; 0e/c340
UndergroundBattleRate:
.byte 8
…Final Fantasy IV Disassembly · field/rand_battle.asm#L41-L59OverworldBattleGrp:
.byte 5,5,5,2,2,3,3,3,5,5,5,2,2,3,3,3
.byte 5,5,1,1,1,3,3,3,5,5,1,1,1,1,3,3
.byte 5,5,0,0,1,1,5,3,6,6,0,0,4,4,4,4
.byte 6,6,6,6,4,4,4,4,6,6,6,6,4,4,4,4
; 0e/c582
UndergroundBattleGrp:
.byte 8,7,7,7
.byte 10,7,7,7
.byte 8,7,7,7
.byte 8,8,8,8
; 0e/c592
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L896-L984"battleGroupWorld": {
"type": "array",
"name": "Battle Group (World)",
"range": "0x0EC796-0x0EC815",
"arrayLength": 16,
"itemLength": 8,
"asmSymbol": "WorldBattles",
"file": "field/data/world_battles.asm",
"assembly": {
"type": "assembly",
"name": "World Battle Group %i",
"assembly": {
…Final Fantasy II (USA) (Rev 1) · 0x74796-0x74815 — $0E:C796: the 16 world groups, 8 battle numbers eachFinal Fantasy IV Disassembly · field/rand_battle.asm#L74-L203CheckBattle:
@8b3c: lda $1704
bne @8b56
lda $a2
and #$40
beq @8b56
lda $c0
bne @8b6b
lda $ab
beq @8b56
lda $d5
beq @8b56 ; branch if player control is disabled
…Final Fantasy IV Disassembly · field/field.asm#L495-L495@8302: lda $1704 ; vehicle idFinal Fantasy IV Disassembly · field/trigger.asm#L830-L833lda $1700
beq @9ddf
lda #$01
@9ddf: sta $1701Each of 512 map numbers has an encounter-rate byte and a battle-group byte; 109 maps have a nonzero rate. On those maps each check for a battle starts one when a random byte (a table byte plus a running offset) is under the rate, so the rate is the chance in 256 for a uniform byte (computed); a second random byte picks one of the group's 8 battles, the first four 43 in 256 each, the next two 32, then 16 and 4 (computed from the code's cutoffs $2B, $56, $81, $AC, $CC, $EC, $FC). Maps 256 and up take battles numbered from 256. CodeChecked by claude, 2026-10-28 — read the grids at the pinned lines and the overworld, underground and moon branches; matched the 16 groups with the ROMRevised after a check by a second AI model, 2026-10-28.The check returns early while any vehicle is set.
The song table has 70 entries, each a three-byte pointer to a song's script; this is the game's track listing, by song number, with where the game plays each, from every request found: the song byte of each of the 383 maps, 375 song commands in the event scripts, 49 song control codes in dialogue, 14 song commands in monster action scripts, the battle properties' song field, the world and vehicle song tables, and constants in the field, battle, menu, and cutscene code. 62 entries are requested; no request found reaches 56, 57, 58, 59, 60, 61, 64, 65. Entries 56, 57, 58, 59, 60, 61 point to the same script as entry 0. ff4-tables/tracks
About: Final Fantasy IV Music driver
CodeFinal Fantasy IV Disassembly ·sound/sound_data.asm#L41-L42SongScriptPtrs:
make_ptr_tbl_far SongScript, 70, SoundDataFinal Fantasy II (USA) (Rev 1) · 0x3721d-0x372ee — $06:F21D: the song table, 70 three-byte pointersFinal Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L7291-L7368"songScripts": {
"type": "array",
"name": "Song Scripts",
"range": "0x06F2EF-0x08B8B8",
"arrayLength": 70,
"asmSymbol": "SongScript",
"file": "sound/data/song_script.asm",
"pointerTable": {
"range": "0x06F21D-0x06F2EE",
"offset": "0x04C000",
"pointerSize": 3
},
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L3371-L3404"mapProperties": {
"type": "array",
"name": "Map Properties",
"range": "0x159C84-0x15AFF6",
"arrayLength": 383,
"itemLength": 13,
"asmSymbol": "MapProp",
"file": "field/data/map_prop_en.asm",
"assembly": {
"type": "assembly",
"name": "Map %i",
"editor": "FF4Map",
…Final Fantasy IV Disassembly · field/field.asm#L1262-L1292PlayMapSong:
@8d5d: lda $1704
beq @8d71
lda $1704
tax
lda VehicleSongTbl,x ; vehicle songs
sta $1e01
lda #$03
jmp @8d87
@8d71: lda $1700
cmp #$03
beq @8d7f
…Final Fantasy IV Disassembly · field/vehicle.asm#L295-L300; [ board chocobo ]
BoardChoco:
@a03e: lda #$01
sta $1704 ; set vehicle
sta $ac ; set movement speedFinal Fantasy IV Disassembly · field/vehicle.asm#L306-L319; [ board black chocobo ]
BoardBkChoco:
@a049: inc $1715
lda $1715
cmp #$01
bne @a05f
lda $1706
sta $1716
lda $1707
sta $1717
@a05f: lda #$02
sta $1704
…Final Fantasy IV Disassembly · field/vehicle.asm#L457-L462; [ board hovercraft ]
BoardHover:
@a168: lda #$03
sta $1704
lda #1Final Fantasy IV Disassembly · field/vehicle.asm#L549-L558; [ board enterprise ]
BoardEnterprise:
@a213: lda $1286
and #$04
beq @a21b
rts
@a21b: lda #$04 ; set vehicle
sta $1704
lda #3Final Fantasy IV Disassembly · field/vehicle.asm#L608-L613; [ board falcon ]
BoardFalcon:
@a283: lda #$05
sta $1704
lda #3Final Fantasy IV Disassembly · field/vehicle.asm#L677-L682; [ board big whale ]
BoardWhale:
@a2ff: lda #$06
sta $1704
lda #3Final Fantasy IV Disassembly · field/event.asm#L817-L833; [ event command $fa: play song ]
EventCmd_fa:
@e7e1: jsr GetNextEventByte
jsr PlaySongEvent
jmp WaitVblankEvent
; ------------------------------------------------------------------------------
; [ ]
PlaySongEvent:
@e7ea: sta $1e01
lda #$01 ; play song
sta $1e00
jsl ExecSound_ext
…Final Fantasy IV Disassembly · field/event.asm#L568-L576; [ event command $ea: play song (fade in) ]
EventCmd_ea:
@e601: jsr GetNextEventByte
sta $1e01
lda #$04
sta $1e00
jsl ExecSound_ext
jmp WaitVblankEventFinal Fantasy IV Disassembly · field/event.asm#L60-L77lda f:EventScript,x
cmp #$ff
bne @e236
lda $1703
stz $3d
lsr
ror $3d
lsr
ror $3d
sta $3e
ldx $3d
lda $1000,x
…Final Fantasy IV Disassembly · field/event.asm#L77-L121@e236: cmp #$eb
bne @e25a
inx
lda f:EventScript,x
sta $0a15
inx
lda f:EventScript,x
sta $07
inx
@e24a: lda f:EventScript,x
sta $09d5,y
inx
…Final Fantasy IV Disassembly · field/event.asm#L1576-L1592; [ event command $f8: show dialogue (yes/no) ]
EventCmd_f8:
@ed71: jsr GetNextEventByte
sta $b2
jsr GetDlgPtr1H
jsr OpenDlgWindow
jsr ShowYesNoWindow
jsr CloseDlgWindow
jsr WaitVblankShort
jsr HideDlgWindow
lda $db
beq @ed93
…Final Fantasy IV Disassembly · field/event.asm#L469-L478FindEventTerminator:
@e55a: ldx $09d3 ; event script pointer
inx
@e55e: lda f:EventScript,x ; event scripts
cmp #$ff
beq @e56a
inx
jmp @e55e
@e56a: stx $09d3
rtsFinal Fantasy IV Disassembly · field/window.asm#L1333-L1339; $03: play song
TextCmd_03:
@b2f6: jsr GetNextByte
sta $1e01
lda #1
sta $1e00
jsl ExecSound_extFinal Fantasy IV Disassembly · battle/battle.asm#L263-L276@80ec: lda $1800
sta $393d ; get pointer to battle properties
lda #8
sta $393f
jsr Mult16
shorta0
ldx $3941
clr_ay
@8103: lda f:BattleProp,x
sta $299c,y ; load battle properties
iny
inx
…Final Fantasy IV Disassembly · battle/init.asm#L28-L29lda $29a2
sta $38e5Final Fantasy IV Disassembly · battle/battle.asm#L393-L400@8219: lda $38e5 ; battle song
and #$0c
lsr2
cmp #$03
beq @822d ; branch if no battle music
tax
lda f:BattleSongTbl,x
jsl PlayBattleSongFinal Fantasy IV Disassembly · battle/battle_data.asm#L373-L375; battle songs
BattleSongTbl:
@ff0c: .byte $27,$1a,$0bFinal Fantasy IV Disassembly · btlgfx/btlgfx.asm#L3343-L3346_03f591:
@f591: lda #$42
sta $38be
inc $38bdFinal Fantasy II (USA) (Rev 1) · 0xb71-0xb7b — the world song table (3 bytes), the vehicle song table (7 bytes), and the byte after them, $8D, which is no song numberFinal Fantasy II (USA) (Rev 1) · 0x90000-0x9668a — $12:8000-$12:E68A, segment event_data1, no line: The 256 event scripts and their pointers.Final Fantasy II (USA) (Rev 1) · 0x80000-0x87e20 — $10:8000-$10:FE20, segment event_dlg1, no line: The first bank of event dialogue: 512 messages and their pointers.Final Fantasy II (USA) (Rev 1) · 0x9a500-0x9cd8f — $13:A500-$13:CD8F, segment event_dlg2, no line: The second bank of event dialogue: 256 messages and their pointers.Final Fantasy II (USA) (Rev 1) · 0x88000-0x8fffa — $11:8000-$11:FFFA, segment map_dlg, no line: The map dialogue: message lists for 384 maps and their pointers.Final Fantasy II (USA) (Rev 1) · 0x76700-0x770b8 — $0E:E700-$0E:F0B8, segment ai_data, no line: The monster AI conditions, then the monsters' action lists.Final Fantasy II (USA) (Rev 1) · 0x736c0-0x73989 — $0E:B6C0-$0E:B989, segment monster_prop, no line: Monster actions for the moon's battles.Final Fantasy II (USA) (Rev 1) · 0x70000-0x70fff — $0E:8000-$0E:8FFF, segment battle_prop, no line: The properties of the 512 battles: up to three monster types and how many of each, their positions and the cursor's, the song, whether the party can run, and the other battle flags.Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L1928-L2108"eventScript": {
"type": "array",
"name": "Event Script",
"range": "0x128200-0x12E68A",
"arrayLength": 256,
"asmSymbol": "EventScript",
"file": "field/data/event_script_en.asm",
"assembly": {
"type": "script",
"encoding": "event"
},
"pointerTable": {
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L9020-L9033"song": {
"name": "Play Song",
"category": "Sound",
"opcode": ["0xEA", "0xFA"],
"length": 2,
"assembly": {
"song": {
"type": "property",
"name": "Song",
"begin": 1,
"stringTable": "songScripts"
}
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L8950-L8967"repeat": {
"name": "Repeat",
"category": "Control",
"opcode": "0xEB",
"length": 3,
"assembly": {
"count": {
"type": "property",
"name": "Count",
"begin": 1
},
"length": {
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L8715-L8730"dialogYesNo": {
"name": "Show Dialog (Yes/No)",
"category": "Dialog",
"opcode": "0xF8",
"length": 2,
"assembly": {
"dialog": {
"type": "property",
"name": "Dialog",
"begin": 1,
"offset": 256,
"stringTable": "eventDialog1",
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L1884-L1905"eventDialog1": {
"type": "array",
"name": "Event Dialogue 1",
"range": "0x108400-0x10FE20",
"arrayLength": 512,
"file": "field/text/event_dlg1_en.asm",
"asmSymbol": "EventDlg1",
"assembly": {
"type": "text",
"name": "Event Dialogue 1-%i",
"encoding": "dialog",
"multiLine": true
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L1906-L1927"eventDialog2": {
"type": "array",
"name": "Event Dialogue 2",
"range": "0x13A700-0x13CD8F",
"arrayLength": 256,
"file": "field/text/event_dlg2_en.asm",
"asmSymbol": "EventDlg2",
"assembly": {
"type": "text",
"name": "Event Dialogue 2-%i",
"encoding": "dialog",
"multiLine": true
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L3132-L3153"mapDialog": {
"type": "array",
"name": "Map Dialogue",
"range": "0x118300-0x11FFFA",
"arrayLength": 384,
"asmSymbol": "MapDlg",
"file": "field/text/map_dlg_en.asm",
"assembly": {
"type": "array",
"terminator": "\\0",
"assembly": {
"type": "text",
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L9644-L9665"text": {
"name": "Text",
"char": {
"0x01": "\\n",
"0x03": "\\song[",
"0x0400": "\\char00",
"0x0401": "\\char01",
"0x0402": "\\char02",
"0x0403": "\\char03",
"0x0404": "\\char04",
"0x0405": "\\char05",
"0x0406": "\\char06",
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L4564-L4701"monsterAction": {
"type": "array",
"name": "Monster Action",
"range": "0x0EE900-0x0EF0B8",
"terminator": "0xFF",
"arrayLength": 254,
"asmSymbol": "AIAction1",
"file": "battle/data/ai_action1_en.asm",
"assembly": {
"type": "script",
"encoding": "monsterAction"
},
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L4702-L4797"monsterActionMoon": {
"type": "array",
"name": "Monster Action (Moon)",
"range": "0x0EB6C0-0x0EB989",
"terminator": "0xFF",
"arrayLength": 89,
"asmSymbol": "AIAction2",
"file": "battle/data/ai_action2_en.asm",
"assembly": {
"type": "script",
"encoding": "monsterAction"
},
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L9299-L9311"song": {
"name": "Play Song",
"opcode": "0xF3",
"length": 2,
"assembly": {
"song": {
"type": "property",
"name": "Song",
"begin": 1,
"stringTable": "song"
}
}
…Final Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L1009-L1146"battleProperties": {
"type": "array",
"name": "Battle Properties",
"range": "0x0E8000-0x0E8FFF",
"arrayLength": 512,
"itemLength": 8,
"asmSymbol": "BattleProp",
"file": "battle/data/battle_prop_en.asm",
"assembly": {
"type": "assembly",
"name": "Battle %i",
"editor": "FF4BattleEditor",
…Each of the 224 monsters has a property block that starts with its level (the top bit marks a boss), its HP, three indexes into a table of three-byte triples (a multiplier, a rate, and a value) for its attack, defense, and magic defense, an index into a table of agility ranges, and a byte whose low six bits pick its item set and top two bits its drop odds; experience and gil sit in tables of two bytes per monster. When a battle starts, the game copies the level, sets current and maximum HP to the HP, sets MP to the HP divided by 16, rolls agility between the range's two values, and copies the attack triple; for defense and magic defense it stores the rate byte and then the value at the same address, so the value overwrites the rate. HP runs from 1 (Shadow) to 65,500 (Golbez) and experience up to 65,000 (Mind); 64 monsters have the boss bit. CodeFinal Fantasy IV Disassembly · battle/ai.asm#L294-L338cmp #$f9
beq @b670
cmp #$e8
bcc @b67b
cmp #$fb
bcs @b67b
cmp #$f0
bcs @b65f
; $e8-$ef: change monster stat
pha
inx
lda $3839,x
…Final Fantasy IV Disassembly · battle/ai.asm#L1233-L1242CopyGfxScript:
@bc1e: ldx $38bb
clr_ay
@bc23: lda $3839,y
sta $3659,x
inx
iny
cpy #$003c
bne @bc23
rtsFinal Fantasy IV Disassembly · btlgfx/btlgfx.asm#L2740-L2746; [ graphics script command $f3: play song ]
GfxScriptCmd_f3:
@cc32: jsr GetNextGfxScriptByte
sta $38be
inc $38bd
rtsFinal Fantasy IV Disassembly · btlgfx/summon.asm#L49-L55@f133: lda $38bd
beq @f14a ; branch if no song change
lda $38be ; song id
sta $1e01
lda #$01 ; play song
sta $1e00
jsl ExecSound_extFinal Fantasy IV Disassembly · field/title_en.asm#L26-L36; [ show title screen ]
ShowTitle:
@85fa: jsr ScreenOff
stz $420b
stz $420c
lda #$01 ; spc command $01 (play song)
sta $1e00
lda #$15 ; song $15 (the prelude)
sta $1e01
jsl ExecSound_extFinal Fantasy IV Disassembly · menu/load.asm#L75-L82; [ game load menu main ]
GameLoadMenu_main:
@95f8: lda #$15 ; song $15 (the prelude)
sta $1e01
lda #$01 ; play song
sta $1e00
jsl ExecSound_extFinal Fantasy IV Disassembly · cutscene/cutscene.asm#L2740-L2795; [ "THE END" ]
_13ef65:
@ef65: ldx #0
stx $02
stx $04
ldx #$4000
stx $00
stx $06
jsr _13efef
jsr WaitVBlank
lda #$80
sta $a0
…Final Fantasy IV Disassembly · field/vehicle.asm#L663-L670; [ enter big whale ]
EnterWhale:
@a2eb: lda #$0e
sta $1e01
lda #$01
sta $1e00
jsl ExecSound_extFinal Fantasy IV Disassembly · field/special.asm#L979-L998; [ special effect $22: giant of babil 3 ]
Special_22:
@caa5: ldx #$0030
stx $ef
ldx #$00e0
stx $f1
ldx #$0100
stx $f3
ldx #$ffe0
stx $f5
jsr _00cb72
ldx #$0140
…Final Fantasy IV Disassembly · field/special.asm#L2455-L2469; [ special effect $03: red wings attack damcyan ]
Special_03:
@d5f6: lda #$04
sta $0acd
stz $0ace
jsr _00e075
ldx #0
lda #$ff
@d606: sta $0a6d,x
inx4
cpx #$0060
bne @d606
…Final Fantasy IV Disassembly · field/special.asm#L2593-L2594@d72e: lda #$23
jsr PlaySongEventFinal Fantasy IV Disassembly · field/special.asm#L2390-L2434; [ special effect $04: rydia/titan battle and aftermath ]
Special_04:
@d55b: lda #$ec ; rydia/titan battle id
sta $1800
stz $1801
lda $0fdb ; default battle bg
and #$8f
sta $1802
jsr BattleSub
jsr FadeOutSongSlow
jsl InitHWRegs
ldx $1706
…Final Fantasy IV Disassembly · menu/fat_choco.asm#L39-L63; [ fat chocobo menu (whistle) ]
FatChocoWhistle:
@ccb3: lda $1e05 ; save current song id
pha
stz $1b19
lda #$01
sta $1a88
ldx $93
stx $1ba5
lda #$85 ; fade out music (slow)
sta $1e00
jsl ExecSound_ext
…Final Fantasy IV Disassembly · menu/menu.asm#L3727-L3742; [ play fanfare ]
; called when rydia learns a spell from a summon item
PlayFanfare:
@c600: lda $1e05 ; current song
pha
lda #$29 ; song $29 (fanfare)
jsr PlaySong
ldx #330 ; 330 frames (5.5 seconds)
@c60c: jsl WaitVblank_far
dex
bne @c60c
pla
…Final Fantasy IV Disassembly · battle/battle.asm#L1175-L1186; victory
@8728: jsr CheckFanfare
lda $a9
bne @8738
lda $38e5
and #$0c
cmp #$0c
beq @8740 ; branch if no battle music
@8738: lda #$08 ; victory fanfare
sta $38be
inc $38bd
@8740: jsr ClearWinStatusFinal Fantasy IV Disassembly · btlgfx/monster_death.asm#L51-L92; [ battle graphics $10: monster death animations ]
MonsterDeath:
@e8f9: lda $f49a
cmp #$8c
bne @e906
sta $f483
stz $f49a
@e906: lda $f473
bne @e91e
clr_ax
@e90d: lda $29b5,x
cmp $f123,x
…Checked by claude, 2026-10-28 — listed every write of a song number to the sound request: map songs, the world and vehicle tables, event commands $EA and $FA (each event script walked to its last byte by the interpreter's rules: past every $FF, since a yes/no answer jumps past a terminator, and through a repeat's body; each walk lands on its script's last byte), dialogue code $03, monster action $F3 (passed into the battle graphics script), the battle song table, and constants in code; the two routines that replay the song that was playing take it from the sound program's current songRevised after a check by a second AI model, 2026-10-28.The rip config names the songs (for example 39 Battle 1, 13 Main Theme); those are its labels, not in-game text, and the game has no sound test. The where column counts event scripts by number.
Song entries 56 to 61 point to the same 18-byte script as entry 0, and no request found asks for any of them. ff4-tables/song-slots-56-61
About: Final Fantasy IV Music driver
Value: 56, 57, 58, 59, 60, 61
Code notesFinal Fantasy II (USA) (Rev 1) ·0x3721d-0x372ee — $06:F21D: the song table; entries 0 and 56-61 hold the same pointerFinal Fantasy II (USA) (Rev 1) · 0x372ef-0x37300 — song 0's scriptFinal Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L7291-L7368"songScripts": {
"type": "array",
"name": "Song Scripts",
"range": "0x06F2EF-0x08B8B8",
"arrayLength": 70,
"asmSymbol": "SongScript",
"file": "sound/data/song_script.asm",
"pointerTable": {
"range": "0x06F21D-0x06F2EE",
"offset": "0x04C000",
"pointerSize": 3
},
…The song table has 70 entries, each a three-byte pointer to a song's script; this is the game's track listing, by song number, with where the game plays each, from every request found: the song byte of each of the 383 maps, 375 song commands in the event scripts, 49 song control codes in dialogue, 14 song commands in monster action scripts, the battle properties' song field, the world and vehicle song tables, and constants in the field, battle, menu, and cutscene code. 62 entries are requested; no request found reaches 56, 57, 58, 59, 60, 61, 64, 65. Entries 56, 57, 58, 59, 60, 61 point to the same script as entry 0. CodeRevised after a check by a second AI model, 2026-10-28.Song 64 has a script of its own, 201 bytes, but no request found asks for it. ff4-tables/song-64
About: Final Fantasy IV Music driver
Value: 64
Code notesFinal Fantasy II (USA) (Rev 1) ·0x3721d-0x372ee — $06:F21D: the song tableFinal Fantasy II (USA) (Rev 1) · 0x374c6-0x3758e — song 64's scriptFinal Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L7291-L7368"songScripts": {
"type": "array",
"name": "Song Scripts",
"range": "0x06F2EF-0x08B8B8",
"arrayLength": 70,
"asmSymbol": "SongScript",
"file": "sound/data/song_script.asm",
"pointerTable": {
"range": "0x06F21D-0x06F2EE",
"offset": "0x04C000",
"pointerSize": 3
},
…The song table has 70 entries, each a three-byte pointer to a song's script; this is the game's track listing, by song number, with where the game plays each, from every request found: the song byte of each of the 383 maps, 375 song commands in the event scripts, 49 song control codes in dialogue, 14 song commands in monster action scripts, the battle properties' song field, the world and vehicle song tables, and constants in the field, battle, menu, and cutscene code. 62 entries are requested; no request found reaches 56, 57, 58, 59, 60, 61, 64, 65. Entries 56, 57, 58, 59, 60, 61 point to the same script as entry 0. CodeRevised after a check by a second AI model, 2026-10-28.Song 65 has a script of its own, 201 bytes, but no request found asks for it. ff4-tables/song-65
About: Final Fantasy IV Music driver
Value: 65
Code notesFinal Fantasy II (USA) (Rev 1) ·0x3721d-0x372ee — $06:F21D: the song tableFinal Fantasy II (USA) (Rev 1) · 0x3758f-0x37657 — song 65's scriptFinal Fantasy IV Disassembly · vanilla/ff4-en-rip.json#L7291-L7368"songScripts": {
"type": "array",
"name": "Song Scripts",
"range": "0x06F2EF-0x08B8B8",
"arrayLength": 70,
"asmSymbol": "SongScript",
"file": "sound/data/song_script.asm",
"pointerTable": {
"range": "0x06F21D-0x06F2EE",
"offset": "0x04C000",
"pointerSize": 3
},
…The song table has 70 entries, each a three-byte pointer to a song's script; this is the game's track listing, by song number, with where the game plays each, from every request found: the song byte of each of the 383 maps, 375 song commands in the event scripts, 49 song control codes in dialogue, 14 song commands in monster action scripts, the battle properties' song field, the world and vehicle song tables, and constants in the field, battle, menu, and cutscene code. 62 entries are requested; no request found reaches 56, 57, 58, 59, 60, 61, 64, 65. Entries 56, 57, 58, 59, 60, 61 point to the same script as entry 0. CodeRevised after a check by a second AI model, 2026-10-28.