BF

From Amicitia Wiki
Jump to navigation Jump to search
BF Format
Purpose Message/Script Format
Games Persona 3
Persona 3 Portable
Persona 4
Persona 4 Golden
Persona Q
Persona 5
Developer Atlus

BF is a binary format compiled from scripts created by Atlus. Logic during gameplay in almost all Persona games and several other Atlus entries is completely handled by BF files. For example, enemy AI, setting and checking flags for displaying dialog, starting scripted battles etc.

BF files usually also contain and reference BMD files (Atlus's compiled message format).

Tools[edit]

AtlusScriptToolchain[edit]

TGE'S AtlusScriptToolchain can manage BF files.

AtlusScriptCompiler[edit]

AtlusScriptCompiler is a commandline program that is part of the AtlusScriptToolchain. By providing the following arguments, for example, you can decompile a BF binary to an editable .flow (flowscript). Any embedded BMD files also get decoded to .msg (messagescript) in the process. Both can be modified using a text editor like Notepad++.

AtlusScriptCompiler.exe input.bf -Decompile -Library P5 -Encoding P5


You can then recompile the .flow (and any other included .flow or .msg files referenced in the .flow) into a new BF file using commandline arguments:

AtlusScriptCompiler.exe input.bf.flow -Compile -OutFormat V3BE -Library P5 -Encoding P5


The compiler can be downloaded here, along with a GUI that allows you to drag and drop files to compile/decompile them automatically without needing to use commandline arguments.

BFMessageScriptEditor[edit]

The compiler is a perpetual work in progress and does not always recompile flowscripts with 100% accuracy. As a result, unexpected glitches may occur ingame. One workaround, if you're only interested in editing the script's text, is to use the BFMessageScriptEditor program. Simply drag a BF file onto the exe to extract a .msg (messagescript), edit it with your text editor of choice, and drag it onto the exe when you're done. This will replace the embedded BMD in the BF without recompiling the script itself.

Format Specs[edit]

Header[edit]

Uses the common header structure used in other files.

Offset Type Description
0x0 U8 File type. Always 0 for BF
0x1 U8 Compression flag. Very rarely used on archives.
0x2 U16 User ID. Always 0 but can be set to any value. Doesn't appear to be used.
0x4 U32 File size.
0x8 U32 Magic identifier. Always "FLW0"
0xC U32 Reserved. Stores the size in memory. This value is calculated during runtime.
0x10 U32 Number of entries of this type table. (Could be U16)
0x14 U16 Unknown count
0x16 U8[10] Padding

Type Table Types[edit]

Describes a type of content in the BF file. In most BF files, there's 5 of these entries.

Offset Type
0 Procedure entries
1 Label entries
2 Instruction data
3 Message script data
4 String data

Label or Procedure Entry[edit]

Labels and procedures are essentially the same with the only difference being their usage semantics.

Offset Type Description
0x0 U8[40] Name of the label or procedure
0x28 U32 Entry point. Opcode index from which the procedure starts
0x2C U32 Reserved. Not verified but it is most likely used to store a runtime value

Procedures, or functions can take in arguments or return values. These however are processed at runtime.
Labels, or jump labels are equivalent to goto's in C-like languages. They directly jump to a location in the current procedure.

Instruction Entry[edit]

An instruction is made up out of an opcode and operand(s).

Offset Type Description
0x0 U16 Opcodes. See opcodes below
0x2 U16 Reserved. Can be used as operand.

Opcodes[edit]

The opcode tells the game's interpreter what to do, and the operands are the data the interpreter processes on.

Value Name Description
0 PUSHI Push integer value onto the stack
1 PUSHF Push float value onto the stack
2 PUSHIX Push integer value onto the stack
3 PUSHIF Push float value onto the stack
4 PUSHREG Push result of a native function onto the stack
5 POPIX Pop integer index from the stack
6 POPFX Pop float index from the stack
7 PROC Begin procedure
8 COMM Call a native function in the game by index
9 END End branch. Used to return from procedures and exit statements such as if, loop, etc. Comparable to 'return' and 'break' in C
10 JUMP Jump to a procedure by index. Comparable to 'goto' in C languages. Does not store the return address.
11 CALL Call into a procedure by index. Pushes the return address to the stack.
12 RUN Not seen
13 GOTO Jump to a label by index. Comparable to 'goto' in C languages
14 ADD Pop 2 values off the stack, calculate the sum and push the result onto the stack
15 SUB Pop 2 values off the stack, subtract the left hand value from the right hand value and push the result onto the stacK
16 MUL Pop 2 values off the stack, multiply them and push the result onto the stack
17 DIV Pop 2 values off the stack, divide the left hand value with the right hand value and push the result onto the stack
18 MINUS Pop a values off the stack, negates it and pushes the result onto the stack
19 NOT Pop a value off the stack, bitwise NOT the value and push the result onto the stack
20 OR Pop 2 values off the stack, bitwise OR the left hand value with the right hand value and push the result onto the stack
21 AND Pop 2 values off the stack, bitwise AND the left hand value with the right hand value and push the result onto the stack
22 EQ Pop 2 values off the stack, push 1 if the left hand value is equal to the right hand value, if not, push 0 to the stack
23 NEQ Pop 2 values off the stack, push 1 if the left hand value is not equal to the right hand value, if not, push 0 to the stack
24 S Pop 2 values off the stack, push 1 if the left hand value is less than the right hand value, if not, push 0 to the stack
25 L Pop 2 values off the stack, push 1 if the left hand value is greater than the right hand value, if not, push 0 to the stack
26 SE Pop 2 values off the stack, push 1 if the left hand value is less than or equal to the right hand value, if not, push 0 to the stack
27 LE Pop 2 values off the stack, push 1 if the left hand value is greater than or equal to the right hand value, if not, push 0 to the stack
28 IF Pop a value off the stack and check if it isn't zero. If it is zero then jump to the specified label by index
29 PUSHIS Push short integer value onto the stack
30 PUSHLIX Push the value of the specified integer index onto the stack
31 PUSHLFX Push the value of the specified float index onto the stack
32 POPLIX Pop an integer value off the stack and store it in the specified integer index
33 POPLFX Pop a float value off the stack and store it in the specified float index
34 PUSHSTR Push the start index of a null terminated string in the string table to the stack

Depending on the opcode either no operands are used, the reserved field is used as an operand or the next 4 bytes are used.