BatBrain -- a central nervous system for consult scripts

2. My second request is: is there a way to identify a combat uniquely? For example, suppose we want to set a flag uniquely identifying our current combat, so that when the script next runs, it could tell whether we are in the same combat or not (really only an issue for relay scripts, but a big one).

This seems feature request worthy since it is a gap in KoLmafia's session logging. Laserrobotics' suggestion seems to be worthwhile. I'd particularly like to hear Veracity's view on the subject since she's particularly invested in it.
 
Upon further thought, I would suggest logging the combat either per ascension or per day of ascension, rather than per session, just in case someone stops working in the middle of combat for whatever reason. Since I don't believe it's possible to remain in a combat across rollover (but I could certainly be wrong), per day of ascension would probably be sufficient, but I could see arguments for per ascension as well. Maybe have this as something that goes in the log, with a reference-able variable that's incremented at the beginning of combat?
 
Last edited:
I'm invested in logging combats correctly. I'm not sure I'm invested in "adding tracking to let scripts do things they can't currently do, per se."

I do like the idea of tracking "a combat has occurred" rather than "a turn has taken place". I'm not sure KoLmafia cares - if you say "spend 10 turns in this location", you really don't care about X random free combats that happened while your were at that location, since they don't advance counter, diminish the duration of effects, or do anything else that KoLmafia itself cares about.

Which is to say, this is something that only (a tiny handlful) of scripts will care about, rather than KoLmafia itself.
 
I'm thinking of feature requesting something quite simple: a property that gets set when you begin a combat. My initial idea is simply that the property would be called something like lastCombatBegun and would simply contain a timestamp. Easy and solves my problem.

Any feedback on the melee skills stuff? Are my guesses accurate or is this a largely unspaded thing?
 
I do like the idea of tracking "a combat has occurred" rather than "a turn has taken place". I'm not sure KoLmafia cares - if you say "spend 10 turns in this location", you really don't care about X random free combats that happened while your were at that location, since they don't advance counter, diminish the duration of effects, or do anything else that KoLmafia itself cares about.

Free combats reduce delay. That is a thing that some scripts running on KoLmafia do care about, so it is relevant. (In addition to BatBrain's own reasons.) As much as a non-sentient program can care about anything, it cares about things that make it more helpful to its users.
 
Does turns_spent increment when you don't spend a turn?

Yes for combats, no for noncombats. The only purpose of turns_spent is to match what KoL thinks for purposes like delay, the boss bat, and so on.

That doesn't cover all cases for what BatBrain wants though, since a puttied free fight monster would have none of that to go by.
 
This is probably a batbrain thing....but WHAM doesn't seem to calculate using the curses, specifically Curse of Weaksauce and Curse of Marinara which give MP/HP at 30% of damage dealt upon the killing blow (50 cap). These bonus don't seem to be mentioned in the batfactors, but I have no idea how to add them.
 
I believe handling for the Curses is accounted for, but you would have to predictively build a combat to see that.

In other words, the curses themselves don't include benefits that they don't give on that round. Also, actions that kill the monster won't include any benefit from a curse unless it has already happened. WHAM or SS could probably stand to automatically choose a curse if it could be profitable when you get a killing blow.
 
WHAM does currently not take advantage of the curses. I was about to look into it when suddenly all my time disappeared in a second kid and it never happened.
 
I understand, kids are time vacuums ;)

On a different note, I am have problems with the batbrain carrying out actions, or what it calls reactions. For a combat library, I feel like it is out of its scope to be doing such things. The particular problem I am having is my Sauceror is getting majorly poisoned by an Asp. Instead of consulting my script (which perm CCs it and kills it) it keeps throwing anti-anti-antidotes to cure the poison, letting the Asp rack up free damage until I am dead. Heres the code I ended up commenting out:
Code:
if (m.poison != $effect[none] && have_effect(m.poison) > 0 &&
       (m.poison == $effect[toad in the hole] || m_hit_chance() > 0.1)) {
      vprint("You're dangerously poisoned!  Will try to remove if possible.","olive",2);
      if (have_effect($effect[Duct Out of Water]) > 0) return act(use_skill($skill[spew poison]));
      if (item_amount($item[anti-anti-antidote]) > 0) return act(throw_item($item[anti-anti-antidote]));
   }
 
I have found two bugs while playing around with batbrain.

1. Your physical damage calculations are slightly off. I believe this is from double dipping from ML resistance and KoLMafia's physical_resistance which now includes the ML resistance. Here are some examples. All have some +ML, and I used a pulled porquise earring for never fumble.
Code:
EoD Thinks: none will do 316.  BatBrain Thinks: none will do 283 Round 2: Foodie Giant takes 330 damage. 
EoD Thinks: none will do 339. BatBrain Thinks: none will do 303 Round 2: Renaissance Giant takes 351 damage. 
EoD Thinks: none will do 60. BatBrain Thinks: none will do 53. Round 2: Possibility Giant takes 60 damage.

And here is an example with no +ML
Code:
 EoD Thinks: none will do 54. BatBrain Thinks: none will do 55.  Round 3: Procrastination Giant takes 54 damage.

2. Seal Clubbers Thrust-Smack/Lunging Thrust-Smack are not calculated correctly when playing that class.
Ts/LTS weapon multipler applies to elemental damage (even works barehanded). You can also TS/LTS with ranged weapons, but it seems to only perform a normal attack with the added the cold shoulder damage.
Here is an example of a no weapon Seal Clubber with only an astral shirt on for elemental damage (No ML).
Code:
EoD Thinks: Lunging Thrust-Smack will do 207. BatBrain Thinks: Lunging Thrust-Smack will do 70. Round 1: CaveSmasher casts LUNGING THRUST-SMACK! Round 2: Procrastination Giant takes 212 damage.
 
ML resistance should never cause double dipping if correctly coded, as ML resistance is not additive (the game takes the max of the two, or just the ML resistance if the physical resistance is unset).
 
ML resistance should never cause double dipping if correctly coded, as ML resistance is not additive (the game takes the max of the two, or just the ML resistance if the physical resistance is unset).

That is what I am referring too, I don't think it is coded correctly.

ML resistance isn't added/multiplicative to innate physical resistance? The game just uses whichever one is higher?
 
Yes. I think one of the first places this was noticed was when Weirdeaux monsters suddenly got 10% physical resistance, and negative ML no longer led to a damage boost.

Also one of the twitch streams leaked that section of fight.php.
 
Ah that is interesting, thanks for the info!

On a different note, does anyone know how to update batfactors? In a recent response in WHAM zarqon says
1. If the information is incorrect in batfactors, edit batfactors.txt to contain correct information (or at least less harmful information) and upload the fixed file. Anyone can do this, and it benefits everyone.
On the wiki page of batfactors it states
As it is publicly editable on the Map Manager....
Unfortunately, I am still lost as to where this map manager is that I am supposed to be uploading too.
 
There's also a link in my sig.

Thanks for the feedback Eliteof.

1. I just bumped ML up to +187 with equipment and $monster[<monster normally lacking physical resistance>].physical_resistance still returns 0, so I don't believe there is any double-dipping happening.

Ok. Now I just adventured at the Noob Cave with that +ML, and BatBrain reported a bunny physical resistance of 75%, which is 50% applied twice, so it appears double-dipping is indeed the culprit.

> ash last_monster().physical_resistance

Returned: 50

> ash $monster[fluffy bunny].physical_resistance

Returned: 0

Huh? So it includes it if it's the last_monster() but otherwise it doesn't? That could be problematic for predicting combats outside of combat, which has always been a concern in scripting BatBrain. Now, just to confirm what we already suspect, when we access the global variable m, do we get the version with or without physical resistance?

> ashq monster m = last_monster(); print(m.physical_resistance)

50

Looks like it still gets the resistance one. Fortunately, heeheehee has pointed out that ML-resistance is not applied on top of special resistance. That information was evidently not yet spaded when I first added this code -- in fact I believe I "fixed" suggested code which applied the resistance additively, so that it was instead applied multiplicatively. As it happens, both were wrong! Anyway, this means we don't have to make any special checks; since we're calculating the number anyway for all the other elements we can just use our calculated number for physical resistance regardless of which version of the proxy field we get, since we're taking the max of the two.

When was this changed, by the way? I usually keep an eye on the commit messages but don't recall seeing anything about this change.

Anyway, I believe we've found the source of the problem. My local BatBrain is a little bit of a mess at the moment so I won't be able to update this right away, so in the meantime simply changing the unnecessary word "supercold" to the word "none" around line 1738 will at least prevent the doubling until the next update fixes it for realsies. Thank you for the report!

2. Just had a look at the Wiki for smacks, and it looks like the information there concerning the 2013 muscle class revamps is now much more thorough than when I was editing BatBrain to support the revamp. It also makes an even bigger mess of the damage formula, since elemental and weapon damage is evidently only multiplied if you are a Seal Clubber, otherwise only the base weapon damage is multiplied, as before. So presently BatBrain only handles smacks correctly for non-Seal Clubbers wielding melee weapons, ha.

I also noted that evidently the various TT butt skills also now work with ranged weapons, so I'm just removing the code that filters SC and TT skills based on a melee weapon being equipped. I'll be able to open up all the smacks and butts to non-melee weapons fairly easily, but the class-conditional doubling won't be quite as easy. Will have a go at that soon.

BatMan: Battle Manger. Would like to see someone with photoshop skills have a go at that.
 
Back
Top