BatBrain -- a central nervous system for consult scripts

I'll just append my entire round-function and you can do what you want with that :)
Code:
string WHAM_round(int mana_cost, int rounds)
{
	buffer macro;
	//Don't fight with temporary amnesia
	append(macro, "if haseffect 297; abort \"You have acquired temporary amnesia, aborting\"; endif; ");
	//Don't try to automate longer than the sepcified turnround
	append(macro, "if pastround " + (to_int(vars["WHAM_maxround"]) - 1) + "; abort \"Stopping fight because it has gone on for too long (set WHAM_maxround to a higher value if you think this was in error)\"; endif; ");
	vprint(macro,9);
	return to_string(macro);
}

The batround_insert-solution sounds like a good compromise as well.
 
Once again, I find myself wanting to dig into BatBrain and batfactors... but looking at them both, after so long of not doing so... I have no idea where to begin!

a) Is there any comprehensive documentation? Any search I perform on this page leads to dozens of results, minimum. It's a maze!

b) Along the way (towards the end of when I last looked at things, I believe), both were changed to better support minimum / maximum / average in batfactors; however, most (if not all) spells seem to be missing this information? Am I missing something, or were they just not updated?

Any help would be appreciated! (For reference, I'm looking at putting together a spell damage simulator for those crazy diamonds; while I believe zarqon eventually plans on having this all supported, a certain crowd has been crying for it ASAP, and I certainly don't want to reinvent ALL the wheels -- batfactors being an especially big wheel.)
 
You should add support for Sick Pythons. The skill most likely adds +20 to hitch-nce. (Weak spading is better than none?)
 
Once again, I find myself wanting to dig into BatBrain and batfactors... but looking at them both, after so long of not doing so... I have no idea where to begin!

a) Is there any comprehensive documentation? Any search I perform on this page leads to dozens of results, minimum. It's a maze!

b) Along the way (towards the end of when I last looked at things, I believe), both were changed to better support minimum / maximum / average in batfactors; however, most (if not all) spells seem to be missing this information? Am I missing something, or were they just not updated?

Any help would be appreciated! (For reference, I'm looking at putting together a spell damage simulator for those crazy diamonds; while I believe zarqon eventually plans on having this all supported, a certain crowd has been crying for it ASAP, and I certainly don't want to reinvent ALL the wheels -- batfactors being an especially big wheel.)

If you want to take a look at how to do simple spell calculations and estimations then I suggest looking at how WHAM does this (this would be the Calculate_options()-function). Apart from this the most important function for spells would probably be dmg_dealt(spread).

By doing:
Code:
skill[int] allMySkills()
{
	skill[int] allmyskills;
	advevent trythis;

	foreach i,opt in opts
	{
		trythis = get_action(to_skill(to_int(excise(opt.id,"skill ",""))));
		if (contains_text(opt.id,"skill ") && dmg_dealt(trythis.dmg) > 0)
				allmyskills[count(allmyskills)] = to_skill(to_int(excise(opt.id,"skill ","")));
	}
	sort allmyskills by -value.mp_cost();
	return allmyskills;
}

void main(int initround, monster foe, string pg)
{
	act(pg);
	print("You are figthing a " + m);
	foreach num, sk in allMySkills() {
		print("Your skill " + sk + " will do " + dmg_dealt(get_action(sk).dmg) + " to it.");
	}
}

You will get a small consult scritp that goes through all your skills and prints the damage they'll do to the current monster.
 
Okay, all three issues are fixed in the above post. A global string variable "batround_insert" exists, default "", which your script can edit to add additional macro commands to batround (a betweenRoundScript, if you will). BB now automatically adds an abort check for Amnesia into the macro, but only when facing Protagonists, and only before skills. Also the Black Cat / O.A.F. skill => attack replacement is properly implemented. I used an arbitrary rate of 30% for this. Is there better spading for their skill/item blocking rate somewhere?

Also added Sick Pythons as +20 to hit. Does that apply even when unarmed?

@StDoodle: BatBrain is becoming pretty dang awesome if I dare say so myself. Glad you're interested again.

a) I really should compile some proper documentation for this. Doodle, if you create the page for it on the ASH Wiki a la ZLib, I'll start adding stuff there.

b) Ranges are fully supported for all formulas in batfactors, however 1) the majority of the entries in batfactors have not been updated to include this information, and 2) BB immediately collapses those ranges to averages just milliseconds after loading the file. In the long view, I want to have a preference for how pessimistic to be with ranges, including hitchance, but that's just not going to happen in the near term. So for now, if you need to access the full range of damage, I'm afraid you might need to use BB as a starting point rather than a workhorse.
 
Also added Sick Pythons as +20 to hit. Does that apply even when unarmed?

Yes. All attacks miss less often.

I note that you did not make it stack with Master of the Surprising Fist... well it is pretty much impossible to have both at the same time so I guess that is okay. That may not always be the case though.
 
Last edited:
Okay, all three issues are fixed in the above post. A global string variable "batround_insert" exists, default "", which your script can edit to add additional macro commands to batround (a betweenRoundScript, if you will). BB now automatically adds an abort check for Amnesia into the macro, but only when facing Protagonists, and only before skills.

Awesome :)
WHAM is now fully compatible with the new Batbrain.
 
Great, if Bale lets us know he's ready for the above to be released we can go ahead and do it.

I just added a bunch of missing items and a few skills to batfactors (mostly "content familiar" stuff), and the appropriate code to BatBrain where needed. In the process, batfactors gained a new "phylum" keyword. Also, I'm going to need to add a happening for the Thorax's fist, whatever that's about.

I wonder if the Carnivorous Dill Plant is a plant.
 
Not... successfully... parsing sentence...

I suspect you omitted a "not" or intended "and" rather than "but", but which and where makes a difference as to what I should do. Help?
 
Any chance of getting a new field added to the happenings-data file? I would love to have a "round this action was performed" field to parse as well. This would help greatly in making multiround stuns available even after they have been macroed away.
 
Not for this update, but maybe later... it's a decent idea. I'm also toying with the idea of adding an informational "times used" field, so you could clear your happenings file before a run and then see how many of each action/item/skill BB used for an entire run.

Right now I'm trying to investigate the issues reported in the SS thread, and add support for some newer items before releasing the new BB/SS. I've fixed the finished() round tracking bug reported in the WHAM thread, and looking into DB combos right now. Also need to add happened() checks in SS when building all the custom actions, since I want the custom action list to be available for my (or anyone's) fight.ash override.
 
Yeah... actually had to stop using my April 17th, 2011 copy of your fight.ash because BatBrain updates finally made it stop working. :) Ah well. Whenever BatMan is done, hopefully the override will join it.
 
Well, why didn't you say so? This is what I'm using at the moment. It might only work with the beta version posted above, not sure at this point, but it will certainly work with the new release. It needs work -- I switched from Tablesorter to Flexigrid but never had time to get it styled/organized/sortable properly. But it has all the abilities I want, if I ever figure out how to use it. If you feel like poking around and making any improvements -- and there are plenty to be made -- please share!

EDIT: attachments removed with BatMan Relay release.
 
Last edited:
So goals if I get a chance would be getting it to sort based on clicked sections? Default sort should be price, high to low meat value... anything else I'm missing? :)
 
Aligning headers and columns is a big one. Default sort should be as BB provides it (i.e. no sort). There are some nifty features and cosmetic enhancements in here since the last fight override I posted, such as deleveling macro buttons for all deleveling skills, which will delevel the monster to safety based on BB's knowledge, and with informative tooltips!

Oh, and: Flexigrid link.
 
I'd like to make a serious request for the forthcoming version of SmartStasis.

Currently main calls various subroutines such as try_custom() and try_combos() which submits a macro to KoL. Currently that looks like this:

Code:
   try_custom();
  // combos
   build_combos();
   try_combos();

I'd appreciate if you changed those functions to merely enque that the code is changed to:

Code:
   try_custom();
  macro();
  // combos
   build_combos();
   try_combos();
   macro()

The advantage is that a consult script could decide the effectiveness of those combos before submitting them. Also, killing moves could be added on to the end to save a server hit.

Finally, it would be nice if the consult script could control if entangling noodles was used before hand.
 
I'm using Winterbay's WHAM script, latest versions of WHAM, Batbrain, and Smart Stasis on r10861 during a Boris run. I've noticing that WHAM is consistently reporting that it's going to take two hits to kill a monster when I can consistently 1-hit them. As a result WHAM is choosing to delevel and / or stun, using Intimidating Bellow and Broadside in almost every combat.

I believe that the information leading to the 2-hit information is coming from Batbrain. The issue with Broadside and Intimidating Bellow has already been reported in the WHAM thread.

Here's a representative combat:

Code:
[1145] Battlefield (Hippy Uniform)
Encounter: War Frat 151st Captain
Round 0: Arbos wins initiative!
Running ZLib version: r35 (current)
1 HP costs 5.333μ. ( 472 / 472 )
1 MP costs 8μ. ( 123 / 143 )
Running BatBrain version: 1.18 (current)
Running SmartStasis version: 3.12 (current)
Running WHAM version: 1.8 (current)
WHAM: We currently think that the round number is: 0
WHAM: No need to do anything with this monster.
beer bomb (9.0 @ +30.0): 150μ * 11.7% = 17.55
beer helmet (5.0 @ +30.0): 600μ * 6.5% = 39.0
bejeweled pledge pin (4.0 @ +30.0): 600μ * 5.2% = 31.2
distressed denim pants (5.0 @ +30.0): 1,100μ * 6.5% = 71.5
keg shield (5.0 @ +30.0): 699μ * 6.5% = 45.435
PADL Phone (2.0 @ +30.0): 401μ * 2.6% = 10.426
perforated battle paddle (15.0 @ +30.0): 683μ * 19.5% = 133.185
red class ring (31.0 @ +30.0): 50μ * 40.3% = 20.15
Value of stat gain: 504.69μ
beer bomb (9.0 @ +30.0): 150μ * 11.7% = 17.55
beer helmet (5.0 @ +30.0): 600μ * 6.5% = 39.0
bejeweled pledge pin (4.0 @ +30.0): 600μ * 5.2% = 31.2
distressed denim pants (5.0 @ +30.0): 1,100μ * 6.5% = 71.5
keg shield (5.0 @ +30.0): 699μ * 6.5% = 45.435
PADL Phone (2.0 @ +30.0): 401μ * 2.6% = 10.426
perforated battle paddle (15.0 @ +30.0): 683μ * 19.5% = 133.185
red class ring (31.0 @ +30.0): 50μ * 40.3% = 20.15
Value of stat gain: 504.69μ
ATT: 190 (94% × 44.05, death in 12)
DEF: 167 (95.45% × 139.2 (15), win in 2200000)
HP: 215, Value: 873.13 μ
Parsed round number: 1
Building options...
Options built! (45 actions)
WHAM: We currently think that the round number is: 1
WHAM: You have no profitable MP restoratives.
WHAM: You have no profitable HP restoratives.
WHAM: You are fighting a War Frat 151st Captain. Mafia considers that this monster has an attack of 190 or 190 when given a monster name.
WHAM: Mafia further considers that this monster has a defense value of 167 or 167 when given a monster name.
WHAM: Mafia further further considers that this monster has a HP value of 215 or 215 when given a monster name.
WHAM: Your current ML-adjustment is: 10.
WHAM: Setting up variables via BatBrain
WHAM: Monster HP is 215.0.
if pastround 49; abort "Stopping fight because it has gone on for too long (set WHAM_maxround to a higher value if you think this was in error)"; endif; 
WHAM: Running SmartStasis
SmartStasis starting.
Profit per round: ActionProfitDamageOtherbase (0μ)0μ--
Building custom actions...
Custom actions built! (0 actions)
Stasis action chosen: skill 11011 (profit: 107.41)
beer bomb (9.0 @ +30.0): 150μ * 11.7% = 17.55
beer helmet (5.0 @ +30.0): 600μ * 6.5% = 39.0
bejeweled pledge pin (4.0 @ +30.0): 600μ * 5.2% = 31.2
distressed denim pants (5.0 @ +30.0): 1,100μ * 6.5% = 71.5
keg shield (5.0 @ +30.0): 699μ * 6.5% = 45.435
PADL Phone (2.0 @ +30.0): 401μ * 2.6% = 10.426
perforated battle paddle (15.0 @ +30.0): 683μ * 19.5% = 133.185
red class ring (31.0 @ +30.0): 50μ * 40.3% = 20.15
Value of stat gain: 504.69μ
Attack action chosen: skill 11001
Top of the stasis loop.
Queued: skill 11011
Building options...
Options built! (44 actions)
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned"; endif; if pastround 49; abort "Stopping fight because it has gone on for too long (set WHAM_maxround to a higher value if you think this was in error)"; endif; endsub; sub finito; skill 11011; call batround; endsub; call finito; repeat hasskill 11011 && (!hpbelow 472.0 && !mpbelow 123.0 && !pastround 25)
Round 1: Arbos executes a macro!
Round 1: Arbos casts INTIMIDATING BELLOW!
Round 2: war frat 151st captain drops 57 attack power.
Round 2: war frat 151st captain drops 57 defense.
Happened: skill 11011
Parsed round number: 2
Building options...
Options built! (44 actions)
Stasis action chosen: use 2678 (profit: -58.3)
beer bomb (9.0 @ +30.0): 150μ * 11.7% = 17.55
beer helmet (5.0 @ +30.0): 600μ * 6.5% = 39.0
bejeweled pledge pin (4.0 @ +30.0): 600μ * 5.2% = 31.2
distressed denim pants (5.0 @ +30.0): 1,100μ * 6.5% = 71.5
keg shield (5.0 @ +30.0): 699μ * 6.5% = 45.435
PADL Phone (2.0 @ +30.0): 401μ * 2.6% = 10.426
perforated battle paddle (15.0 @ +30.0): 683μ * 19.5% = 133.185
red class ring (31.0 @ +30.0): 50μ * 40.3% = 20.15
Value of stat gain: 504.69μ
Attack action chosen: skill 11000
This monster is not your huckleberry.
Stasis loop complete.
This monster is not your huckleberry.
Queued: skill 11003
Building options...
Options built! (43 actions)
WHAM: We estimate that the monster is stunned for 4.0 more turns and correct this with -1 for the turn the stun started on.
SmartStasis complete.
WHAM: Running SmartStasis took 3.908 seconds.
WHAM: We currently think that the round number is: 3
WHAM: Starting evaluation and performing of attack
WHAM: We currently think that the round number is: 3
WHAM: You will kill the monster in 2 rounds with your basic attack.
WHAM: The monster will take more than 30 rounds to kill you.
rounds_to_kill: 2, round_limit: 10, maxround: 30, die_rounds(): 33, hitchance("attack"): 0.95454544
WHAM: Expected received damage per round: 0.0, Rounds to kill: 2, Expected damage: 212.48181, Hit chance: 1.0
WHAM: Monster is weak. We are just going to bash its head in. It'll take 2 rounds.
Queued: skill 11000
Building options...
Options built! (43 actions)
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned"; endif; if pastround 49; abort "Stopping fight because it has gone on for too long (set WHAM_maxround to a higher value if you think this was in error)"; endif; endsub; skill 11003; call batround; sub finito; skill 11000; call batround; endsub; call finito; repeat hasskill 11000
Round 2: Arbos executes a macro!
Round 2: Arbos casts BROADSIDE!
Round 3: Arbos casts MIGHTY AXING!
Round 4: war frat 151st captain takes 214 damage.
Round 4: Arbos casts MIGHTY AXING!
Round 5: war frat 151st captain takes 190 damage.
Round 5: Arbos wins the fight!
You gain 17 hit points
You gain 10 Muscularity Points
You acquire an item: red class ring
You acquire an item: perforated battle paddle
You gain 28 Strengthliness
You gain 14 Magicalness
You gain 10 Sarcasm
16 frat boys defeated; 80 down, 920 left.
Running ZLib version: r35 (current)
Running Character Info Toolbox version: 0.6.3.2
Running ZLib version: r35 (current)
Happened: skill 11003
Running Character Info Toolbox version: 0.6.3.2
Happened: skill 11000
Happened: skill 11000
Parsed round number: 0
Look! You found 1 perforated battle paddle (683μ)!
Look! You found 1 red class ring (50μ)!
Happened: crit
WHAM: Evaluating the attack and performing it took 9.216 seconds.
WHAM: We currently think that the round number is: 31
WHAM: We currently think that the round number is: 31
 
Last edited:
1.20 Update For Great Smacking!

Okay, this update to BatBrain was quite big in the number of things that changed, so it took me a while to write up the description. Technically most of these were in the 1.19 update -- the 1.20 update simply added a missing check to avoid submitting an empty queue as a macro. But since that could mean a wasted server hit per fight, I considered it important enough to merit its own update bump.

Here are the rest of the changes from the 1.19 update:

  • The big one, of course, was already discussed above: enqueue() and macro() were significantly reworked to get macro information out of the queue. This keeps action id's "canonical" and allowed for two other neat changes:
  • 1) A new get_macro() function which returns the current queue as a macro. You can view this as a means of collapsing the queue into a string. If called on an empty queue, returns an empty string.
  • 2) Auto-funkslinging has been mostly re-implemented. Yay! Now if you enqueue two consecutive single item actions for a character with funkslinging, the second item will be merged with the previous item in the queue, without adding another round. This is imperfectly implemented at the moment: it fails to account for reduced player damage if the second item stuns or weakens the monster. That's on the to-do list, but this 90% implementation is much better than nothing.
  • The Black Cat and O.A.F. sometimes convert skills into regular attacks. Additionally, the Black Cat sometimes blocks item use, and the O.A.F. sometimes converts item use into a regular attack. BB now accounts for this, assuming a 30% chance for all of them. I drew that number out of thin air, since I couldn't find any number given anywhere for this. If you know a better number, please let me know.
  • Support for Sick Pythons adding +20 to-hit.
  • Skip Bifurcating Blow if you have the effect Foe-Spattered.
  • Clumsiness bark does extra damage vs. the Fox in Spats.
  • The orange agent is not available without enough meat to fuel it.
  • Auto-response added: throw clumsiness bark at the Thorax when he draws his fist.
  • Auto-response added: Sing when you get Earworms.
  • Streamlined code in multiple places: As cases and checks have gradually accumulated in certain areas, make those more efficient where possible by merging them all under a switch statement. Did this in at least four places, most notably in the responses sections of act() and batround().
  • Another speed tweak: Added a "profit" field to advevents. BB now uses this to cache the profit of advevents when to_profit() is called on them. This means that to_profit() -- an oft-used function, especially for sorting opts -- is much less expensive. No pun intended.
  • Since BB effectively tracks all actions performed during the combat, use this to detect base pairs thrown at Cyrus and set the tracking property when this is detected, rather than setting it before enqueueing the base pair.
  • Only return 50 for items with neither autosell nor historical value. This should help SS with a NPZR not to continue stasising for unreasonably valuable toast, among other things.
  • Fix combat completion detection for monsters with no Adventure Again link.
  • Significantly improve the sort in attack_action(). I recently tried to do a telescope dive using nothing but my SimpleSmack script, and was quite disappointed by some of the actions chosen by attack_action() when the fights started getting harder. This improved version was usable longer, until I ran into the auto-funk issue. Haven't yet tested again with both this improvement and auto-funk, but excited to do so. My basementing in the early levels (where it would be quite wasteful to funksling love songs) was absolutely perfect! Even its choice of love songs was exciting to see -- sometimes it would switch songs when the monster had enough HP remaining to kill it with a cheaper but less-damage song.
  • Some other changes already mentioned in this thread: Parse "perfect" damage even for non-skill actions. Allow macro inserts using global variable "batround_insert". Include an abort for acquiring Amnesia in submitted macros when fighting Protagonists.

And since Bale suggested it here rather than in SS, I'll also explain an SS change:

I didn't change the functionality of try_custom() or try_combos(), but I did split them into two parts. So now, for both custom and combos, there are three functions your SS-importing consult script may want to use in its main():

build_x() -- builds a separate list of events of that type.
enqueue_x() -- according to survival or profitability criteria, enqueue actions from the previously built list, but do not submit the macro.
try_x() -- calls enqueue_x(), then if there are any actions at all in the queue, calls macro(). You'll generally want to use either this function or the previous one.

SS was changed to use these as follows:

PHP:
  // custom actions
   build_custom();
  // snip -- adding Cyrpt miniboss items removed for this post
   if (queue[0].id == "pickpocket" && my_class() == $class[disco bandit]) try_custom();
    else enqueue_custom();
  // combos
   build_combos();
   try_combos();

First it builds the custom action list, then adds some more custom actions of its own. Then if you are a DB and pickpocket was one of the custom actions, it calls try_custom() which enqueues and then performs all the custom actions. This is because the profitability of Rave Steal or other +items combos may depend on the results of your pickpocketing. If you didn't get the jump or you're not a DB, it simply enqueues the custom actions but does not perform them. Next, it builds the disco combos, then calls try_combos(), which queues up any profitable combos and then calls macro() if the queue contains actions (even for non-DB's). Nice!

I think that will accomplish what you suggested nicely, Bale! Also thanks -- that was a great suggestion towards reducing server hits and speeding up combats.

I'm very happy with this latest update -- I feel that as of 1.20 this script has made leaps and bounds toward becoming the script I envisioned. Enjoy, everyone!
 
Back
Top