Moveset Files (Smash 4)

From OpenSA: Smash Engine Documentation Wiki
Jump to: navigation, search

Overview

In Smash 4, the moveset system got a partial overhaul. Instead of being comprised entirely of ACMD script, Fighters are now comprised of two scripting languages. AnimCmD and a new bytecode based scripting format which was created to handle calling the ACMD subscripts, called MSC (MotionScript). This would be the equivalent to "actions" in brawl.

Each fighter has 4 ACMD files and 1 motion.mtable file in their AnimCmd script folders. In addition, fighter's who have articles or weapons will have a folder specific to them containing the same file structure. The ACMD files are split into 4 purposes. One for main game code like hitboxes, one for graphics, one for sound effects, and one for "expressions" or the why the character stands on stage and such. The lists in each file are read line by line and executed simultaneously.

The motion.mtable file is simply a list of all Animation CRC's that the character uses. MSC will index into this table later in order to find the acmd event lists to read from the other files.


ACMD

ACMD script handles most of the bulk of the moveset including timers, frame speeds, hitboxes, sounds, effects and more. The format contains a list of animation name CRC's that are linked to each event list. The animation names that produce the CRC are not specified anywhere aside from the character's animation file, which is external. However, some are still not present.

Header: Size = 0x10
Offset(in hex) Data Note
0x00 "ACMD" Header magic.
0x04 Version? Always 2
0x08 List Count Total Number of event lists in the file
0x0C Command Count Total number of AnimCMD's used in the file.
0x10 Event List Entries List of u32 pairs.
Entry: Size = 0x8
Offset(in hex) Data Note
0x00 CRC CRC of the name of the Animation associated with the script
0x04 Offset Offset to the eventlist

Event Lists

Event lists are simply a list of AnimCMD Events (Smash 4) that are played in sequence. The size of the event list isn't specified anywhere, but since the list needs to end in a specific command, we can just walk the list until we hit that. Alternatively, you could do some math with the offsets to get the sizes.


MSC

Not much is currently known about MSC other than the fact that it is a bytecode based scripting system governing the execution of ACMD subscripts. MSC files are comprised of a header, script data section, offsets to those scripts, and a list of strings referenced by the printf command used by the scripts.

The very first script run by the game when executing any MSC file is the "Entrypoint" script, which is specified in the header.

Header

Header: Size = 0x30
Offset(in hex) Length Data Note
0x00 0x10 Header magic, always the same
0x10 0x04 Entries Offset Offset to the Entries section
0x14 0x04 Entrypoint Offset to the Entrypoint script
0x18 0x04 Entry Count Total number of MSC scripts in the file.
0x1C 0x04 unk Unknown
0x20 0x04 String Size Size of each String chunk
0x24 0x04 Strings Count Number of strings in the file.
0x28 0x04 unk Unknown
0x2C 0x04 unk Unknown
0x30 0x04 unk Unknown

Scripts

The first data section after the header of the file is the Script Data section. It contains all the scripts of the file packed back to back with no padding. These scripts are referenced by the Script Offset Section later in the file.

Unlike ACMD, MotionScript (MSC) more resembles a full programming language with variable declarations (local and global), cross-referenced functions, and even it's own printf built right in. Each command can also be used as the parameter to another command. for example, if(command_2(localVariable1)){ doSomething(); } .

Commands

The definition of any MSC command is simply the single byte command identifier, and the parameter list. The byte identifier also has a bitfield (bit 7, mask 0x80) that determines whether or not the command is passed to the next command as a parameter.

For a full list of MSC commands, look at MSC_Commands_(Smash_4)

Data Length Note
Bytecode identifier 1 bit 7 determines whether or not the command is being passed to the next command or not.
Parameters  ?? Parameter size, datatype, and number of params is different for each command.

Script Offset Section

The next section encountered in the file is the Script Offset Section. This section is simply a list of offsets into the Script Data Section. All offsets are relative to the header. The order of these offsets is particular, because scripts will reference each other using the index of the offset in this list.

String Section

The final section encountered in the file is the string section. This section is a list of chunks of string data of X size, where X is specified in the header. All strings are aligned to this size and filled with padding if it doesn't consume the whole space. These strings are strings used by the printf command, used for debug purposes while the script is executing.

The parameter stack

MSC scripts and commands pass their parameters around to other commands via a stack. This stack is a LIFO data construct that can have parameters such as integers, variables, function pointers, and even other commands pushed onto it.

The stack is manipulated using the Push series of MSC commands. Commands that have bit 7 set automatically push themselves onto the stack rather than needing a separate command to do it.

Items/Parameters are popped off the stack by the command that uses them (any command that doesn't have bit 7 set). In this sense, the language allows you to combine a large number of parameters/expressions into single functions. This is how the language is able to achieve the high level of flexibility and power it possesses. It is also the chief reason that the language is harder to decompile.

For a full list of commands that push to and use the stack, look at MSC_Commands_(Smash_4)