Parry
A timed defense that turns an incoming hit aside when the input comes shortly before it lands.
On this page
A parry trades a held guard for timing: the input comes shortly before the hit, which is turned aside. In Street Fighter III: 3rd Strike a tap opens a window of 10 passes1 of the input check1, a guarding defender must tap within the first 2 or 3 passes2,2, and a parry leaves the attacker stopped for 16 to 203 counts3.
- Tap windowStreet Fighter III: 3rd Strike (1999). A fresh lever tap sets a counter of 11 (8 in the air, 6 against jumping attacks) that counts down each pass, and the parry works while it's nonzero.1,3
- From a guardStreet Fighter III: 3rd Strike (1999). While already guarding, the tap must come within the window's first 3 passes against a normal move, 2 against others.2
Games
| Game | Year | How | Note |
|---|---|---|---|
| Street Fighter III: 3rd Strike | 1999 | Tap window | a fresh lever tap sets a counter of 11 (8 in the air, 6 against jumping attacks) that counts down each pass, and the parry works while it's nonzero |
| Street Fighter III: 3rd Strike | 1999 | From a guard | while already guarding, the tap must come within the window's first 3 passes against a normal move, 2 against others |
Every claim about this mechanic, by game (3)
References
- ^ abcIn the PS2 port of Street Fighter III: 3rd Strike that crowded-street/3s-decomp rebuilds (the Street Fighter Anniversary Collection build), the parry is an input command that
check_10in CMD_MAIN.c reads. Once the lever has been neutral, a fresh lever press equal to the command's lever value (4 for the high parry and the air parry, 2 for the low one; the whole lever is compared, so a diagonal doesn't match; the air parry only while the character is above the ground) sets the parry's counter inwaza_flagto the command'sresetvalue, andcommand_ok_movetakes 1 off it on every pass, the tap's own included. When a press sets one parry counter,check_10zeroes each of the other parry counters (entries 3, 4, 5, 6, and 12) that is smaller than the new one, and an air parry press (entry 5) is zeroed at once while the entry-6 command'sfree3is above 0. The command tables every character shares givereset11 for the high and low parries (entries 3 and 4), 8 for the air parry (entry 5), and 6 for entry 12, so the counter stays nonzero for 10, 7, and 5 passes (computed).defense_groundchecks entry 12, not entry 3, against a jumping attack parried high (guard bit 2 withjump_att_flag); a jumping attack parried low still uses entry 4, and both of those branches are gated by bit 0x800. The System Direction setting adds −2, 0, 2, or 4 to each, and its defaults add 0. The window closes early if the held lever turns to another value or includes bit 8, if it's still held 6 passes after the press, or if any direction is pressed after it's let go. The command arms again only after a second counter, set toresetplus 10, has counted below zero. While the defender'sguard_chuuisn't 1 to 4 (the test isguard_chuu != 0 && guard_chuu < 5),defense_groundanddefense_skyturn a hit that the attack's guard bits let it parry into a parry when the matching counter is nonzero, unless the defender is stunned, itsguard_flaghas bit 2 set, or a System Direction setting has switched that parry off.Codecrowded-street/3s-decomprevisedHow we know
610void check_10() { 611 switch (waza_ptr->shot_ok) { 612 case 0: 613 if (chk_pl->sw_lever == 0) { 614 waza_ptr->shot_ok++; ⋮ 618 case 1: 619 if ((cmd_pl->wu.xyz[1].disp.pos > 0 || (waza_type[cmd_id] != 5 && waza_type[cmd_id] != 6)) && 620 chk_pl->now_lvbt & 0xF) { 621 if (chk_pl->sw_lever == waza_ptr->w_lvr) { 622 waza_ptr->shot_ok++; 623 wcp[cmd_id].waza_flag[waza_type[cmd_id]] = wcp[cmd_id].reset[waza_type[cmd_id]]; 624 waza_ptr->free3 = wcp[cmd_id].reset[waza_type[cmd_id]] + 10; ⋮
src/anniversary/sf33rd/Source/Game/CMD_MAIN.c lines 610–625 at be9b9bc · upstream ↗ 627 switch (waza_type[cmd_id]) { 628 case 3: 629 if (wcp[cmd_id].waza_flag[3] > wcp[cmd_id].waza_flag[4]) { 630 wcp[cmd_id].waza_flag[4] = 0; ⋮ 634 wcp[cmd_id].waza_flag[5] = 0; ⋮ 641 if (wcp[cmd_id].waza_flag[3] > wcp[cmd_id].waza_flag[12]) { 642 wcp[cmd_id].waza_flag[12] = 0; ⋮ 649 wcp[cmd_id].waza_flag[3] = 0; ⋮ 653 wcp[cmd_id].waza_flag[5] = 0; ⋮ 661 wcp[cmd_id].waza_flag[12] = 0; ⋮ 666 case 5: ⋮ 668 wcp[cmd_id].waza_flag[3] = 0; ⋮
src/anniversary/sf33rd/Source/Game/CMD_MAIN.c lines 627–728 at be9b9bc · upstream ↗ 739 case 2: 740 waza_ptr->w_int--; 741 waza_ptr->free3--; ⋮ 743 if (waza_ptr->w_int > 0) { 744 if (chk_pl->sw_lever == 0) { 745 waza_ptr->shot_ok++; 746 break; ⋮ 749 if (chk_pl->sw_lever & 8) { 750 wcp[cmd_id].waza_flag[waza_type[cmd_id]] = 0; 751 waza_ptr->shot_ok++; 752 break; ⋮ 755 if (chk_pl->sw_lever != waza_ptr->w_lvr) { ⋮
src/anniversary/sf33rd/Source/Game/CMD_MAIN.c lines 739–785 at be9b9bc · upstream ↗ 107 for (j = 0; j < 56; j++) { 108 if (wcp[cmd_id].waza_flag[j] != -1) { ⋮ 111 waza_ptr = &waza_work[cmd_id][j]; 112 chk_move_jp[waza_ptr->w_type](); ⋮ 116 for (j = 0; j < 56; j++) { 117 if ((wcp[cmd_id].waza_flag[j] != -1) && (wcp[cmd_id].waza_flag[j] != 0)) { 118 waza_ptr = &waza_work[cmd_id][j]; 119 command_ok_move(j);
src/anniversary/sf33rd/Source/Game/CMD_MAIN.c lines 107–121 at be9b9bc · upstream ↗ 1530void command_ok_move(s16 waza_num) { 1531 if (dead_lvr_check()) { ⋮ 1536 wcp[cmd_id].waza_flag[waza_num]--;
src/anniversary/sf33rd/Source/Game/CMD_MAIN.c lines 1530–1536 at be9b9bc · upstream ↗ 9void (*chk_move_jp[28])() = { check_init, check_0, check_1, check_2, check_3, check_4, check_5, 10 check_6, check_7, check_7, check_9, check_10, check_11, check_12,
src/anniversary/sf33rd/Source/Game/CMD_MAIN.c lines 9–10 at be9b9bc · upstream ↗ 124void check_init() { 125 cmd_tbl_ptr += 12; 126 waza_ptr->w_type = *cmd_tbl_ptr++; 127 waza_ptr->w_int = *cmd_tbl_ptr++; 128 waza_ptr->free1 = *cmd_tbl_ptr; 129 waza_ptr->free2 = *cmd_tbl_ptr++; 130 waza_ptr->w_lvr = *cmd_tbl_ptr++;
src/anniversary/sf33rd/Source/Game/CMD_MAIN.c lines 124–130 at be9b9bc · upstream ↗ 37 wcp[cmd_id].reset[i] = *cmd_tbl_ptr++;src/anniversary/sf33rd/Source/Game/CMD_MAIN.c line 37 at be9b9bc · upstream ↗ 43const s16 pc_cmd_03[17] = { 11, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 11, 0, 0, 4, 28 }; ⋮ 45const s16 pc_cmd_04[17] = { 11, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 11, 0, 0, 2, 28 }; ⋮ 47const s16 pc_cmd_05[17] = { 8, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 11, 0, 0, 4, 28 };
src/anniversary/sf33rd/Source/Game/cmd_data.c lines 43–49 at be9b9bc · upstream ↗ 61const s16 pc_cmd_12[17] = { 6, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 11, 0, 0, 4, 28 };src/anniversary/sf33rd/Source/Game/cmd_data.c line 61 at be9b9bc · upstream ↗ 781const_s16_arr p0_cmd[56] = { pc_cmd_00, pc_cmd_01, pc_cmd_02, pc_cmd_03, pc_cmd_04, pc_cmd_05, pc_cmd_06, pc_cmd_07, 782 pc_cmd_08, pc_cmd_09, pc_cmd_10, pc_cmd_11, pc_cmd_12, pc_cmd_13, pc_cmd_14, pc_cmd_15,
src/anniversary/sf33rd/Source/Game/cmd_data.c lines 781–782 at be9b9bc · upstream ↗ 55 switch (i) { 56 case 3: 57 case 4: 58 case 5: 59 wcp[cmd_id].reset[i] += blok_b_omake[omop_b_block_ix[cmd_id]]; 60 make_red_blocking_time(cmd_id, i, wcp[cmd_id].reset[i]); 61 break; ⋮ 63 case 6: 64 case 12: 65 wcp[cmd_id].reset[i] += blok_b_omake[omop_b_block_ix[cmd_id]]; 66 break;
src/anniversary/sf33rd/Source/Game/CMD_MAIN.c lines 55–66 at be9b9bc · upstream ↗ 45const s16 blok_b_omake[4] = { -2, 0, 2, 4 };src/anniversary/sf33rd/Source/Game/SysDir.c line 45 at be9b9bc · upstream ↗ 168void get_system_direction_parameter(DirData* sysdir_data) { 169 if (sysdir_data->contents[0][0] == 0) { 170 omop_spmv_ng_table[0] |= 0x300; ⋮ 173 if (sysdir_data->contents[0][1] == 0) { 174 omop_spmv_ng_table[0] |= 0x800; ⋮ 177 if (sysdir_data->contents[0][2] == 0) { 178 omop_spmv_ng_table[0] |= 0x400; ⋮ 181 omop_b_block_ix[0] = sysdir_data->contents[0][3];
src/anniversary/sf33rd/Source/Game/SysDir.c lines 168–181 at be9b9bc · upstream ↗ 9const DirData Dir_Default_Data = { .contents = { { 1, 1, 1, 1, 1, 1, 1 },src/anniversary/sf33rd/Source/Game/DIR_DATA.c line 9 at be9b9bc · upstream ↗ 102 system_dir[ix] = Dir_Default_Data;src/anniversary/sf33rd/Source/Game/init3rd.c line 102 at be9b9bc · upstream ↗ 1179 if (ds->py->flag == 0 && !(ds->guard_flag & 2) && as->wu.att.guard & 3) { 1180 if (as->wu.att.guard & 2) {
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 1179–1180 at be9b9bc · upstream ↗ 1198 } else if (!(ds->spmv_ng_flag & 0x100)) { 1199 if (as->wu.jump_att_flag) { 1200 if (!(ds->spmv_ng_flag & 0x800) && (ds->cp->waza_flag[12] != 0 || abs)) { ⋮ 1216 } else if (ds->cp->waza_flag[3] != 0 || abs) {
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 1198–1216 at be9b9bc · upstream ↗ 1248 } else if (!(ds->spmv_ng_flag & 0x200)) { 1249 if (as->wu.jump_att_flag) { 1250 if (!(ds->spmv_ng_flag & 0x800) && (ds->cp->waza_flag[4] != 0 || abs)) { ⋮ 1261 } else if (ds->cp->waza_flag[4] != 0 || abs) {
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 1248–1261 at be9b9bc · upstream ↗ 1172 just_now = 0; ⋮ 1174 if (ds->guard_chuu != 0 && ds->guard_chuu < 5) { 1175 just_now = 1;
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 1172–1175 at be9b9bc · upstream ↗ 1080 if (ds->py->flag == 0 && !(ds->guard_flag & 2) && as->wu.att.guard & 4) { ⋮ 1093 } else if (!(ds->spmv_ng_flag & 0x400) && ((ds->cp->waza_flag[5] != 0) || abs)) {
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 1080–1093 at be9b9bc · 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.
- ^ abcIn the PS2 port of Street Fighter III: 3rd Strike that crowded-street/3s-decomp rebuilds, a defender who is already guarding (
guard_chuu1 to 4, whichDamage_04000andDamage_07000set in damage routines 4 to 7) parries a hit only if the parry's counter is still at least the thresholdmake_red_blocking_timestores from that parry'sreset:resetless 3 against movescheck_normal_attackcounts as normal, and less 2 against the rest, less a second System Direction offset of −1, 0, 1, or 2 (0 at its defaults). For the high and low parries (reset11) that is 8 or 9, and for the air parry (reset8) 5 or 6, so the press must come in the window's first 3 passes against a normal move or first 2 against others (computed). Otherwise the code goes on to the guard checks. A System Direction setting (bit 0x1000) turns this parry off.Codecrowded-street/3s-decompHow we know
36void make_red_blocking_time(s16 id, s16 ix, s16 num) { 37 switch (ix) { 38 case 3: 39 grdb[id][0][0] = num - (blok_r_omake[omop_r_block_ix[id]] + 2); 40 grdb[id][1][0] = num - (blok_r_omake[omop_r_block_ix[id]] + 3); 41 break; ⋮ 43 case 4: 44 grdb[id][0][1] = num - (blok_r_omake[omop_r_block_ix[id]] + 2); 45 grdb[id][1][1] = num - (blok_r_omake[omop_r_block_ix[id]] + 3); 46 break; ⋮ 48 case 5: 49 grdb2[id][0] = num - (blok_r_omake[omop_r_block_ix[id]] + 2); ⋮
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 36–52 at be9b9bc · upstream ↗ 1172 just_now = 0; ⋮ 1174 if (ds->guard_chuu != 0 && ds->guard_chuu < 5) { 1175 just_now = 1; 1176 attr_att = check_normal_attack(as->wu.kind_of_waza); ⋮ 1179 if (ds->py->flag == 0 && !(ds->guard_flag & 2) && as->wu.att.guard & 3) { 1180 if (as->wu.att.guard & 2) { 1181 if (just_now) { 1182 if (!(ds->spmv_ng_flag & 0x1000) && ((ds->cp->waza_flag[3] >= grdb[ds->wu.id][attr_att][0]) || abs)) {
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 1172–1182 at be9b9bc · upstream ↗ 1236 if (just_now) { 1237 if (!(ds->spmv_ng_flag & 0x1000) && (!(ds->cp->waza_flag[4] < grdb[ds->wu.id][attr_att][1]) || abs)) {
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 1236–1237 at be9b9bc · upstream ↗ 1081 if (just_now) { 1082 if (!(ds->spmv_ng_flag & 0x1000) && (ds->cp->waza_flag[5] >= grdb2[ds->wu.id][attr_att] || abs)) {
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 1081–1082 at be9b9bc · upstream ↗ 759s32 check_normal_attack(u8 waza) { 760 return sel_sp_ch_tbl[waza >> 3] == 0;
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 759–760 at be9b9bc · upstream ↗ 147const u8 guard_kind[12] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0 }; ⋮ 150 Damage_00000, Damage_01000, Damage_01000, Damage_01000, Damage_04000, Damage_04000, Damage_04000, Damage_07000, 151 Damage_04000, Damage_04000, Damage_04000, Damage_07000, Damage_12000, Damage_12000, Damage_14000, Damage_14000,
src/anniversary/sf33rd/Source/Game/PLPDM.c lines 147–151 at be9b9bc · upstream ↗ 304void Damage_04000(PLW* wk) { ⋮ 310 wk->guard_chuu = guard_kind[wk->wu.routine_no[2] - 4];
src/anniversary/sf33rd/Source/Game/PLPDM.c lines 304–310 at be9b9bc · upstream ↗ 353void Damage_07000(PLW* wk) { ⋮ 359 wk->guard_chuu = guard_kind[wk->wu.routine_no[2] - 4];
src/anniversary/sf33rd/Source/Game/PLPDM.c lines 353–359 at be9b9bc · upstream ↗ 47const s16 blok_r_omake[4] = { -1, 0, 1, 2 };src/anniversary/sf33rd/Source/Game/SysDir.c line 47 at be9b9bc · upstream ↗ 183 if (sysdir_data->contents[0][4] == 0) { 184 omop_spmv_ng_table[0] |= 0x1000; ⋮ 187 omop_r_block_ix[0] = sysdir_data->contents[0][5];
src/anniversary/sf33rd/Source/Game/SysDir.c lines 183–187 at be9b9bc · upstream ↗ 9const DirData Dir_Default_Data = { .contents = { { 1, 1, 1, 1, 1, 1, 1 },src/anniversary/sf33rd/Source/Game/DIR_DATA.c line 9 at be9b9bc · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abcIn the PS2 port of Street Fighter III: 3rd Strike that crowded-street/3s-decomp rebuilds, when a parried attack has any hit stop,
set_paring_statussets the parrying defender'sdm_stopto −15 and the attacker'shit_stopto 16. When the attacker is on the ground and the parry is a ground one (routines 31 to 33), a move whosekind_of_wazais 0 to 7 gets 4, 3, 2, or 1 more, bykind_of_waza / 2. The defender's parry status makes its stop negative and moves it tohit_stop.check_hit_stopcounts a negative stop up to 0 while still callingchar_move, and a positive one down without calling it. The attacker's count is 1 to 5 longer than the defender's 15 (computed). The same routine sets the hit's stun (dm_piyo) and its gauge points (dm_arts_point) to 0.Codecrowded-street/3s-decompHow we know
662const s16 sel_hs_add_tbl[6] = { 4, 3, 2, 1, 0, 0 }; ⋮ 664void set_paring_status(PLW* as, PLW* ds) { ⋮ 667 if ((as->wu.att.hs_you == 0) && (as->wu.att.hs_me == 0)) { 668 ds->wu.routine_no[2] = ds->wu.old_rno[2]; 669 } else { 670 hsadix = 4; 671 if ((as->wu.kind_of_waza & 0xF8) == 0) { 672 hsadix = (as->wu.kind_of_waza / 2) & 3; ⋮ 677 dm_status_copy(&as->wu, &ds->wu); 678 ds->wu.dm_piyo = 0; ⋮ 681 switch ((as->wu.xyz[1].disp.pos > 0) + (ds->wu.routine_no[2] - 31) * 2) { 682 case 0: ⋮
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 662–689 at be9b9bc · upstream ↗ 690 case 1: 691 case 3: 692 case 5: 693 ds->wu.dm_stop = -15; 694 as->wu.hit_stop = 16; 695 as->wu.hit_quake = 16; 696 break; ⋮ 699 ds->wu.dm_stop = -15; 700 as->wu.hit_stop = 16; 701 as->wu.hit_quake = 16; 702 break; ⋮ 705 ds->wu.dm_stop = -15; ⋮
src/anniversary/sf33rd/Source/Game/HITCHECK.c lines 690–735 at be9b9bc · upstream ↗ 586void Normal_31000(PLW* wk) { ⋮ 604 if (wk->wu.dm_stop > 0) { 605 wk->wu.dm_stop = -wk->wu.dm_stop; ⋮ 608 set_hit_stop_hit_quake(&wk->wu);
src/anniversary/sf33rd/Source/Game/PLPNM.c lines 586–608 at be9b9bc · upstream ↗ 833void set_hit_stop_hit_quake(WORK* wk) { 834 if (wk->dm_stop) { 835 wk->hit_stop = wk->dm_stop; 836 wk->dm_stop = 0;
src/anniversary/sf33rd/Source/Game/PLS02.c lines 832–836 at be9b9bc · upstream ↗ 329 if (wk->wu.hit_stop) { 330 num = 1; ⋮ 332 if (wk->wu.hit_stop > 0) { 333 wk->wu.hit_stop--; ⋮ 337 wk->wu.hit_stop++; ⋮ 345 } else { 346 wk->wu.hit_stop++; 347 char_move(&wk->wu);
src/anniversary/sf33rd/Source/Game/PLMAIN.c lines 329–348 at be9b9bc · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
Sources
Code
- Crowded Street contributors. 2026. “3s-decomp: a decompilation of Street Fighter III: 3rd Strike for PlayStation 2 (crowded-street/3s-decomp).” Commit be9b9bc. crowded-street/3s-decomp @ be9b9bc · licence, all uses