;-----------------------------------------------------------------------
; DASH_FWD
[Statedef 100]
type = S
physics = S
anim = 99+var(1)*30000
ctrl = 0
velset = 0
sprpriority = 1
[State 220,2]
type = ChangeState
trigger1 = AnimTime = 0
value = 101
[Statedef 101]
type = S
physics = N
anim = 100+var(1)*30000
ctrl = 0
velset = 0
sprpriority = 1
[State -3, dash]
type = PlaySnd
trigger1 = time = 1
value = 2+(var(32)*10),8
loop = 1
channel = 27
[State 100, 1]
type = VelSet
trigger1 = 1
x = const(velocity.run.fwd.x)
[State 100, 2] ;Prevent run from canceling into walk
type = AssertSpecial
trigger1 = 1
flag = NoWalk
[State 100, 3] ;Prevent from turning
type = AssertSpecial
trigger1 = 1
flag = NoAutoTurn
[State 100, VarSet]
type = VarSet
trigger1 = !time && prevstateno != 102
var(26) = 0
[State 100, VarSet]
type = VarSet
trigger1 = time > 10
var(26) = 1
[State 220,2]
type = ChangeState
trigger1 = command = "holdup"
value = 40
[State 100, GoToCrouch]
type = ChangeState
trigger1 = Time > 9
trigger1 = Command = "holddown" && Command != "holdfwd"
value = 15
[State 101, 6]
type = ChangeState
trigger1 = Time > 9
trigger1 = command != "holdfwd"
value = 102
[Statedef 102]
type = S
physics = S
anim = 101+var(1)*30000
ctrl = 0
velset = 0
sprpriority = 1
[State 102, 3]
type = StopSnd
trigger1 = time = 0
channel = 27
[State 100, 4]
type = ChangeState
triggerall = var(26)
trigger1 = command = "holdfwd"
value = 101
[State 220,2]
type = ChangeState
trigger1 = AnimTime = 0
value = 0
ctrl = 1
;RUN BACK
[Statedef 105]
type = S
physics = S
ctrl = 0
anim = 105+var(1)*30000
sprpriority = 1
[State 105, 3]
type = ChangeState
trigger1 = animtime = 0
value = 106
;---------------------------------------------------------------------------
; RUN_BACK
[Statedef 106]
type = A
physics = N
ctrl = 0
anim = 106+var(1)*30000
sprpriority = 1
[State 105, 1]
type = VelSet
trigger1 = 1
x = (const(velocity.run.back.x)*exp((const(velocity.airjump.back.x))*(time)))
[State 105, 1]
type = VelSet
trigger1 = !time
y = const(velocity.run.back.y)
[State 105, VelAdd]
type = VelAdd
trigger1 = time > 0
y = const(velocity.airjump.fwd.x)
[State -3, hop]
type = PlaySnd
trigger1 = !time
value = 2+(var(32)*10),12
[State 105, 3]
type = ChangeState
trigger1 = Vel Y + Pos Y >= 0
value = 107
; RUN_BACK2 (land)
[Statedef 107]
type = S
physics = S
ctrl = 0
anim = 107+var(1)*30000
[State -3, land]
type = PlaySnd
trigger1 = !time
value = 2+(var(32)*10),2
[State 106, 1]
type = VelSet
trigger1 = Time = 0
x = 0
y = 0
[State 107, CtrlSet]
type = CtrlSet
trigger1 = time = 2
value = 1
[State 106, 2]
type = PosSet
trigger1 = Time = 0
y = 0
[State 106, 4]
type = ChangeState
trigger1 = animtime = 0
value = 0
ctrl = 1
;================================================================================
; Downed get-hit (hit ground from fall)
[Statedef 5100]
type = L
movetype= H
physics = N
[State 5100, EnvShake]
type = FallEnvShake
trigger1 = Time = 0
[State 5100, Var] ;Save fall velocity
type = VarSet
trigger1 = Time = 0
sysvar(1) = floor(vel y)
[State 5100, 2] ;Hit ground anim (normal)
type = ChangeAnim
triggerall = time = 0
trigger1 = (anim != [5051,5059]) && (anim != [5061,5069])
trigger2 = !SelfAnimExist(5100 + (anim % 10))
value = 5100
[State 5100, 3] ;Hit ground anim (for hit up)
type = ChangeAnim
trigger1 = time = 0
trigger1 = (anim = [5051,5059]) || (anim = [5061,5069])
trigger1 = SelfAnimExist(5100 + (anim % 10))
value = 5100 + (anim % 10)
[State 5100, 4]
type = PosSet
trigger1 = Time = 0
y = 0
[State 5100, 5]
type = VelSet
trigger1 = Time = 0
y = 0
[State 5100, 6] ;Reduce speed
type = VelMul
trigger1 = Time = 0
x = 0.75
[State 5100, 7]
type = ChangeState
trigger1 = Time = 0
trigger1 = GetHitVar(fall.yvel) = 0
value = 5110 ;Downed get-hit (lying down)
[State 5100, 10]
type = PlaySnd
trigger1 = Time = 1
value = 2+(var(32)*10),5
channel = 1
volume = 200
[State 5100, Explod]
type = Explod
trigger1 = !time && (sysvar(1) < 14)
anim = 12000
pos = 0,0
postype = p1 ;p2,front,back,left,right
sprpriority = -4
ownpal = 1
[State 5100, 9]
type = HitFallDamage
trigger1 = Time = 3
[State 5100, 11]
type = PosFreeze
trigger1 = 1
[State 5100, 12]
type = ChangeState
trigger1 = AnimTime = 0
value = 5101 ;Downed get-hit (bounce off ground)
[State 5100, 13]
type = ForceFeedback
trigger1 = Time = 0
waveform = sinesquare
ampl = 128,-3,-.2,.005
time = 20
;================================================================================
; HIT_BOUNCE (bounce into air)
[Statedef 5101]
type = L
movetype= H
physics = N
[State 5101, 1] ;Coming hit ground anim (normal)
type = ChangeAnim
triggerall = time = 0
trigger1 = anim != [5101,5109]
trigger2 = !SelfAnimExist(5160 + (anim % 10))
value = 5160
[State 5101, 2] ;Coming hit ground anim (for hit up)
type = ChangeAnim
triggerall = time = 0
trigger1 = anim = [5101,5109]
trigger1 = SelfAnimExist(5160 + (anim % 10))
value = 5160 + (anim % 10)
[State 5101, 3]
type = HitFallVel
trigger1 = Time = 0
[State 5101, 4]
type = VelSet
trigger1 = Time = 0
y = -3
[State 5101, 5] ;Acceleration
type = VelAdd
trigger1 = time > 0
y = gethitvar(yaccel)
[State 5101, 6] ;Hit ground
trigger1 = Pos Y + Vel Y >= 0
type = ChangeState
value = 5110
;================================================================================
; HIT_LIEDOWN
[Statedef 5110]
type = L
movetype= H
physics = N
[State 5110, 0]
type = ChangeState
trigger1 = 1
value = 5111
;================================================================================
; HIT_LIEDOWN
[Statedef 5111]
type = L
movetype= H
physics = N
velset = 0,0
[State 5110, EnvShake]
type = FallEnvShake
trigger1 = Time = 0
[State 5110, 1] ;For hit up/up-diag type (from state 5081)
type = ChangeAnim
persistent = 0
trigger1 = SelfAnimExist(5110 + (anim % 10))
trigger1 = anim = [5081,5089]
value = 5110 + (anim % 10)
[State 5110, 2] ;Hit ground anim (normal)
type = ChangeAnim
triggerall = time = 0
triggerall = anim != [5110,5119] ;Not already changed anim
trigger1 = anim != [5161,5169]
trigger2 = !SelfAnimExist(5170 + (anim % 10))
value = 5170
[State 5110, 3] ;Hit ground anim (for hit up)
type = ChangeAnim
triggerall = time = 0
triggerall = anim != [5110,5119] ;Not already changed anim
trigger1 = anim = [5161,5169]
trigger1 = SelfAnimExist(5170 + (anim % 10))
value = 5170 + (anim % 10)
[State 5110, 4]
type = HitFallDamage
trigger1 = Time = 0
[State 5110, 5]
type = PosSet
trigger1 = Time = 0
y = 0
[State 5110, Var] ;Get fall velocity
type = VarSet
trigger1 = Time = 0
trigger1 = GetHitVar(fall.yvel) != 0
sysvar(1) = floor(vel y)
[State 5100, 10]
type = PlaySnd
trigger1 = Time = 1
value = 2+(var(32)*10),5
channel = 1
volume = 200
[State 5110, 8]
type = VelSet
trigger1 = Time = 0
y = 0
[State 5110, 9] ;For hit up type
type = ChangeAnim
persistent = 0
triggerall = anim = [5171,5179]
triggerall = SelfAnimExist(5110 + (anim % 10))
trigger1 = AnimTime = 0
trigger2 = SysVar(0) ;SysVar(0) = 1 avoids hit ground anim
value = 5110 + (anim % 10)
[State 5110, 10] ;For normal
type = ChangeAnim
persistent = 0
triggerall = Anim != [5111,5119]
trigger1 = AnimTime = 0
trigger2 = SysVar(0) ;SysVar(0) = 1 avoids hit ground frame
value = 5110
[State 5110, 11] ;If just died
type = ChangeState
triggerall = !alive
trigger1 = AnimTime = 0
trigger2 = SysVar(0) ;SysVar(0) = 1 avoids hit ground frame
trigger3 = Anim = [5110,5119]
value = 5150
[State 5110, 11] ;If just died
type = ChangeState
trigger1 = time = 10 + 10*(anim=5111||anim=5112)
value = 5120
[State 5110, 12]
type = VarSet
trigger1 = SysVar(0)
trigger1 = Time = 0
sysvar(0) = 0
[State 5110, 13] ;Friction
type = VelMul
trigger1 = 1
x = 0.85
[State 5110, 14]
type = ForceFeedback
trigger1 = alive
trigger1 = Time = 0
time = 8
ampl = 240
waveform = sine
[State 5110, 15]
type = ForceFeedback
trigger1 = !alive
trigger1 = Time = 0
ampl = 200, 7, -.467
time = 30
waveform = sine
;================================================================================
; HIT_GETUP
[Statedef 5120]
type = L
movetype= I
physics = N
[State 5120, 1a] ;Get up anim (normal)
type = ChangeAnim
triggerall = time = 0
trigger1 = anim != [5111,5119]
trigger2 = !SelfAnimExist(5120 + (anim % 10))
value = 5120
[State 5120, 1b] ;Get up anim (for hit up/diag-up)
type = ChangeAnim
triggerall = time = 0
trigger1 = anim = [5111,5119]
trigger1 = SelfAnimExist(5120 + (anim % 10))
value = 5120 + (anim % 10)
[State 5120, 2]
type = VelSet
trigger1 = Time = 0
x = 0
[State 5120, 3]
type = NotHitBy
trigger1 = 1
value = SCA
time = 1
[State 5120, 4]
type = HitFallSet
trigger1 = AnimTime = 0
value = 1
[State 5120, 7]
type = ChangeState
trigger1 = AnimTime = 0
value = 0
ctrl = 1
;---------------------------------------------------------------------------
; HIT_FALLRECOVER (on the ground)
[Statedef 5201]
type = S
movetype= H
physics = N
anim = 5200
[State 5201, 1]
type = Turn
trigger1 = Time = 0
trigger1 = p2dist X < -5
[State 5201, 3]
type = PosSet
trigger1 = Time = 0
y = 0
[State 5201, VelSet]
type = VelSet
trigger1 = !time
x =-11.5
y = 0
[State 5201, VelSet]
type = VelSet
trigger1 = time = 1
x = -7.921875
[State 5201, VelMul]
type = VelMul
trigger1 = 1
x = 0.8125
[State 750, Push]
type = PlayerPush
trigger1 = 1
value = 0
[State 5201, 4]
type = NotHitBy
trigger1 = 1
value = SCA
time = 1
[State 705, 1]
type = SelfState
trigger1 = Animtime = 0
value = 0
ctrl = 1
Click on "Search", and use type "Custom". Uncheck everything but "Integer 2 bytes" and click OK. Click OK again to start the search.
Now move the character a bit to the right and press "filter", "Unknown value", "was increased". Click OK.
Now move the character all the way to the left again and click on "filter", Exact value = "480", click OK.
A few values should be on the list at your left, select one of them and select "P1 Pos X" on the list at the right and press CTRL + A (or right click and apply offset to all). You will know you synced with the correct value when the character no longer moves if you "freeze" the Pos X.
When we have Kyo walk backwards, Artmoney shows "P1 Vel X Integer" as "65532" and "P1 Vel X Float" as "60160." Clearly this isn't right (well it is, but you know what I mean). This is how "negative" values appear. Here's how you convert them. For a negative integer, subtract 65535 from it. In this case we get -3. For a negative float, subtract 65556 (-5376) and then divide a positive version of that result by 65536. This gives us 0.08203125.shouldn't this be 65535?
sparkxy
There's no reliable way of getting sparkxy that I know of. I usually try to get the y position of the spark relative to P2, and run with that.
Other times, I align it by eye (I am a very lazy person when it comes to this). Keep in mind that the x-parameter depends on P2.
Pausetimes, keep in mind pausetime is the number of ticks the character will be frozen for.
In Iori's example, his standing D lasts for 4-frames. If this attack hits, Iori is frozen in this frame for 16 ticks.
This means that the pausetime is the difference between these two values, 16-4 = 12. 12 ticks of pausetime.
Calculating guard pausetimes uses the same principle.
Priority. Impossible, there is no "priority" concept in KOF, everything is decided via CLSN.
The only reason we all keep using these priority parameters is because they were standards set by previous KOF creators (CCIronmugen, OrochiKOF97 among others).
We keep them in order to maintain whatever sense of balance we managed to achieve. But technically, priority should be the same for every single move.
Guard.ctrltime
This value starts counting from pausetime onwards. To calculate, hit an opponent. As soon as they enter the blocking animation, start counting down.
For Iori's close HP you can clearly see it lasts for 28 ticks.
Air.velocity. KOF uses exponential friction for several air gethits, it has only been recently that we've started adding these via custom states.
The values you see in Iori_WLS are merely approximations to replicate the same velocity structure using MUGEN's calculations.
The only way around this is making everything a custom state, but by doing that you are violating a fellow author's gameplay standards. This (in my case) should be avoided as much as possible, and due to this, I've decided to use approximations for these values in order to preserve my opponent's states.
Keep in mind that if the mugenversion is 1.0, these become 11 for the attacker.Wait... shouldn't it be 13 if version is Win? Since it's Win that has that bug, it works normally in 1.0?
TBH I'm not sure there is much difference. I'm not sure exactly what that bug affects.Well, for one, it allows combos that shouldn't be possible.
The only reason we all keep using these priority parameters is because they were standards set by previous KOF creators (CCIronmugen, OrochiKOF97 among others).
To add on to that question, it was mentioned that air.velocity was best done through approximation (unless using custom states were applied, which wouldn't work ideally). What would be a recommended yaccel number to prevent the character from falling all floaty and stuff? Also, (when they're not in a fall state) doesn't yaccel vary between characters in commercial games?
Btw, thanks for the tutorials... they helped me a whole lot.
[State 1, Anim]
Type = ChangeAnim
Trigger1 = !Time && !prevstateno
Value = 3005 ;This stops the projectile anim from resetting whenever it goes back into this state
[State 1, projectiles only]
type = HitBy
trigger1 = 1
value = SCA, NP, SP, HP ;Can only be hit by projectiles
ignorehitpause = 1
[State 1, Override]
type = HitOverride
trigger1 = !time
attr = SCA, AA, AP, AT ;But can override anything just in case
stateno = stateno ;Goes into the same state
time = -1
slot = 2
ignorehitpause = 1
[State 1 VarSet]
type = VarSet
trigger1 = !time && !prevstateno
var(5) = 5 ;this is the primary "hitpoint" value set when the projectile is created
[State 1, VarAdd]
type = VarAdd
trigger1 = !time && prevstateno
var(5) = -1 ;Whenever the projectile goes back into this state it loses a "hitpoint"
ignorehitpause = 1
persistent = 0
[State -2, FlagHit]
type = VarSet
trigger1 = Movecontact && NumTarget
var(5) = 0 ;This is a safety for when the projectile makes contact with a character and the changestate doesn't activate
ignorehitpause = 1
[State 1, hits a projectile or is parried]
type=changeState
trigger1 = movecontact && !NumTarget
value= ifelse(var(5)=0,stateno+1,stateno)
ignorehitpause = 0
[State 1000, DestroySelf]
type = DestroySelf
triggerall = time > 1
trigger1 = FrontEdgeDist <= -40; flies off screen
[State 1005, End]
type=changeState
trigger1 = movecontact && NumTarget ;hits an opponent
trigger2 = var(5) <= 0 ;has run of hitpoints
value= stateno+1
ignorehitpause = 0
Spoiler: Collapse/Cheese Kill/Crumple - 5950, 5955, (click to see content)Spoiler: KOF hard knockdown - 5420, 5421, 5422, 5423, 5424, 5430 (click to see content)Spoiler: Throw Escape/Tech Hit - 5940 (click to see content)Spoiler: Throw has been escaped out of - 5945 (click to see content)what have I gotten myself into???
[State 10900, 1]
type = VelSet
trigger1 = time < 7
x = ifelse((facing=enemynear,facing),((abs(gethitvar(xvel))*exp((-0.20763936477824450161544104426739)*(time)))),(-(abs(gethitvar(xvel))*exp((-0.20763936477824450161544104426739)*(time)))))
[State 10900, 1]
type = VelSet
trigger1 = time < 7
x = ifelse((facing=enemynear,facing),((abs(gethitvar(xvel))*exp((-0.20763936477824450161544104426739)*(time)))),(-(abs(gethitvar(xvel))*exp((-0.20763936477824450161544104426739)*(time-1)))));time changed to time-1
damage = floor(42*ifelse(var(56),1.25,1))I tried to figure out for weeks and I still can't get it.
yaccel = 0.807692307692307692307692307692308and also the fall.yvelocity
fall.yvelocity = -2-(p2statetype=A)*0.5they are very much different from the rest of the yaccel and I can't figure out how this is calculated, can anyone explain in-depth on how I should calculate these?
- Can anyone explain to me how do I use this formula to calculate the damage?:Code:damage = floor(42*ifelse(var(56),1.25,1))I tried to figure out for weeks and I still can't get it.
- for air.velocity, I am still not sure how this is calculated, can anyone explain more in depth about the calculation of the air.velocity?
[State -2, VelSet]
type = VelSet
trigger1 = time < 6
x = (-12*exp((-0.20763936477824450161544104426739)*(time)))
Hope that helps you out. Well....you really shouldn't need to recalculate get hits since you can just use the values that I use. :PYeah, I notice all characters uses the same air.velocity and fall.yvelocity value :P
- Can anyone explain to me how do I use this formula to calculate the damage?:Code:damage = floor(42*ifelse(var(56),1.25,1))I tried to figure out for weeks and I still can't get it.
This one is pretty simple. If var(56) (counter hit check) is true, than the damaged will be multiplied by 1.25 (floor is used to round it down to an integer, since you can't use floats for damages). So 42*1.25 = 52.5 which is rounded down to 52
If var(56) = 0, than the damage will be multiplied by 1 giving the same value. 42*1 = 42
;CLOSE ASo 42 is the damage value and when I check using kof98's Kyo from the art money table, it show that the damage value is 99
[Statedef 200]
type = S
movetype= A
physics = S
velset = 0,0
ctrl = 0
anim = 200
poweradd= 0
sprpriority = 2
juggle =10
facep2 = 1
[State 200, snd]
type=playsnd
trigger1= animelem=1 && random<500
value=200,0
channel=0
[State 200, Punch Attempt Sound]
type = Playsnd
trigger1 = time = 0
value = 3+(var(32)*2),0
[State 205, 1]
type = HitDef
triggerall = var(40) < 1 || var(57) > 0 || var(16) > 0
trigger1 = AnimElemtime(2) >= 0 && animelemtime(3) < 0
[b]damage = floor(42*ifelse(var(56),1.25,1))[/b]
sparkno = s17000+(var(31)*10000)
sparkxy = -10, -80
hitsound = s3+(var(32)*2+((random%3)*var(32))),1
guardsound = s3+(var(32)*2), 12
guard.sparkno = s17500+(var(31)*10000)
attr = S, NA
animtype = Light
air.animtype = Back
ground.type = High
guardflag = MA
hitflag = MAF
priority = 6, Hit
pausetime = 7,9
guard.pausetime = 7,8
ground.slidetime = 9
ground.hittime = 8
guard.hittime = 8
guard.slidetime = 9
guard.ctrltime = 16
ground.velocity = -5.796875
air.velocity = -4.5,-7
air.juggle = 0
getpower = 47,47
givepower = 16,16
air.fall = 0
forcenofall = 1
ground.cornerpush.veloff = 0
guard.cornerpush.veloff = 0
air.cornerpush.veloff = 0
yaccel = .5
persistent = 0
[State 200, 7]
type = ChangeState
trigger1 = AnimTime = 0
value = 0
ctrl = 1
damagevalue / maxlife * 1000 = MUGEN damage value99/103 * 1000 = 961 :S
-The max life in 2002 is 102, 103 in 98 and 120 in 2002 UM. I don't know the rest. :D120 is for 2002 Unlimited Match but still (using kyo from kof98's close weak punch as an example):
Forgive the lateness of this part. There are too many things on the mind. Most of which ARE mugen related and this tutorial is a good way to get everything covered.
Part 2: AIR Making
Now this can be the longest part of character creation. I recommend you have some music or a good podcast to listen to. It really helps. First things first, you need a program to make the .air file. Of course you could just use notepad, but I'm guessing that would take a longer time than most of the dedicated programs we have now. I personally use Fighter Factory Classic. I would suggest that newer creators get used to fighter factory 3. Here is some info that may interest you regarding Fighter Factory:
How clsns appear in FF isn't accurate to how they appear in mugen. Clsn made in FF will be drawn 1 pixel lower and one pixel to the right in mugen. I believe mcm and the latest FF3 show clsn correctly. However this isn't usually a problem if you add sprites with clsn in order to trace. A bit of a moot point when you can get perfect clsn, but it's always good to know. For those times when you don't have axis to the clsn viewer (nbc/kof xi and higher).
So as previously mentioned, the way to get clsn right is by adding frames with clsn visible to the sff, then tracing over them. Some of us have different....methods of getting clsn but this is the one that works for all. For get hits, I suggest using correct clsns (I know most of my characters don't) just because there are some things that won't work right with incorrect get hit clsns
In terms of animation timings, get them in game and not from the debug viewer as they tend to be different. To get the correct timings, pause kawaks and use l shift + spacebar to frameskip. If you are getting timings from a console game, you can make a 60fps video. pcsx2 can do this regardless of the speed the game runs on your pc (hold a direction during the end of a move, so you can see the correct last frame (in case the last frame is the same as the first frame of the character stance)).
For some moves, it's sometimes best to split the animation up into parts. For example, Kyo's oniyaki. You should make the landing part separate from when he jumps (this seems obvious) but you may also want to separate it into 3 parts (startup, jumping attack, landing). Because mugen is dumb, sometimes a move with an autoguard frame will cause problems regarding the combo counter, so I would split up the part with the autoguard from the rest of the move.
Because of how the bounce states work in mugen, I would suggest moving the bouce frames (5160 etc) up by 20 pixels. You can override the bounce states (in fact I will make sure that you do (for another reason)) but I think it's best just to do it the way it's done now. I feel like it's too late to change something like that now.
There are a few non required anims that are used in KOF, check out an existing character to see what numbers they use. This will be great for consistency.
This concludes the AIR making tutorial. If you have any information that can be added or questions regarding things I may have missed, feel free to post.
What Jesuszilla said. 1.0 is the very best when it comes to pcsx2. If you would like, I could explain how I would synch a table for the ps2 games.Is it possible to make a tutorial for this? I wanted to find datas for Geese Howard from Kof98um since he is not available in the original kof98.
Doesn't seem to have special moves sadly but it's something.Ask and ye shall receive:
; Run forward
[Statedef 100]
type = S
physics = S
anim = 100
sprpriority = 1
[State 100, 0]
type = PlaySnd
trigger1 = Time = 0
value = S100,0
channel = 1
loop = 1
[State 100, 1]
type = VelSet
trigger1 = 1
x = const(velocity.run.fwd.x)
[State 100, 2] ;Prevent run from canceling into walk
type = AssertSpecial
trigger1 = 1
flag = NoWalk
[State 100, 3] ;Prevent from turning
type = AssertSpecial
trigger1 = 1
flag = NoAutoTurn
[State 100, 4]
type = ChangeState
trigger1 = command != "holdfwd"
value = 0
[State -2, Stop Running Loop]
type = StopSnd
trigger1 = stateno != 100
trigger1 = command != "holdfwd"
channel = 1