Format: Mjo script - AtomCrafty/MajiroTools Wiki

Format: MajoriObj (Mjo) script

Compiled Majiro scenario scripts (and other UI scripts like the console) use the .mjo extension. The extension most often seen for text source scripts is .mjs and .txt.

File structure

Type Value Description
char[16] "MajiroObjV1.000""MajiroObjX1.000" File SignatureV = decryptedX = encrypted
uint32 MainOffset Bytecode offset to $main function
uint32 LineCount1 Number of lines in the script(equal to value of last line instruction)
uint32 FunctionCount Number of functions in following table
Function[Count] Functions Function name hashes and their bytecode offsets
uint32 BytecodeSize Size of following bytecode data.
byte[Size] Bytecode Bytecode instructions (encryption starts here)

[1] : LineCount is only non-zero when the #use_readflg on preprocessor is added to the script before compilation. Essentially only seen in story scripts.

Function structure

Type Value Description
uint32 Hash Hash of original function name
uint32 Offset Bytecode offset to function start

Bytecode structure

See [here](/AtomCrafty/MajiroTools/wiki/Method: XOR cipher#Mjo script key) for information on bytecode encryption.

The bytecode is a continuous set of [instructions](/AtomCrafty/MajiroTools/wiki/List of Majiro IL instructions), each with variable length depending on the opcode.

Instruction structure

Type Value Description
uint16 Opcode Opcode ID that determines how the instruction is read and behaves
... Operands All remaining data depends on the opcode. An instruction can have 0 bytes of operands

Instruction operands


Operand Data Description
Integer int32
JumpOffset int32
Hash uint32
Placeholder uint32 Placeholder for call address after first being run. Must be 0
Float float32
VarOffset int16
VarFlags uint16 (bitmask)
ArgCount uint16 Number of values on stack consumed by function call (first in, last out)
LineNumber uint16 Line number from source script (1-indexed)
String uint16 (N), char[N] N includes the string null terminator.Majiro often treats N==0' as null` for this reason.But there's no evidence of this being supported in scripts.
TypeList uint16 (N), byte[N]
CaseList uint16 (N), int32[N] List of switch case offsets, each absolute offset is calculated relative to the end of the respective offset element.i.e. case\[n\] += OperandOffset + 2 + (n+1) * 4

Instructions by operands

See also