BatBrain -- a central nervous system for consult scripts

Sorry, but I don't believe that fits the bill for a script setting. The maximum round is always 30, unless it's 50. If the script is getting you killed then there is a problem with the script's use of the combat scenario information. Tricking the script by using false information is not a road I want to head down.

Both yesterday and today I've been having two issues with BatBrain.

One is that SS is stasising for WAY too long due to mafia not having proper information about the various fights in the frat battle side. Any monster with unknown defence is considered at 0 defence levels, not 370, where I've placed unknown monsters, so I have 29 rounds of stasis and one round to do 237 damage and win, as an accordion thief with no combat skills and a purse rat as their (100%) familiar. This does not end well. War frat kegrider is such an enemy.

Second, kill_rounds is returning false information about what will work. This specifically refers to the NSN and her healing. It expects my character doing about 45 damage a round to finish her off in 4 rounds, instead of needing some sort of miracle of 6 crit rounds and 4-5 botches from her. Basically though, whatever calculation kill_rounds does, it doesn't appear to actually check monster healing in terms of what is going to be needed.

My usual fix for both of these sorts of things is to change max_round down to ~-10 to give me time to fix things if SS goes bad and DAM believes the figures that BB has given it which don't work. Since you mention that they shouldn't be needed, and I just watched another bout go down the tubes, I figured I should post though.
 
I think that it'd be better to adjust the safety margin in SS rather than artificially changing the maxround in batbrain. Changing the "1" on line 424 in SS to 5 or 10 should give you a lot more room to kill the monster off. And that number is much more fitting to use as a user setting than maxround.
 
Indeed... that's the value I tend to modify, usually. But the underlying problem appears to be not handling unknown monsters properly, which causes SS to run too long, which causes the issues with not being able to complete.
 
Unknown monsters should be handled with unknown_ml and was during crimbo for me at least, has anything changed there you think? OR is the problem that these specific monsters have strange data?
 
Well, the unknown monster is listed as having 370 (well, 333, for the 10% cut) defence, but some of the stasis and combat decisions are still being done as if it had 0 defence and will be a pushover.
 
There appears to be a bug with set_happenings/happened. The fight below ended the fight with a cocktail napkin on turn 492:
Code:
[492] F'c'le
Encounter: clingy pirate
Strategy:     C:\Privat\Dropbox\Mafia\ccs\PM.ccs [default]
Round 0: winterbay wins     initiative!
1 HP costs 2.08μ. ( 108 / 254 )
1     MP costs 8μ. ( 2 / 109 )
ATT: 110 (94% × 10.02,     death in 12)
DEF: 99 (97.73% × 50.26 (3)     (3) (3)     (3) (3),     win in 1050000)
HP: 100, Value: 530.21     μ
WHAM: Monster HP is 100.0.
WHAM:     Running SmartStasis
Profit per round:                             Action                          Profit                          Damage                          Other                                      base (0μ)                          0μ                          --                                                
    Custom action: use 2956 (no stun)
Round 1:     winterbay executes a macro!
Round 1: winterbay uses the cocktail napkin!

However in the happenings-file it is listed as having happened on turn 491 which means that "happened("use 2956")" returns false since it is 1 turn off.
Code:
use 2956	491	0	1
 
Zarqon, I found a small, but significant and easily fixable bug. You forgot the bit in red.

Code:
float item_val(item i) {
   if ([COLOR="#FF0000"][B]can_interact() &&[/B][/COLOR] is_tradeable(i) && historical_price(i) > max(100,2*autosell_price(i))) return historical_price(i);
   return max(autosell_price(i), [COLOR="#FF0000"][B]can_interact().to_int() *[/B][/COLOR] 50);
}

In hardcore or ronin, mallprices are irrelevant.
 
Last edited:
One more thing: How can I add information to batfactors that Candyblast only drops candy at rate 0.33? As far as I can tell, the "rate" keyword is only checked by famevent(). Does this need to be added to to_event() before it can be added to batfactors?
 
Zarqon, I found a small, but significant and easily fixable bug. You forgot the bit in red.

Code:
float item_val(item i) {
   if ([COLOR="#FF0000"][B]can_interact() &&[/B][/COLOR] is_tradeable(i) && historical_price(i) > max(100,2*autosell_price(i))) return historical_price(i);
   return max(autosell_price(i), [COLOR="#FF0000"][B]can_interact().to_int() *[/B][/COLOR] 50);
}

In hardcore or ronin, mallprices are irrelevant.

Personally, I like still considering the mall prices, because once I get out of ronin, I can sell my junk. As well, changing that second one means that quest items and anything non-saleable has a value of 0 while in ronin. I'm guessing that's not what you intended.
 
As well, changing that second one means that quest items and anything non-saleable has a value of 0 while in ronin. I'm guessing that's not what you intended.

Why would that be bad? Why would a value of 50 be better for such items?
 
What about the rest of what I said. About not using mall price when in ronin/hardcore and this...

One more thing: How can I add information to batfactors that Candyblast only drops candy at rate 0.33? As far as I can tell, the "rate" keyword is only checked by famevent(). Does this need to be added to to_event() before it can be added to batfactors?
 
Presently, it's not possible to account for drop rate with the item keyword. I suppose the item keyword should be made usable within formulas -- perhaps when loading the data file item flags could be replaced with values. That's probably the best solution. I'll put that on the list.

I already answered the bit about HC/Ronin.
 
I think I've found the problem with happened() and set_happened(). my_turncount() which is used to set the turn on which something happened updates to the current turn at the end of combat (as shown in the copy below):
Code:
> ash my_turncount()

Returned: 158090

[158091] F'c'le
Encounter: crusty pirate
Round 0: molman wins initiative!

> ash my_turncount()

Returned: 158090
Round 1: molman executes a macro!
Round 1: molman tries to steal an item!
Round 2: crusty pirate takes 1 damage.
Round 2: crusty pirate takes 9 damage.
Round 2: crusty pirate takes 3 damage.
You lose 8 hit points
Round 2: molman casts RUN LIKE THE WIND!
Round 3: crusty pirate takes 7 damage.
Round 3: molman casts BREAK IT ON DOWN!
Round 4: crusty pirate takes 15 damage.
Round 4: molman casts POP AND LOCK IT!
Round 5: crusty pirate takes 20 damage.
You acquire an item: barrrnacle
Round 5: molman casts BREAK IT ON DOWN!
Round 6: crusty pirate takes 8 damage.
Round 6: molman casts POP AND LOCK IT!
Round 7: crusty pirate takes 14 damage.
Round 7: molman casts RUN LIKE THE WIND!
Round 8: crusty pirate takes 17 damage.
You acquire an effect: Rave Concentration (duration: 1 Adventure)
Round 8: molman wins the fight!
After Battle: Trofflesby winks at you.
You gain 217 Meat
You gain 11 Beefiness
You gain 6 Enchantedness
You gain 7 Cheek

> ash my_turncount()

Returned: 158091

So, SmartStasis sets "I did this in turn X" and that ends the fight, if something checks happened() afterwards it'll return false since the turncount-number updated after SmartStasis ended the fight.
My current workaround is to use a has_happened(string) function in my consult script that tests for my_turncount() - 1 in order to get around this until something more stable comes up.
 
Sorry... I don't get how that is a problem; it looks like correct behavior to me. Your turncount shouldn't increase until the fight is over. And when the fight is over, what point is there in checking happened()? At that point, happened() is no longer in reference to the combat which just finished, since you are no longer in combat.
 
The point is when a script is imported into another, such as SmartStasis is in both WHAM and DAM, and SS finishes the fight and the run returns to the starting scritp which gets confused due to there not being a fight anymore and the check to see if there still is a fight won't work since the turncount is off by one.
I'll continue using my own has_happened() then.
 
Aha, I get it now. If you have a BB-powered script that is designed for following other BB-powered scripts, and you can't just import them and make it one script (i.e. they are maintained by two different authors, which I believe is the case here), you can just check if the round number > maxround at the very beginning, right after act(). If the fight is already over, the round number will be maxround + 1.

From the sound of it this wasn't your issue, but I should also mention that I generally recommend only having one instance of BB per combat where possible, i.e. import SS into your script rather than making a script which you call after SS. It won't really hurt anything to load everything multiple times, it's just uglier. :)
 
Last edited:
Well, I am importing SS into WHAM (and invoking it by basically copying the main function of SS to a function within WHAM and calling that), which works fine apart from the end-of-fight detection. The problem is really, I realize now, that I've set up WHAM to always try and perform at least one action (via a repeat-until-loop rather than a while-loop) which will fail if there's nothing to do. I could check for "WIN!WIN!WIN!" in mroe places than one as well I guess.
 
Don't check WINWINWIN; check round > maxround, which will also work for losing the fight or fighting too long (even page load failures). As an additional perk, it's also less bulky than searching page text.
 
I believe that I've found a tricky bug in BatBrain. After using "Throw Shield" it assumes everything will be a critical, not just the next action. I'm not quite sure how best to fix that. For now I'm dealing with it by not throwing my shield.
 
Back
Top