F4C is a comprehensive system for applying patches to the Final Fantasy IV ROM; the main initial output of running the FF4FE generator is a F4C script which in turn is applied to the base ROM to produce the final output. The .f4c file format represents the set of patching instructions to be applied to the ROM.
A .f4c script is parsed using the Lark parser; the technical specifications can be found in f4c/grammar*.lark
.
A .f4c script consists of one or more blocks, specified as a block type, any parameters to the block type in parentheses immediately following the block type identifier, and a body enclosed in braces. Comments are also permissible via a double slash //; these can also be used to create conditionals in the FF4FE context specifically.
As an example, here are the first three blocks of FreeEnt/scripts/randomizer_keyitems.f4c
:
//------------------------------------------------------------------- // set up Hook item consts(item) { $FC fe_Hook } text(item name #fe_Hook) {Hook} //------------------------------------------------------------------- // make PinkPuffs just directly drop Adamant Armor droptable($28) { common #Ether2 uncommon #Elixir rare #NinjaStar mythic // %pink_tail_item const% #AdamantArmor // %end% }
The permissible block types in f4c scripts are as follows:
The consts
block defines constants that can be used by name. The sole parameter is the “family” of constants, which is a namespace used when referring to the constants.
As seen in the above code snippet, references to constants are prefixed with a # character. The #fe_Hook
example above could also be referenced via #item.fe_Hook
.
The event
block defines the script for an FF4 event. The sole parameter is the event ID that the block (re-)defines.
The text
block represents a new piece of text to be used. The parameters define which text is to be set - this can be one of the following:
The trigger
block overwrites or deletes a map trigger. The two parameters are the map number and the number of the trigger to be overwritten or deleted.
The ai_script
block overwrites a monster AI script, The parameters are either a script number by itself for overworld encounters or moon
followed by a script number for underworld/moon encounters.
The placement
block overwrites or removes an NPC placement. The two parameters are a map number and the placement index.
The map
block sets properties of a map. The single parameter is the map number.
The mapgrid
block sets tiles on a map. The three parameters are the map number, X coordinate, and Y coordinate.
The npc
block sets properties of an NPC. The single parameter is the NPC number.
The eventcall
block sets the logic for an event call hook; these hooks are used both by NPCs and map triggers. The single parameter is the event call ID.
The shop
block sets the contents of a shop. The single parameter is the shop ID.
The actor
block sets the properties of an actor - basically a party member slot. The single parameter is the actor ID.
The droptable
block sets the drop table for a monster. The single parameter is the monster ID.
The formation
block sets the properties of a monster formation. The single parameter is the formation ID.
The monster
block sets the properties of an individual monster. The single parameter is the monster ID.
The spellset
block sets a character spellset. The single parameter is the spellset ID.
The patch
block directly specifies new bytes to be written to the ROM. The parameter is a ROM address; as with other ROM address specifications this can be for an address in an unheadered
ROM (the implicit default if not otherwise specified), an address in a headered
ROM, or a bus
address.
The msfpatch
block specifies new assembly instructions in the msf
patch format. This block takes no parameters.
The chr
block adds or overwrites text characters. The parameters are a ROM address (usually a bus
address) and (optionally) the bit depth of the character data (2bit
, 3bit
, or 4bit
(the default)).
The pal
block sets palette data. The parameter is a ROM address.