An effective mouse macro recorder – AutoHotKey
My foray into the versatile AutoHotKey. I’ve made a super simple program that allows the user to record and then play a sequence of mouse moments/actions. It can iterate any number of times and will be useful in removing the needless grind that plagues many games.
Full script below (Creative Commons 4.0).
Usage
The application is simple and easy to use. Simply download below and you’re ready to go! You may have to install AutoHotKey but I’m not sure that it’s necessary.
The Mouse Repeat app is the one showcased in the video that records all mouse movements, the Mouse Click Repeat only mimics clicks.
Press Ctrl-R to prepare for recording. The sequence will begin when you first click you mouse. When done recording, press Esc.
Press Ctrl-E to execute the sequence you just recorded. You’ll get a prompt for the amount of times you want it to repeat (leave it blank for infinite).
That’s it. Press Esc to cancel any active operation and then once more to exit the app. Enjoy!
I originally make this in the effort to disenchant a plethora of champion shards in League of Legends but it’s use is limitless. You could even expand it to pick up on other recordings.
I’m aware plenty of apps like already this exist but this is quite lightweight and it was a super fun project.
Downloads
Unzip and run the application (the .exe file), then follow the instructions above. Or, compile the code yourself, it’s all included in the zip.
Code
As follows is the main script, see the tutorial above for the in-depth overview of its functionality.
#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. ;ArmanDoesStuff 2020 ;records mouse moves/clicks and repeats them a desired amount of times ;ctrl+r to record, ctrl+e to execute, esc to stop recording/playing or exit application ;Sequence vars - A sequence is made up of multiple 10 milisecond intervals (denoted by i) and checks mouse position (x & y) ;and whether or not the mouse is pressed (so far only 0 or 1 for mouseVals, but could expand with other buttons) posX := [] posY := [] mouseVals := [] i := 0 ;Timer that cuts off the begginging of the recording startTimerRunning := true timer := 0 recording := false playing := false ;Auto execute/Start/Main ;Set cord mode here otherwise user must keep window selected CoordMode, Mouse , Screen MsgBox, 0, Mouse Repeat, Press ctrl-r to record and ctrl-e to execute`nEsc will stop record/play or close the app if no operation is active Return ^r:: MsgBox, 0, Recording, Click to start recording - Esc to stop, 1 playing := false ;reset vars i := 0 timer := 0 startTimerRunning := true recording := true while(recording = true) { MouseGetPos, x, y posX[i] := x posY[i] := y mouseVals[i] := 0 sleep 40 i++ if(startTimerRunning = true) { timer++ } } if(startTimerRunning = true) { i := 0 MsgBox, 0, Recording, Recording failed - you must click to start, 2 } else { MsgBox, 0, Recording, Recording completed, 2 } recording := false return LButton:: Send {LButton down} if(recording = true) { startTimerRunning = false; mouseVals[i] := 1 } return LButton up::Send {LButton Up} ^e:: if(recording = true) { MsgBox, 0, Still recording, Press esc to finish current recording, 1 } else if(i = 0) { MsgBox, 0, No recording, Please use ctrl+r to record mouse sequence, 2 } else { iterations := 0 InputBox, iterations, Set Iterations, Leave blank for infinity if(iterations <= 0) { iterations := -1 MsgBox, 0, Playing, Playing sequence infinitely - esc to stop, 1 } else { MsgBox, 0, Playing, Playing sequence %iterations% times - esc to stop, 1 } playing := true l := i while(iterations != 0 && playing = true) { j := timer while(j <= l && playing = true) { x := posX[j] y := posY[j] MouseMove, %x%, %y% if(mouseVals[j] = 1) { Click } sleep 40 j++ } iterations-- } MsgBox, 0, Playing, Sequence has ended, 1 playing := false } return Escape:: if(recording = true) { recording := false return } if(playing = true) { playing := false return } MsgBox, 0, App Closed, Exiting Application, 1 ExitApp return
Below is a more compact/more efficient code that doesn’t track mouse movement and handles the clicks using a timer instead of frame by frame
#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. ;ArmanDoesStuff 2020 ;records mouse clicks and repeats them a desired amount of times ;ctrl+r to record, ctrl+e to execute, esc to stop recording/playing or exit application posX := [] posY := [] timer := [] i := 0 t := 0 recording := false playing := false ;Auto execute/Start function ;Set cord mode here otherwise user must keep window selected CoordMode, Mouse , Screen MsgBox, 0, Mouse Click Repeat, Press ctrl-r to record and ctrl-e to execute - Esc will stop record/play or close the app if nothing is no operation is active Return ^r:: MsgBox, 0, Recording, Recording Starting, 1 playing := false recording := true iterations := 0 i := 0 t := 0 while(recording = true) { t++ sleep 10 } MsgBox, 0, Recording, Recording completed, 2 Return LButton:: Send {LButton down} if(recording) { MouseGetPos, x, y posX[i] := x posY[i] := y timer[i] := t * 10 t = 0 i++ } Return LButton up::Send {LButton Up} ^e:: if(recording = true) { MsgBox, 0, Still recording, Press esc to finish current recording, 1 } else if(i = 0) { MsgBox, 0, No recording, Please use ctrl+r to record mouse sequence, 2 } else { iterations := 0 InputBox, iterations, Set Iterations, Leave blank for infinity if(iterations <= 0) { iterations := -1 MsgBox, 0, Playing, Playing sequence infinitely - esc to stop, 1 } else { MsgBox, 0, Playing, Playing sequence %iterations% times - esc to stop, 1 } playing := true l := i ;also have to check "playing" here otherwise infinite loops never break while(iterations != 0 && playing = true) { j := 0 while(j <= l && playing = true) { sleep timer[j] x := posX[j] y := posY[j] Click, %x%, %y% j++ } iterations-- } MsgBox, 0, Playing, Sequence has ended, 1 } Return Escape:: if(recording = true) { recording := false Return } if(playing = true) { playing := false Return } MsgBox, 0, App Closed, Exiting Application, 1 ExitApp Return