Next parts:
Part 2: Run, Dash, Evade, Power Charge, Zero Counter, Parry
Part 3: Custom Combo, Recovery, Guard
Part 4: Lose and Intro animations
Part 5: Constants, Win animations, Taunts
Part 6: Universal Helpers
Part 1: Basic Movements
This might be my greatest idea ever, or a recipe for complete disaster.
Ok, what is going on here?
I spent the lockdown editing some P.o.t.S styled characters for my build. This led me to study the codes a bit more deeply, and soon I noticed the heterogeneity in the basics. While the fact that every creator can express himself is in itself the true beauty of Mugen, I grew a bit frustrated. I wanted a personal build with a roster of similar-styled characters, to have the feeling of an actual game.
While I love the overall P.o.t.S style, there's a lot of sub-styles with some slight core differences. I decided that Jmorphman's style (which is in turn emulated by others) is what suits best my tastes. Don't get me wrong, I'm not saying that DW and Infinite's styles are inferior, it's just a matter of personal tastes.
So, I'm gonna use some of his (and Knuckles8864, Deathschyte and KarmaChameleon) characters as a reference to re-create some characters. I'm gonna do P.o.t.S's old Ryu. Hopefully I won't get overwhelmed and finish this.
What I'm trying to accomplish?
This will not be a guide, nor a "true" explanation of sorts. This will be a log of my progresses while I'm actively trying to learn how to make a character in this style (that's why there's "Diary" and not "Guide" in the title). Really, it is best described as a "dissection".
Hopefully, this project will attract (A) some people that, like me, want to learn and can benefit from my references and (B) some of the more experienced creators, including the ones I mentioned, that can give me feedback and corrections if I do/post bullshit. I hope this will become an interactive experience, and as such I take the liberty to edit this whenever I want based on feedbacks. And if I don't get any I'll still continue, I'm doing this for myself after all.
What I'm NOT trying to accomplish?
The end result won't be a template in which people (myself included) will just slap some sprites and say "hEY gUys cHecK ThiS PieCe-Of-tHE-sHiT stYLe cHarACteR I MadE huRr DuRR". Again, this will be the diary of a learning experience, hopefully.
Final disclaimer: from now on, just assume I'm saying "I might be wrong, though" at the end of every sentence. Ok, let's get started.
STANDING
Let's start easy, shall we? I know I should be making the .def and Constants.cns files first, but we'll get there, trust me.
Nothing too fancy here, the reference code is pretty much unchanged from the original PotS Ryu. The statedef is 0. This is the code I'll be putting:
Spoiler, click to toggle visibilty
;==============================================================================================
;=======================================<SYSTEM STATES>========================================
;==============================================================================================
;====================<STANDING>====================
[StateDef 0]
type = S
physics = S
moveType = I
velSet = 0,0
sprPriority = 0
[State 0, Remove Explods]
type = RemoveExplod
trigger1 = IsHelper
[State 0, Destroy Helpers]
type = DestroySelf
trigger1 = IsHelper
[State 0, Anim] ; <------ (this will give us different stances for different modes)
type = changeanim
trigger1 = ((var(1) <= 1) && anim != 0) || (var(1) = 2 && anim != 2)
trigger1 = anim != 5
trigger2 = anim = 5 && !animtime
value = ifelse(var(1) = 2, 2, 0
[State 0, Skywalker]
type = ChangeState
triggerall = pos y < 0
trigger1 = !NumEnemy
trigger2 = NumEnemy = 1
trigger2 = (Enemy, Name = "M -NES Game 1" + Enemy, Name = "M -NES Game 2" + Enemy, Name = "M -GB Game 1" + Enemy, AuthorName = "Bane84") < 2
trigger3 = Numenemy >= 2
trigger3 = (Enemy(0), Name = "M -NES Game 1" + Enemy(0), Name = "M -NES Game 2" + Enemy(0), Name = "M -GB Game 1" + Enemy(0), AuthorName = "Bane84") < 2
trigger3 = (Enemy(1), Name = "M -NES Game 1" + Enemy(1), Name = "M -NES Game 2" + Enemy(1), Name = "M -GB Game 1" + Enemy(1), AuthorName = "Bane84") < 2
value = 50
[State 0, Dead]
type = ChangeState
trigger1 = !Alive
value = 5050
As far as I understand, this block of code does nothing more than setting the animation for the stance (0) and changing it for when the character turns (5) or is dead (statedef = 5050).
Now, something fun. One of the reasons I chose Ryu is because the original has multiple modes (var(1)), and I'll be giving him a stance for every mode: Normal and Evil Ryu. The original has a Master mode, but I don't want an overpowered version, plus his stance sucked. Seriosly, who fights with folded arms? Except Frieza, maybe...
Instead, I'll be giving him a tentatively SFIII reminiscent version, with an unused stance. I don't know yet what the differences will be, probably I'll give him the Jouen side kick special and Denjin Hadouken. I'm open to suggestions.
Edit: after a bit of brainstormin I decided that this Ryu will only have two modes, for two main reasons: (1) the SFIII stance actually kinda sucks, and (2) the only reason I can think of for giving him such a variation is to give him the Denjin. So yeah. I'm editing out any reference to a SFIII variation, if you see any it's because I forgot, ignore it.
Spoiler, click to toggle visibilty
;Standing (Normal)
[Begin Action 0]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
0,0, 0,0, 6
0,1, 0,0, 6
0,2, 0,0, 6
0,3, 0,0, 6
0,4, 0,0, 6
0,5, 0,0, 6
0,0, 0,0, 6
0,1, 0,0, 6
0,2, 0,0, 6
0,3, 0,0, 6
0,4, 0,0, 6
0,5, 0,0, 6
0,6, 0,0, 6
0,1, 0,0, 6
0,2, 0,0, 6
0,3, 0,0, 6
0,4, 0,0, 6
0,5, 0,0, 6
Needless to say, the sprite group 0 refer to the standing animation. I will be putting some images as simple visual references, but don't expect me to make gifs or something.
EDIT: as per KarmaChameleon's suggestion, I'm revising all the hitboxes. Turns out most CvS-accurate characters use the same hitboxes for the animations of the same type (one for the standing animations, one for crouched positions, one when in air, with some exceptions).
Unsurprisingly, and maybe a bit lazily, I'm using Jmorphman's Ken as a template. Less lazily, I'm updating the images.
;Standing (Evil)
[Begin Action 2]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
1,0, 0,0, 6
1,1, 0,0, 6
1,2, 0,0, 6
1,3, 0,0, 8
1,4, 0,0, 6
1,5, 0,0, 6
1,6, 0,0, 6
1,7, 0,0, 6
1,8, 0,0, 12
1,0, 0,0, 6
1,1, 0,0, 6
1,2, 0,0, 6
1,3, 0,0, 8
1,4, 0,0, 6
1,5, 0,0, 6
1,6, 0,0, 6
1,7, 0,0, 6
1,8, 0,0, 12
1,9, 0,0, 6
1,1, 0,0, 6
1,2, 0,0, 6
1,3, 0,0, 8
1,4, 0,0, 6
1,5, 0,0, 6
1,6, 0,0, 6
1,7, 0,0, 6
1,8, 0,0, 12
The group 1 refers to the evil stance, which is a bit less linear to give an idea of heavy breathing.
;Standing (SF3)
[Begin Action 3]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
3,0, 0,0, 7
3,1, 0,0, 5
3,2, 0,0, 5
3,3, 0,0, 5
3,4, 0,0, 5
3,5, 0,0, 5
This one is noticeably simpler and shorter, being an edit. It will end up unused, though.
Something worthy of note: the original version of Ryu had Evil Ryu's stance as anim 1. More recent characters, including Jmorphman's, use the anim 1 as a blank for invisible helpers, so I'll be putting the stance at 2. The first time I tried to mess with this character I wasn't aware of this, so I had a lot of little Evil Ryus on screen.
Now, about the modes themselves: the character mode is decided by the var(1). Var(1) = 1 means Normal Ryu, var(1) = 2 means Evil Ryu. As such, anything that has, for example, a "var(1) = 2" on the triggers only works with Evil Ryu.
Looking at the code above, we can see how for each var(1) there's a different stance. For now I'll leave this like that, but I'll need to put the VarSet for it under the Statedef 5900 later, to decide how the modes will be chosen.
In case you're wondering, I'm not using the value = 0 because P.o.t.S didn't, and if I have to replace the values I'll probably mess up somewhere (which I already did but I edited out my mess before anyone could notice).
Also, most modern characters use var(40) for this purpose, but I won't be changing that for one simple reason: this is used in other character's codes to decide stuff such as the winquotes against him or Evil Ryu, intro interactions and so forth. If I change it now, I need to patch every single character that has any kind of interaction with Ryu, including winquotes. And since it's Ryu we're talking about, this means pretty much every Capcom character.
Before continuing, we need some more animations: the aforementioned blank at 1, and the turning and crouch turning animations at 5 and 6. These last two are always needed, or the character will crash.
Spoiler, click to toggle visibilty
;Blank Animation
[Begin Action 1]
-1,-1, 0,0, -1
;Turning
[Begin Action 5]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
5,0, 0,0, 2
5,1, 0,0, 2
5,2, 0,0, 2
;Crouch Turning
[Begin Action 6]
Clsn2Default: 3
Clsn2[0] = -1, -64, 16, -48
Clsn2[1] = -18, -54, 23, -28
Clsn2[2] = -20, -28, 23, 0
6,0, 0,0, 2
6,1, 0,0, 2
6,2, 0,0, 2
CROUCHING
Again, these codes are mostly shared between the original and the reference characters, so I'm leaving this as that. Not much to analyze, it's pretty intuitive what these codes are.
Spoiler, click to toggle visibilty
;====================<CROUCHING>====================
;Stand to Crouch
[StateDef 10]
type = C
physics = C
moveType = I
velSet = 0,0
sprPriority = 0
[State 10, ChangeAnim]
type = ChangeAnim
trigger1 = !Time && Anim = 12
value = 10
elem = 3 - AnimElemNo(0)
[State 10, ChangeAnim]
type = ChangeAnim
trigger1 = Anim != 10
value = 10
[State 10, End]
type = ChangeState
trigger1 = !AnimTime
value = 11
;Crouching
[StateDef 11]
type = C
physics = C
moveType = I
anim = 11
velSet = 0,0
sprPriority = 0
[State 11, ChangeAnim]
type = ChangeAnim
trigger1 = Anim = 6 && !AnimTime
value = 11
;Crouch to Stand
[StateDef 12]
type = S
physics = S
moveType = I
velSet = 0,0
sprPriority = 0
[State 12, ChangeAnim]
type = ChangeAnim
trigger1 = !Time && Anim = 10
value = 12
elem = 3 - AnimElemNo(0)
[State 12, ChangeAnim]
type = ChangeAnim
trigger1 = Anim != 12
value = 12
[State 12, End]
type = ChangeState
trigger1 = command = "holddown" && command != "holdup"
value = 10
; Note: I will not be using the EXPLODsive system that is found
; in some Jmorphman characters, because it is too complicated
; to implement for inexperienced creators (i.e.: me). Gotta keep
; it simple for now.
[State 12, End]
type = ChangeState
trigger1 = !AnimTime
value = 0
There's nothing much to customize here. At this point, you need to have the anims 10 (stand to crouch), 11 (crouch), and 12 (crouch to stand). Just keep in mind that these values are for the source Ryu and, unless stated, unchanged. Of course, if you're making your character from zero you need to make your own animations, which I'll probably do for future projects. Please, if you're using this post as a reference, don't just copypaste animations.
Spoiler, click to toggle visibilty
;Stand to Crouching
[Begin Action 10]
Clsn2Default: 3
Clsn2[0] = -1, -64, 16, -48
Clsn2[1] = -18, -54, 23, -28
Clsn2[2] = -20, -28, 23, 0
11,0, 0,0, 3
11,1, 0,0, 3
;Crouching
[Begin Action 11]
Clsn2Default: 3
Clsn2[0] = -1, -64, 16, -48
Clsn2[1] = -18, -54, 23, -28
Clsn2[2] = -20, -28, 23, 0
11,2, 0,0, 1
;Crouching to Stand
[Begin Action 12]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
11,1, 0,0, 2
11,0, 0,0, 2
Group 11 refers to the crouching animations, which (as usual) consists of three sprites.
WALKING
A journey of a thousand miles begins with a single step, right?
Spoiler, click to toggle visibilty
;====================<WALKING>====================
[StateDef 20]
type = S
physics = S
moveType = I
sprPriority = 0
[State 20, VelSet]
type = VelSet
trigger1 = command = "holdfwd"
x = const(velocity.walk.fwd.x)
[State 20, VelSet]
type = VelSet
trigger1 = command = "holdback"
x = const(velocity.walk.back.x)
[State 20, ChangeAnim]
type = ChangeAnim
triggerAll = vel x > 0
trigger1 = Anim != 20 && Anim != 5
trigger2 = Anim = 5 && AnimElemTime(1) >= 1
value = 20
[State 20, ChangeAnim]
type = ChangeAnim
triggerAll = vel x < 0
trigger1 = Anim != 21 && Anim != 5
trigger2 = Anim = 5 && AnimElemTime(1) >= 1
value = 21
Animations we need: 20 and 21.
Spoiler, click to toggle visibilty
;Walking Forward
[Begin Action 20]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
20,0, 0,0, 4
20,1, 0,0, 5
20,2, 0,0, 4
20,3, 0,0, 5
20,4, 0,0, 4
20,5, 0,0, 5
20,6, 0,0, 4
20,7, 0,0, 5
;Walking Backwards
[Begin Action 21]
Clsn2Default: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
21,0, 0,0, 4
21,1, 0,0, 5
21,2, 0,0, 4
21,3, 0,0, 5
21,4, 0,0, 4
21,5, 0,0, 5
21,6, 0,0, 4
21,7, 0,0, 5
Two sets of sprites: group 20 and group 21.
JUMPING
This will get a little trickier. Here's where the reference codes start to deviate from P.o.t.S's old codes.
Spoiler, click to toggle visibilty
;====================<JUMPING>====================
;Jumping
[StateDef 40]
type = S
physics = S
moveType = I
anim = 40
ctrl = 0
velSet = 0,0
sprPriority = 1
faceP2 = 1
[State 40, Direction]
type = VarSet
trigger1 = !AILevel
sysvar(1) = ifElse(!Time, 0, ifElse(command = "holdfwd", 1, ifElse(command = "holdback", -1, sysvar(1))))
[State 40, Direction (AI)]
type = VarSet
trigger1 = AILevel
sysvar(1) = ifElse((EnemyNear, MoveType != A || BackEdgeBodyDist <= 10), 1, ifElse((EnemyNear, MoveType = A), -1, 0))
; these two blocks above are unchanged from the original, although displaced.
; While the first it's obviously the command for the jump direction, I'm not sure
; if the second dictates when the AI makes him jump or something else.
; I'm not sure what the sysvar is, either.
[State 40, High Jump]
type = VarSet
trigger1 = !Time && !AILevel
var(3) = ifElse(command = "highjump", 3, 0)
[State 40, High Jump (AI)]
type = VarSet
trigger1 = !Time && AILevel
var(3) = ifElse((P2BodyDist x >= 160 || Random < (125 * (AILevel ** 2 / 64.0))), 3, 0)
[State 40, High Jump]
type = VarSet
trigger1 = !Time && PrevStateNo = 100
var(3) = 3
[State 40, Low Jump]
type = VarSet
trigger1 = !AILevel && command != "holdup" && (var(3) != [1,2])
var(3) = ifElse((var(3) = 3 && sysvar(1)), 2, 1)
[State 40, Low Jump (AI)]
type = VarSet
trigger1 = AILevel && (var(3) != [1,2])
trigger1 = (EnemyNear, StateType = C) && Random < 500
var(3) = ifElse((var(3) = 3 && sysvar(1)), 2, 1)
; something I discovered only after looking at these codes: the original Ryu's
; high and low jump were coded differently, and the AI for them was also different.
; Note: var(3) refers to the different jumps (0 = normal, 1 = low, 2 = long low, 3 = long),
; and these codes dictate how they behave differently.
[State 40, Jump Sound]
type = PlaySnd
trigger1 = !AnimTime
value = ifElse((var(3) = [2,3]), 41, 40), 0
; ok so, for some reason the original Ryu had the jump sounds coded in
; the statedef 50, so he grunted while in the air instead of at the act. A minimal
; difference, but I'll be changing that. Also, his jump sounds are grouped as
; 0,40 and 0,41 instead of 40,0 and 41,0. I'll regroup the sounds in the .snd later.
[State 40, Dust Helper]
type = Helper
trigger1 = !AnimTime
helperType = Normal
stateNo = 8100
ID = 8100
name = "Jump Dust"
posType = P1
ownPal = 1
; luckily, most helpers are coded under the same stateno, so I can leave this as it is.
[State 40, Velocity: Normal Jump]
type = VelSet
trigger1 = !AnimTime
x = ifElse(!sysvar(1), const(velocity.jump.neu.x), ifElse(sysvar(1) = 1, const(velocity.jump.fwd.x), const(velocity.jump.back.x)))
y = const(velocity.jump.y)
[State 40, Velocity: Low Jump]
type = VelSet
trigger1 = !AnimTime && var(3) = 1
x = ifElse(!sysvar(1), const(velocity.jump.neu.x), ifElse(sysvar(1) = 1, const(velocity.jump.fwd.x), const(velocity.jump.back.x)))
y = 0.75 * const(velocity.jump.y)
[State 40, Velocity: Long Low Jump]
type = VelSet
trigger1 = !AnimTime && var(3) = 2
x = ifElse(!sysvar(1), const(velocity.jump.neu.x), ifElse(sysvar(1) = 1, const(velocity.runjump.fwd.x), const(velocity.runjump.back.x)))
y = 0.75 * const(velocity.jump.y)
[State 40, Velocity: Long Jump]
type = VelSet
trigger1 = !AnimTime && var(3) = 3
x = ifElse(!sysvar(1), const(velocity.jump.neu.x), ifElse(sysvar(1) = 1, 1.5 * const(velocity.runjump.fwd.x), 1.5 * const(velocity.runjump.back.x)))
y = ifElse(!sysvar(1), const(velocity.runjump.y), const(velocity.jump.y))
; Here's where we can differentiate the velocities of various jump types.
; To be honest, I'm not sure I translated correctly the values of the original Ryu,
; because it was more heavily structured around the sysvar(1), which I didn't
; get the meaning of. I'll change the values in case I'll need to, after testing.
[State 40, End]
type = ChangeState
trigger1 = !AnimTime
value = 50
ctrl = 1
For some reason, the patched version of Ryu by Jmorphman used a var(9) instead, but I don't think there's any true difference.
The next statedefs are MUCH different on the old Ryu, but are pretty much unchanged between Jmorphman's characters. Since these are mostly to dictate how the landing and the switch between states behave, I'm positive I can just replace the old ones with these. I hope I won't regret this lazy decision.
Spoiler, click to toggle visibilty
;In Air
[StateDef 50]
type = A
physics = N
moveType = I
sprPriority = 1
[State 50, ChangeAnim]
type = ChangeAnim
trigger1 = !Time
value = ifElse(!vel x , 41, ifElse(vel x > 0, 42, 43)) + 10 * (var(3) = [1,2])
persistent = 0
[State 50, Assert: No Guard]
type = AssertSpecial
trigger1 = var(3) = [1,2]
flag = NoAirGuard
ignoreHitPause = 1
[State 50, Grounded Frame]
type = PosFreeze
trigger1 = Time < 1 && PrevStateNo = 40
value = 1
[State 50, Gravity]
type = Gravity
trigger1 = Time >= 1 || PrevStateNo != 40
[State 51, VelAdd]
type = VelAdd
trigger1 = vel x
trigger1 = Time >= 1 || PrevStateNo != 40
x = ifElse((var(3) = [2,3]), -0.04577636719, -0.03051757813) * ifElse(vel x < 0, -1, 1)
[State 50, Landing]
type = ChangeState
trigger1 = pos y > -vel y
value = 52
[StateDef 51]
type = A
physics = N
moveType = I
sprPriority = 1
[State 51, Gravity]
type = Gravity
trigger1 = 1
[State 51, VelAdd]
type = VelAdd
trigger1 = vel x
trigger1 = Time >= 1 || PrevStateNo != 40
x = ifElse((var(3) = [2,3]), -0.04577636719, -0.03051757813) * ifElse(vel x < 0, -1, 1)
[State 51, Landing]
type = ChangeState
trigger1 = pos y > -vel y
value = 52
;Landing
[StateDef 52]
type = S
physics = S
moveType = I
anim = 47
ctrl = 0
velSet = 0,0
sprPriority = 1
[State 52, ChangeAnim]
type = ChangeAnim
trigger1 = !Time && (var(3) = 1 || var(3) = 2)
trigger1 = (PrevStateNo = [600,699])
value = 57
[State 52, PosSet]
type = PosSet
trigger1 = 1
y = 0
[State 52, CtrlSet]
type = CtrlSet
trigger1 = !Time && (PrevStateNo != [600,699])
trigger2 = Time = 1 && Anim != 57
value = 1
[State 52, ChangeState to Guarding]
type = ChangeState
trigger1 = ctrl && command = "holdback"
trigger1 = InGuardDist && (PrevStateNo != [600,699])
value = 120
[State 52, Assert: NoWalk]
type = AssertSpecial
trigger1 = Anim != 5
flag = NoWalk
ignoreHitPause = 1
[State 52, Landing Sound] ; <---- as above, I'll need to edit Ryu's original .snd file and adjust it to the new codes.
type = PlaySnd
trigger1 = !Time
value = 52,0
[State 52, Landing Dust Explod]
type = Explod
trigger1 = !Time
anim = 8102
sprPriority = -3
posType = P1
scale = 0.5,0.5
pauseMoveTime = -1
superMoveTime = -1
ownPal = 1
[State 52, ChangeAnim to Turning]
type = ChangeAnim
trigger1 = ctrl && P2Dist x < 0
trigger1 = Anim != 5
value = 5
[State 52, Turn]
type = Turn
trigger1 = Anim = 5 && AnimElem = 1
[State 52, End]
type = ChangeState
trigger1 = !AnimTime
value = 0
ctrl = 1
As far as I understand, you can put some additional VelAdds to customize a bit the jumps, which is neat if you're editing floaty characters such as, say, Dhalsim.
Jmoprhman's Chun-Li, for example, has this on both statedef 50 and 51:
EDIT: as KarmaChameleon pointed out, this VelAdd is specific for CvS2 accurate characters. Since I'm going in that direction, I'll be adding it.
Spoiler, click to toggle visibilty
[State 51, VelAdd]
type = VelAdd
trigger1 = vel x
trigger1 = Time >= 1 || PrevStateNo != 40
x = ifElse((var(3) = [2,3]), -0.04577636719, -0.03051757813) * ifElse(vel x < 0, -1, 1)
That being said, here's some anims we need to be sure to have:
Spoiler, click to toggle visibilty
;Jump Start
[Begin Action 40]
Clsn2: 3
Clsn2[0] = 1, -96, 16, -80
Clsn2[1] = -19, -88, 18, -32
Clsn2[2] = -23, -32, 18, 0
11,0, 0,0, 5
;Jumping up
[Begin Action 41]
Clsn2Default: 1
Clsn2[0] = -21, -102, 26, -34
41,0, 0,0, 8
41,1, 0,0, 4
41,2, 0,0, 4
41,3, 0,0, 3
41,4, 0,0, 3
41,5, 0,0, 3
41,7, 0,0, 3
41,9, 0,0, -1
;Jumping Forward
[Begin Action 42]
Clsn2Default: 1
Clsn2[0] = -21, -102, 26, -34
42,0, 0,0, 3
42,1, 0,0, 4
42,2, 0,0, 4
42,3, 0,0, 4
42,4, 0,0, 4
42,5, 0,0, 4
42,6, 0,0, 4
41,8, 0,0, -1
;Jumping Backwards
[Begin Action 43]
Clsn2Default: 1
Clsn2[0] = -21, -102, 26, -34
42,7, 0,0, 3
42,6, 0,0, 4
42,5, 0,0, 4
42,4, 0,0, 4
42,3, 0,0, 4
42,2, 0,0, 4
42,1, 0,0, 4
42,0, 0,0, -1
;Jump Landing
[Begin Action 47]
Clsn2Default: 3
Clsn2[0] = -19, -88, 18, -32
Clsn2[1] = -23, -32, 18, 0
Clsn2[2] = 1, -96, 16, -80
11,1, 0,0, 1
11,0, 0,0, 1
;Jumping Up (Small)
[Begin Action 51]
Clsn2Default: 1
Clsn2[0] = -21, -102, 26, -34
41,0, 0,0, 4
41,1, 0,0, 3
41,2, 0,0, 3
41,3, 0,0, 2
41,4, 0,0, 2
41,5, 0,0, 2
41,7, 0,0, 2
41,9, 0,0, -1
;Jumping Forward (Small)
[Begin Action 52]
Clsn2Default: 1
Clsn2[0] = -21, -102, 26, -34
42,0, 0,0, 2
42,1, 0,0, 3
42,2, 0,0, 3
42,3, 0,0, 3
42,4, 0,0, 3
42,5, 0,0, 3
42,6, 0,0, 3
41,8, 0,0, -1
;Jumping Backwards (Small)
[Begin Action 53]
Clsn2Default: 1
Clsn2[0] = -21, -102, 26, -34
42,7, 0,0, 2
42,6, 0,0, 3
42,5, 0,0, 3
42,4, 0,0, 3
42,3, 0,0, 3
42,2, 0,0, 3
42,1, 0,0, 3
42,0, 0,0, -1
;Small Jump Landing (After Attack)
[Begin Action 57]
Clsn2Default: 3
Clsn2[0] = -19, -88, 18, -32
Clsn2[1] = -23, -32, 18, 0
Clsn2[2] = 1, -96, 16, -80
11,1, 0,0, 3
11,0, 0,0, 3
The jump sprites are grouped under 41 and 42. For the startup and landing, we're using some of the group 11 sprites (you bend your knee when you jump, right?).
Note: the anim 57 was NOT in the original Ryu. It's identical to 47, so I created it by just duplicating it.
And with this, I'll call it a day. Next time, I'll tackle the run, dashes, and maybe the dodges. Hope this series of posts can be useful to someone, and that can be the chance for me to learn something. Before leaving, I'll tackle some questions you may or may not want to ask.
Who the hell are you, and who do you think you are?
I'm just a guy trying to learn how to make characters. I'm also slightly obsessive-compulsive, that's why I'm unhappy with having a bunch of characters with different playstyles thrown together in a build. I'd rather have less characters that actually feel they belong to the same "game", with differences due to the character themselves instead of the coding.
Why don't you buy yourself an actual game then?
Boring.
Ok then, but why Ryu? The original version is perfect, and already set the standard.
The standard evolved a bit since P.o.t.S., and precisely because Ryu set the standards he wasn't touched much. Plus, he has pretty much everything I want to learn about without being too complex, so it's a starting point.
Will you release the final result?
If it doesn't suck. Which I can't guarantee.
When's the next part?
When I feel like it.
Don't you have anything better to do?
I'm an overstressed phd student, Mugen is one of my few ways to relax and deal with stress and anxiety, plus it gives vent to my obsessive compulsions by allowing me to "construct" games. But yeah, I promise I'll begin meditating and exercising again soon. Thanks for asking.
Who's the lizard on your avatar?
Ziltoid the Omniscient! If you're into metal and/or weird music, give Devin Townsend a listen.
Next parts:
Part 2: Run, Dash, Evade, Power Charge, Zero Counter, Parry
Part 3: Custom Combo, Recovery, Guard
Part 4: Lose and Intro animations
Part 5: Constants, Win animations, Taunts
Part 6: Universal Helpers