How I Created a Bot for this F# Incremental Clicker Game using JavaScript
Date: 2024-12-18 | create | build | fsharp | javascript | automation | games |
The 2024 F# Advent Calendar is in full swing and it includes this write up of creating a web-game using F#, Fable, and Feliz.
That web game is Truffle Wizard - an incremental clicker.
I have a habit of trying to automate clickers like this one and I thought this project deserved some more air time so here we'll attempt to automate it.
Automating Clicks
Truffle Wizard displays its game board in two sections:
- Inventory - with buttons to click to add resources, increase storage, and create generators
- Adventures - To progress the story and unlock new technologies
So to automate this we attempt to find the game view, find the relevant buttons and click them. We add a little randomness to try to jiggle ourselves out of local maxima (like we keep spending our money on storage when we should spend it on generators) but that's ab as "smart" as this script gets.
Code:
const shuffle_array = array => [...array].sort(() => Math.random() - 0.5);
function click_all_game_buttons() {
const table_buttons = document.querySelectorAll('#feliz-app .table-container button');
const adventure_buttons = document.querySelectorAll('#feliz-app .adventures button');
const all_buttons = shuffle_array([...table_buttons, ...adventure_buttons])
if (Math.random() < 0.001)
console.log(`Clicking ${all_buttons.length} buttons`)
all_buttons.forEach(button => {
// Randomize button clicks so that we don't _always_ click the low cost ones
const coin_flip = Math.random()
const click_chance = 0.5
if(coin_flip < click_chance)
button.click()
})
}
const click_buttons_interval = setInterval(click_all_game_buttons, 10)
- Creates function to randomize array order - we use this to add randomness
- Find table buttons
- Find adventure buttons
- Shuffle them
- Iterate over buttons and click them if passes coinflip
Usage:
- Load up Truffle Wizard in browser
- Right click on table and click Inspect to open dev tools
- Note: Open elements tab and expand iframe to force it to be queryable (see known issues)
- Paste the script into Console
- Note: Chrome requires you to opt-in to pasting scripts into console for safety so you may need to follow instructions in console to allow this
Known Issues:
- Script spends lots of clicks on low priority purchases - netting you 10ks of some resources but slowly progressing story.
- Workaround: Sometimes it is faster to just reload the browser (stopping script) manually click to progress story, then run script again.
- Script cannot find table on initial load in Chrome. You need to inspect the game view's iframe before the querySelectors start working. Claude says this is a known quirk in Chrome, idk.
- Workaround: Inspect the table such that the iframe expands in
Elements
explorer then paste script into Console.
- Workaround: Inspect the table such that the iframe expands in
Next
I probably spent more time trying to automate the game than playing it myself but that's how I like to game sometimes so that's okay.
I've previously attempted some F# game builds in Godot but didn't get very far - agree that F# does not integrate super smoothly with some of these game engines. But I'm happy to see the author's success and experiments trying out other paths and may pick it up again soon. In particular I've been leaning more into web builds and it's cool F# integrates so nicely here.
If you liked this post you might also like:
Want more like this?
The best / easiest way to support my work is by subscribing for future updates and sharing with your network.