Everyone knows there are random elements in the SF2 engine, including the amount of damage and stun done by most attacks. But what kind of randomness, exactly? Here are the general rules:
|attack type||random dizzy||random damage||lifebar scaling*|
- I didn't examine lifebar scaling in depth, but a little testing can confirm T.Akiba's findings. Just set the opponent's life to 30 and see the difference.
- Some holds like Blanka's and Balrog's always do no dizzy.
- Throws do fixed damage except the following:
- Gief's SPD (SSF2 and SSF2T versions only)
- Gief's close 360+K, 2nd hit
- Gief's far 360+K
- Gief's super, 3rd hit
- Hawk's super, 2nd hit
- Vega's super, 3rd hit
- Honda's oicho, both hits
Now for the details. To reveal the exact damage and dizzy formula for all attacks and help compile more accurate attack data, I developed the following breakpoints for use in the MAME debugger:
|breakpoints||helper Lua script|
|(local copy)||(local copy)|
You run MAME with the
-debug switch on, then copypaste each of the
bp lines for your game into the console. Then anytime either player gets attacked, the damage and stun info is displayed there. Since the FBA/MAME-rr Lua implementation doesn't support breakpoints, there's no pure-Lua way to get the formulas. What the helper script does is it prints out damage/stun/timeout dealt whenever someone gets hurt. You can use it to more easily verify that the formulas jive with the real figures.
(There's supposed to be a way to enter multiple commands at once, but it doesn't work. Also, these will only work on the current parent ROMs, not clones. However, every ROM address is given relative to the breakpoint address, the
pc, so getting these to work with a clone should only require offsetting the
bp by a constant value.)
How random damage works: there's a base damage for every hit, then a random value is added. The random values are looked up from a table of 32 possibilities, with the actual one selected determined by the output of a pseudorandom number generator. The sum is then scaled down by a certain factor and rounded up to produce the final damage.
The lookup table is dependent on the attack, and all the relevant random number tables are included in the bp file. The scale factor, however, is dependent on the opponent: it's a defense rating.
|damage scaling||ST characters|
|27/32||Ryu, Guile, Ken, Chun Li, Dhalsim, |
Claw, Fei Long, Cammy, Dee Jay, Akuma
|25/32||E.Honda, Blanka, Boxer, Sagat, Dictator|
Random dizzy works the same way, but there's only one lookup table for all attacks, and there's no scaledown afterward. Dizzy timeout increases are not random, but each type of attack has different hardcoded values and it would be a needless hassle to use breakpoints to find them. It's much easier to use the helper script.
Here's an example of how to get the formulas for some attacks in SSF2T. Start by running MAME with the debugger on:
Paste each breakpoint line from the ssf2t section into the console and hit enter after each one. Press F5 to release the debugger lock and allow the game to run. Now click over to the game window and set up a Chun Li vs. Ken match.
Try throwing Ken. The debugger prints out "
throw dizzy: 10 + randval@ $(07F39A + 00~1F)" and then "
throw damage (A): 32". (Notice how the dizzy is applied when the opponent is released, and the damage is applied when they hit the ground or wall.) Throw damage is fixed, but it will change depending on the round and who won what round. There may not be any significance to whether it's a type (A), (B) or (C) throw. I added those labels just to keep track of the different bps.
The base dizzy is 10, plus a random one of these values from the table in the bp file:
These numbers are in hex, so 0xFF = -1, 0xFE = -2, etc. Looking them over, there's a certain chance of getting each value.
This distribution happens to be symmetric about zero, but not all are. If you only care about the extremes, you could put this move down as 7~13 dizzy. As for the stun timeout, it increases by 100, which you can tell from the Lua console.
Now hit with c.HK. The debugger gives "
hit damage: (22 + randval@ $(0E7996 + 40~5F)) x 27/32" and the dizzy data. Look up the random values from the damage table. This attack doesn't read from the top, but from offset 0x40:
The min is -3 and the max is +4, for a range of 19~26. Since this is vs. Ken it's then reduced by 27/32, or 17~22 after rounding up. Against T.Hawk it would be 22/32, or 14~18.
Now grab Chun Li with Ken's MK throw, the knee bash. It's a straight 26 damage for the first hit and 4 for any subsequent hits. This particular hold does no dizzy damage. (The breakpoints and the script work for both players.)
And that's all there is to using it. One last note is MAME-rr will crash if a ROM is unloaded while breakpoints or watchpoints are installed, so enter
bpclear in the debugger before quitting. And, be sure to report any errors, or else I'll never be able to fix them.