In World of Warcraft, Fishing is a time consuming task which is simple and so lends itself to automation very well. There are many fishing bots out there. This article describes the bot that I wrote for fun and the problems I solved to make it work.
Fishing is a way to catch fish which can be used to cook food, which is used to heal or increase the stats of your character. You can also gain achievements through fishing.
The mechanics of fishing involve casting your line into in-land or sea waters and then waiting up to 30 seconds for a bite, then clicking to loot within a couple of seconds to catch the fish.
https://www.youtube.com/watch?v=T6reHXxA5f0
Put the contents of the repo into a folder. e.g "C:\FishingFun". I am going to refer to this folder from now on, so just substitute your own folder path.
You will need to install Visual Studio, get it here: https://visualstudio.microsoft.com/vs/ use Community 2019 or later.
Requires: Dot net framework 4.7 https://dotnet.microsoft.com/download/dotnet-framework, this should automatically be installed with visual studio.
Double click on the solution file to open it: "C:\FishingFun\source\FishingFun.sln", or open it from visual studio.
Once loaded click the Start button, this should build and run the project FishingFun.UI. Alternatively use F5 or menu 'Debug -> Start Debugging'.
Once it has built you can run it without visual studio by navigating with File Explorer to folder C:\FishingFun\Source\bin\Debug and run by double clicking on Chrome.exe
If you want run a version without a GUI you need to set the startup project in visual studio to FishingFun.Console by right clicking on the project in the Solution Explorer and choosing 'Set as startup project', then build (F6). You should now have C:\FishingFun\Source\bin\Debug\powershell.exe which you can run outside of visual studio.
To get the 'Fire Ammonite Angler' achievement you need to fish in Lava. Lava is red making it impossible to see the red feather, so you need to switch to the blue feather. On the main page click the orange configuration button, then change the 'Watch Feather' combo from Red to 'Blue'
Use a macro like this on your fishing key:
/use Fire Ammonite Bait
/cast Fishing
The bot needs to transition through the following states:
The main problems are:
The bobber is tiny on the screen, we need to make it easier to find.
Changing the character view to fully zoomed in means that the bobber is bigger and there is less clutter on the screen.
To further simplify finding the bobber, it must appear in the middle half of the screen as viewed by the character. Indicated by the red area in the image below.
The bobber is pretty easy for us to spot now, but a computer needs a simple way to determine where the bobber is. We could train an AI to find the float, but that seems like an over complicated solution. Perhaps we can use the red colour of the bobber to locate it ?
If we find all the red pixels in middle half of the screen, then find the pixel with most red pixels around it then we should have our bobber location !
We can get a bitmap of the screen as below:
public static Bitmap GetBitmap() { var bmpScreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width / 2, Screen.PrimaryScreen.Bounds.Height / 2); var graphics = Graphics.FromImage(bmpScreen); graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.Width / 4, Screen.PrimaryScreen.Bounds.Height / 4, 0, 0, bmpScreen.Size); graphics.Dispose(); return bmpScreen; }
When a bite occurs the bobber moves down a few pixels. If we track the position of the bobber while fishing, we can see an obvious change in the Y position when the bite happens.
Due to the different times of day and environments in the game, the red bobber feather changes its shade of red, it also has a range of red shades within it. We need to classify all these colours as being red.
The pixels we are looking for are going have an RGB value with a high Red value compared to the Green and Blue. In the colour cube below we are looking for the colours in the back left.
This is the algorithm I have created to determine redness:
public double ColourMultiplier { get; set; } = 0.5; public double ColourClosenessMultiplier { get; set; } = 2.0; public bool IsMatch(byte red, byte green, byte blue) { return isBigger(red, green) && isBigger(red, blue) && areClose(blue, green); } private bool isBigger(byte red, byte other) { return (red * ColourMultiplier) > other; } private bool areClose(byte color1, byte color2) { var max = Math.Max(color1, color2); var min = Math.Min(color1, color2); return min * ColourClosenessMultiplier > max - 20; }
In the animation below which shows the Red value changing from 0 to 255 within a 2D square of all possible Blue and Green values, the algorithm matches the red colours within the white boundary. These are all the possible colours which it considers as being in the red feather.
The WPF user interface I created allows the user to see what the bot sees and how it is doing finding the bobber. This helps to determine how well it is working.
On the left of the UI there is an screenshot which shows the part of the screen being monitored, the bobber position is indicated by a recticle, the recognised red pixels are shown in pure red colour.
In the top right the amplitude of the bobber is shown in an animated graph (lvcharts.net). It moves up and down a few pixels during fishing. When the bite occurs it drops 7 or more pixels.
A second configuration screen allows the investigation of different settings for the 'Red' pixel detection.
A console version is also available if the UI is not needed. It exposes the log so that some feedback on the bot performance is given to the user.