Rapid fire stucks

Ask gaming related questions
nailer
Posts: 3
Joined: 27 Jan 2019, 11:33
GitHub: nailerNAS

Rapid fire stucks

27 Jan 2019, 11:42

Hello. I am trying to make a reliable macros for Warframe for a few days now. I faced some hotkeys getting stuck when using something like

Code: Select all

while GetKeyState("key", "P")
for example and found recommendations to use key up events instead. But I have the same problem with them. Currently I tried using both up events and timers, here's my code:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#SingleInstance,Force
#InstallKeybdHook
#InstallMouseHook

window := "Warframe"

; modes
rapidMode := false
meleeMode := false

F12::Suspend

#if WinActive(window) and rapidMode
	~$LButton::
		SetTimer, rapidLabel, 50
		Gosub, rapidLabel
	return
	
	~$LButton Up::
		SetTimer, rapidLabel, Off
	return
#if

#if WinActive(window) and meleeMode
	~$e::
		SetTimer, meleeLabel, 50
		Gosub, meleeLabel
	return
	
	~$e Up::
		SetTimer, meleeLabel, Off
#if

#if WinActive(window)
	F1::
		rapidMode := !rapidMode
	return
	
	F2::
		meleeMode := !meleeMode
	return

	~$XButton1::
		Send, {w Down}
		SetTimer, slideLabel, 250
		Gosub, slideLabel
	return
	
	~$XButton1 Up::
		SetTimer, slideLabel, Off
		if (!GetKeyState("w", "p")) {
			Send, {w Up}
		}
	return
	
	~$XButton2::
		Send, {w Down}
		SetTimer, bulletLabel, 100
		Gosub, bulletLabel
	return
	
	~$XButton2 Up::
		SetTimer, bulletLabel, Off
		if (!GetKeyState("w", "p")) {
			Send, {w Up}
		}
	return
#if

rapidLabel:
	Send, {Blind}}{Click}
return

meleeLabel:
	Send, {Blind}e
return

slideLabel:
	Send, ^e
return

bulletLabel:
	Send, {LControl Down}
	Sleep, 10
	Send, {Space}
	Send, {LControl Up}
return
That's strange that only rapid fire (my LButton hotkey) gets stuck when I click it few times quickly or use WASD keys at the same time, while other hotkeys don't get stuck, but as you can see, the code is identical to other hotkeys (like my e hotkey for example, it's almost the same as rapid fire but just other key)

Help me please. Also I noticed that just before rapid fire get's stuck, I loose control of my mouse for about 2 seconds, then it starts spamming Clicks endlessly
User avatar
evilC
Posts: 4776
Joined: 27 Feb 2014, 12:30

Re: Rapid fire stucks

28 Jan 2019, 05:51

Your code looks fine
I would suggest trying to remove the line SendMode Input, as that mode does not tend to play nicely with games, just use the default mode.
50 is also probably too fast a spam rate.

When you send keys too fast (Too little time between press and release), games will often miss key events, which may result in what you speak of.
I would try changing the spam rate to 100, and add the line SetKeyDelay, 0, 50 at the start of the script - this will cause all Send commands to ensure all keys are held for at least 50ms.
nailer
Posts: 3
Joined: 27 Jan 2019, 11:33
GitHub: nailerNAS

Re: Rapid fire stucks

28 Jan 2019, 05:55

Thanks for reply, but well, my problem was that autohotkey sometimes doesn't detect that I released my key and keeps spamming it. I'll try changing the send mode..
User avatar
evilC
Posts: 4776
Joined: 27 Feb 2014, 12:30

Re: Rapid fire stucks

28 Jan 2019, 06:59

I think you will find that AutoHotkey detected it just fine, but the game did not.

Assume the game polls (checks) the state of the keys every 50ms

At t+0, AHK sends key press
at t+50, game checks state of key, sees it pressed
at t+60, AHK releases key
at t+70, AHK presses key again
at t+100, game checks state of key again - it is pressed at this point, same as last time it checked, so it does nothing. It has NO IDEA that the key was released and re-pressed since the last time it checked.

This is what SetKeyDelay, 0, 50 will fix for you - it makes sure that each press always lasts at least 50ms, so a press/release can never happen between polls
nailer
Posts: 3
Joined: 27 Jan 2019, 11:33
GitHub: nailerNAS

Re: Rapid fire stucks

30 Jan 2019, 02:58

So I did the SetKeyDelay trick, increased all Sleeps to 100 ms and the problem persisted, only for LButton hotkey, when I click it few times quickly
Steely Wing
Posts: 6
Joined: 12 Dec 2019, 06:26

Re: Rapid fire stucks

09 Jan 2020, 09:35

I have the same issue, sometimes I released the key e, GetKeyState("e", "P") still return False, I have tried KeyWait("e"), also sometimes not working.
It should be the keyboard hook bug, while GetKeyState("e", "P") should return the physical key state but it return wrong state.

But it very rarely to happen, less than 1% chance trigger this bug.

It happen on AHK v1 & v2.



Try this fix (not working)

Feel like using Send("{e}") instead of Send("e") will fewer happen
Last edited by Steely Wing on 10 Jan 2020, 10:50, edited 2 times in total.
User avatar
evilC
Posts: 4776
Joined: 27 Feb 2014, 12:30

Re: Rapid fire stucks

09 Jan 2020, 12:14

My guess is that it's nothing to do with GetKeyState not returning what it should, it's some other flaw in your code.
When you say you also tried KeyWait, that's a huge red flag to me, indicating that you have blocking waits in your code, which is guaranteed to cause intermittent bugs in some scenarios
If you post the code that you are using, then we can maybe help, without knowing what your code is, it's pretty unlikely we can help
Steely Wing
Posts: 6
Joined: 12 Dec 2019, 06:26

Re: Rapid fire stucks

09 Jan 2020, 12:52

Thanks for reply, my code in AHK v2

Code: Select all

; KeyWait version

#MenuMaskKey vkFF
#InstallKeybdHook

MeleeAttack() {
    Send("e")
}

$*e::
    SetTimer("MeleeAttack", 200)
    KeyWait("e")
    SetTimer("MeleeAttack", 0)
return

Code: Select all

; GetKeyState version

#MenuMaskKey vkFF
#InstallKeybdHook

SendMode "Input"

ToggleAttack(state) {
    Hotkey "*e", (!state) ? "On" : "Off"
    SetTimer "Attack", state ? 200 : 0
}

Attack() {
    if (!GetKeyState("e", "P")) {
        ToggleAttack(False)
        return
    }
    Send "e"
}

*e::
    ToggleAttack(True)
return
Last edited by Steely Wing on 09 Jan 2020, 13:36, edited 2 times in total.
Steely Wing
Posts: 6
Joined: 12 Dec 2019, 06:26

Re: Rapid fire stucks

09 Jan 2020, 13:30

AHK v1

Code: Select all

; KeyWait version

#MenuMaskKey vkFF
#InstallKeybdHook

SendMode, Input

Attack() {
    Send e
}

*e::
    SetTimer Attack, 200
    KeyWait e
    SetTimer Attack, Off
return

Code: Select all

; GetKeyState version

#MenuMaskKey vkFF
#InstallKeybdHook

SendMode, Input

ToggleAttack(state) {
    Hotkey *e, % (!state) ? "On" : "Off"
    SetTimer Attack, % state ? 200 : "Off"
}

Attack() {
    if (!GetKeyState("e", "P")) {
        ToggleAttack(False)
        return
    }
    Send e
}

*e::
    ToggleAttack(True)
return
User avatar
evilC
Posts: 4776
Joined: 27 Feb 2014, 12:30

Re: Rapid fire stucks

09 Jan 2020, 18:54

It's pointless to use KeyWait to detect release of a key when you can just use an up event hotkey

Code: Select all

#MenuMaskKey vkFF
#InstallKeybdHook

SendMode, Input

Attack() {
    Send e
}

*e::
    SetTimer Attack, 200
    return

*e up::
    SetTimer Attack, Off
    return
Steely Wing
Posts: 6
Joined: 12 Dec 2019, 06:26

Re: Rapid fire stucks

13 Jan 2020, 02:37

evilC wrote:
09 Jan 2020, 18:54
It's pointless to use KeyWait to detect release of a key when you can just use an up event hotkey

Code: Select all

#MenuMaskKey vkFF
#InstallKeybdHook

SendMode, Input

Attack() {
    Send e
}

*e::
    SetTimer Attack, 200
    return

*e up::
    SetTimer Attack, Off
    return
No, your script will not work as expect, because hotkey *e will trigger on keyboard (repeat on holding) auto repeat, if you change the timer to 1000, and hold the e, it will never trigger Attack() when holding, because every auto repeat will call SetTimer and reset the timer.

Of cause you can add a variable to check this, but I prefer the KeyWait method.
User avatar
evilC
Posts: 4776
Joined: 27 Feb 2014, 12:30

Re: Rapid fire stucks

13 Jan 2020, 04:42

Then just do

Code: Select all

*e::
If (eState)
   Return
eState := 1
SetTimer, Attack, 200
Return

*e up::
eState := 0
SetTimer, Attack, Off
Return
Using KeyWait to detect key up WILL CAUSE BUGS AND STICKING ISSUES. This technique doesn't
Steely Wing
Posts: 6
Joined: 12 Dec 2019, 06:26

Re: Rapid fire stucks

13 Jan 2020, 07:24

evilC wrote:
13 Jan 2020, 04:42
Then just do

Code: Select all

*e::
If (eState)
   Return
eState := 1
SetTimer, Attack, 200
Return

*e up::
eState := 0
SetTimer, Attack, Off
Return
Using KeyWait to detect key up WILL CAUSE BUGS AND STICKING ISSUES. This technique doesn't
I tried your code, sometimes still get stick :?

Return to “Gaming”

Who is online

Users browsing this forum: Bing [Bot], rmbrewer1, tobsto occupied and 16 guests