This fishing bot consists only of about 50 lines of code, it incorporates the mechanics of World of Warcraft and some simple Windows API Calls.
The bot has about ~99% success rate, there are some extremely rare cases where the bot won’t catch it and I will explain why later. The method that the bot is using, should work in almost any fishing scenario in the game, I would personally avoid crowded places. The testing has been done in the current expansion (Shadowlands).
The bot is running on the currently Active Window, I haven’t performed checks wether this is the window of the game or not. It waits for about 2 seconds before it starts.
Zereth Mortis: 29m 33s Items Looted: 161
That means that we loot roughly about ~5.4 fish per minute.
Installation & Usage
requirements.txt, for the Python Requirements and install them via
pip install -r requirements.txt. The tests are done under Python3.10 however I believe everything should work with Python>=3.6.
Set the bait
Before using the bot, you need to supply it with an image of the bait. The image has to be on the bottom parts of the bait. Here is an example image, the green area indicates what would be a good image of the bait, it needs to be as small as possible.
Save the image and place it at the root of the script as
bait.png, additionally you can adjust the variable
BAIT_IMAGE in the `fishingbot.py.
⚠️ It is important for you to take the photo because of the graphical/display settings which can be different for each computer.
Fine-tune the script
The fine tunning that you have to do consists of:
FISHING_BUTTON = "b" TUNE_BAIT_MOUSE_UNDER_PX = 35 EDGE_RESET = 10, 10 ACTIVE_AFTER = 2 CONFIDENCE = 0.7
|FISHING_BUTTON||The button that you use for fishing, in my case it was |
|TUNE_BAIT_MOUSE_UNDER_PX||The offset pixels where the mouse is going to be whenever there is a bait, see the How it works? section|
|EDGE_RESET||Those are the |
|ACTIVE_AFTER||The bot simply waits 2 secs before it starts|
|CONFIDENCE||The confidence of the template matching|
How it works?
The method is extremely simple, it utilizes two things. The first one is the Template Matching, this is what
pyautogui.locateOnScreen uses under the hood and the second one is the PyGetCursorInfo function which is exposed by the
The solution lies in the gif from the beginning, whenever the bobber actually catches a fish the AoE (Area of Effect) for the bobber becomes bigger allowing us to detect a change on the cursor, then we use the
GetCursorInfo to catch the change of the cursor and if it becomes a different
tuple from the default one which we set when there is nothing active on our cursor. Then we execute the click.
Now about the fine-tuning, look at this example
TUNE_BAIT_MOUSE_UNDER_PX variable which doesn’t have the best name ever is indicated with red, in simple terms it is how many pixels under the located bobber to place the mouse. For myself the range between 28-32 works the best, but as I said earlier this could differ.
There is a rare edge case when the default tuple for the cursor doesn’t change which happens if the script isn’t tune right, I’ve solved this by resetting the cursor at
x=10, y=10 position of the screen and then bringing it back. In a case when the cursor’s icon doesn’t change and if it sits with the bait icon the bot would just wait the duration of the fishing and reset itself.
I’ve added a bit of randomness in the timings between each press of the fishing and the click of the bobber with additionally pressing space every now and then. Apparently the server can detect that something fishy is going on when this randomness is removed.