So I wasn't 100% correct in my assessment of what was causing the problem.
if I release LShift and then W in quick succession, AHK begins the subroutine attached to "w Up::"while the subroutine for "LShift Up::" also is happening.
If I understand correctly, what is actually happening is that if W is released very soon after LShift is released, the thread for the "w Up::" routine
interrupts the thread of the "LShift Up::" routine. The thread with the remainder of the "LShift Up::" routine gets buffered, or put in a queue and won't continue until the current thread of the most recent
event ("w UP") is completed.
If the timing is just right, then "Send, {w Down}" gets buffered to the end of the thread queue and becomes the last action of the whole sequence.
While reading the reference on
Threading Behavior, I discovered the entry regarding
Critical, and applied it to the routine that I do not want to be buffered under any circumstance:
Code: Select all
#NoEnv
#SingleInstance, Force
SendMode, Input
SetBatchLines, -1
SetWorkingDir, %A_ScriptDir%
Walking :=False
Sprinting := False
w::
Send {w down}
Walking := True
If (Sprinting)
Send, {LShift}
Return
w Up::
Send {w Up}
Walking := False
Return
LShift::
Send {LShift}
Sprinting := True
Return
LShift Up::
Critical
If (Walking) {
Send {w Up}
Sleep, 30
Send, {w Down}
}
Sprinting := False
Return
And it has solved 99.9% of the errors. For some reason it still squeaks through very, very rarely, but that may be because I am spamming the keys over and over during testing, so it could be related to #MaxThreadsPerHotkey or something else that I don't quite understand.