Holiday Hack Challenge 2023 Report Cody Travis <cwtravis@gmail.com>
Top

Fishing Mastery Challenge

The Geese Islands have amazing fish which are really fun to catch. They seem to be AI generated as many of the assets of the challenge are this year.

Getting Started

Before you get started fishing you need to grab the fishing pole as part of the Orientation objective. Be sure to chat with Poinsetta McMittens at Squarewheel Yard on the Island of Misfit Toys. They have some information about the fish here.

Below is a comprehensive list of fish available to be caught in the Geese Islands area. I also included the density map for each fish. The density map tells you where to look for the highest probability of catching that particular fish.

Pescadex

Pescadex

1234

Hash:

 
   

Fishing Basics

Fishing Basics

Once you have your pole, simply jump in your ship and click the "Cast Reel" button once your ship has come to a complete stop.

When the "Reel It In" button turns red, click it to reel the fish in.

Catch Em' All

Catch Em' All

But how do you know where to fish catch them all? Take a look at the HTML source of the iframe thats present while you are sailing around. To do this, just bring up the developer tools and use the element inspector to view the content, or (in Firefox) right click where your ship is, click "This Frame", then "View Frame Source".

The resulting source code reveals a link to a page apparently meant only for the Devs, but in their haste to produce this game, "forgot" to remove it:

  </>
HTML
<body>
    <!-- <a href='fishdensityref.html'>[DEV ONLY] Fish Density Reference</a> -->
    <div class="overlay"></div>
    <div class="ui">
        <button class="quitrace">Exit Race</button>
        <button class="castreel">Cast Line</button>
        <button class="reelitin">Reel it in</button>
        <button class="openpescadex">Pescadex</button>
        <button class="setbearing">Set Bearing</button>
        <button class="sayAhoy">AHOY!</button>
        <button class="settingsBtn">
Link in HTML Comment
Checking out the link in the comment:
fishdensityref.html

On that page is the full list of available fish that can be caught as well as a density map that reveals where in the Geese Islands that fish can be caught. The white areas indicate hot spots for the fish and dark areas indicate where the fish is not present.

Here is an example of a fish density map for the "Flutterfin Rainbow-Roll":

Flutterfin Rainbow-Roll Density Map

Feel free to sail and catch all the fish manually, or scroll down and check out how I automated it.

Secret Fish

The Secret Fish

Regardless how you caught the fish, you may end up with 170 different fish caught. Which is nearly all of them, but not quite. If you look at the density map page, you will see there is one fish with a very small area where it can be caught. Unless you got really lucky and fished that particular spot, you will likely have missed it. If you compare the list of fish you caught (which is in the javascript console under playerData.fishCaught) and the fish on the density map page, the missing fish is the "Piscis Cyberneticus Skodo". Check out the density map for it to see where it can be caught. I overlayed the island map to make the location more clear:

Piscis Cyberneticus Skodo Density Map

There is only one small area by the "goose neck" of Steampunk Island where this fish can be caught. Go there and fish for a few minutes and you will likely catch it. It looks like this:

Piscis Cyberneticus Skodo

It is quite fitting that this fish is found near Steampunk Island seeing as it bears a striking resemblance to the one and only Ed Skoudis!

Once you have caught all the fish, including Piscis Cyberneticus Skodo, head back to Squarewheel Yard on the Island of Misfit Toys and speak with Poinsetta McMittens to complete the "BONUS! Fishing Mastery" challenge. Note: If you will also complete the "BONUS! Fishing Guide" challenge simultaneously if you did not speak with Poinsetta McMittens in between catching 170 and 171 fish.

Fishing Bot

Fishing Bot

Now if you are like me and can't handle the monotony of fishing minigames, you could always automate the process. There are several ways to automate this process including sending manual websocket messages, external automation tools (AutoIt, AutoHotkey, etc), or Javascript manipulation. The path I chose was to use Local Overrides to inject some custom javascript at the top of the javascript file that controls the sailing and fishing.

If you need a refresher on Local Overrides check out my solution to Elf Hunt

Once Local Overrides are setup, you can edit the document and those changes will persist on reload. After analyzing the fishing process, I decided to add a checkbox at the top of the screen to turn the bot on and off, timer functions to cast the reel, wait for a fish, reel it in, dismiss the pescadex dialog, and repeat. The file to edit is https://2023.holidayhackchallenge.com/sea/js/client.js

I injected the following code. I will add comments for clarity:

  </>
Javascript
//Global variable to know when the fishing bot is active
var fishingBotGo = false;

// Function called when the checkbox is clicked to toggle
// Fishing bot on and off
function toggleFishing(){
    let ele = document.getElementById("fishingLabel");
    fishingBotGo = !fishingBotGo;
    if(fishingBotGo){
        ele.innerHTML = "Fishing Bot <img src='img/loading.gif' style='margin-top: 5px; height:20px; width:auto;'>";
    }else{
        ele.innerHTML = "Fishing Bot";
    }
}

// Function that gets called 2s after page load that injects the
// Fishing Bot checkbox
setTimeout(function() {
    var elemDiv = document.createElement('div');
    elemDiv.style.cssText = "position:absolute; top: 30px; width: 200px; height: 50px; color: white; leftbackground-color: red; z-index:9999; vertical-align: middle;";
    elemDiv.innerHTML = `
<input type='checkbox' id='fishingBotGo' value='Fishing Bot' onclick='toggleFishing();' unchecked>
<label id='fishingLabel' for="fishingBotGo">Fishing Bot</label>
`;
    document.body.appendChild(elemDiv);
}, 2000);

// Function that is called over 500ms that clicks the "Reel It In" button
// when there is a fish on
setInterval(function() {
    if(!fishingBotGo) return;
    
    let reelBtn = document.getElementsByClassName("reelitin");

    if (reelBtn.length > 0) {
        if (reelBtn[0].classList.contains("gotone") && reelBtn[0].style.display == "block") {
            reelBtn[0].click();
            setTimeout(updateFishCaught, 1000);
        }
    }
}, 500);

// Function called every 500ms to dismiss the pescadex dialog
// when a fish is caught
setInterval(function() {
    if(!fishingBotGo) return;
    let closePescBtn = document.getElementsByClassName("closefeesh smol");

    if (closePescBtn.length > 0) {
        if (closePescBtn[0].style.display != "none") {
            closePescBtn[0].click();
        }
    }
}, 500);

// Function that is called every 500ms to cast the reel when
// its available to do so
setInterval(function() {
    if(!fishingBotGo) return;
    let castBtn = document.getElementsByClassName("castreel");

    if (castBtn.length > 0) {
        if (castBtn[0].style.display != "none") {
            castBtn[0].click();
        }
    }
}, 500);
Changes to /sea/js/client.js

Check it out in action:

Fishing Bot