(Information on opcodes provided by Terence Fergusson. Almost all information comes from this post on the forums.)

There are four actions to be explained when dealing with any opcode in AI script: Arguments, Values to take from the stack, what to do with Arguments and Values, and what to put back on the stack. So to fully understand what is happening a brief explanation of the stack is necessary.

The stack is more-or-less a list of values with different lengths. Only the top of the stack (the most recently added value) can be accessed at any given time, but when that value is accessed it is removed from the top of the stack and the previously added value now becomes the top of the stack. Adding to the stack is called “Pushing” a value and taking a value off is called “Popping”. When pushing a value to the stack, the value of the number is pushed followed by the value type. The value type can be one of three different things:

{| border=”1” cellspacing=”1” cellpadding=”3” align=”center” style=”border: 1px solid black; border-collapse: collapse;” ! style=”background:rgb(204,204,204)” align=”center” | Code ! style=”background:rgb(204,204,204)” align=”center” | Type |- | align=”center” | 0Xh | Value |- | align=”center” | 1Xh | Address |- | align=”center” | 2Xh | Multiple (between 1-10) Values |- |}
They are stored as DWords, but the X will determine how many bytes to use: 0 = bit, 1 = Byte, 2 = Word, 3 = Three bytes

Now that we’ve seen the stack, here are the opcodes:

Code

Arguments

Value(s) to pop

Value to push

style="background:rgb(224,224,224)" align="center" colspan = "4" | Push Values

0Xh

2 byte Memory Address

Type 0X stored at translated Address

style="background:rgb(224,224,224)" align="center" colspan = "4" | Push Addresses

1Xh

2 byte Memory Address

Address value with a scope of X

style="background:rgb(224,224,224)" align="center" colspan = "4" | Mathematical and Bit-wise Operators

30h

Two of any type

Sum of pops

31h

Two of any type

Difference of pops

32h

Two of any type

Product of pops

33h

Two of any type

Quotient of pops

34h

Two of any type

Remainder from quotient of pops

35h

Two of any type

Bit-wise AND of pops

36h

Two of any type

Bit-wise OR of pops

37h

One of any type

Bit-wise NOT of pop

style="background:rgb(224,224,224)" align="center" colspan = "4" | Logical Operators

40h

Two of any type

True if pops are EQUAL

41h

Two of any type

True if pops are NOT EQUAL

42h

Two of any type

True if first pop is GREATER THAN OR EQUAL TO second pop

43h

Two of any type

True if first pop is LESS THAN OR EQUAL TO second pop

44h

Two of any type

True if first pop is GREATER THAN second pop

45h

Two of any type

True if first pop is LESS THAN second pop

style="background:rgb(224,224,224)" align="center" colspan = "4" | Logical Comparisons

50h

Two of any type

True if both pops are NON-ZERO (Logical AND)

51h

Two of any type

True if either pop is NON-ZERO (Logical OR)

52h

One of any type

True if pop is ZERO (Logical NOT)

style="background:rgb(224,224,224)" align="center" colspan = "4" | Push Constants

60h

1 byte Value

Argument of type 01

61h

2 byte Value

Argument of type 02

62h

3 byte Value

Argument of type 03

style="background:rgb(224,224,224)" align="center" colspan = "4" | Script Jumps (No Pushes)

70h

2 byte Script Address

One of any type

Jumps to script address in argument if pop is 0

71h

2 byte Script Address

One of any type

Jumps to script address in argument if pop and top of stack are not equal

72h

2 byte Script Address

Jumps to script address in argument

73h

This ends the script

74h

One of any type

Pops one value from stack. (Not used)

75h

One of any type

Link all scripts of script owner to popped Character ID.

style="background:rgb(224,224,224)" align="center" colspan = "4" | Bit Operations

80h

Two of any type

First pop masked by second pop

81h

Random Word (0-65535)

82h

One of any type

Random bit of pop stored as type 02

83h

One of any type

If pop is Type 01, Type 01 with count of number of bits set in pop
If pop is Type 02, Type 02 filled with value of first non-null value in pop

84h

One of type 2X

Type 02 indicating which values in popped set were greatest

85h

One of type 2X

Type 02 indicating which values in popped set were least

86h

One of type 1X

Type 02 indicating MP Cost of attack index referenced in pop

87h

One of any type

Type 02 with only bit in pop turned on (1 << [pop])

 

style=”background:rgb(204,204,204)” align=”center” colspan = “4” | Command
Code
90h
90h
91h
92h
93h
94h
95h
96h
A0h
A1h
 

GENERAL NOTES:

0X & 1X CODES NOTES:

3X CODES NOTES:

4X CODES NOTES:

86 CODE NOTES:

 If Value >= 0xFFFF, return 0
 If Value <= 0x00FF, Addr = 00DAAC78 + Value*0x1C
 If Value >= 0x0100, match Value with wr[0099AAF4+(ID=[0..31])*2]
    First ID it matches, Addr = 0099A774 + ID*0x1C
 If no Addr is found, return 0
 Otherwise, return wr[Addr + 4]

The pushed value is, thus, the MP cost of the defined ability as a type 02. Note that 0x00 to 0xFF are standard magic and always loaded, while 0x100+ are the unique abilities loaded through scene.bin.

92 CODE NOTES:

Command index in case of character AI

20h - For enemy attack

22h - Force execution of script (referenced by first pop)

24h - Pauses battle engine while string is displayed (in conjunction with code 93)