Format: Mjo script - AtomCrafty/MajiroTools GitHub 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 Signature
V = decrypted
X = 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 for information on bytecode encryption.

The bytecode is a continuous set of 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

WIP

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

Opcode Operands
ldc.i Integer
ldc.r Float
ldstr
ctrl
text
String
st.
stp.
stelem.
stelemp.
ld
ldelem
VarFlags, Hash, VarOffset
call
callp
Hash, Placeholder, ArgCount
syscall
syscallp
Hash, ArgCount
line LineNumber
argcheck
alloca
TypeList
switch CaseOffsets
br
brfalse
brtrue
br.case
bne.case
blt.case
ble.case
bgt.case
bge.case
bsel.1
bsel.2
bsel.3
bsel.4
bsel.5
bsel.x
JumpOffset
add.
sub.
mul.
div.
rem
shl
shr
ceq.
cne.
clt.
cle.
cgt.
cge.
and
andl
or
orl
xor
neg.
not
notl
nop.191
nop.1a8
nop.1a9
conv.
ret
pop
proc
bsel.clr
bsel.jmp.4
(none)

See also

⚠️ **GitHub.com Fallback** ⚠️