BatBrain -- a central nervous system for consult scripts

Also, as zarqon pointed out, Cleave/Mighty Axing were both being considered to have a fumble chance. Which they don't have. Which turns a 1 round guaranteed kill into a "maybe 2 round" kill.
 
For example, I saw something about Song of Battle guaranteeing that your attacks hit?

Yup. It guarantees that you will not fumble or miss with any attack, including skills like mighty axing and cleave. Personally confirmed.

Offtopic: With 100% damage bonus in addition to never missing it would be awesome for any class except Boris, but for Boris it isn't even one of his most powerful combat skills, being useful exclusively for the +20% combat rate. Now that is awesome!
 
It guarantees that you will not fumble or miss with any attack, including skills like mighty axing and cleave. Personally confirmed.

By any chance did you confirm this with Cunctatitis active, or when fighting Dr. Awkward? If I get it right the first time I won't need to update it when someone corrects me. :)

Offtopic: Agreed. Other than the +20% combats, I haven't ever considered Song of Battle useful enough to replace one of the other songs.

@Magus: I added the Song of Fortune auto-crit several updates back. If there is a problem, I doubt that's the reason why, but if I get the chance I'll take Fortune this run and test it.
 
By any chance did you confirm this with Cunctatitis active, or when fighting Dr. Awkward? If I get it right the first time I won't need to update it when someone corrects me. :)

I did not try it under either of those circumstances. I'll have to test that when I have a chance. I just started a leisurely ascension right now so I won't mind doing a little spading like that.
 
(Note this is not against the non-RAM Orc Chasm monsters.) I've been getting silent fails when using macro($item[facsimile dictionary]) until I turned the verbosity up to 10. That's when I started getting "Unable to enqueue empty action." After a few tests, I found that "use 1316" didn't exist when build_options() got finished. I've hard-coded my CCS to use fat stacks of cash now, but this just seemed odd that it wouldn't list it as any kind of option. Does BatBrain eliminate this as an option since the monster is, for example, a Raver Giant?
 
I've just started to seriously play around with the predictive power of BatBrain. I've got a little bit of code that illustrates what I am doing. It is very simplistic at the moment and obviously tuned for Boris, but it seems to work. I would like comments/criticisms/suggestions. Am I doing this right?

PHP:
void enqueueDelevel() {
	if(my_path() == "Avatar of Boris")
		enqueue($skill[Intimidating Bellow]);
}

void enqueueKill() {
	while(monster_stat("hp") > 0 && my_stat("hp") > 0 && round <= maxround - safetyMargin)
		if(!enqueue(attack_action())) return;
}

boolean enqueueFight() {
	record combat_set {
		string macro;
		int profit;
	};
	combat_set [int] set;

	combat_set queue_value() {
		combat_set tmp;
		tmp.profit = (adj.mp * meatpermp) + ((my_stat("hp") - my_hp()) * meatperhp) + adj.meat;
		tmp.macro = get_macro();
		return tmp;
	}

	advevent stun = stun_action(false);

	enqueue(stun);
	enqueueDelevel();
	enqueue_combos();
	enqueueKill();
	set[0] = queue_value();
	reset_queue();

	enqueueDelevel();
	enqueue_combos();
	enqueueKill();
	set[1] = queue_value();
	reset_queue();

	enqueue(stun);
	enqueue_combos();
	enqueueKill();
	set[2] = queue_value();
	reset_queue();

	enqueue_combos();
	enqueueKill();
	set[3] = queue_value();
	reset_queue();
	
	sort set by -value.profit;
	macro(set[0].macro);
	return true;

}
 
That looks good to me. I don't suppose there is a "wrong" way to do something as long as it works well.

You are approaching it from the opposite direction I had; creating some preformed macros and then checking the results, rather than predicting results in order to form the macro. It's a good idea for the contained environment of Boriscore, where there are only so many combat strategies.

I'd really like to help people get away entirely from referencing actions by name and instead sort opts to find the action that best matches their criteria -- because that will work both now and later when other skills are added. Ideally, BatBrain will create a scripting environment where scripters can access actions simply based on results. Basically, if you find yourself needing to reference an action by name, tell me why and I'll see if we can't create a more general solution. Like everything in KoL, I'm sure there will be exceptions and special cases, but where possible I'd like to get away from names. In your example, I'm seeing a good case for a delevel_action() function, since there already exist such functions for attack, stun, and stasis.

EDIT: I'd make the profit field a float rather than an int. There may be differences almost as big as 1.0 which would be treated as identical when truncating the floats to ints. (In ASH to_int(float) truncates rather than rounds, meaning that 1.999 and 1.0001 are the same when converted to ints.)

@Fluxxx: Hmmm, for items that are flagged as only being effective against certain monsters, BB skips that item unless you are fighting one of those monsters. That is one of the present weaknesses with the monster flag; various results for different monsters can't be included. I'll look into a fix, because even though a seal tooth is not hard to get for stasis, BB shouldn't be in the dark about this.
 
Last edited:
I'd really like to help people get away entirely from referencing actions by name and instead sort opts to find the action that best matches their criteria -- because that will work both now and later when other skills are added. Ideally, BatBrain will create a scripting environment where scripters can access actions simply based on results. Basically, if you find yourself needing to reference an action by name, tell me why and I'll see if we can't create a more general solution. Like everything in KoL, I'm sure there will be exceptions and special cases, but where possible I'd like to get away from names. In your example, I'm seeing a good case for a delevel_action() function, since there already exist such functions for attack, stun, and stasis.

My attemtp at doing that worked... not very well due to the script trying to use items in higher amounts than I actually had when running something like:
Code:
advevent thing = attack_action();
while(monster_stat("hp") > 0){
   enqueue(thing);
   thing = attack_action();
}
macro();

Granted this is a very crude implementation but it seemed to do some odd things like enqueueing as I said more of an item than I actually had. Is there any way of getting BatBrain to only enqueue an item for as logn as I actually have it? Skills are selfregulated via my_stat("mp"), but that doesn't work for items.
 
Yeah I remember deciding to leave that till later long ago before BatBrain had a proper queue, but now that we are tracking all happenings it's possible to skip items when all of them have been enqueued! Thanks for mentioning that, it's a very useful tweak.

Okay, I've added Song of Battle (as a guaranteed 100% hitrate for all actions for now, until Bale or anyone else spades otherwise regarding Cunctatitis and Dr. Awkward) and added the aforementioned "items queued" check when building items. And now that attack_action() has pretty much settled down into awesomeness, I've been tweaking stun_action() to also be more awesome and was still in the middle of it when I ran out of turns to test today. Once that's finished, we'll have us an update, we will.

EDIT: Whoa, I just squashed a big ugly bug. kill_rounds() was pessimistic about monster HP variance, but dmg_dealt() capped the damage at the monster's average HP (not pessimistic), meaning that actions which definitely overkill the monster were still being calculated as requiring 2 rounds! For example monster HP: 100, pessimistically 105. Attack action deals 9999 damage, capped at the monster's HP of 100. Still 5 HP left, hmmm. Aaaack! Wrong wrong wrong!! Fixed that by simply being pessimistic about monster HP variance throughout the whole script -- as Bale had requested before -- at least for now. It will make up for being slightly suboptimal by not underkilling monsters and getting consult scripts confused, not to mention fixing a glaring bug in one of the most-used BatBrain functions.
 
Last edited:
Okay, I've added Song of Battle (as a guaranteed 100% hitrate for all actions for now, until Bale or anyone else spades otherwise regarding Cunctatitis and Dr. Awkward)

Song of Battle does not counteract either Cunctatitis or Dr. Awkward and I've got the kicked ass to prove it!
 
Last edited:
I think I also fixed the odd flyering issue Bale reported (and which I also encountered) where it would only flyer every other combat when automating. That was another repercussion of the server-hit-reducing change to SS.

Still only getting flyered on alternate rounds.

Code:
> zlib verbosity = 8

Previous value of verbosity: 3
Changed to 8.
Validating adventure sequence...

Running ZLib version: r35 (current)

Request 1 of 5 (Beanstalk: Hole in the Sky) in progress...

[700] Hole in the Sky
Encounter: The Astronomer
Strategy: C:\Documents and Settings\David.QUICKSILVER\My Documents\My Dropbox\KolMafia\ccs\default.ccs [default]
Round 0: bale loses initiative!
You lose 95 hit points
Running ZLib version: r35 (current)
1 HP costs 5.333μ. ( 24 / 423 )
1 MP costs 8μ. ( 34 / 103 )
Running BatBrain version: 1.22 (current)
Running SmartStasis version: 3.14 (current)
Running Destroy All Monsters version: 0.4.1 (current)
star chart (100.0 @ +108.90416): 100μ * 100.0% = 100.0
Value of stat gain: 698.59μ
star chart (100.0 @ +108.90416): 100μ * 100.0% = 100.0
Value of stat gain: 698.59μ
ATT: 263 (94% × 124.3, death in 1)
DEF: 237 (95.45% × 68.8, win in 4)
HP: 245, Value: 798.59 μ
Parsed round number: 1
Profit per round: ActionProfitDamageOtherbase (0μ)0μ--
Stun action chosen: skill 11003
Stun action chosen: skill 11003
Custom action: use 2405 (stun first with skill 11003)
Stun action chosen: skill 11003
Queued: skill 11003
Queued: use 2405
Stasis action chosen: skill 11000 (round 3, profit: 0)
star chart (100.0 @ +108.90416): 100μ * 100.0% = 100.0
Value of stat gain: 698.59μ
Attack action chosen: skill 11001 (round 3, profit: -40)
Unable to enqueue empty action.
Unable to enqueue empty action.
Custom action: use 2405 (no stun)
Queued: use 2405
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; use 2405; call batround; 
Unable to enqueue empty action.
Stun action chosen: skill 11003
Stun action chosen: skill 11003
Custom action: use 2405 (stun first with skill 11003)
Stun action chosen: skill 11003
Queued: skill 11003
Queued: use 2405
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11003; call batround; use 2405; call batround; skill 11000; call batround; skill 11001; call batround; 
Unable to enqueue empty action.
Custom action: use 2405 (no stun)
Queued: use 2405
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; use 2405; call batround; 
Stun action chosen: skill 11003
Stun action chosen: skill 11003
Custom action: use 2405 (stun first with skill 11003)
Stun action chosen: skill 11003
Queued: skill 11003
Queued: use 2405
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11003; call batround; use 2405; call batround; skill 11000; call batround; skill 11001; call batround; 
Macro: Broadside
Macro: rock band flyers
Macro: Mighty Axing
Macro: Cleave
Round 1: bale executes a macro!
Round 1: bale casts BROADSIDE!
Round 2: bale uses the rock band flyers!
Round 3: bale casts MIGHTY AXING!
Round 4: the astronomer takes 170 damage.
Round 4: bale casts CLEAVE!
Round 5: the astronomer takes 170 damage.
Round 5: bale wins the fight!
You gain 9 Muscularity Points
You acquire an item: star chart
You gain 37 Strongness
You gain 15 Magicalness
You gain 19 Roguishness
You gain a Moxie point!
Happened: skill 11003
Flyering completed: 1544
Happened: use 2405
Happened: skill 11000
Happened: skill 11001
Parsed round number: 5
Look! You found 1 star chart (100μ)!
Happened: crit

Running ZLib version: r35 (current)
Restoring HP! Currently at 33 of 423 HP, 28 of 103 MP, current meat: 9930 ... Target HP = 402.
Casting Laugh It Off 1 times...
You gain 1 hit point
Laugh It Off was successfully cast.
Restoring MP! Currently at 34 of 423 HP, 27 of 103 MP, current meat: 9930 ... Target MP = 103.
Purchasing black cherry soda (8 @ 80)...
You acquire black cherry soda (8)
You spent 640 Meat
Purchases complete.
Using 8 black cherry soda...
You gain 80 Muscularity Points
Finished using 8 black cherry soda.
Casting Laugh It Off 103 times...
You gain 156 hit points
Laugh It Off was successfully cast.
Restoring MP! Currently at 190 of 423 HP, 0 of 103 MP, current meat: 9290 ... Target MP = 103.
Purchasing black cherry soda (11 @ 80)...
You acquire black cherry soda (11)
You spent 880 Meat
Purchases complete.
Using 11 black cherry soda...
You gain 111 Muscularity Points
Finished using 11 black cherry soda.
Casting Laugh It Off 103 times...
You gain 151 hit points
Laugh It Off was successfully cast.
Restoring MP! Currently at 341 of 423 HP, 0 of 103 MP, current meat: 8410 ... Target MP = 40.
Purchasing black cherry soda (4 @ 80)...
You acquire black cherry soda (4)
You spent 320 Meat
Purchases complete.
Using 4 black cherry soda...
You gain 40 Muscularity Points
Finished using 4 black cherry soda.
Casting Laugh It Off 40 times...
You gain 61 hit points
Laugh It Off was successfully cast.
Restoring MP! Currently at 402 of 423 HP, 0 of 103 MP, current meat: 8090 ... Target MP = 16.
Purchasing black cherry soda (2 @ 80)...
You acquire black cherry soda (2)
You spent 160 Meat
Purchases complete.
Using 2 black cherry soda...
You gain 22 Muscularity Points
Finished using 2 black cherry soda.

Request 2 of 5 (Beanstalk: Hole in the Sky) in progress...

[701] Hole in the Sky
Encounter: The Axe Wound
Strategy: C:\Documents and Settings\David.QUICKSILVER\My Documents\My Dropbox\KolMafia\ccs\default.ccs [default]
Round 0: bale wins initiative!
Running ZLib version: r35 (current)
1 HP costs 5.333μ. ( 402 / 423 )
1 MP costs 8μ. ( 22 / 103 )
Running BatBrain version: 1.22 (current)
Running SmartStasis version: 3.14 (current)
Running Destroy All Monsters version: 0.4.1 (current)
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
star (30.0 @ +108.90416): 425μ * 62.67125% = 266.3528
Value of stat gain: 685.31μ
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
star (30.0 @ +108.90416): 425μ * 62.67125% = 266.3528
Value of stat gain: 685.31μ
ATT: 258 (94% × 96.13, death in 5)
DEF: 233 (95.45% × 68.8, win in 4)
HP: 245, Value: 1,014.34 μ
Parsed round number: 1
Profit per round: ActionProfitDamageOtherbase (0μ)0μ--
Stasis action chosen: skill 11011 (round 1, profit: 196.7)
Unable to enqueue empty action.
Queued: skill 11011
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11011; call batround; skill 11000; call batround; skill 11000; call batround; 
Unable to enqueue empty action.
Attack action chosen: attack
Queued: attack
Attack action chosen: Mighty Axing
Queued: skill 11000
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; attack; call batround; skill 11000; call batround; 
Unable to enqueue empty action.
Attack action chosen: Heroic Belch
Queued: skill 11026
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11026; call batround; skill 11001; call batround; 
Attack action chosen: Heroic Belch
Queued: skill 11026
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11026; call batround; skill 11001; call batround; 
Macro: Intimidating Bellow
Macro: Mighty Axing
Macro: Mighty Axing
Round 1: bale executes a macro!
Round 1: bale casts INTIMIDATING BELLOW!
Round 2: the axe wound drops 77 attack power.
Round 2: the axe wound drops 77 defense.
Round 2: bale casts MIGHTY AXING!
Round 3: the axe wound takes 387 damage.
Round 3: bale wins the fight!
You gain 7 Muscularity Points
You acquire an item: star
You acquire an item: line
You gain 36 Strongness
You gain 17 Magicalness
You gain a Mysticality point!
You gain 17 Cheek
Happened: skill 11011
Happened: skill 11000
Parsed round number: 3
Look! You found 1 line (50μ)!
Look! You found 1 star (425μ)!
Happened: crit

Running ZLib version: r35 (current)

Request 3 of 5 (Beanstalk: Hole in the Sky) in progress...

[702] Hole in the Sky
Encounter: The Little Man in the Canoe
Strategy: C:\Documents and Settings\David.QUICKSILVER\My Documents\My Dropbox\KolMafia\ccs\default.ccs [default]
Round 0: bale wins initiative!
Running ZLib version: r35 (current)
1 HP costs 5.333μ. ( 412 / 423 )
1 MP costs 8μ. ( 26 / 104 )
Running BatBrain version: 1.22 (current)
Running SmartStasis version: 3.14 (current)
Running Destroy All Monsters version: 0.4.1 (current)
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
star (30.0 @ +108.90416): 425μ * 62.67125% = 266.3528
star (30.0 @ +108.90416): 425μ * 62.67125% = 266.3528
Value of stat gain: 690.63μ
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
star (30.0 @ +108.90416): 425μ * 62.67125% = 266.3528
star (30.0 @ +108.90416): 425μ * 62.67125% = 266.3528
Value of stat gain: 690.63μ
ATT: 260 (94% × 97.27, death in 5)
DEF: 234 (95.45% × 68.8, win in 4)
HP: 245, Value: 1,254.67 μ
Parsed round number: 1
Profit per round: ActionProfitDamageOtherbase (0μ)0μ--
Stun action chosen: skill 11003
Stun action chosen: skill 11003
Custom action: use 2405 (stun first with skill 11003)
Stun action chosen: skill 11003
Queued: skill 11003
Queued: use 2405
Stasis action chosen: skill 11000 (round 3, profit: 0)
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
star (30.0 @ +108.90416): 425μ * 62.67125% = 266.3528
star (30.0 @ +108.90416): 425μ * 62.67125% = 266.3528
Value of stat gain: 690.63μ
Attack action chosen: skill 11000 (round 3, profit: 0)
Unable to enqueue empty action.
Unable to enqueue empty action.
Custom action: use 2405 (no stun)
Queued: use 2405
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; use 2405; call batround; skill 11001; call batround; 
Unable to enqueue empty action.
Stun action chosen: skill 11003
Stun action chosen: skill 11003
Custom action: use 2405 (stun first with skill 11003)
Stun action chosen: skill 11003
Queued: skill 11003
Queued: use 2405
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11003; call batround; use 2405; call batround; skill 11000; call batround; skill 11000; call batround; skill 11000; call batround; skill 11000; call batround; 
Unable to enqueue empty action.
Custom action: use 2405 (no stun)
Queued: use 2405
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; use 2405; call batround; skill 11001; call batround; 
Stun action chosen: skill 11003
Stun action chosen: skill 11003
Custom action: use 2405 (stun first with skill 11003)
Stun action chosen: skill 11003
Queued: skill 11003
Queued: use 2405
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11003; call batround; use 2405; call batround; skill 11000; call batround; skill 11000; call batround; skill 11000; call batround; skill 11000; call batround; 
Macro: Broadside
Macro: rock band flyers
Macro: Mighty Axing
Macro: Mighty Axing
Macro: Mighty Axing
Macro: Mighty Axing
Round 1: bale executes a macro!
Round 1: bale casts BROADSIDE!
Round 2: bale uses the rock band flyers!
Round 3: bale casts MIGHTY AXING!
Round 4: the little man in the canoe takes 278 damage.
Round 4: bale wins the fight!
You gain 7 Muscularity Points
You acquire an item: star
You acquire an item: line
You gain 33 Beefiness
You gain 19 Wizardliness
You gain 17 Smarm
Happened: skill 11003
Flyering completed: 1804
Happened: use 2405
Happened: skill 11000
Parsed round number: 4
Look! You found 1 line (50μ)!
Look! You found 1 star (425μ)!
Happened: crit

Running ZLib version: r35 (current)

Request 4 of 5 (Beanstalk: Hole in the Sky) in progress...

[703] Hole in the Sky
Encounter: The Box
Strategy: C:\Documents and Settings\David.QUICKSILVER\My Documents\My Dropbox\KolMafia\ccs\default.ccs [default]
Round 0: bale loses initiative!
You lose 68 hit points
Running ZLib version: r35 (current)
1 HP costs 5.333μ. ( 353 / 423 )
1 MP costs 8μ. ( 23 / 104 )
Running BatBrain version: 1.22 (current)
Running SmartStasis version: 3.14 (current)
Running Destroy All Monsters version: 0.4.1 (current)
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
Value of stat gain: 650.78μ
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
Value of stat gain: 650.78μ
ATT: 245 (94% × 88.74, death in 5)
DEF: 221 (95.45% × 87.5, win in 3)
HP: 245, Value: 744.79 μ
Parsed round number: 1
Profit per round: ActionProfitDamageOtherbase (0μ)0μ--
Stasis action chosen: skill 11011 (round 1, profit: 185.58)
Unable to enqueue empty action.
Queued: skill 11011
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11011; call batround; skill 11000; call batround; skill 11000; call batround; 
Unable to enqueue empty action.
Attack action chosen: attack
Queued: attack
Attack action chosen: Mighty Axing
Queued: skill 11000
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; attack; call batround; skill 11000; call batround; 
Unable to enqueue empty action.
Attack action chosen: attack
Queued: attack
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; attack; call batround; skill 11001; call batround; 
Attack action chosen: attack
Queued: attack
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; attack; call batround; skill 11001; call batround; 
Macro: Intimidating Bellow
Macro: Mighty Axing
Macro: Mighty Axing
Round 1: bale executes a macro!
Round 1: bale casts INTIMIDATING BELLOW!
Round 2: the box drops 74 attack power.
Round 2: the box drops 74 defense.
Round 2: bale casts MIGHTY AXING!
Round 3: the box takes 341 damage.
Round 3: bale wins the fight!
You gain 8 Muscularity Points
You acquire an item: line
You acquire an item: line
You gain 40 Muscleboundness
You gain 16 Enchantedness
You gain 11 Roguishness
Happened: skill 11011
Happened: skill 11000
Parsed round number: 3
Look! You found 2 line (100μ)!
Happened: crit

Running ZLib version: r35 (current)

Request 5 of 5 (Beanstalk: Hole in the Sky) in progress...

[704] Hole in the Sky
Encounter: The Box
Strategy: C:\Documents and Settings\David.QUICKSILVER\My Documents\My Dropbox\KolMafia\ccs\default.ccs [default]
Round 0: bale wins initiative!
Running ZLib version: r35 (current)
1 HP costs 5.333μ. ( 361 / 423 )
1 MP costs 8μ. ( 28 / 104 )
Running BatBrain version: 1.22 (current)
Running SmartStasis version: 3.14 (current)
Running Destroy All Monsters version: 0.4.1 (current)
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
Value of stat gain: 650.78μ
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
Value of stat gain: 650.78μ
ATT: 245 (94% × 88.74, death in 5)
DEF: 221 (95.45% × 87.5, win in 3)
HP: 245, Value: 744.79 μ
Parsed round number: 1
Profit per round: ActionProfitDamageOtherbase (0μ)0μ--
Stun action chosen: skill 11003
Stun action chosen: skill 11003
Custom action: use 2405 (stun first with skill 11003)
Stun action chosen: skill 11003
Queued: skill 11003
Queued: use 2405
Stasis action chosen: skill 11000 (round 3, profit: 0)
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
line (30.0 @ +108.90416): 50μ * 62.67125% = 31.335625
Value of stat gain: 650.78μ
Attack action chosen: skill 11000 (round 3, profit: 0)
Unable to enqueue empty action.
Unable to enqueue empty action.
Custom action: use 2405 (no stun)
Queued: use 2405
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; use 2405; call batround; skill 11001; call batround; 
Unable to enqueue empty action.
Stun action chosen: skill 11003
Stun action chosen: skill 11003
Custom action: use 2405 (stun first with skill 11003)
Stun action chosen: skill 11003
Queued: skill 11003
Queued: use 2405
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11003; call batround; use 2405; call batround; skill 11000; call batround; skill 11000; call batround; skill 11000; call batround; 
Unable to enqueue empty action.
Custom action: use 2405 (no stun)
Queued: use 2405
Attack action chosen: Cleave
Queued: skill 11001
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; use 2405; call batround; skill 11001; call batround; 
Stun action chosen: skill 11003
Stun action chosen: skill 11003
Custom action: use 2405 (stun first with skill 11003)
Stun action chosen: skill 11003
Queued: skill 11003
Queued: use 2405
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Attack action chosen: Mighty Axing
Queued: skill 11000
Constructed macro: scrollwhendone; sub batround; if haseffect 8 || haseffect 264 || haseffect 282 || haseffect 283 || haseffect 284; abort "BatBrain abort: poisoned."; endif; endsub; skill 11003; call batround; use 2405; call batround; skill 11000; call batround; skill 11000; call batround; skill 11000; call batround; 
Macro: Broadside
Macro: rock band flyers
Macro: Mighty Axing
Macro: Mighty Axing
Macro: Mighty Axing
Round 1: bale executes a macro!
Round 1: bale casts BROADSIDE!
Round 2: bale uses the rock band flyers!
Round 3: bale casts MIGHTY AXING!
Round 4: the box takes 219 damage.
Round 4: bale casts MIGHTY AXING!
Round 5: the box takes 107 damage.
Round 5: bale wins the fight!
You gain 8 Muscularity Points
You acquire an item: line
You acquire an item: line
You gain 31 Strongness
You gain 16 Enchantedness
You gain 18 Cheek
Happened: skill 11003
Flyering completed: 2049
Happened: use 2405
Happened: skill 11000
Happened: skill 11000
Parsed round number: 5
Look! You found 2 line (100μ)!
Happened: crit

Requests complete.
 
The alternate flyering might be related to the alternate round stunning with broadsides. Was noticing that it was stunning every other battle a few days ago.

Any chance that the whole happening being off thing Winterbay reported back on #566 is happening again, but +1 instead of -1 now?
 
Last edited:
Any chance that the whole happening being off thing Winterbay reported back on #566 is happening again, but +1 instead of -1 now?

Well, I will admit that it worked properly when I added +1 to my_turncount() here:

PHP:
   if (happenings contains occurrence) return (happenings[occurrence].turn == my_turncount() +1 && 
       happenings[occurrence].queued + happenings[occurrence].done > 0);

Although that fix makes me feel extremely uneasy since I cannot figure out why that should be true so I am sure I'm breaking something by making that change.



edit: Oh wow. Experimenting in a zone with non-combats I changed that to "my_turncount() -1" instead of plus. I found that it worked unless I ran into a non-combat. Under those circumstances if the flyering happened 2 rounds ago it skipped flyering. (previous round with -1 hacked in by me.) That supports the likelihood that it is checking for flyering in the previous round and the plus 1 is actually a solution. I'd need to stick a few print statements in there to actually see what it considers my_turncount() and the round of the happening to believe that though.
 
Last edited:
Oh heck. I don't know what to make of this. I stuck in a print statement to debug as I suggested I should do and... well, I added the red line to happened():

Code:
boolean happened(string occurrence) {
[COLOR="#FF0000"][B]if(occurrence == "use 2405") print("Last happened on turn: "+happenings[occurrence].turn+", Current turn: "+my_turncount());[/B][/COLOR]
   if (count(happenings) == 0) file_to_map("happenings_"+replace_string(my_name()," ","_")+".txt",happenings);
   if (happenings contains occurrence) return (happenings[occurrence].turn == my_turncount() +1 && 
       happenings[occurrence].queued + happenings[occurrence].done > 0);
   return false;
}

Here's what happened to me...

Code:
[747] Hey Deze Arena
Encounter: suckubus
Round 0: bale wins initiative!
Last happened on turn: 746, Current turn: 746

The heck? It clearly says that my current turncount is 747! Yet the print statement identifies this as turn 747. More confusingly flyering is correctly reported as last happening on the previous turn 746. Shouldn't such a thing at least be consistent?! No wonder I needed that +1 to indicate this as the corrent turn. I don't understand it at all.

PS. That was not a momentary glitch. It does that on successive round after round.
 
Last edited:
Presently, BatBrain registers happenings as occurring on my_turncount(), unless the combat is finished, in which case it registers them as my_turncount() - 1. That last bit was the part I had thought would fix the flyering issue. If it's still happening, it seems to mean that my_turncount() is inconsistent during/after a fight, perhaps due to the fight page and the charpane arriving in arbitrary order?

Bale, what you posted was not as confusing as it may seem; my_turncount() advances after you spend a turn, not when you start to spend it. If you had 1 turn of a buff remaining, you would be upset if it disappeared at the beginning of combat, right? If [747] Hey Deze Arena did not consume a turn, your turn count would still be 746. But the actual number is not particularly relevant -- it's only relevant relative to itself. It doesn't matter whether we use turncount, turncount+1, or turncount+432 -- the point is that it ought to be a different number from one combat to the next. (For the moment ignoring free runaways, seals, and hipster fights.)

I'd suggest adding some debug prints which effectively watch my_turncount() throughout combat; beginning, middle, and end. I'll do the same and hopefully we can get to the bottom of this. For a temporary fix with flyering, remove the happened() check from flyers in SS's build_custom(). That will cause undesirable results for fight.php overrides which include custom actions (such as my upcoming relay script which is AWESOME if I do say so myself), but will otherwise be entirely harmless.
 
The new updated version of WHAM prints out the round number and turn number for different portions of a fight with verbosity set to 9, should anyone using my scritp want to help ddebug this :)
 
Found it!

But first, something interesting. In relay play I got the same turn number throughout the entire fight, including on the last page when combat is finished. In automated play, however, I got a number one higher on the last page load.

That means that I would never have found the problem in the relay browser, which is where I often test things since I can twiddle my thumbs to reload the combat without taking up another turn. This was the source of my confusion. Now that I know the difference, I was able to track down the problem. It was a problem of sequence.

Happenings are recorded during round parsing. At that time the round number hasn't actually been set yet. This means that checking for finished() is inaccurate within set_happened() when it is called during the round checking. So, my_turncount() advances, but the compensatory -1 was not added when recording the happening. In other words, actions that happen on the last page of combat were being recorded as happening on your next turn.

This is why Bale could partially fix it with a blanket +1 -- if flyers happened on the same page as the end of combat, he set the occurrence to two turns in the future. As long as he kept flyering every turn, happened(flyers) would always be false, but when he had a noncombat adventure, on the next combat it was true since he hadn't moved it into the future last turn. Optionally, a blanket -1 would also partially work, but it would fail for actions which happened during combat, before the final page load, setting them to your previous turn.

I have fixed this by saving my_turncount() at the top of BatBrain, and using the variable rather than the function for happenings tracking. No more +1/-1 business. Thus, for relay play the constant number will be used, and for automated play the initial number will be used, not the increased end-of-combat number. I can now say confidently that happenings tracking has been fixed. Thanks everyone for helping me track this down!
 
Last edited:
Very excited for the turncount fix in the new BB... that should GREATLY reduce my meat spent during the upper levels, since it will properly stun every fight now. :) Much better than the current sad-fix of turncount+1, which makes it keep trying to use once-per-battle items repeatedly.
 
Back
Top