PC Players: Enhancing Training Mode using macro programs

It seems all works fine, autohotkey is putting out the keystrokes. I can start and stop the script with the arcade stick.

But ingame it just doesnt work. Now when I try to manually input the commands that the script is putting out, it works (typing my self)…

WHAAT IS WRONG :frowning:

Wait a minit you’re saying that the software is mashing “z” (or whatever key you test) fine out of game (on notepad) but once back in training room, the char controlled by keyboard (the same keyboard hm ?) don’t mash neutral jump ? (and of course “z” is neutral jump on your command option for this keyboard in game hm ? meaning if YOU mash “z” yourself, the gyu DO jump).

Now that’s weird indeed.
By the way, I use to set the Player 1 as my dummy so I can see the input the script try to execute. Just a tip for later :slight_smile:

there is an update on Bison corner pressure training :



; Against Dictator
; He'll pressure you with LK xx LK xx LK Scissor and a mix of st.HK / MK and grab
; Mission : Guard and find the best counter.
 
#include common.ahk
Scissor_pressure()
{
Global
release_all()
wait(2)
dash(forward)
push(DOWN)
push(backward)
wait(15)
 
push(LK)
Wait(2)
release(LK)
Wait(20.6)
 
push(LK)
Wait(2)
release(LK)
Wait(20.8)
 
push(LK)
Wait(2)
release(LK)
release(backward)
push(forward)
wait(2)
push(LK)
release(forward)
wait(2)
release(LK)
push(backward)
Wait(74)
 
push(LK)
Wait(2)
release(LK)
release(backward)
push(forward)
wait(2)
push(LK)
release(forward)
wait(2)
release(LK)
push(backward)
Wait(74)
}
 
Random, , 123456
 
do_the_setup()
{
Global
Run := ""
Loop
{
Random, Guess, 0, 30
if(Guess > 16)
{
Scissor_pressure()
}
else if(Guess > 5)
{
 
release(DOWN)
wait(4)
push(MK)
wait(2)
release(MK)
 
wait(37)
 
release_all()
push(forward)
push(LK)
wait(2)
release_all()
 
push(backward)
push(DOWN)
wait(74)
 
 
}
else
{
 
release(DOWN)
wait(4)
push(HK)
wait(10)
release_all()
 
walk(forward,38)
 
push(HK)
wait(2)
release(HK)
wait(28)
 
dash(forward)
wait(20)
grab()
wait(2)
grab()
wait(2)
grab()
wait(2)
push(DOWN)
push(backward)
wait(60)
 
}
Stop_it(Run)
}
}
 
 
 
1joy8::
Wait(8)
Sweep()
return
 
1joy5::
do_the_setup()
return
 
1joy9::
Run := "stop"
return
 
LEFT::
forward := LEFT
backward := RIGHT
return
 
RIGHT::
forward := RIGHT
backward := LEFT
return
 


copy paste this, override the whole previous file. And update “common.ahk” with this :
ONE_FRAME_IN_MS = 15

I have better timing control with this number over the exact one.

Every time I hit the LB button on the stick, autohotkey produces the up command (key: F in my case) no spam, unless I spam it.

As soon as I got ingame, only the keyboard F works to jump, and not the autohotkey F

Strange right? any idea?

Ok it seems they blocked DirectInput keystrokes before patch 2012. I have problems with my laptop to download. I installed the game from a friend, who was so lucky to buy it for 5 euros :stuck_out_tongue:

Ima buy it today as well on steam, since my laptop is having problems with internet. So that seems to be the problem.

I will let you know.

And thanks for the help

Maybe we will have other people feedback on using this tool ? with or without trouble.

Aah I think I remember now, the first time the game was released many controllers just wouldn’t work without the update patch. Even certain wireless keyboards. You needed to install xinput as a workaround. That could be the problem.

Ok it works now!

Update 2012 was the problem, without it, it doesnt work :slight_smile:

Now I just need to figure out the side selection and its all good.

If any of you have more scripts id love to have some more! Im gonna start making them as well, but il need to learn first how to do it.

So ye, thanks for this awesome training way :slight_smile: And feel free to drop any scripts you dont mind to share :slight_smile:

Since everything works now, I want to start learning to write my own scripts, some input would be nice :slight_smile:

Especialy the random command (“Guess” command) is something I need to figure out.

The idea for this script is to have cammy do:

Footsie walk
Randomly poke with cr.HK (Either whiff punish, or since her cr.HK is -8 on block, punish with combo of choice, or simply sweep her.
Jump-in with MK, to Anti Air her.
And a low chance of her doing random spiral arrow (lets say 50% less then the jump-in MK)

Other things I could add:

Even a smaller chance to do random Cannon Spike (say a 5% chance overal)
1, 2 or 3 x jab (and random 1 jab, throw. 2 jabs throw)
Make it so that when ever I do a fireball she has a small chance to do EX Spiral Arrow, to get spacing better. (Fireball being a trigger kinda, but only a small chance lets say 10% of every fireball I throw)

I could ask you to make me scrips, but Id rather make em my self :slight_smile:
But a little help to get started would be great.

I have so many good ideas for this, but scripting is kinda hard for now :stuck_out_tongue:

Some things:

Spoiler

#include common.ahk Loads the common.ahk files (should always be included)

do_the_setup()
{
Global
Run := "go"
While(Run = “go”)
{
Random, Guess, 0, 60 (Can you explain please how this works, I have seen 0, 30 as well)
Footsy_Walk() (refers to common.ahk footsie walk script, If I include this, it makes sure the character is doing the footsie walk)

if (Guess > 30) { ; Randomly do cr.mk xx fireball (in order for it to do this less or more frequent, how can I change this?)
push(backward)
Wait(4)
release(backward) ; slight walk back to avoid SRK motion
Cr_MK_xx_Fireball(forward, HP)
Wait(14)
}
else if (Guess < 10) { ; Or randomly do jump in hk (same thing here for less or more frequent)
push(backward)
Wait(6)
release(backward) ; to avoid SRK instead of fireball
Jump(forward)
Wait(20)
push(HK)
Wait(18)
release(HK)
Jump(backward)
}
else
{
; Do nothing
}
}
}

; 2 because my stick is recognisez as the N°2 (no idea why…), joy for Joystick, 8 for button 8 (=HK)
;This syntax listen to the key, here HK on my stick, and do something, here a Sweep for the player that use the keyboard
; So everytime I inout HK the dymmy react with sweep after a 8 frames wait.
2joy8::
Wait(8)
Sweep()
return

; controls for Cancel and side selection
; This launch the setup, L1 button on the stick if you use the keyboard (separate keys that the dummy of course), change every 2joyX to your own keyboard keys
2joy5::
do_the_setup()
return
; This is teh Select button on the stick, and it stop the setup after the dummy finished his actual moves
2joy9::
Run := "stop"
return
; this is how I tell the dummy where I’m at, at his Left or Right so he knwo how to go “forward” and “backward”, keep it like that it’s teh same if you use the keyboard and don’t use the arrow keys for your moves or the dummy’s moves.
LEFT::
forward := LEFT
backward := RIGHT
return

RIGHT::
forward := RIGHT
backward := LEFT
return

Lets say I want to make this for cammy. The idea would be to punish Spiral Arrow’s that I block. Practicing combos is one thing, actually pulling them of for a punish is another thing.

So lets say I want Cammy to do random Spiral Arrow’s

I guess I would 1st have to include Spiral Arrow in the common.ahk file.

}
SpiralArrow(direction, Kick)
{
Global
push(DOWN)
Wait(2)
push(direction)
Wait(2)
push(MK)
Wait(2)
release(DOWN)
release(MK)
release(direction)
Wait(2)


; Against Cammy
; Foosty Walk
; Spiral Arrow
; jump In MK, jump back
; Mission : Try to stay close for pressure, avoid sweep damage, punish random Spiral Arrow’s and anti air her.

#include common.ahk

do_the_setup()
{
Global
Run := "go"
While(Run = “go”)
{
Random, Guess, 0, 60
Footsy_Walk()

if (Guess > 30) { ; Randomly do cr.HK
push(backward)
Wait(4)
release(backward) ; slight walk back to avoid SRK motion
Cr_HK
Wait(14)
}
else if (Guess < 10) { ; Or randomly do jump in mk
push(backward)
Wait(6)
release(backward) ; to avoid SRK instead of fireball
Jump(forward)
Wait(20)
push(MK)
Wait(18)
release(MK)
Jump(backward)
}
else
{
; Do nothing
}
}
}

Now where and how can I fit in the random Spiral Arrow?

My guess would be to put it at the marked (else)

So something like:

Wait(18)
release(MK)
Jump(backward)
}
*else if (Guess < 10) { ;SpiralArrow(direction, Kick) *(What should I set the Guess < 10 to? I want here to do this move not as frequent as the Jump Foward MK, so can I just set it to something like (Guess < 2) for example?

  • {*
  • Global*
  • push(DOWN)*
  • Wait(2)*
  • push(direction)*
  • Wait(2)*
  • push(MK)*
  • Wait(2)*
  • release(DOWN)*
  • release(MK)*
  • release(direction)*
  • Wait(2)*

Random is a command that define a new variable “var” with a random number between the range you decide.
The syntax is Random var , min , max
There’s a lot of information about scripting on the documentation on the autohotkey website.
Like loop, random, and general information about how to deal with variables etc.

There’s no way to trigger anything with more than one button. In other way you can’t ask the app to recognise a combination of several buttons.

You’re training is quite the same as the Ruy 3 mid range mix up script I made. You can use this as a template.

There’s old scripts that weren’t made with the current version of the common.ahk file, so some may look like they could be upgraded, or may be off in timing but you know what to do then. I’ll rewrite em all in some days because that’s defo not serious to let it like that. Also I should stick with an universal frame number and go back to 16.68ms (iirc ??). Now I know I can set wait command using fractional numbers.

Ok i have been trying to make a simple cammy script. (based on the basics of the ryu footsie one)

; Against Cammy
; Foosty Walk
; cr.HK to punish with punish combo.
; jump In MK, jump back
; Mission : Try to stay close for pressure, avoid damage and anti air her.
; Randomly HP Spiral arrow, punish with punish combo.
; Randomly MK Cannon spike, BIG punish time.

Please tell me if this would work. I have not updated the common.ahk file (do I need to for this file to work?)

I hope it works!

Im not to lazy to learn how to make em my self, but all the help is appreciated :slight_smile:

Spoiler

; Against Cammy
; Foosty Walk
; cr.HK to punish with punish combo.
; jump In MK, jump back
; Mission : Try to stay close for pressure, avoid damage and anti air her.
; Randomly HP Spiral arrow, punish with punish combo.
; Randomly MK Cannon spike, BIG punish time.

#include common.ahk

do_the_setup()
{
Global
Run := "go"
While(Run = “go”)
{
Random, Guess, 0, 60
Footsy_Walk()

if (Guess > 34) { ; Randomly do cr.hk
push(DOWN)
wait(2)
push(HK)
Wait(14)
release(DOWN)
release(HK)
}
else if (Guess < 8) { ; Or randomly do jump in mk
push(backward)
Wait(6)
release(backward) ; to avoid SRK instead of fireball
Jump(forward)
Wait(20)
push(MK)
Wait(18)
release(MK)
Jump(backward)
}
else if (guess < 5) { ; Spiral Arrow
{
Global
push(DOWN)
Wait(2)
push(direction)
Wait(2)
push(MK)
Wait(2)
release(DOWN)
release(MK)
release(direction)
}
else if (guess > 56) { ; Cannon Spike
Global
push(direction)
Wait(4)
release(direction)
push(DOWN)
Wait(2)
push(direction)
Wait(2)
push (MK)
wait (2)
release (DOWN)
release (MK)
release (direction)
}
}
}

; controls for Cancel and side selection
1joy5:: ; the L1 button for a stick
do_the_setup()
return

1joy9:: ; the Select button for a stick
Run := "stop"
return

LEFT:: ; keyboard left arrow
forward := LEFT
backward := RIGHT
return

RIGHT:: ; keyboard right arrow
forward := RIGHT
backward := LEFT
return

And the previous frames to MS was:

ONE_FRAME_IN_MS = 16.67

what’s that ?? Cr_HK(forward, HK)
Use Sweep() included in common file instead. I wonder why you put the direction in your custom cr.HK shortcut.

This part isn’t needed as you do a jump instead of a fireball in the native script (where walk forward plus fireball would do a SRK by mistake) :

And Global is a key that allow the use of external vars in a function. You could then include a Global at the beginning of every function you create but not in every If Else you type :slight_smile:
This is a function:

And you need a bit more organization in the If Else sequences. The app will only check one time it a condition is true or false, then jump to the END of the entire IF loop avoiding any other ElseIF that are maybe true but redundant. If you start with If X > 35 and later add a Else If X > 89 you’re doing it wrong and the app will never test the last condition because the first respond to the question just fine. If X is > 89 it’s off course > 35 right ?
same for X < Y
You need to think of your hierarchy here. Exclusive -> general conditions.
if X < 10
do this
else if X < 20
do this
else if X < 30
do this
else
do that

Lets say I want her to do a walk forward for a little longer, every time the random number is (< 5) and then have her do:

Spoiler

Jabs_Thick_Throw(approach)
{
Global
Walk**(forward, 55)**
Wait(55)
push(DOWN)
push(backward)
Wait(2)
push(LP)
Wait(2)
release(LP)
Wait(14)
release(backward)
release(DOWN)
Wait(2)
Walk(forward, 10)
Throw(forward)

Somewhere I guess I should be able to add a timing command, I guess where the bold letters are should be the spot, one of the two?

Or I guess I could add this to the common.ahk file:

MIN_WALK_FRAMES := 8
MAX_WALK_FRAMES := 18
TICKTHROW_WALK_FRAMES := 55

So it would be:

Spoiler

}
else if (guess < 5) { ;Jabs_Thick_Throw(approach)
{
Global
Walk**(forward, TICKTHROW_WALK_FRAMES)**
push(DOWN)
push(backward)
Wait(2)
push(LP)
Wait(2)
release(LP)
Wait(14)
release(backward)
release(DOWN)
Wait(2)
Walk(forward, 10)
Throw(forward)

Ah ye fail :stuck_out_tongue: he… im still learning! day one

Ok so ye I should just use “sweep” and remove the direction ofcourse.

If you would have the time, and the will ofcourse could you perhaps change it so it would work, and perhaps add the Tick throw setup that I posted?

And when should I use “if” and “else if” hmmmm I will try and find this info my self, but if you could correct my script that would be great.

the Walk function already have a timing variable, if you add a wait (55) after it she’ll sit here for 55 frames AFTER she walked forward 55 frames…
And you are doing your own function for Spiral arrow where it’s just a QCF and there’s already this QC_X function that do whatever fireball move you want. Forward or backward motion with kicks punch and even ex moves.

Anyway I suggest you to put this on the side for a moment and try to write separate script for each mixup you need, then when all is going smooth, you can make a single file for em all with the random loop. But that’s only when you got all the parts ready.

yeah you need some read of programming language like php for example. If else loop are easy to learn and universal almost in many language. And just like in real talk, you will start with a “If” and only If you have another condition use a “Else If” :slight_smile:
If you only have 2 conditions an “Else” alone is enough, if you have more conditions you chain em with “Else If” and finish by the single “Else”.
It’s really explained everywhere on the web. Just google “else if” :slight_smile:

I can understand you’re excited to use this new tool but you gotta work a bit for that :slight_smile:
I’m too busy atm to do it for you, even for me it would take quite some time to make it smooth, like 2 hours at least. Split the task in separate scripts, easier task. Walk slowly. You need to understand the way to script moves before you start programming random behaviour that need programming knowledge.

Ok il do that first then.

Ye im pretty excited about all of this :slight_smile: I always hoped for a better training mode, maby something they should add in the newly announced update to SSF4 AE (can be Ono troll tho)

Thanks again

Is it possible to maby assign specific numbers as a trigger?

So instead of:

if (Guess > 6 { ;Spiral Arrow

Make it:

if (Guess = 1,2,3,4,5) { ; Spiral Arrow
if (Guess = 6,7,8,9,10) { ; Cannon Spike
if (Guess = 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,29 { ; Sweep

Leaving open 30 to 60 for footsie walk

Or something like this:

if(myNumber.isBetween(1,5))

Is , a valid command for it?

I hope you know what I mean :slight_smile:

That’s exactly what regular If else loop do.

if (Guess < 6) { spiral }
else if (Guess < 10) { spike }
else if (Guess < 30) { Sweep }
else { footsy }

This do exactly what you want. No need to ask for “between” when you script the right way :slight_smile:
You have to understand that once 1 condition is right, the loop end and restart from the top with another random number to check.
If Guess is 4, the first condition is right, the other condition will never be checked. If Guess is 15, the first 2 conditions are wrong, the third will be right and end the loop, etc.

It’s all about how you order your conditions to avoid overlapping the same “right” state. Just like I said before.