BeachComber - fast and efficient beach combing


Currently, this will go to a random beach section every turn. I'm considering a mode of operation which will repeatedly go to the same section to collect 't' squares, until there are none left, before moving on to a different section.

Pro: Every time you go to a different section of beach, there is a chance that it will be cleaned out of 't' squares. Collecting in the same section until it is fully collected will alleviate some of that chance, since we'll be changing sections less often..
Pro: We don't know about the distribution of 't' squares within a beach. I don't find sand dollars or fish scales to be as interesting as equipment, say. Is there always a "higher quality" drop in a beach section, or is it purely random? I suspect the latter, but if the former, fully harvesting 't' squares in a beach section will potentially give you a better haul
Con: Cleaning out all the 't' squares is exactly how the next person to randomly visit the square doesn't find any 't' squares. Which is to say, it is selfish, rather than cooperative.

I may or may not do anything like this, but be aware that I can and do make commits for any reason. For example, the last one also fixed a typo in a message, and even if the new discovery hadn't been announced, I might have submitted that change alone, and your local mods would be discarded for something you probably wouldn't have cared about.


in /scripts... didn't expect an update of the script after 4+ months... :(

If you know about the feature that would protect you and choose not to use it then OK. My comment was for those who did not know.

See Revision Merging at

The way I was saying it, I actually meant it as "why I didn't keep a backup of my changes". I DID NOT know about the merging feature, and should keep this in mind in the future!


Is it possible to add a feature to let you only use a certain amount of your free combings? (For if you plan to comb some beach heads later on)
The argument parsing is super primitive currently.

    int turns =
	command == "free" ? 0 :
	command == "all" ? my_adventures() :
	command.is_integer() ? command.to_int() :

    if ( turns < 0 ) {
To allow

BeachComber 3
BeachComber free
BeachComber all

It wouldn't be too complicated to allow something like

BeachComber 5 free

Or, to enable new options:

BeachComber specific 842

(to go to 842 minutes)

BeachComber 5 free twinkles

(to use 5 free turns focusing on rough sand with a twinkle)

Right now, I'm working on the "go to the same square multiple times to get twinkles" feature.


Revision 214 does this:

set VBC.PickStrategy=twinkle

... will behave as described above.

start by going to a random beach section
while there are twinkles, pick them
rinse and repeat

I'll look into making the command parsing more capable, by and by.


Since KoLmafia now automatically marks the square you just combed with a 'c', this script doesn't need to do that any more.
This eliminates KoLmafia's logging that the _beachLayout property has changed.
It only does that if a script changes a built-in property, not if KoLmafia itself changes a property.


It seems that every tile has a permanent set rarity (see, and is re-combable after a certain amount of time (more rare, more time to reset). It might be a good feature to at least build a map of which tiles have which rarity. In the future it might also be cool to have a strategy that revisits certain tiles after they have probably reset, or at the very least farms them if it notices they've reset while happening to visit the same part of beach.


I'll think about that. It's especially appealing considering what I encountered today. I'm glad I made this script save the HTML for "special" combings.
I can now confirm that "whale.png" is titled "a beached whale".

Screen Shot 2020-08-18 at 5.23.37 PM.png


The past few days, I've been running into a little issue. Using the script menu to call beachcomber and entering 0 in the little thing that pops up to put a number in, on the first time it's done per day: it gives this error message: e1dfe7566837ed32319aaf977a4aaed0.png
However, doing the exact same thing a second time after that, it combs the free comb limit just fine.


Update: Now with Debug Log. It actually didn't do it last night, but did it tonight.


  • DEBUG_20200909.txt
    806.6 KB · Views: 3



Starting ASH script: BeachComber.ash
All is well!

Field: Location = [choice.php?forceoption=0]
ResponseText has 17012 characters.

Starting spading script: excavator.ash
Connecting to
ResponseText has 25 characters.
<font color="black">You have the latest use_for_items.txt.  Will not check again today.</font>
Finished spading script: excavator.ash

ResponseText has 2722 characters.

Items combed:
Offset 0 out of bounds (BeachComber.ash, line 287)
  at square_at (BeachComber.ash:287)
  at comb_beach (BeachComber.ash:457)
  at comb_random_beach (BeachComber.ash:535)
  at comb_next_beach (BeachComber.ash:566)
  at beach_comb_free (BeachComber.ash:585)
  at beach_comb_free_only (BeachComber.ash:608)
  at main (BeachComber.ash:694)
Finished ASH script: BeachComber.ash
We used the Beach Comb.
-> That left us sitting in choice #1388
KoLmafia started a spading script
The script called an external URL - something on zarqon's server
KoLmafia finished the spading script
BeachComer tries to do this:

buffer comb_random_beach()
    // Wander to a random spot
    buffer page = run_choice( 2 );
    return comb_beach( page );
Which should have submitted: choice.php?whichchoice=1388&option=2
But that is not in the DEBUG log.

I conclude that the call/response of that external URL left KoLmafia thining we were no longer in a choice.
That's a bug.

Funny that this was a result of a spading script. :)

I'll look at this later today.


I wonder why it did anything with zarqon's server at all! No spading project should have been activated by that choice. Perhaps something happens the first time you run a script that imports zlib?


I wonder why it did anything with zarqon's server at all! No spading project should have been activated by that choice. Perhaps something happens the first time you run a script that imports zlib?

Almost certainly. There are a couple of map files that are checked for newer versions and some of the pre-SVN version checking gets run. The debug log shows use_for_items being checked.