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

The atlas reads Super Smash Bros. Melee through the doldecomp decompilation, C that compiles to the NTSC 1.02 release’s own code. Names and comments quoted here are theirs. Most of the game’s tuning isn’t in that code: it’s read from the disc file PlCo.dat, so the claims here give the shape of each rule with its constants named by their offset in that file. Nothing has been measured in the game yet.

The knockback formula has the same terms as Super Smash Bros.’s, but the fighter’s weight attribute now divides the launch where the earlier game multiplied by it1. Hitstun is the knockback times a value from the disc, and after a hit at an angle in a set range, a falling fighter can end it with an air jump or up special2. How fast the shield wears while held, and how much a hit takes from it, both depend on how far the analog trigger is pressed3. A trigger press shortly before an aerial lands divides its landing lag, where Super Smash Bros. skipped the lag on a Z press4.

Mechanics

MechanicKindHow
KnockbackPercent-scaledSuper Smash Bros.'s formula with its constants moved to a data file, and the weight dividing the launch rather than multiplying it
HitstunFrom 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
BlockingGuard metera shield whose wear while held and damage from hits both depend on how far the analog trigger is pressed
Landing lagPress reduces ita trigger or Z press shortly before an aerial lands divides its landing lag
Every claim about this game, by concept (4)
BlockingIn the NTSC 1.02 version of Super Smash Bros. Melee, a fighter's shield_health is a float that starts at x260_startShieldHealth. Each time Fighter_procCollResolve runs for a fighter that isn't asleep (is_sleeping), a fighter whose unnamed flag x221A_b7 is clear regains c_27C, up to the start value. That flag is set when the guard statuses switch on the shield's collision (ftColl_8007B1B8), and the atlas reads it as "shield up". While it's set, the fighter instead loses c_284 × s × (1 − (l·(c_2E0 − c_2DC) + c_2DC)) + c_288, where s is x19A0_shieldDamageTaken, each shield hit's damage plus its unnamed x34 (a fighter's hit counts only while the flag x221C_b2, set on entering ftCo_MS_GuardReflect, is clear), and l is lightshield_amount. Below 0, the health is set to x280_unkShieldHealth, and on the hit path the shield break (ftCo_80098B20, which enters ftCo_MS_ShieldBreakFly) starts only in the branch taken when the fighter has no knockback to apply (kb_applied is 0), the unnamed x18a0 is 0, and a shield hit is recorded (x19A4). While the fighter holds the shield, the animation routines of ftCo_MS_GuardOn and ftCo_MS_Guard call ftCo_800925A4, which, while x221B_b0 is set, sets l from the analog trigger past its deadzone, (trigger − deadzone) / (1 − deadzone), keeping the old value when that's negative, and takes c_278 × (l·(c_2F0 − c_2EC) + c_2EC) off the health; below 0 it sets the health to 0 and starts the shield break. Every c is a field of p_ftCommonData, from the disc file PlCo.dat, so the numbers aren't in the code. Where Super Smash Bros. counts whole points from a fixed 55 and resets to 30, with no say for how hard the button is pressed (ssb64/shield), Melee's wear while held and its damage from hits both depend on l.Code
HitstunIn 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
KnockbackIn the NTSC 1.02 version of Super Smash Bros. Melee, ftColl_80079AB0 computes a hit's knockback as D⋅A⋅r⋅(0.01g⋅(c11C⋅(cF8−cF8w1+w)⋅(c110d+c114nd)+c120)+b) capped at c_108. Every c is an unnamed field of p_ftCommonData, which Fighter_LoadCommonData loads from the disc file PlCo.dat, so the constants aren't in the code. Here d is the target's x1830_percent plus x1838_percentTemp, or, while the unnamed flag x2225_b7 is set, c_6D4 (c_6D8 if stamina_dead) plus x1838_percentTemp; n is the hit capsule's unk_count; w is the target's weight attribute times c_F4; g and b are the capsule's unnamed x24 and x2C; r is gm_8016B248(), the match rules' x30, which the VS setup in gm_1601.c sets to 0.1 × the rules' damage_ratio; and A and D are Player_GetAttackRatio for the attacker and Player_GetDefenseRatio for the target. A capsule whose unnamed x28 (k) isn't 0 uses c_118·c_110 + c_114·c_118·k in place of the percent term. The terms sit where Super Smash Bros.'s 0.1, 0.05, 1.4, 18, and its set-knockback 10 and cap 2500 do (ssb64/knockback), and the atlas reads g as the growth and b as the base by that position. Where Super Smash Bros. multiplies by its weight attribute, Melee's weight term equals c_F8 / (1 + w) (computed), so the weight divides. Of the hits a fighter logs in one update, ftColl_8007A06C keeps the largest knockback and writes it to kb_applied; ftCo_Damage_CalcKnockback then multiplies it by kb_squat_mul in ftCo_MS_Squat or ftCo_MS_SquatWait, by kb_ice_mul in ftCo_MS_DamageIce, and by kb_smashcharge_mul while a smash attack charges, rescales it with ftCo_CalcYScaledKnockback when the fighter's vertical scale isn't 1, subtracts the larger of armor0 and armor1 (plus metal_armor for a metal fighter), and raises it to kb_min if it falls below.Code
Landing lagIn the NTSC 1.02 version of Super Smash Bros. Melee, an aerial attack (statuses ftCo_MS_AttackAirN to ftCo_MS_AttackAirLw) that touches down calls ftCo_LandingAir_EnterWithLag from its collision routine ftCo_AttackAir_Coll, through ft_80082C74, which calls it when the unnamed ft_80081D0C returns true. If the move's command script has set cmd_vars[0], which entering the aerial clears, the fighter enters that aerial's LandingAir status with the fighter's landing-lag attribute for it (landingairn_lag and the four like it), and the animation plays at a rate of (ftAnim_8006F484 + 0.1) / lag, where ftAnim_8006F484 returns the animation's end frame. If the unnamed count x67F is below c_E4 at that moment, the lag is first divided by c_E8, truncated to a whole number, and raised to 1 if that's 0; c_E4 and c_E8 are p_ftCommonData fields from PlCo.dat, so the window and divisor aren't in the code. Fighter_procInput sets x67F to 0 on an update where the HSD_PAD_LR bit is newly pressed and otherwise adds 1, up to 255. That bit is on while L or R is held, while the analog trigger is past its deadzone, or while Z is held unless gm_GetDbPauseFlag(0) is true, and it's off while the unnamed gm_8016B0FC is true. Without cmd_vars[0], the fighter takes the basic landing (ftCo_Landing_Enter_Basic). Super Smash Bros. reads the same moment differently (ftCommonAttackAirProcMap): when the aerial's flag1 is clear or Z was pressed no more than 10 counts before (tics_since_last_z ≤ 10), it skips the aerial's landing lag outright, landing in Wait if the air speed is above −20 and in Landing otherwise, where Melee divides the lag.Code

References

  1. ^In the NTSC 1.02 version of Super Smash Bros. Melee, ftColl_80079AB0 computes a hit's knockback as D⋅A⋅r⋅(0.01g⋅(c11C⋅(cF8−cF8w1+w)⋅(c110d+c114nd)+c120)+b) capped at c_108. Every c is an unnamed field of p_ftCommonData, which Fighter_LoadCommonData loads from the disc file PlCo.dat, so the constants aren't in the code. Here d is the target's x1830_percent plus x1838_percentTemp, or, while the unnamed flag x2225_b7 is set, c_6D4 (c_6D8 if stamina_dead) plus x1838_percentTemp; n is the hit capsule's unk_count; w is the target's weight attribute times c_F4; g and b are the capsule's unnamed x24 and x2C; r is gm_8016B248(), the match rules' x30, which the VS setup in gm_1601.c sets to 0.1 × the rules' damage_ratio; and A and D are Player_GetAttackRatio for the attacker and Player_GetDefenseRatio for the target. A capsule whose unnamed x28 (k) isn't 0 uses c_118·c_110 + c_114·c_118·k in place of the percent term. The terms sit where Super Smash Bros.'s 0.1, 0.05, 1.4, 18, and its set-knockback 10 and cap 2500 do (ssb64/knockback), and the atlas reads g as the growth and b as the base by that position. Where Super Smash Bros. multiplies by its weight attribute, Melee's weight term equals c_F8 / (1 + w) (computed), so the weight divides. Of the hits a fighter logs in one update, ftColl_8007A06C keeps the largest knockback and writes it to kb_applied; ftCo_Damage_CalcKnockback then multiplies it by kb_squat_mul in ftCo_MS_Squat or ftCo_MS_SquatWait, by kb_ice_mul in ftCo_MS_DamageIce, and by kb_smashcharge_mul while a smash attack charges, rescales it with ftCo_CalcYScaledKnockback when the fighter's vertical scale isn't 1, subtracts the larger of armor0 and armor1 (plus metal_armor for a metal fighter), and raises it to kb_min if it falls below.Codedoldecomp/melee · VetriTheRetri/ssb-decomp-re
    How we know
    2061static inline s32 ftColl_GetDamageCount(Fighter* fp, ftCommonData* ftd)
    ⋮
    2063    if (fp->x2225_b7) {
    2064        if (fp->stamina_dead) {
    2065            return ftd->x6D8;
    ⋮
    2067        return ftd->x6D4;
    ⋮
    2069    return (s32) fp->dmg.x1830_percent;
    
    src/melee/ft/ftcoll.c lines 2061–2069 at f0cdbb0 · upstream ↗
    2075#define KNOCKBACK(defense, attack, arg3, one, ftd, hit, w, inner)             \
    2076    ((defense) *                                                              \
    2077     ((attack) *                                                              \
    2078      ((arg3) * ((0.01F * (hit)->x24 *                                        \
    2079                  ((ftd)->x11C *                                              \
    2080                       (((ftd)->xF8 - (((w) * (ftd)->xF8) / ((one) + (w)))) * \
    2081                        (inner)) +                                            \
    2082                   (ftd)->x120)) +                                            \
    2083                 (hit)->x2C))))
    ⋮
    2091    float w = weight;
    2092    w *= ftd->xF4;
    ⋮
    2094    if (hit->x28 != 0) {
    ⋮
    
    src/melee/ft/ftcoll.c lines 2075–2118 at f0cdbb0 · upstream ↗
    2120float ftColl_80079C70(Fighter* fp, Fighter* attacker, HitCapsule* hit,
    2121                      int unk_count)
    ⋮
    2123    ftCo_DatAttrs* co = &fp->co_attrs;
    2124    return ftColl_80079AB0(fp, hit, unk_count, gm_8016B248(),
    2125                           Player_GetAttackRatio(attacker->player_idx),
    2126                           Player_GetDefenseRatio(fp->player_idx), co->weight);
    
    src/melee/ft/ftcoll.c lines 2120–2126 at f0cdbb0 · upstream ↗
    37    /*  +8 */ u32 unk_count;
    ⋮
    42    /* +24 */ u32 x24;
    43    /* +28 */ u32 x28;
    44    /* +2C */ u32 x2C;
    
    src/melee/lb/types.h lines 37–44 at f0cdbb0 · upstream ↗
    918    /* +088 fp+198 */ float weight;
    
    src/melee/ft/types.h line 918 at f0cdbb0 · upstream ↗
    182    lbArchive_LoadSymbols("PlCo.dat", &data, "ftLoadCommonData", 0);
    ⋮
    188    p_ftCommonData = data->common; // p_ftCommonData
    
    src/melee/ft/fighter.c lines 182–189 at f0cdbb0 · upstream ↗
    263f32 gm_8016B248(void)
    ⋮
    265    return gm_GetStartMeleeRules()->x30;
    
    src/melee/gm/gmvs.c lines 263–266 at f0cdbb0 · upstream ↗
    3810    vs_data->start.rules.x30 = 0.1f * rules->damage_ratio;
    
    src/melee/gm/gm_1601.c line 3810 at f0cdbb0 · upstream ↗
    2253            kb = ftColl_80079C70(fp, attacker_fp, hit, unk_count);
    
    src/melee/ft/ftcoll.c line 2253 at f0cdbb0 · upstream ↗
    2298        if (kb > best_kb.v) {
    ⋮
    2306            best_kb.v = kb;
    2307            best_idx = i;
    
    src/melee/ft/ftcoll.c lines 2298–2307 at f0cdbb0 · upstream ↗
    2194struct DmgResult {
    2195    /* 0x00 */ float dir;
    2196    /* 0x04 */ int angle;
    2197    /* 0x08 */ int hurt_height;
    2198    /* 0x0C */ float kb;
    
    src/melee/ft/ftcoll.c lines 2194–2198 at f0cdbb0 · upstream ↗
    2389    out->kb = best_kb.v;
    
    src/melee/ft/ftcoll.c line 2389 at f0cdbb0 · upstream ↗
    2452    ftColl_8007A06C(gobj, &fp->dmg.facing_dir_1, dmg_log0, dmg_log0_idx, 1);
    
    src/melee/ft/ftcoll.c line 2452 at f0cdbb0 · upstream ↗
    1660        /* fp+1844 */ float facing_dir_1;
    1661        /* fp+1848 */ int x1848_kb_angle;
    1662        /* fp+184C */ int x184c_damaged_hurtbox;
    1663        /* fp+1850 */ float kb_applied;
    
    src/melee/ft/types.h lines 1660–1663 at f0cdbb0 · upstream ↗
    2852        forceAppliedOnHit = fp->dmg.kb_applied;
    ⋮
    2859            ftCo_Damage_CalcKnockback(fp);
    
    src/melee/ft/fighter.c lines 2852–2859 at f0cdbb0 · upstream ↗
    118void ftCo_Damage_CalcKnockback(Fighter* fp)
    ⋮
    120    if (!fp->dmg.kb_applied) {
    121        return;
    ⋮
    123    if (fp->motion_id == ftCo_MS_Squat || fp->motion_id == ftCo_MS_SquatWait) {
    124        fp->dmg.kb_applied *= p_ftCommonData->kb_squat_mul;
    ⋮
    126    if (fp->motion_id == ftCo_MS_DamageIce) {
    127        fp->dmg.kb_applied *= p_ftCommonData->kb_ice_mul;
    ⋮
    129    if (fp->smash_attrs.state == SmashState_Charging) {
    130        fp->dmg.kb_applied *= p_ftCommonData->kb_smashcharge_mul;
    ⋮
    132    if (fp->x34_scale.y != 1) {
    133        fp->dmg.kb_applied = ftCo_CalcYScaledKnockback(
    134            fp->dmg.kb_applied, fp->x34_scale.y, Fighter_804D6524->x0);
    ⋮
    
    src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 118–146 at f0cdbb0 · upstream ↗
    1451f32 ftParamGetCommonKnockback(s32 percent_damage, s32 recent_damage, s32 hit_damage, s32 knockback_weight, s32 knockback_scale, s32 knockback_base, f32 weight, s32 attack_handicap, s32 defend_handicap)
    ⋮
    1457        knockback = ( ( ( ( ( ( 1 + ( 10.0F * knockback_weight * 0.05F ) ) * weight * 1.4F ) + 18.0F ) * ( knockback_scale * 0.01F ) ) + knockback_base ) * ( gSCManagerBattleState->damage_ratio * 0.01F ) * dFTCommonDataHandicapTable[attack_handicap - 1][0] ) * dFTCommonDataHandicapTable[defend_handicap - 1][1];
    ⋮
    1463        knockback = ( ( ( ( ( ( ( damage_add * 0.1F ) + ( damage_add * hit_damage * 0.05F ) ) * weight * 1.4F ) + 18.0F ) * ( knockback_scale * 0.01F ) ) + knockback_base ) * ( gSCManagerBattleState->damage_ratio * 0.01F ) * dFTCommonDataHandicapTable[attack_handicap - 1][0] ) * dFTCommonDataHandicapTable[defend_handicap - 1][1];
    ⋮
    1465    if (knockback >= 2500.0F)
    ⋮
    1467        knockback = 2500.0F;
    
    src/ft/ftparam.c lines 1451–1468 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. ^In 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

  3. ^In the NTSC 1.02 version of Super Smash Bros. Melee, a fighter's shield_health is a float that starts at x260_startShieldHealth. Each time Fighter_procCollResolve runs for a fighter that isn't asleep (is_sleeping), a fighter whose unnamed flag x221A_b7 is clear regains c_27C, up to the start value. That flag is set when the guard statuses switch on the shield's collision (ftColl_8007B1B8), and the atlas reads it as "shield up". While it's set, the fighter instead loses c_284 × s × (1 − (l·(c_2E0 − c_2DC) + c_2DC)) + c_288, where s is x19A0_shieldDamageTaken, each shield hit's damage plus its unnamed x34 (a fighter's hit counts only while the flag x221C_b2, set on entering ftCo_MS_GuardReflect, is clear), and l is lightshield_amount. Below 0, the health is set to x280_unkShieldHealth, and on the hit path the shield break (ftCo_80098B20, which enters ftCo_MS_ShieldBreakFly) starts only in the branch taken when the fighter has no knockback to apply (kb_applied is 0), the unnamed x18a0 is 0, and a shield hit is recorded (x19A4). While the fighter holds the shield, the animation routines of ftCo_MS_GuardOn and ftCo_MS_Guard call ftCo_800925A4, which, while x221B_b0 is set, sets l from the analog trigger past its deadzone, (trigger − deadzone) / (1 − deadzone), keeping the old value when that's negative, and takes c_278 × (l·(c_2F0 − c_2EC) + c_2EC) off the health; below 0 it sets the health to 0 and starts the shield break. Every c is a field of p_ftCommonData, from the disc file PlCo.dat, so the numbers aren't in the code. Where Super Smash Bros. counts whole points from a fixed 55 and resets to 30, with no say for how hard the button is pressed (ssb64/shield), Melee's wear while held and its damage from hits both depend on l.Codedoldecomp/melee · VetriTheRetri/ssb-decomp-rerevised
    How we know
    420    fp->shield_health = p_ftCommonData->x260_startShieldHealth;
    
    src/melee/ft/fighter.c line 420 at f0cdbb0 · upstream ↗
    1741    /* fp+1998 */ float shield_health;
    1742    /* fp+199C */ float lightshield_amount;
    1743    /* fp+19A0 */ s32 x19A0_shieldDamageTaken;
    
    src/melee/ft/types.h lines 1741–1743 at f0cdbb0 · upstream ↗
    2806void Fighter_procCollResolve(Fighter_GObj* gobj)
    ⋮
    2816    if (!fp->is_sleeping) {
    2817        if (!fp->x221A_b7) {
    2818            if (fp->shield_health < p_ftCommonData->x260_startShieldHealth) {
    2819                fp->shield_health += p_ftCommonData->x27C;
    2820                if (fp->shield_health > p_ftCommonData->x260_startShieldHealth)
    ⋮
    2822                    fp->shield_health = p_ftCommonData->x260_startShieldHealth;
    ⋮
    2827        if (fp->x221A_b7) {
    2828            fp->shield_health -=
    2829                (p_ftCommonData->x284 *
    2830                 ((fp->x19A0_shieldDamageTaken) *
    2831                  (1.0f - ((fp->lightshield_amount *
    ⋮
    
    src/melee/ft/fighter.c lines 2806–2842 at f0cdbb0 · upstream ↗
    2853        if (forceAppliedOnHit) {
    
    src/melee/ft/fighter.c line 2853 at f0cdbb0 · upstream ↗
    2907        } else if (fp->dmg.x18a0) {
    ⋮
    2910        } else if (fp->x19A4) {
    2911            if (bool3) {
    2912                ftCo_80098B20(gobj);
    
    src/melee/ft/fighter.c lines 2907–2912 at f0cdbb0 · upstream ↗
    21void ftCo_80098B20(Fighter_GObj* gobj)
    ⋮
    25    Fighter_ChangeMotionState(gobj, ftCo_MS_ShieldBreakFly, Ft_MF_Unk06, 0, 1,
    
    src/melee/ft/kinds/ftCommon/ftCo_ShieldBreakFly.c lines 21–26 at f0cdbb0 · upstream ↗
    301        if (!fp1->x221C_b2) {
    302            int tmp_dmg = int_dmg + hit0->x34;
    303            PAD_STACK(4);
    304            fp1->x19A0_shieldDamageTaken += tmp_dmg < 0 ? 0 : tmp_dmg;
    
    src/melee/ft/ftcoll.c lines 301–304 at f0cdbb0 · upstream ↗
    763        int total = dmg + hurt->x34;
    ⋮
    770        fp->x19A0_shieldDamageTaken += clamped_total;
    
    src/melee/ft/ftcoll.c lines 763–770 at f0cdbb0 · upstream ↗
    899void ftCo_8009388C(HSD_GObj* gobj)
    ⋮
    902    Fighter_ChangeMotionState(gobj, ftCo_MS_GuardReflect,
    ⋮
    910    fp->x221C_b2 = true;
    
    src/melee/ft/kinds/ftCommon/ftCo_Guard.c lines 899–910 at f0cdbb0 · upstream ↗
    507void ftCo_80092908(Fighter_GObj* gobj)
    ⋮
    510    Fighter_ChangeMotionState(gobj, ftCo_MS_Guard, Ft_MF_SkipAnim, 0, 1, 0,
    ⋮
    523            ftColl_8007B1B8(gobj, (ShieldDesc*) &absorb, ftCo_80092E50);
    524            fp2->x221A_b7 = true;
    
    src/melee/ft/kinds/ftCommon/ftCo_Guard.c lines 507–526 at f0cdbb0 · upstream ↗
    2651void ftColl_8007B1B8(Fighter_GObj* gobj, ShieldDesc* shield, HSD_GObjEvent cb)
    ⋮
    2653    Fighter* fp = GET_FIGHTER(gobj);
    2654    fp->x221B.x221B_b0 = true;
    
    src/melee/ft/ftcoll.c lines 2651–2654 at f0cdbb0 · upstream ↗
    400bool ftCo_800925A4(HSD_GObj* gobj)
    ⋮
    404    if (fp->x221B.x221B_b0) {
    405        fp->mv.co.guard.x2C = fp->lightshield_amount;
    ⋮
    407            fp->lightshield_amount =
    408                (fp->input.triggers[0] -
    409                 p_ftCommonData->analog_shoulder_deadzone) /
    410                            (1 - p_ftCommonData->analog_shoulder_deadzone) <
    ⋮
    412                    ? fp->mv.co.guard.x2C
    413                    : (fp->input.triggers[0] -
    414                       p_ftCommonData->analog_shoulder_deadzone) /
    415                          (1 - p_ftCommonData->analog_shoulder_deadzone);
    ⋮
    417        fp->shield_health -= p_ftCommonData->x278 *
    ⋮
    
    src/melee/ft/kinds/ftCommon/ftCo_Guard.c lines 400–427 at f0cdbb0 · upstream ↗
    440void ftCo_GuardOn_Anim(Fighter_GObj* gobj)
    ⋮
    442    Fighter* fp = gobj->user_data;
    443    fp->mv.co.guard.x0 += 1;
    444    if (ftCo_800925A4(gobj) == 0) {
    
    src/melee/ft/kinds/ftCommon/ftCo_Guard.c lines 440–444 at f0cdbb0 · upstream ↗
    530void ftCo_Guard_Anim(Fighter_GObj* gobj)
    ⋮
    535    if (!ftCo_800925A4(gobj)) {
    
    src/melee/ft/kinds/ftCommon/ftCo_Guard.c lines 530–535 at f0cdbb0 · upstream ↗
    2093        // ftCo_MS_GuardOn = 178
    ⋮
    2097        ftCo_GuardOn_Anim,
    ⋮
    2104        // ftCo_MS_Guard = 179
    ⋮
    2108        ftCo_Guard_Anim,
    
    src/melee/ft/ftmotionstates.c lines 2093–2108 at f0cdbb0 · upstream ↗
    431    fp->shield_health = (fp->fkind == nFTKindYoshi) ? 55 : 55;
    
    src/ft/ftmanager.c line 431 at 572a747 · upstream ↗
    3837    if (!(fp->is_shield) && (fp->shield_health < 55))
    ⋮
    3848    fp->shield_health -= fp->shield_damage_total;
    ⋮
    3850    if (fp->shield_health <= 0)
    ⋮
    3852        fp->shield_health = (fp->fkind == nFTKindYoshi) ? 30 : 30;
    
    src/ft/ftmain.c lines 3837–3854 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

  4. ^In the NTSC 1.02 version of Super Smash Bros. Melee, an aerial attack (statuses ftCo_MS_AttackAirN to ftCo_MS_AttackAirLw) that touches down calls ftCo_LandingAir_EnterWithLag from its collision routine ftCo_AttackAir_Coll, through ft_80082C74, which calls it when the unnamed ft_80081D0C returns true. If the move's command script has set cmd_vars[0], which entering the aerial clears, the fighter enters that aerial's LandingAir status with the fighter's landing-lag attribute for it (landingairn_lag and the four like it), and the animation plays at a rate of (ftAnim_8006F484 + 0.1) / lag, where ftAnim_8006F484 returns the animation's end frame. If the unnamed count x67F is below c_E4 at that moment, the lag is first divided by c_E8, truncated to a whole number, and raised to 1 if that's 0; c_E4 and c_E8 are p_ftCommonData fields from PlCo.dat, so the window and divisor aren't in the code. Fighter_procInput sets x67F to 0 on an update where the HSD_PAD_LR bit is newly pressed and otherwise adds 1, up to 255. That bit is on while L or R is held, while the analog trigger is past its deadzone, or while Z is held unless gm_GetDbPauseFlag(0) is true, and it's off while the unnamed gm_8016B0FC is true. Without cmd_vars[0], the fighter takes the basic landing (ftCo_Landing_Enter_Basic). Super Smash Bros. reads the same moment differently (ftCommonAttackAirProcMap): when the aerial's flag1 is clear or Z was pressed no more than 10 counts before (tics_since_last_z ≤ 10), it skips the aerial's landing lag outright, landing in Wait if the air speed is above −20 and in Landing otherwise, where Melee divides the lag.Codedoldecomp/melee · VetriTheRetri/ssb-decomp-re
    How we know
    14void ftCo_LandingAir_EnterWithLag(Fighter_GObj* gobj)
    ⋮
    20    if (fp->cmd_vars[0]) {
    21        switch (fp->motion_id) {
    22        case ftCo_MS_AttackAirN:
    23            lag = fp->co_attrs.landingairn_lag;
    24            msid = ftCo_MS_LandingAirN;
    25            break;
    ⋮
    29            break;
    ⋮
    33            break;
    ⋮
    37            break;
    ⋮
    41            break;
    ⋮
    43        if (msid != ftCo_MS_None && fp->x67F < p_ftCommonData->xE4) {
    ⋮
    
    src/melee/ft/kinds/ftCommon/ftCo_LandingAir.c lines 14–56 at f0cdbb0 · upstream ↗
    59void ftCo_LandingAir_EnterWithMsidLag(Fighter_GObj* gobj, FtMotionId msid,
    60                                      float lag)
    ⋮
    64    Fighter_ChangeMotionState(gobj, msid, Ft_MF_None, 0, 1, 0, NULL);
    65    ftAnim_SetAnimRate(gobj, (ftAnim_8006F484(gobj) + 0.1f) / lag);
    
    src/melee/ft/kinds/ftCommon/ftCo_LandingAir.c lines 59–65 at f0cdbb0 · upstream ↗
    575float ftAnim_8006F484(Fighter_GObj* fighter_gobj)
    ⋮
    580        return lbGetJObjEndFrame(jobj);
    ⋮
    582    return lbGetJObjEndFrame(fp->x8AC_animSkeleton);
    
    src/melee/ft/ftanim.c lines 575–582 at f0cdbb0 · upstream ↗
    125void ftCo_AttackAir_EnterFromMsid(Fighter_GObj* gobj, FtMotionId msid)
    ⋮
    129    fp->cmd_vars[0] = 0;
    
    src/melee/ft/kinds/ftCommon/ftCo_AttackAir.c lines 125–129 at f0cdbb0 · upstream ↗
    189void ftCo_AttackAir_Coll(Fighter_GObj* gobj)
    ⋮
    191    ft_80082C74(gobj, ftCo_LandingAir_EnterWithLag);
    
    src/melee/ft/kinds/ftCommon/ftCo_AttackAir.c lines 189–191 at f0cdbb0 · upstream ↗
    850        // ftCo_MS_AttackAirN = 65
    ⋮
    857        ftCo_AttackAir_Coll,
    
    src/melee/ft/ftmotionstates.c lines 850–857 at f0cdbb0 · upstream ↗
    548void ft_80082C74(Fighter_GObj* gobj, HSD_GObjEvent cb)
    ⋮
    550    bool var_r0 = ft_80081D0C(gobj);
    551    PAD_STACK(8);
    552    if (var_r0) {
    553        cb(gobj);
    
    src/melee/ft/ft_081B.c lines 548–554 at f0cdbb0 · upstream ↗
    456void ftAction_80071820(Fighter_GObj* gobj, CommandInfo* cmd)
    ⋮
    460    switch (cmd->x8.u->set_cmd_var.idx) {
    461    case 0:
    462        fp->cmd_vars[0] = cmd->x8.u->set_cmd_var.value;
    
    src/melee/ft/ftaction.c lines 456–462 at f0cdbb0 · upstream ↗
    947    /* +0E8 fp+1F8 */ float landingairn_lag;
    948    /* +0EC fp+1FC */ float landingairf_lag;
    949    /* +0F0 fp+200 */ float landingairb_lag;
    950    /* +0F4 fp+204 */ float landingairhi_lag;
    951    /* +0F8 fp+208 */ float landingairlw_lag;
    
    src/melee/ft/types.h lines 947–951 at f0cdbb0 · upstream ↗
    1879            if (gm_8016B0FC()) {
    1880                fp->input.triggers[0] = 0.0f;
    1881                if (ftCo_IsCpuControlled(fp)) {
    1882                    fp->input.held_buttons[0] &= HSD_PAD_A | HSD_PAD_XY;
    1883                } else {
    1884                    fp->input.held_buttons[0] &= HSD_PAD_A;
    ⋮
    1886            } else {
    1887                if (fp->input.held_buttons[0] & (HSD_PAD_L | HSD_PAD_R)) {
    1888                    fp->input.held_buttons[0] |= HSD_PAD_LR;
    1889                    fp->input.triggers[0] = 1.0f;
    1890                } else if (fp->input.triggers[0]) {
    1891                    fp->input.held_buttons[0] |= HSD_PAD_LR;
    ⋮
    
    src/melee/ft/fighter.c lines 1879–1898 at f0cdbb0 · upstream ↗
    1866            if (fp->input.triggers[0] <=
    1867                p_ftCommonData->analog_shoulder_deadzone)
    ⋮
    1869                fp->input.triggers[0] = 0.0f;
    
    src/melee/ft/fighter.c lines 1866–1869 at f0cdbb0 · upstream ↗
    1759static void Fighter_procInput_Inner1(Fighter* fp)
    ⋮
    1764    temp0_loc_0 = (fp->input.held_buttons[0] &
    1765                   (fp->input.held_buttons[1] ^ fp->input.held_buttons[0]));
    
    src/melee/ft/fighter.c lines 1759–1765 at f0cdbb0 · upstream ↗
    1902            Fighter_procInput_Inner1(fp);
    
    src/melee/ft/fighter.c line 1902 at f0cdbb0 · upstream ↗
    2105            if (fp->input.pressed_buttons & HSD_PAD_LR) {
    2106                fp->x67F = 0;
    2107            } else if (fp->x67F < 255) {
    2108                fp->x67F++;
    
    src/melee/ft/fighter.c lines 2105–2109 at f0cdbb0 · upstream ↗
    53void ftCommonAttackAirProcMap(GObj *fighter_gobj)
    ⋮
    57    if (mpCommonCheckFighterLanding(fighter_gobj) != FALSE)
    ⋮
    59        if ((fp->motion_vars.flags.flag1 != 0) && (fp->tics_since_last_z > FTCOMMON_ATTACKAIR_SMOOTHLANDING_TICS_MAX))
    ⋮
    65                ftCommonLandingAirSetStatus(fighter_gobj);
    ⋮
    67            else ftCommonLandingAirNullSetStatus(fighter_gobj, F_PCT_TO_DEC(fp->motion_vars.flags.flag1));
    ⋮
    69        else if (fp->physics.vel_air.y > FTCOMMON_ATTACKAIR_SKIPLANDING_VEL_Y_MAX)
    ⋮
    71            ftCommonWaitSetStatus(fighter_gobj);
    ⋮
    73        else ftCommonLandingSetStatus(fighter_gobj);
    
    src/ft/ftcommon/ftcommonattackair.c lines 53–74 at 572a747 · upstream ↗
    361#define FTCOMMON_ATTACKAIR_SMOOTHLANDING_TICS_MAX 10
    362#define FTCOMMON_ATTACKAIR_SKIPLANDING_VEL_Y_MAX (-20.0F)
    
    src/ft/ftcommon.h lines 361–362 at 572a747 · upstream ↗
    1373    if (this_fp->tics_since_last_z < FTINPUT_ZTRIGLAST_TICS_MAX)
    ⋮
    1375        this_fp->tics_since_last_z++;
    ⋮
    1377    if (this_fp->input.pl.button_tap & this_fp->input.button_mask_z)
    ⋮
    1379        this_fp->tics_since_last_z = 0;
    
    src/ft/ftmain.c lines 1373–1380 at 572a747 · upstream ↗
    190                fp->motion_vars.flags.flag1 = 0;
    
    src/ft/ftcommon/ftcommonattackair.c line 190 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

Sources

Code