MUGEN's process
|
So far, we've gone over
specific things ; they were what you will come across very often in
Mugen coding. Now, let's talk about what brings all of that together,
what makes Mugen tick - what makes it work the way it does, and what
gives a meaning to the code you type.
|
Mugen reads from top to bottom - within the state you are currently
in. This is an important point, however simple it may sound. If two
sctrls are one above the other, Mugen will first read the one at the top
(and activate it if its trigger allow it), then the second one. If the
triggers overlap, you will see the result on the same frame as it is
displayed, but just before actually displaying that frame, Mugen will
still read and execute what it read first before considering what comes
later in the file, even within the same tick. For that reason, all
ChangeStates should usually be placed at the end of the statedef it is
in - for example, if you have an effect that has triggers overlapping
with the ChangeState, but placed behind it, Mugen will first read the
ChangeState and apply it, and it will never read your effect.
This is also how command input detection works. In StateDef -1,
Mugen will read the list of ChangeStates you wrote, and the first
ChangeState it finds with triggers matching the input you just made, it
will stop reading and immediately send you to that state. So, if you
have a qcf+a and a f+a, if you press qcf+a, you do not want Mugen to
first detect f+a and never detect your qcf+a, thus you will put the
ChangeState triggered by qcf+a before the one triggered by f+a.
Essentially, this means that most of the time, you will have to put the
Type=ChangeState for your supers before those for your special moves,
which in turn will be before your command moves and basic moves. Well,
unless your super moves are done with just one button, but there aren't
many games where this is the case. Simply put, ChangeStates triggered by
a single button have to be at the very end of StateDef -1.
|
We have seen so far that the character was always in exactly one (no
more, no less) state at the time, and that Mugen would read only the
state you currently are in on each tick ; however, there are special
states that are always read in addition to the state you are in, at
every single tick, also from top to bottom. These are the negative
states ; there are three of them, no more, no less, and that can not be
changed. If you are in StateDef 200, Mugen will read that statedef, but
it will also read these negative states.
StateDef -1 is used to detect command inputs, not
only for the character (of course) but also for helpers if you give them
KeyCtrl (we'll go over Helpers in a minute). To create a new move, you
will first have to define the command and then define a ChangeState
triggered by that command - this will be placed in StateDef -1. StateDef -2 is always checked, no questions asked - except only by the character, never by Helpers. StateDef -3
is always read (also only by the character, not helpers) as long as the
player is one of his own states and not in a custom GetHit state (also
to be explained in a minute). Basically, anything related to detecting
commands go to statedef -1, and any state controller you want to be
constantly checked regardless of which state number you are in (if
you're coding a timer, for example) will usually go into statedef -2.
You must not remove statedef -1, and you probably don't want to
remove statedef -2 unless you really have nothing to put in there.
Statedef -3 is not used all too often, but may come in handy in
particular cases. Also, anything you need to be constantly checked /
activated can be dumped in statedef -2 without any mandatory
organization, as it's all the same statedef. There can be exceptions to
this "no order" bit if you are trying to set up some specific coding
that actually does require some order (timers are again an example),
since, as you remember, Mugen reads from top to bottom, and this can be
taken advantage of when you start coding more complicated things.
These negative statedefs do specific things, so don't go and try to
make a statedef -4 and keep in mind that if you need to add something
that must be constantly checked or activated regardless of what state
you are in, you'll want to put it in statedef -2, and it's not a problem
if there's already something in it.
|
COMMON1.CNS AND FILE ORDER PRIORITY IN THE DEF (Show/hide)
As we've seen several times now, Mugen reads from top to bottom.
This is again true for the DEF file, if you have multiple CNS/ST files
(which you can). Let's say you just used a Type = ChangeState : Mugen
will look at the DEF file, and take the first CNS/ST file, and look in
that. In case it didn't find it there, it will then move on to the next
CNS/ST file, and so on until it finds the StateDef you're looking for.
At that point, it will stop looking. This means that if you have several
StateDefs with the same number, Mugen will stop at the first one it
finds. This is true even if you have only one CNS/St file, but this gets
interesting with the common states.
We have mentionned the common1.cns file a couple of times earlier.
Just as it says on the tin, this file contains the common states :
walking, jumping, getting hit... Now, what's interesting is that, if you
are making a character with some unique particularities, you might want
to add special coding to those states. So what do you do ? Since the
common1.cns is made to be used by everyone (as defined in everyone's DEF
file), you're not going to modify that file ; instead, you copy the
state you need into your own CNS or ST file. As long as your file is
linked to before the common1.cns in your DEF file, as we have just seen,
Mugen will find that copy of the state in your file before finding it
in the common1, and it will stop there and not read the common1 for that
state. This is called overriding. This will be useful only for very
specific cases, but it's always a good thing to be aware of. For
example, coding things like a Super Armor (don't flinch when getting
hit) is done through that process.
|
On every single tick, Mugen will pass over the state you currently
are. Anything it finds will have its triggers evaluated, and if one set
of triggers evaluates to true, the corresponding sctrl will be
activated. For that reason, a same sctrl that has already been activated
can still be activated a second time on the next tick, as long as it
has at least one set of triggers (trigger1s, trigger2s...) that evaluate
to true at the moment they are read. Ultimately, ordering your state
controllers is mostly for you to be able to read them (except special
cases that actually rely on Mugen reading from top to bottom even if two
sctrls have the same triggers), as Mugen will read the entire state and
all its sctrls once per tick regardless of the order of the sctrls. For
that reason, setting up your triggers correctly is usually the one
thing you will spend most of your time on : you want them to activate
the sctrl at the right time, and you want them to not activate it when
they should not do so. There are additional safeguards you can use in
such situations : some sctrls let you assign an ID to each element
(explod, helper) you create, and you just need to add a trigger that
checks if that ID is not already being used ; alternatively, there also
is an extra parameter that can be used for every single sctrl, called
"persistent" - you just have to give it the value 0 to make sure it will
never activate more than once until you leave that statedef.
|
When you get hit, you go to special states, called the gethit
states. They are coded exactly the same as the rest of your movements ;
the key to these gethit states is the MoveType, which is set to H. This
MoveType is what lets Mugen know that you are losing life. Everything
else -the way you slide on the ground, how long you stay in that state,
how high you fly- is coded in the normal Mugen language. you can read it
normally in the common1.cns. Most of the time you do not want to mess
with them, unless you are coding a very specific feature (such as Super
Armor). If you do so, you'll want to copy the gethit states in your own
files, as we have seen earlier about overriding.
This is for simple, common attacks, like a punch, an uppercut, a
fireball. But there are a specific kind of attack that needs much more
attention in the gethit state department : throws. This can be a bit
disorienting for people who don't have a lot of experience, but
ultimately, this is one of those things that simply need some
dedication, attention and organization.
All throws are unique. Obviously, the behavior of the target cannot
be streamlined in the common1.cns ; the thrower wants to be able to do
whatever he wants to his victim. For that, we create custom gethit
states.
First, there is a sctrl that is used to put the target in a custom
gethit state : TargetState. The critical point is that you are placing
the opponent into a state that is coded in YOUR file. He will be reading
the statedef in your CNS file (the one you put him in), and the
animation in your AIR file (but still displaying his own sprites). The
code itself is the same as anything else : once you have control over
your target, it is nothing more than a matter of timing the animation he
is put in, the position changes, and your own action. You have to
create the corresponding custom gethit animation and time it right so
that, when your character moves his hands to lift his target over his
head, the target animates correspondingly. If you jump while holding the
character, you have to use the proper SCTRLs in your custom gethit
state so that the target moves around together with your character. Also
make good use of all the sctrls related to binding - like "Type =
TargetBind". Along with timing both animations properly, this is the
tool to make sure the target follows you around properly. From there,
once things move around the way you want, it's only a matter of coding
the special effects (hit sparks, dust, hit sounds...) the exact same way
you would code any normal visual or sound effect, and throw in a "Type =
LifeAdd" (with a negative value) in the custom gethit state you put the
target in. Just make sure this state has a MoveType = H, because this
is what lets Mugen know that you actually do have a target. Give it
another movetype and Mugen will consider you don't have a target
anymore.
Another thing to note is that you should not manipulate variables in
a custom gethit state : the variables that will be changed are the
variable of the target put in the gethit state, not yours, and this can
be quite bad as you don't know what variable the opponent uses.
Once you are done, ALWAYS release the character with a "Type =
SelfState" to send him to his own LieDown state. For that, you simply
have to look at the common1.cns to make sure of which one of the common
states you need to leave him in. This SelfState is important, because if
you simply use a ChangeState, he will remain in the states of your own
file, always using ChangeState into your own states, until you tell him
to go back where he comes from. This is the kind of error that can lead
to very random bugs. For the restless, an example of actual code will
come in the Coding section of this overview (it'd be a bother to
copy-paste the same information twice in two pages).
Most of the work for custom gethit states is spent on proper
animation timing and proper binding. This may give very strange results
if you do a rush job on it, so it's one of those things that take some
dedication and organization.
|
We've just been talking about custom gethit states, and how they use
animations defined in the AIR file of the attacker. But how does that
work if the animation is defined in the attacker's file, yet the sprites
displayed are still the ones in the ragdoll's SFF file ? The answer is
required sprites. These sprites, the gethit sprites, are required for a
reason : they all have very specific group/sprite numbers just so that
someone who tries to throw you can safely use those group/sprite numbers
and know what they correspond to. Getting hit by a strong attack to the
belly is always the same group/sprite number, and getting hit in the
chin into flying up always uses the same group/sprite number, or being
slammed into the ground head first, also same numbers. Between all the
required sprites that are part of the current standard, you can usually
manage to make a throw look correct for everyone.
Oh, if you don't know yet how to deal with the SFF and how to add
those required sprites, it doesn't matter, as long as you remember that
the required sprites are required just so that you can be sure they are
the same for everyone. We'll talk about the SFF later on in this
overview, anyway.
|
So, we've talked about a lot of things, it's time to sum the very basics a little.
Your character is standing there, chilling and doing nothing. At
some point, you press a key combination on your keyboard. Since Mugen is
constantly reading the negative states, including state -1, it reads
your CMD file and comes across a type = ChangeState triggered by the
command you've just entered. If all the triggers are evaluated to
"true", then the ChangeState is executed, and you move from your current
state into the state defined in your controller (if it finds it in your
CNS or ST files).
As the character enters that state, it reads the number of the
animation to display, goes to fetch that number in the AIR file, and
displays the corresponding sprite from the SFF. Then, various state
controllers control graphic effects, play a sound from your SND file,
move your character around, make it interact with the other elements on
the screen - starting with the opponent. At the end of the state,
usually it will find a ChangeState that sends you back to state 0 - or
depending on your state and your physics, you will automatically land,
and the land state ends up sending you back to state 0, and regain
control if you didn't have it. Then, right before moving on the the next
frame, states -2 and -3 are also read the same way. And you can start
over from the top.
This is done for every element on every tick. One tick starts, Mugen
reads the state of one character, of all his helpers, then of the other
character(s), and also the stage, and finally the display is updated on
the screen. And then, Mugen moves on to the next tick, and starts over
and does the same thing again.
|
|