Moveset Files (Smash 4)
Contents
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.
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. |
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
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)