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.
|
|