On this page
  1. Related
  2. Games
  3. References
  4. Sources

Hitstun is the time a character can’t act after a hit. In Super Smash Bros. it’s the knockback divided by 1.8751, so harder launches stun for longer1. In its NTSC 1.02 version, Super Smash Bros. Melee multiplies the knockback instead, by a value from a disc file that the code doesn’t hold2.

  • From knockbackSuper Smash Bros. (1999). The knockback divided by 1.875, as a whole count of at least 1.1Super Smash Bros. Melee (2001). The knockback times a data-file value, as a whole count of at least 1; an air jump or up special can end it early after a hit at an angle in a set range.2

Games

GameYearHowNote
Super Smash Bros.1999From knockbackthe knockback divided by 1.875, as a whole count of at least 1
Super Smash Bros. Melee2001From knockbackthe knockback times a data-file value, as a whole count of at least 1; an air jump or up special can end it early after a hit at an angle in a set range
Every claim about this mechanic, by game (2)
Super Smash Bros. 1999In the US version of Super Smash Bros., ftCommonDamageInitDamageVars sets a hit fighter's hitstun_tics, a whole-number count, to its knockback divided by 1.875 (ftParamGetHitStun), and to 1 if that comes to 0. The damage statuses' common update routines take 1 off the count each time they run. Until it reaches 0, their common interrupt routines don't run the standing, falling, or hammer interrupt checks (ftCommonWaitProcInterrupt, ftCommonFallProcInterrupt, and the hammer's), so the fighter can't act, and an airborne fighter gets friction in place of the usual drift and fast-fall. At 0, the status ends once its animation has run out. A knockback of 100 gives 53 counts (computed).Code
Super Smash Bros. Melee 2001In the NTSC 1.02 version of Super Smash Bros. Melee, ftCo_8008DCE0, the routine that puts a hit fighter into a Damage status, sets the unnamed count mv.co.damage.x0 to the knockback (kb_applied) times p_ftCommonData->x154, a value from the disc file PlCo.dat, truncated to a whole number, and to 1 if that comes to 0. It also sets the flag x221C_b6, which ftLib_IsInHitstun returns. Where Super Smash Bros. divides the knockback by 1.875 (ssb64/hitstun), Melee multiplies it by a value the code doesn't hold. The animation routines of the Damage statuses (75 to 86) and the DamageFly statuses (87 to 90) take 1 off the count while it's above 0 (ftCo_8008F744) and clear the flag once it's 0 or below; the status ends when its animation has run out with the flag clear. While the flag is set, their interrupt routines run only doIasa, as the decompilers name it, in place of the wait, fall, or hammer checks, so the fighter can't act, with one exception: after a hit whose angle ftColl_8007AC68 accepts (between unk_kb_angle_min and unk_kb_angle_max), once an unnamed countdown from c_7F0 runs out, an airborne fighter moving down can leave through an air up special (ftCo_800D69C4) or an air jump (ftCo_800CB8E0), which the atlas reads as the meteor cancel. A jump pressed in hitstun otherwise only records the count left. While the flag is set an airborne fighter gets gravity and aerial_friction (ft_80084EEC) in place of fast-fall and drift (ft_80084DB0). A change of motion state clears the flag unless the new state is entered with Ft_MF_SkipHitStun. The DamageFlyRoll status's own routines aren't read here.Code

References

  1. ^ abcIn the US version of Super Smash Bros., ftCommonDamageInitDamageVars sets a hit fighter's hitstun_tics, a whole-number count, to its knockback divided by 1.875 (ftParamGetHitStun), and to 1 if that comes to 0. The damage statuses' common update routines take 1 off the count each time they run. Until it reaches 0, their common interrupt routines don't run the standing, falling, or hammer interrupt checks (ftCommonWaitProcInterrupt, ftCommonFallProcInterrupt, and the hammer's), so the fighter can't act, and an airborne fighter gets friction in place of the usual drift and fast-fall. At 0, the status ends once its animation has run out. A knockback of 100 gives 53 counts (computed).CodeVetriTheRetri/ssb-decomp-re
    How we know
    1505f32 ftParamGetHitStun(f32 knockback)
    ⋮
    1507    return knockback / 1.875F;
    
    src/ft/ftparam.c lines 1505–1508 at 572a747 · upstream ↗
    482    f32 hitstun_tics = ftParamGetHitStun(knockback);
    ⋮
    491    this_fp->status_vars.common.damage.hitstun_tics = hitstun_tics;
    ⋮
    493    if (this_fp->status_vars.common.damage.hitstun_tics == 0)
    ⋮
    495        this_fp->status_vars.common.damage.hitstun_tics = 1;
    
    src/ft/ftcommon/ftcommondamage.c lines 482–496 at 572a747 · upstream ↗
    468typedef struct ftCommonDamageStatusVars
    ⋮
    470	s32 hitstun_tics;
    
    src/ft/ftcommon.h lines 468–470 at 572a747 · upstream ↗
    662void ftCommonDamageGotoDamageStatus(GObj *fighter_gobj)
    ⋮
    674    else ftCommonDamageInitDamageVars(fighter_gobj, -1, fp->damage_queue, fp->damage_knockback, fp->damage_angle, fp->damage_lr, fp->damage_index, fp->damage_element, fp->damage_player_num, FALSE, FALSE, TRUE);
    
    src/ft/ftcommon/ftcommondamage.c lines 662–674 at 572a747 · upstream ↗
    85void ftCommonDamageDecHitStunSetPublic(GObj *fighter_gobj)
    ⋮
    89    if (fp->status_vars.common.damage.hitstun_tics != 0)
    ⋮
    91        fp->status_vars.common.damage.hitstun_tics--;
    ⋮
    101void ftCommonDamageCommonProcUpdate(GObj *fighter_gobj)
    ⋮
    105    ftCommonDamageDecHitStunSetPublic(fighter_gobj);
    ⋮
    107    if ((fighter_gobj->anim_frame <= 0.0F) && (fp->status_vars.common.damage.hitstun_tics == 0))
    ⋮
    109        mpCommonSetFighterWaitOrFall(fighter_gobj);
    ⋮
    114void ftCommonDamageAirCommonProcUpdate(GObj *fighter_gobj)
    ⋮
    119    ftCommonDamageDecHitStunSetPublic(fighter_gobj);
    ⋮
    121    if ((fighter_gobj->anim_frame <= 0.0F) && (fp->status_vars.common.damage.hitstun_tics == 0))
    ⋮
    123        ftCommonDamageFallSetStatusFromDamage(fighter_gobj);
    
    src/ft/ftcommon/ftcommondamage.c lines 85–123 at 572a747 · upstream ↗
    166void ftCommonDamageCommonProcInterrupt(GObj *fighter_gobj)
    ⋮
    170    if (fp->status_vars.common.damage.hitstun_tics == 0)
    ⋮
    172        fp->is_hitstun = FALSE;
    ⋮
    176            if (ftHammerCheckHoldHammer(fighter_gobj) != FALSE)
    ⋮
    178                ftCommonHammerFallProcInterrupt(fighter_gobj);
    ⋮
    180            else ftCommonFallProcInterrupt(fighter_gobj);
    ⋮
    182        else if (ftHammerCheckHoldHammer(fighter_gobj) != FALSE)
    ⋮
    184            ftHammerProcInterrupt(fighter_gobj);
    ⋮
    186        else ftCommonWaitProcInterrupt(fighter_gobj);
    ⋮
    191void ftCommonDamageAirCommonProcInterrupt(GObj *fighter_gobj)
    ⋮
    195    if (fp->status_vars.common.damage.hitstun_tics == 0)
    ⋮
    197        fp->is_hitstun = FALSE;
    ⋮
    
    src/ft/ftcommon/ftcommondamage.c lines 166–199 at 572a747 · upstream ↗
    214void ftCommonDamageCommonProcPhysics(GObj *fighter_gobj)
    ⋮
    218    if (fp->ga == nMPKineticsAir)
    ⋮
    220        if (fp->status_vars.common.damage.hitstun_tics == 0)
    ⋮
    222            ftPhysicsApplyAirVelDriftFastFall(fighter_gobj);
    ⋮
    224        else ftPhysicsApplyAirVelFriction(fighter_gobj);
    
    src/ft/ftcommon/ftcommondamage.c lines 214–224 at 572a747 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  2. ^ abIn the NTSC 1.02 version of Super Smash Bros. Melee, ftCo_8008DCE0, the routine that puts a hit fighter into a Damage status, sets the unnamed count mv.co.damage.x0 to the knockback (kb_applied) times p_ftCommonData->x154, a value from the disc file PlCo.dat, truncated to a whole number, and to 1 if that comes to 0. It also sets the flag x221C_b6, which ftLib_IsInHitstun returns. Where Super Smash Bros. divides the knockback by 1.875 (ssb64/hitstun), Melee multiplies it by a value the code doesn't hold. The animation routines of the Damage statuses (75 to 86) and the DamageFly statuses (87 to 90) take 1 off the count while it's above 0 (ftCo_8008F744) and clear the flag once it's 0 or below; the status ends when its animation has run out with the flag clear. While the flag is set, their interrupt routines run only doIasa, as the decompilers name it, in place of the wait, fall, or hammer checks, so the fighter can't act, with one exception: after a hit whose angle ftColl_8007AC68 accepts (between unk_kb_angle_min and unk_kb_angle_max), once an unnamed countdown from c_7F0 runs out, an airborne fighter moving down can leave through an air up special (ftCo_800D69C4) or an air jump (ftCo_800CB8E0), which the atlas reads as the meteor cancel. A jump pressed in hitstun otherwise only records the count left. While the flag is set an airborne fighter gets gravity and aerial_friction (ft_80084EEC) in place of fast-fall and drift (ft_80084DB0). A change of motion state clears the flag unless the new state is entered with Ft_MF_SkipHitStun. The DamageFlyRoll status's own routines aren't read here.Codedoldecomp/melee · VetriTheRetri/ssb-decomp-rerevised
    How we know
    263void ftCo_8008DCE0(Fighter_GObj* gobj, int arg1, float facing_dir)
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c line 263 at f0cdbb0 · upstream ↗
    282    float kb_applied = fp->dmg.kb_applied;
    ⋮
    287    scaled_kb_154 = kb_applied * p_ftCommonData->x154;
    288    fp->mv.co.damage.x0 = (int) scaled_kb_154;
    289    if (!fp->mv.co.damage.x0) {
    290        fp->mv.co.damage.x0 = 1;
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 282–291 at f0cdbb0 · upstream ↗
    61int ftCo_803C5520[2][4][3] = {
    ⋮
    63        { 81, 78, 75 },
    64        { 82, 79, 76 },
    65        { 83, 80, 77 },
    66        { 89, 88, 87 },
    ⋮
    69        { 84, 84, 84 },
    70        { 85, 85, 85 },
    71        { 86, 86, 86 },
    72        { 89, 88, 87 },
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 60–73 at f0cdbb0 · upstream ↗
    405    Fighter_ChangeMotionState(gobj, msid, 0x40U, 0, 1, 0, NULL);
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c line 405 at f0cdbb0 · upstream ↗
    423    fp->x221C_b6 = true;
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c line 423 at f0cdbb0 · upstream ↗
    665bool ftLib_IsInHitstun(HSD_GObj* gobj)
    ⋮
    667    Fighter* fp = GET_FIGHTER(gobj);
    668    return fp->x221C_b6;
    
    src/melee/ft/ftlib.c lines 665–669 at f0cdbb0 · upstream ↗
    843void ftCo_8008F744(Fighter_GObj* gobj)
    ⋮
    845    Fighter* fp = GET_FIGHTER(gobj);
    846    if (fp->mv.co.damage.x0 > 0) {
    847        fp->mv.co.damage.x0 -= 1;
    ⋮
    849    if (fp->x221C_b6) {
    850        if (fp->mv.co.damage.x0 <= 0) {
    851            fp->x221C_b6 = false;
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 843–852 at f0cdbb0 · upstream ↗
    872void ftCo_Damage_Anim(Fighter_GObj* gobj)
    ⋮
    874    Fighter* fp = GET_FIGHTER(gobj);
    875    ftCo_8008F744(gobj);
    876    if (!ftAnim_IsFramesRemaining(gobj) && !fp->x221C_b6) {
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 872–876 at f0cdbb0 · upstream ↗
    890bool doIasa(Fighter_GObj* gobj)
    ⋮
    892    Fighter* fp = gobj->user_data;
    893    if (fp->mv.co.damage.x1A) {
    894        if (fp->mv.co.damage.x1B) {
    895            --fp->mv.co.damage.x1B;
    ⋮
    897        if (!fp->mv.co.damage.x1B && fp->ground_or_air == GA_Air &&
    898            fp->x8c_kb_vel.y < 0 &&
    899            (ftCo_800D69C4(gobj) || ftCo_800CB8E0(gobj)))
    ⋮
    905            return true;
    ⋮
    909    if (ftCo_Jump_GetInput(gobj)) {
    910        fp->mv.co.damage.x14 = fp->mv.co.damage.x0;
    911        return true;
    ⋮
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 890–914 at f0cdbb0 · upstream ↗
    916void ftCo_Damage_IASA(Fighter_GObj* gobj)
    ⋮
    918    Fighter* fp = gobj->user_data;
    919    if (!fp->x221C_b6) {
    920        if (ftCo_800C5240(gobj)) {
    921            if (fp->ground_or_air == GA_Air) {
    922                ftCo_HammerFall_IASA(gobj);
    923            } else {
    924                ftCo_HammerWait_IASA(gobj);
    ⋮
    926        } else {
    ⋮
    932            if (fp->ground_or_air == GA_Air) {
    933                ftCo_Fall_IASA_Inner(gobj);
    934            } else {
    ⋮
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 916–941 at f0cdbb0 · upstream ↗
    79float ftCo_Damage_CalcAngle(Fighter* fp, float f)
    ⋮
    81    if (fp->dmg.x1848_kb_angle != 361) {
    82        if (ftColl_8007AC68(fp->dmg.x1848_kb_angle)) {
    83            fp->mv.co.damage.x1A = 1;
    84            fp->mv.co.damage.x1B = p_ftCommonData->x7F0;
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 79–85 at f0cdbb0 · upstream ↗
    312        fp->mv.co.damage.x1A = 0;
    313        fp->mv.co.damage.x14 = 0;
    314        kb_angle = ftCo_Damage_CalcAngle(fp, kb_applied);
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 312–314 at f0cdbb0 · upstream ↗
    2481bool ftColl_8007AC68(u32 kb_angle)
    ⋮
    2483    if (kb_angle != 361 && p_ftCommonData->unk_kb_angle_min <= kb_angle &&
    2484        kb_angle <= p_ftCommonData->unk_kb_angle_max)
    ⋮
    2486        return true;
    ⋮
    2488    return false;
    
    src/melee/ft/ftcoll.c lines 2481–2489 at f0cdbb0 · upstream ↗
    103bool ftCo_800D69C4(Fighter_GObj* gobj)
    ⋮
    110        ftData_SpecialAirHi[fp->kind](gobj);
    111        return true;
    
    src/melee/ft/kinds/ftCommon/ftCo_Attack100.c lines 103–111 at f0cdbb0 · upstream ↗
    73bool ftCo_800CB8E0(Fighter_GObj* gobj)
    ⋮
    83    return ftCo_JumpAerial_CheckInput(gobj, true);
    
    src/melee/ft/kinds/ftCommon/ftCo_JumpAerial.c lines 73–83 at f0cdbb0 · upstream ↗
    943void ftCo_Damage_Phys(Fighter_GObj* gobj)
    ⋮
    945    Fighter* fp = gobj->user_data;
    946    if (fp->ground_or_air == GA_Air) {
    947        if (!fp->x221C_b6) {
    948            ft_80084DB0(gobj);
    949        } else {
    950            ft_80084EEC(gobj);
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 943–951 at f0cdbb0 · upstream ↗
    34void ft_80084EEC(Fighter_GObj* gobj)
    ⋮
    39    ftCommon_Fall(fp, co_attrs->gravity, co_attrs->terminal_velocity);
    40    ftCommon_CalcSelfAccel_Deaccel(fp, co_attrs->aerial_friction);
    
    src/melee/ft/ft_084E.c lines 34–41 at f0cdbb0 · upstream ↗
    1371void ft_80084DB0(Fighter_GObj* gobj)
    ⋮
    1376    ftCommon_CheckFallFast(fp);
    1377    if (fp->fall_fast) {
    1378        ftCommon_FallFast(fp);
    ⋮
    1382    ftCommon_CalcSelfAccel_Drift(fp);
    
    src/melee/ft/ft_081B.c lines 1371–1382 at f0cdbb0 · upstream ↗
    1032void ftCo_DamageFly_Anim(Fighter_GObj* gobj)
    ⋮
    1036    ftCo_8008F744(gobj);
    1037    if (!ftAnim_IsFramesRemaining(gobj) && !fp->x221C_b6) {
    ⋮
    1044void ftCo_DamageFly_IASA(Fighter_GObj* gobj)
    ⋮
    1046    if (!GET_FIGHTER(gobj)->x221C_b6) {
    1047        ftCo_DamageFall_IASA(gobj);
    1048    } else {
    1049        RETURN_IF(doIasa(gobj));
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 1032–1050 at f0cdbb0 · upstream ↗
    1062static void inlineE0(Fighter_GObj* gobj)
    ⋮
    1064    Fighter* fp = GET_FIGHTER(gobj);
    1065    if (!fp->x221C_b6) {
    1066        ft_80084DB0(gobj);
    1067    } else {
    1068        ft_80084EEC(gobj);
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 1062–1070 at f0cdbb0 · upstream ↗
    960        // ftCo_MS_DamageHi1 = 75
    961        ftCo_SM_DamageHi1,
    962        ftCo_MF_Damage,
    963        FtMoveId_Default << 24,
    964        ftCo_Damage_Anim,
    965        ftCo_Damage_IASA,
    966        ftCo_Damage_Phys,
    
    src/melee/ft/ftmotionstates.c lines 960–966 at f0cdbb0 · upstream ↗
    1092        // ftCo_MS_DamageFlyHi = 87
    ⋮
    1096        ftCo_DamageFly_Anim,
    1097        ftCo_DamageFly_IASA,
    1098        ftCo_DamageFly_Phys,
    
    src/melee/ft/ftmotionstates.c lines 1092–1098 at f0cdbb0 · upstream ↗
    1035    if (((flags & Ft_MF_SkipHitStun) == 0) && (fp->x221C_b6 != 0U)) {
    1036        fp->x221C_b6 = 0;
    
    src/melee/ft/fighter.c lines 1035–1037 at f0cdbb0 · upstream ↗
    1505f32 ftParamGetHitStun(f32 knockback)
    ⋮
    1507    return knockback / 1.875F;
    
    src/ft/ftparam.c lines 1505–1508 at 572a747 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

Sources

Code