Learn how to program
by playing video games.

PyAutoGUI Video Game Bot Tutorial

Your First PyAutoGUI Game Bot

November 15, 2019
Part of: PyAutoGUI Video Game Bot Tutorial

Let's create our first simple video game bot, a timing bot! We'll be learning the basics of PyAutoGUI mouse and keyboard input controls.

Links
GitHub repo for this project: https://github.com/learncodebygaming/enb_bot
PyAutoGUI Documentation: https://pyautogui.readthedocs.io/en/latest/
Download Earth & Beyond: https://www.net-7.org/
Earth & Beyond Emulator donations: https://forum.enb-emulator.com/index.php?/donate/make-donation/
Additional PyAutoGUI tutorial at Automate the Boring Stuff with Python: http://automatetheboringstuff.com/chapter18/

A timing bot takes a predetermined series of actions, in a specific order, for a specific length of time. For example: press the 'W' key for 5 seconds (to move forward), press 'D' for half a second (to turn right), mouse click on the screen position 120, 200 (to open a menu), then wait 2 seconds (while the menu loads).

Inside Earth & Beyond, create a new character and make it a Terran Tradesman, so that you start at the same station as me.

Install PyAutoGUI using the terminal with pip install pyautogui. Now create a new Python script with a main function, and importing pyautogui and sleep. Enable the PyAutoGUI failsafe by setting the FAILSAFE flag to True. With the failsafe enabled, whenever our bot gets off course we can simply move the mouse to the very upper left corner of the screen to stop our script.

import pyautogui
from time import sleep


def main():
    initializePyAutoGUI()
    print("Done")


def initializePyAutoGUI():
    # Initialized PyAutoGUI
    # When fail-safe mode is True, moving the mouse to the upper-left
    # corner will abort your program.
    pyautogui.FAILSAFE = True


if __name__ == "__main__":
    main()

The first thing we need to think about with this bot is where is our starting location going to be inside Loki Station. Because if we're always inputting the same commands, then we need to have a consistent starting point in order to arrive at the desired destination using those fixed commands. At Loki Station, lets begin our character wedge to the left of Louden MacEwen. Open a chat dialog with him and then close it to also give our character a consistent orientation.

Let's begin our code with a countdown timer to allow ourselves a window of time to switch to the game window when we start our Python script. You could simply sleep for 10 seconds, but I've created a loop that will print out another dot for each second that passes in our countdown. We'll call this from main().

def countdownTimer():
    # Countdown timer
    print("Starting", end="")
    for i in range(0, 10):
        print(".", end="")
        sleep(1)
    print("Go")

Now let's try doing any action to confirm that Earth & Beyond is recognizing our PyAutoGUI inputs. Let's press the 'D' key for 1 second.

# hold down the 'd' key for 1 second.
# we do this in main(), after the initialization and countdown,
# and before printing "Done".
pyautogui.keyDown('d')
sleep(1)
pyautogui.keyUp('d')

Run this and confirm that your character turns like it should. If nothing happens, confirm that the program you're using to launch your script is in administrator mode.

We're going to be using this pyautogui.keyDown(), time.sleep(), pyautogui.keyUp() pattern often, so I recommend making a function to encapsulate that behavior. I've called mine holdKey().

DELAY_BETWEEN_COMMANDS = 1.00

def holdKey(key, seconds=1.00):
    pyautogui.keyDown(key)
    sleep(seconds)
    pyautogui.keyUp(key)
    sleep(DELAY_BETWEEN_COMMANDS)

So beginning from our starting location again, what we want to do is automate the process of moving our character through the station, into the bizarre, and starting a conversation with Eddie DuChampe. That's going to require a series of key presses and pauses. I've created the code below by first estimating how long each keypress needed, and then running the script and refining the numbers each time until the goal destination is reached.

def goToMerchant():
    # Back away from Louden MacEwen
    holdKey('s', 6.00)
    # Face the entrance
    holdKey('a', 0.10)
    # Go through the entrance into the main lobby
    holdKey('w', 7.00)
    # Turn to the bazaar lobby
    holdKey('d', 0.65)
    # Go through the entrance into the bazaar lobby
    holdKey('w', 5.60)
    # Turn to the trade merchant
    holdKey('d', 1.16)
    # Walk up to the trade merchant
    holdKey('w', 1.50)

Now that we've automated walking our character over to the trade merchant, the next thing we need to do is start a conversation with him so we can begin trading. To do that, we'll need to click on him with the mouse. We can do this using pyautogui.moveTo(x, y, duration) to move the mouse, and then pyautogui.click() to perform the click. But first we need to know the x and y position on the screen where we want to click. I've written a function to figure out what our current mouse location is, using pyautogui.position(), and print it to the console.

def reportMousePosition(seconds=10):
    for i in range(0, seconds):
        print(pyautogui.position())
        sleep(1)

Using this, we're able to determine the x and y coordinates of the mouse when we hover it over the trade vendor, so we can complete our mouse click code.

def tradeWithMerchant():
    # Hover our mouse over the merchant
    pyautogui.moveTo(1200, 355, 0.25)
    sleep(DELAY_BETWEEN_COMMANDS)
    # Click the merchant to start our chat
    pyautogui.click()
    # Allow time for the chat to begin
    sleep(3.00)

While talking with Eddie DuChampe, we want to buy as many "Manufacturing Robots" as our ship can hold. These we can sell for a profit at the next station.

You could click on the item, then click the "Buy" button, but you can also buy items by holding 'Shift' while you click them. I've demonstrated that second method here.

# inside tradeWithMerchant()
    # Buy the item
    numToBuy = 28
    pyautogui.keyDown('shiftleft')
    for i in range(0, numToBuy):
        pyautogui.click()
        sleep(0.5)
    pyautogui.keyUp('shiftleft')

We know the 'shiftleft' string means the left shift button by referring to the PyAutoGUI documentation: https://pyautogui.readthedocs.io/en/latest/keyboard.html#keyboard-keys

Using the strategies we've learned here, we now know enough to complete one half of our trading loop. Starting from Louden MacEwen, I've written code, using a combination of estimation and trial-and-error to get the timings right, to go to the merchant, conduct the trades, return to the ship, and fly to Earth Station, where we ultimately want to sell our goods.

You can compare my finished script with your own here: https://github.com/learncodebygaming/enb_bot/blob/master/timing_bot/main.py

At Earth Station, we'll need to find a new starting location. We'll continue from here in the next tutorial.

If you'd like to get more practice using this botting method, go ahead and complete the second half of the trade loop. You'll want to sell your "Manufacturing Robots" and buy "Alpha Rads" from Earth Station, and take them back to Loki Station to sell.


Automate Your Bot Script Creation
In this video, I show you how to use pynput to capture mouse and keyboard inputs in the game, and then use those recordings to …
Basic Image Recognition
PyAutoGUI's image matching features allow us to get information from the screen. In this video, I show you how to use these simple image recognition …
Complete Botting Loop
Here's what the completed Earth & Beyond automated trading loop should look like once you've finished the PyAutoGUI Video Game Bot Tutorial! If you want …
Ben Johnson My name is Ben and I help people learn how to code by gaming. I believe in the power of project-based learning to foster a deep understanding and joy in the craft of software development. On this site I share programming tutorials, coding-game reviews, and project ideas for you to explore.