This is the table that actually drives the monster configurations that your party will be confronted with over the course of the adventure.
Primary Table location: 0×2288b4 — 0xx22a587.
Data structure size: 0×14, or 20 bytes per record.
Number of records: 0×171, or 369 battle records.
I should note that there is a separate version of the table in 0×22d3e4 — 0×22f0b7. You will need to modify both to be sure of getting the changes you desire.
Another interesting tidbit is that the first 256 Battle Records (IDs 0×000 — 0×0ff) are battles that may show up in the standard overworld map, or standard dungeons (defined as dungeons that were in the NES version of Final Fantasy). Battle records with IDs of 0×100 or greater may only be assigned to Dawn of Souls dungeons.
Note that the Battle ID is not present in the Battle Record table, and is provided here merely for reference.
Battle ID | Config | Run? | Preempt | Zeroes | Monster #1 | Monster #2 | Monster #3 | Monster #4 |
000 | 00 | 00 | 04 | 00 | 00 03 05 00 | 01 00 00 00 | ff 00 00 00 | ff 00 00 00 |
3-5 Goblins | 0 Goblin Guards | |||||||
00e | 01 | 00 | 21 | 00 | 01 00 05 00 | 04 01 03 00 | 09 00 02 00 | 06 00 02 00 |
0-5 Goblin Guards | 1-3 Werewolves | 0-2 Hill Gigases | 0-2 Lizards | |||||
022 | 02 | 01 | 37 | 00 | 1a 00 01 00 | 1d 01 02 00 | ff 00 00 00 | ff 00 00 00 |
0-1 Hellhounds | 1-2 Ogre Mages | |||||||
04a | 05 | 00 | 04 | 00 | 51 00 08 00 | 52 00 08 00 | 50 01 05 00 | 4f 00 08 00 |
0-8 Cockatrices | 0-8 Pyrolisks | 1-5 King Mummies | 0-8 Mummies | |||||
07d | 04 | 01 | 04 | 00 | 71 01 01 00 | ff 00 00 00 | ff 00 00 00 | ff 00 00 00 |
1 Astos |
If you’ve played Final Fantasy at all, you may have noticed that certain monsters are larger than others. Others are really big. This forces the game engine to position monsters differently, based on the kinds of monsters that are present. This byte alerts the engine to the kinds of monsters present. Editing Battle Regions requires a knowledge of the sizes of the various critters in the game; the game knows which monsters are small, which are large, and which are boss-sized, and based on the Configuration byte will load valid monsters. If a battle record provides no valid monsters for its Battle Configuration, Very Bad Things will happen (game execution will probably freeze). Be careful!
It can’t get much simpler than this… this is 00 if you can run, and 01 if you can’t.
This is the chance that your party won’t be able to react in the first round of battle against these monsters; higher values increase the chance of monsters striking first. I am not sure if this chance is out of 100, or some other hexidecimal friendly number.
Each battle can feature up to four types of monsters. The final four groups of four bytes determine which monster is encountered, along with how many may appear. All four groups follow these same conventions, but again, it is unwise to have all of these monsters set to null (meaning ff 00 00 00, or any time that the final three bytes are 00 00 00).
The first byte is the Monster ID referenced. See the Bestiary article to look up individual Monster IDs.
The second byte is the minimum number of that monster that can be encountered. The third byte is the maximum number that can be encountered. The fourth byte is always 00. Again, make sure at least one monster has a “minimum encountered” value of at least 1; an encounter yielding no monsters is untested and could lead to Very Bad Things.
It is safe to reference more monsters of a specific size than can be displayed; the excess monsters simply are ignored when setting up the battle.
Note Battle ID #4a above, this is a very interesting case! There is a potential of 29 monsters being placed (8 Cockatrices, 8 Pyrolisks, 5 King Mummies, and 8 Mummies). The monsters are placed in a first come, first served format. It loads Cockatrices first, then Pyrolisks, then King Mummies, and finally Mummies. Thus, it is possible that you will not face King Mummies (even though there is a minimum of one, as defined by the record), because it is very possible to encounter 9 or more Cockatrices and Pyrolisks combined.
]]>First, you need a little bit of background. Final Fantasy assigns a “Battle Region” to your position, based on your location on the overworld map, or which dungeon labyrinth your party is exploring. Each region has eight battle configurations defined. Final Fantasy rolls a number between 0×01 and 0×40 (1 — 64), and based on this random number decides which monsters jump your hapless characters (this is defined in a Battle Record).
This is the table that defines what our random number between 1 — 64 means.
Table location: 0×2170a0 — 0×2170df.
Data structure size: 64 bytes.
In stock FF1, this is what the table looks like:
0×2170a0 — 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01
0×2170b0 — 01 01 01 01 01 01 01 01 02 02 02 02 02 02 02 02
0×2170c0 — 02 02 02 02 03 03 03 03 03 03 03 03 03 03 03 03
0×2170d0 — 04 04 04 04 04 04 05 05 05 05 05 05 06 06 06 07
What do these values mean? Each byte has a value between 00 and 07. If you count the instances of each value, we arrive at this:
So, battle #1 through #4 show up 12/64 of the time on average. Battles #5 and #6 show up 6/64 of the time on average. Battle #7 shows up show up 3/64 of the time, and battle #8 is quite rare… it has only a 1/64 chance of showing up.
]]>Every enemy has, in its bestiary definition, a defined AI ID. Changing this does not actually have any discernable effect; I’m not sure why that byte is in the monster definition. I’m not arguing, because it provided me a clue as to how to find the following table: the AI IDs are found at 0×22f0b8 to 0×22f17a. This is a span of 195 bytes, so each monster gets exactly one byte. The bytes are listed in monster ID order, so you’ll need to refer back to the bestiary entry to get the listing for the various IDs.
It will be noted that the value 2c is plentiful. That’s because this value is set to “fight 100% of the time”.
To save you the trouble of figuring out what each ID refers to, I’ve got a handy-dandy chart showing the first monster to use each AI ID.
0×00 | Winter Wolf | Fire Lizard | Basilisk | Big Eyes |
0×04 | Deep Eyes | Hellhound | Ogre Mage | Sand Worm |
0×08 | Evil Eye | Death Eye | Rakshasa | Vampire |
0×0c | Vampire Lord | Horned Devil | White Dragon | Red Dragon |
0×10 | Pyrolisk | Fire Hydra | Water Naga | Spirit Naga |
0×14 | Chimera | Rhyos | Mindflayer | Green Dragon |
0×18 | Blue Dragon | Clay Golem | Stone Golem | Iron Golem |
0×1c | Death Knight | Dark Wizard | Dark Fighter | Nightmare |
0×20 | Death Machine | Manticore | Lich | Lich (Chaos) |
0×24 | Marilith | Marilith (Chaos) | Kraken | Kraken (Chaos) |
0×28 | Tiamat | Tiamat (Chaos) | CHAOS | Astos |
0×2c | —— | Echidna | Cerberus | Ahriman |
0×30 | Scarmiglione (cloaked) | Scarmiglione (undead) | Cagnazzo | Barbariccia |
0×34 | Rubicante | Gilgamesh | Omega | Shin Ryuu |
0×38 | Atomos | Typhon | Orthros | Phantom Train |
0×3c | Death Gaze | Devil Wizard | Holy Dragon | Bloody Eye |
0×40 | Black Dragon | Earth Plant | Yamatano Orochi | Dark Elemental |
0×44 | Prototype |
Table location: 0×22f17c — 0×22f5cb.
Data structure size: 16 bytes per AI entry.
AI Record | Spell % | Ability % | Spell Queue | FF | Ability Queue | FF | |
03— Big Eyes | 00 | 80 | ff ff ff ff ff ff ff ff | ff | 03 03 03 03 | ff | |
06— Ogre Mage | 40 | 00 | 04 26 22 2a 30 ff ff ff | ff | ff ff ff ff | ff | |
28— Tiamat | 00 | 40 | ff ff ff ff ff ff ff ff | ff | 11 10 0a 0b | ff | |
29— Tiamat (Chaos) | 40 | 40 | 32 30 2b 29 32 30 2b 29 | ff | 11 10 0a 0b | ff |
These values I’ve misnamed a bit, as they are not technically “percent” values. IIRC, the game first checks to see whether the monster casts a spell. A random number is rolled between 1 and 0×80, or 128, and if this number is less than the value stated in Spell %, then the next spell in the individual monster’s queue is cast.
If the monster didn’t cast a spell, then the game checks whether it used an ability. This is done in the same manner, using another number rolled between 1 and 128.
Of course, if the monster didn’t cast a spell and didn’t use an ability, then it will attack. And a 00 in these values guarantees that the monster will fail its check to use a spell or use an ability (depending on where the 0×80 is placed).
Each AI is allotted a queue of up to eight spells, and up to four monster abilities. A monster may be able to cast spells, use abilities, and some intrepid critters can even do both of these things.
The first time a monster uses a spell, the game picks the first spell in the queue, and that’s the monster’s action. The second time a monster casts a spell, the second spell is used. When it reaches the end of the list (denoted by ff), the list gets reused. Setting the Spell (or Ability) % to a non-zero number, and setting the Spell (or Ability) Queue to all ff‘s will very likely lead to Very Bad Things. Don’t do this, it isn’t nice.
For help in figuring out what values correspond to which Spells or Monster attacks, you’ll need to refer back to the Spells and Monster Attacks article. The IDs listed there for the Spells is accurate. The IDs for Monster Abilities listed in that page do not correspond to the values in the AI table. To calculate what the IDs should be in the Ability Queue, take the ID from the Spells and Monster Attacks article and subtract 0×41.
]]>As with other lists, before I get into defining monster characteristics, I will list out the monsters in Final Fantasy 1, in ID order. This is the order that they are listed in the Bestiary. The Bestiary # and the monster IDs below are not related.
0×00 | Goblin | Goblin Guard | Wolf | Warg Wolf |
0×04 | Werewolf | Winterwolf | Lizard | Fire Lizard |
0×08 | Basilisk | Hill Gigas | Ice Gigas | Fire Gigas |
0×0c | Sahagin | Sahagin Chief | Sahagin Prince | Pirate |
0×10 | Buccaneer | Shark | White Shark | Bigeyes |
0×14 | Deepeyes | Skeleton | Bloodblones | Gigas Worm |
0×18 | Crawler | Hyenadon | Hellhound | Ogre |
0×1c | Ogre Chief | Ogre Mage | Cobra | Anaconda |
0×20 | Sea Snake | Scorpion | Sea Scorpion | Minotaur |
0×24 | Minotaur Zombie | Troll | Sea Troll | Shadow |
0×28 | Wraith | Specter | Ghost | Zombie |
0×2c | Ghoul | Ghast | Wight | Purple Worm |
0×30 | Sand Worm | Lava Worm | Evil Eye | Death Eye |
0×34 | Medusa | Earth Medusa | Weretiger | Rakshasa |
0×38 | Ankheg | Remorazz | Lesser Tiger | Sabertooth |
0×3c | Vampire | Vampire Lord | Gargoyle | Horned Devil |
0×40 | Earth Elemental | Fire Elemental | White Dragon | Red Dragon |
0×44 | Dragon Zombie | Green Slime | Grey Ooze | Ochre Jelly |
0×48 | Black Flan | Black Widow | Tarantula | Manticore |
0×4c | Sphinx | Baretta | Desert Baretta | Mummy |
0×50 | King Mummy | Cockatrice | Pyrolisk | Wyvern |
0×54 | Wyrm | Allosaurus | Tyrannosaur | Pirahna |
0×58 | Red Pirahna | Crocodile | White Croc | Ochu |
0×5c | Neochu | Hydra | Fire Hydra | Guardian |
0×60 | Soldier | Water Elemental | Air Elemental | Water Naga |
0×64 | Spirit Naga | Chimera | Rhyos | Piscodemon |
0×68 | Mindflayer | Garland | Green Dragon | Blue Dragon |
0×6c | Clay Golem | Stone Golem | Iron Golem | Black Knight |
0×70 | Death Knight | Astos | Dark Wizard | Dark Fighter |
0×74 | Crazy Horse | Nightmare | Death Machine | Lich |
0×78 | Lich (Chaos) | Marilith | Marilith (Chaos) | Kraken |
0×7c | Kraken (Chaos) | Tiamat | Tiamat (Chaos) | CHAOS |
0×80 | Echidna | Cerberus | Ahriman | 2-Headed Dragon |
0×84 | Scarmiglione (cloaked) | Scarmiglione (undead) | Cagnazzo | Barbariccia |
0×88 | Rubicante | Gilgamesh | Omega | Shin Ryuu |
0×8c | Atomos | Typhon | Orthros | Phantom Train |
0×90 | Death Gaze | Devil Wizard | Abyss Worm | Elm Gigas |
0×94 | Flare Gigas | Unicorn | Yellow Ogre | Mad Ogre |
0×98 | Mage Chimera | Yellow Dragon | Holy Dragon | Mythril Golem |
0×9c | Killer Shark | Death Manticore | Blood Tiger | Dark Eye |
0xa0 | Bloody Eye | Flood Gigas | Poison Eagle | Black Goblin |
0xa4 | Knocker | Desert Pede | Gloom Widow | Duel Knight |
0xa8 | Squidkraken | Pharoah | Bonesnatch | Silver Dragon |
0xac | Black Dragon | Blue Troll | Earth Troll | Poison Naga |
0xb0 | Earth Plant | Yamatano Orochi | Dark Elemental | Devil Hound |
0xb4 | Sekhret | Catoblepas | Hundlegs | Undergrounder |
0xb8 | Death Elemental | Wild Nakk | Dark Wolf | Rock Gargoyle |
0xbc | Sahagin Queen | Reaper | Python | Skuldier |
0xc0 | Red Flan | Prototype | Revenant |
Table location: There are four separate instances of the FF1 bestiary stored in the ROM. You’ll need to edit all four to make intelligible changes to the monsters.
Data structure size: 32 bytes per monster.
This means that each table is 0×1860 bytes in size. With a good hex editor, you can change one table, copy it, and paste that table over the others.
Monster | Exp. | Gil | HP | Cowardice | AI byte | Evasion | Defense | # of hits | Hit Rate | Attack | Agility | Intellect | Luck |
Goblin | 0600 | 0600 | 0800 | 6a | ff | 06 | 04 | 01 | 02 | 04 | 03 | 01 | 01 |
Warg Wolf | 5d00 | 1600 | 4800 | 6c | ff | 36 | 00 | 01 | 12 | 0e | 1b | 03 | 01 |
Werewolf | 8700 | 4300 | 4400 | 78 | ff | 2a | 06 | 01 | 11 | 0e | 15 | 08 | 01 |
Death Machine | 007d | 007d | d007 | c8 | 20 | 60 | 50 | 02 | c8 | 80 | 30 | 32 | 01 |
Minotaur | e901 | e901 | a400 | 7c | ff | 30 | 04 | 02 | 29 | 16 | 18 | 08 | 01 |
Monster | Cond? | Inflict | Family | Magic Def. | Weakness | Resist | Item drop | Drop % | Zeroes |
Goblin | 00 00 | 00 | 04 | 10 00 | 00 00 | 00 00 | 00 00 | 00 | 00 00 00 |
Warg Wolf | 00 00 | 00 | 00 | 2e 00 | 00 00 | 00 00 | 01 0b | 04 | 00 00 00 |
Werewolf | 02 01 | 04 | 91 | 2D 00 | 00 00 | 00 00 | 00 00 | 00 | 00 00 00 |
Death Machine | 00 00 | 00 | 80 | c8 00 | 00 00 | fb 3f | 03 1b | 05 | 00 00 00 |
Minotaur | 00 00 | 00 | 00 | 5f 00 | 00 00 | 00 00 | 02 02 | 06 | 00 00 00 |
I’m not exactly sure exactly how this byte works, but it has a definite effect on the threshold when a monster runs from the party. The higher the value, the more powerful the party needs to be for it to run, and the less likely it is to run.
This byte is the ID of the AI entry from which the monster will pick its special attacks. See an explanation of the AI table here.
I do not know what effect these values have, but they seem to be non-zero when a monster has a condition inflict bound to their physical attack.
This byte controls which condition or conditions might be inflicted in the event of a successful physical attack. The Werewolf is illustrative here:
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
Confuse | Mute | Sleep | Stun | Blind | Poison | Stone | Kill |
The 8 bits that make up this byte specify which families this monster is a member of. Let’s look at the Werewolf.
91 = | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | |
Regenerating | Magical | Aquatic | Lycanthrope | Undead | Giant | Dragon | Evil |
The Werewolf regenerates, and is a Lycanthrope, as well as Evil. It’s important to note that “Regenerating” is both a property as well as a Family designation… if this bit is set, the monster will regain about 5% of its maximum HP every turn.
The Weakness and Resist bytes follow the same bit pattern. This also is the same bit pattern as found in the Weapons structure and the Armor structure. To illustrate these bytes, let’s take a look at the Death Machine’s Resist bytes:
Byte 1— fb = | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | |
Quake | Lightning | Ice | Fire | Death | Time | Stone | Stun | ||
Byte 2— 3f = | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | |
—- | —- | Mind | Confuse | Silence | Sleep | Blind | Poison |
So we see that the only attack that a Death Machine does not resist outright are Time-based attacks (Stop spell, for instance).
The first Item Drop byte specifies the item type that will be dropped. A 0×01 denotes a consumable item, a 0×02 signifies a weapon, and a 0×03 references an armor.
The second Item Drop byte specifies the ID of the item from the correct table. Therefore an Item Drop combo of 02 03 would drop a Staff (ID 0×03 from the Weapon table.
The Drop % byte, predictably, is the percentage chance for the specified item to drop. Each individual monster has a chance to drop an item, and you can receive more than one item in a single battle.
]]>0×1e09b0 — 0×1e0a95. This is the important table, the one that the game seems to use exclusively.
0×1dfc9c — 0×1dfd81. It is unclear to me why this bit-for-bit equivalent table is found in the ROM, but it does not seem to serve any purpose.
The data structure size is variable, and is driven by the shop pointer table. Again, this will be discussed later.
To illustrate the merchandise available in all the shops in Final Fantasy 1 DOS, I’ve decided to list the data in a table format that shows exactly where to find the data, and the data you’ll find there. I have not ascertained exactly where some of the shops are, as some of them are in Dawn of Souls dungeons. There are 51 shops in the game.
Hex | Location | Merchandise | Hex Data |
0×1e09b0 | Coneria | Weapons | FD 01 02 03 04 05 |
0×1e09b6 | Coneria | Armor | FC 01 02 03 |
0×1e09ba | Coneria | Items | FE 01 0b 09 10 |
0×1e09bf | Coneria | White Magic | 01 02 03 04 |
0×1e09c3 | Coneria | Black Magic | 21 22 23 24 |
0×1e09c7 | Pravoka | Weapons | FD 05 06 07 08 |
0×1e09cc | Pravoka | Armor | FC 02 03 04 1c 3a |
0×1e09d2 | Pravoka | Items | FE 01 04 0b 0d 09 |
0×1e09d8 | Pravoka | White Magic | 05 06 07 08 |
0×1e09dc | Pravoka | Black Magic | 25 26 27 28 |
0×1e09e0 | Elfheim | Weapons | FD090a0b0c |
0×1e09e5 | Elfheim | Armor | FC040b1d2a2b |
0×1e09eb | Elfheim | Items | FE010b0c0e11 |
0×1e09f1 | Elfheim | White Magic, Lv. 3 | 090a0b0c |
0×1e09f5 | Elfheim | White Magic, Lv. 4 | 0d0e0f10 |
0×1e09f9 | Elfheim | Black Magic, Lv. 3 | 29 2a 2b 2c |
0×1e09fd | Elfheim | Black Magic, Lv. 4 | 2d 2e 2f 30 |
0×1e0a01 | Melmond | Weapons | FD 0b 0c 0d 0f |
0×1e0a06 | Melmond | Armor | FC 05 0c 2c 3b 3c |
0×1e0a0c | Melmond | White Magic | 11 12 13 14 |
0×1e0a10 | Melmond | Black Magic | 31 32 33 34 |
0×1e0a14 | Crescent Lake | Weapons | FD 10 11 12 13 |
0×1e0a19 | Crescent Lake | Armor | FC 06 1e 23 2d 3d |
0×1e0a1f | Crescent Lake | Items | FE 01 02 04 09 11 |
0×1e0a25 | Crescent Lake | White Magic | 15 16 17 18 |
0×1e0a29 | Crescent Lake | Black Magic | 35 36 37 38 |
0×1e0a2d | Onlac | Items | FE 02 04 0a 0c 12 |
0×1e0a33 | Onlac | White Magic | 1b 1c |
0×1e0a35 | Onlac | Black Magic | 3b 3c |
0×1e0a37 | Gaia | Weapons | FD 23 |
0×1e0a39 | Gaia | Armor | FC 0d 41 |
0×1e0a3c | Gaia | Items | FE 02 04 09 11 12 |
0×1e0a42 | Gaia | White Magic, Lv. 7 | 19 1a |
0×1e0a44 | Gaia | White Magic, Lv. 8 | 1e 1f 20 |
0×1e0a47 | Gaia | Black Magic, Lv. 7 | 39 3a |
0×1e0a49 | Gaia | Black Magic, Lv. 8 | 3e 3f 40 |
0×1e0a4c | Lefein | White Magic | 1d |
0×1e0a4d | Lefein | Black Magic | 3d |
0×1e0a4e | Caravan | Bottle | 0f |
0×1e0a4f | Caravan | Items | 1f 20 21 22 23 |
0×1e0a54 | Dawn of Souls | Items | FD 30 3f FC 1a FE 02 22 |
0×1e0a5c | Dawn of Souls | Items | FD 35 3e FC 17 FE 05 09 |
0×1e0a64 | Dawn of Souls | Items | FD 3a FC 14 28 38 FE 0a |
0×1e0a6c | Dawn of Souls | Items | FD 3b 37 FC 39 29 FE 1c |
0×1e0a74 | Dawn of Souls | White Magic | 19 1a 1b 1c |
0×1e0a78 | Dawn of Souls | White Magic | 1d 1e 1f 20 |
0×1e0a7c | Dawn of Souls | Black Magic | 39 3a 3b 3c |
0×1e0a80 | Dawn of Souls | Black Magic | 3d 3e 3f 40 |
0×1e0a84 | Dawn of Souls | Weapons | FD 21 24 1e 1f 1d |
0×1e0a8a | Dawn of Souls | Armor | FC 0f 10 24 41 3e |
0×1e0a90 | Dawn of Souls | Items | FE 17 18 19 1a 1b |
Merchandise can be preceded by one of three special characters, as can be deduced from the above table. FD denotes that the IDs to follow will denote weapons. FC denotes that the IDs to follow will specify armor, shields, helmets, or gauntlets. FE denotes that the IDs to follow will denote a non-equipable item. If the merchandise is not preceded by one of these special IDs, they pertain to magic spells.
It is possible to have different merchandise types in a store. It is also possible to have more than five items in a store, as the developers allowed for scrolling merchandise windows without any extra hacking!
0×1e070c — 0×1e08a3. This is the real pointer table, that the game uses.
0×1dfb04 — 0×1dfc8b. As above, this bit-for-bit equivalent of the table above is found in the ROM and I do not know why it is there. In my mod, I actually made this table point to the same table as the first pointer table above, without ill effects.
Data structure size: 8 bytes
Let’s take a look at the first record, at 0×1e070c:
15 | 00 00 00 | b0 09 1e 08 |
Contents | Zeroes | Pointer |
This byte is broken up into two 4-bit sections. The first four bits in the above example, rendered as 1, specifies the graphic to be displayed when navigating shop menus. The last four bits, rendered as 5, specify how many bytes to read for this shop. This is not necessarily the number of items sold! This count does not account for any FC’s, FD’s, and FE’s present in the data string. Therefore, a 5 could signify an shop string like this: FD 01 02 03 04 05.
Here’s a list of the Graphic IDs:
Remember, all pointers are stored in Little Endian style, so the above pointer would read data from 0×081e09b0.
]]>