16 Jun 2019

A World of Warcraft Fishing Bot

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 post describes the bot that I wrote for fun and the problems I solved to make it work.

Why Fish ?

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 machanics 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.

What would a bot have to do ?

The bot needs to transition through the following states:

  • Casting.
  • Watching the bobber for a bite. If a bite is seen then move to Looting. If the bobber is not seen for a few seconds or 30 seconds elapses then move back to the casting state.
  • Looting.

What problems are there to solve ?

The main problems are:

  • Finding the coordinates of the bobber on the screen.
  • Then determining when a bite has taken place.

Problem 1: Finding the bobber

The bobber is tiny on the screen, we need to make it easier to find.

Screen Zoomed Out

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.

Screen Zoomed In

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;
        }

Problem 2: Determining when a bite has taken place.

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.

Determining the location of the red feather on the bobber

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.

Fishing Bobbers

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.

Colour Cube

This is the algorithm I have created to determine redness:

  • Red is greater that Blue and Green by a chosen percentage e.g. 200%.
  • Blue and Green are reasonably close together.
        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.

Red Match Animation


The User Interface

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.

Main Screen

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.

Screenshot1

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.

Colour Configuration Screen

A second configuration screen allows the investigation of different settings for the ‘Red’ pixel detection.

Screenshot3

Video of the bot in action

Fishing Fun YouTube

Console Version

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.

Screenshot Console

Sourcecode

The souce code is here: FishingFun

blog comments powered by Disqus

About Me


My first computer was a Commodore VIC-20, I had great fun trying to code text adventures and side scrolling shoot ‘em ups in BASIC. This helped me lead the way as the first in my school to pass a computer exam.

Currently I work as a Senior Software Engineer in Bedford for a FTSE 100 Company. Coding daily in C#, JavaScript and SQL. Outside of work I work on whatever is interesting me at that time.