autoBasement.ash - Better basement automation

I'm not you should make sure your combat action can defeat basement monsters.
 
Last edited:
Large update incoming, see the revision log for version 1.6 changes.

It's also painfully obvious to me that outfit caching takes a long time now that I've hit 200 base stats, this suggestion from Bale for the maximizer would really, really, really be helpful. I'd also need a way to get all equipment a custom outfit contains. Without both of these features I probably won't be able to optimize the outfit caching much at all.
 
Last edited:
I worked on a increase_stat() that goes through all the combinations of effects you don't have yet to find the cheapest one that buffs your stat enough to attain goal. I'm pretty proud of the result!

Considering only the effects you don't have yet, from a restricted list of potions, makes increase_stat() pretty fast. I guess the list of potions could be expanded to include a few cheap absolute increasing potions (for stats, hp or mp), but I imagine that considering *everything*, like the maximizer does, requires a handling way different than just testing everything, and cutting down branches of trees is something that is out of my league.

increase_stat will only use the potions once the best combination is found, so you won't buff with everything only to find out that it wasn't enough. it would be easy to do a 'simulation' mode, in order to decide if it's cheaper to use an elemental form potion or to buff muscle a little bit, for example.

You can see a verbose example of it in test_stat.ash (edit to change goal and stat).

I included my version of Rinn's autoBasement (based on version 1.5) to see how it is implemented.

There are a couple of changes/fixes in my version:
- fixed the have_outfit() returning false issue (Rinn did that already apparently)
- I maximize mainstat for combats in order to use love songs (Rinn has that covered already too).
- I added a maximize_outfit() container function for calls to maximize. Since I don't have a disembodied hand, I don't want the maximizer to choose an equipment for my familiars (wasting sugar shields). maximize_outfit() adds the correct ending to the maximizer command (switch disembodied hand if you have one, switch parrot for elemental tests if you have one, -familiar in other cases).

Rinn : I hope you will find this useful! It should be easy to track the meat used for buffing too in case you want to add this.

EDIT: Accidentally removed a line when including increase_stat() in autoBasement_slyz, added it back.
 

Attachments

Last edited:
I worked on a increase_stat() that goes through all the combinations of effects you don't have yet to find the cheapest one that buffs your stat enough to attain goal. I'm pretty proud of the result!

Considering only the effects you don't have yet, from a restricted list of potions, makes increase_stat() pretty fast. I guess the list of potions could be expanded to include a few cheap absolute increasing potions (for stats, hp or mp), but I imagine that considering *everything*, like the maximizer does, requires a handling way different than just testing everything, and cutting down branches of trees is something that is out of my league.

increase_stat will only use the potions once the best combination is found, so you won't buff with everything only to find out that it wasn't enough. it would be easy to do a 'simulation' mode, in order to decide if it's cheaper to use an elemental form potion or to buff muscle a little bit, for example.

You can see a verbose example of it in test_stat.ash (edit to change goal and stat).

I included my version of Rinn's autoBasement (based on version 1.5) to see how it is implemented.

There are a couple of changes/fixes in my version:
- fixed the have_outfit() returning false issue (Rinn did that already apparently)
- I maximize mainstat for combats in order to use love songs (Rinn has that covered already too).
- I added a maximize_outfit() container function for calls to maximize. Since I don't have a disembodied hand, I don't want the maximizer to choose an equipment for my familiars (wasting sugar shields). maximize_outfit() adds the correct ending to the maximizer command (switch disembodied hand if you have one, switch parrot for elemental tests if you have one, -familiar in other cases).

Rinn : I hope you will find this useful! It should be easy to track the meat used for buffing too in case you want to add this.

EDIT: Accidentally removed a line when including increase_stat() in autoBasement_slyz, added it back.

Unfortunately besides semi-rares, all the cheap potions that buff a stat by an absolute amount are almost completely terrible. I've already added cost effectiveness of a buff in preparation for finding the most cost effect way to buff to a set goal and typically absolute potions give the worst possible increase per meat spent, even worse then sea potions. While precalculating the benefit of effects will be nice and I honestly don't think it's going to help anyone until I add in food/drink/spleen consumption. Typically when this script thinks it's going to fail a basement test, your stats are going to be almost enough to pass the next test and you can typically find some simple way to push your stats over the boundary.

Think of it this way, if you're been running the basement for 100 turns before you hit a test you can almost beat, you're typically going to have a bunch of effects on your character already. What's more cost effective at that point, cutting your losses as soon as we you predict you can't win with automation, or using those potions and then deciding this is the point you finally want to burn some spleen on wads to beat this test then see if you get lucky and encounter a few combats. No matter what I do this script just isn't going to save anyone massive amounts of meat on basement diving.

Also unfortunate (well not really I was going to implement this anyway) is that I'm going to have to rewrite everything you just did because I completely changed the way potions are handled.
 
Last edited:
I agree that on later levels, you would need to run most of the effects all the time anyway, but earlier on, it can be a lot cheaper to skip directly to a 100% sauceror potion instead of using an equalizer, a ! potion, a tomato juice, and finally potion of gr8tness.

As for implementing this, it's just a matter of populating to_try, which is easily done from the potions map (don't forget to recalculate the equalizer's .percent_mod).

I forgot to add one of the changes I put in my version: support for the Moxie Magnet without using the maximizer.
 
A little issue with 1.7 here -- I didn't have previous outfits with the normal basement names, so in the outfit caching section it would try to put them on (i.e. outfit("Damage")) and then Mafia would display "You can't wear that outfit" in red and stop the script.

Silly Mafia. I can't wear it because it doesn't exist yet!

Of course the work-around was simple; create arbitrary outfits with the expected names and let your nice script do the work of changing them to actually have the right equipment in them. Still, it might be something to keep in mind.

Edit: additional outfit bug-reporting-ness: You create an outfit called "MPRegen", but the outfit you're trying to put in maximize_mp_regen() is "MP Regen". Fortunately it maximizes when equipping "MP Regen" fails, so no real harm done except lack of cache-using.
 
Last edited:
Yeah I just realized that, the problem is that have_outfit doesn't work on custom outfits. I'll force it to skip the error by using the cli outfit command with try in the next update.
 
You can't wear that

Just started using this. Thank you.
Have run into a couple of snags. It seems that with v1.6 and 1.7, I get a "you can't wear that" with every stat reward.

Basement level 160: Stat reward
You can't wear that outfit.

as shown below.
Code:
[57686] Fernswarthy's Basement (Level 11)
Encounter: 13-Dimensional Horror
Round 0: e85 wins initiative!
Round 1: e85 casts SPECTRAL SNAPPER!
Round 1: 13-dimensional horror takes 458 damage.
You lose 217 hit points
Round 2: e85 casts SPECTRAL SNAPPER!
Round 2: 13-dimensional horror takes 450 damage.
You lose 240 hit points
Round 3: e85 casts SPECTRAL SNAPPER!
Round 3: 13-dimensional horror takes 437 damage.
You lose 226 hit points
Round 4: e85 casts SPECTRAL SNAPPER!
Round 4: 13-dimensional horror takes 433 damage.
You lose 224 hit points
Round 5: e85 casts SPECTRAL SNAPPER!
Round 5: 13-dimensional horror takes 458 damage.
You gain 283 Muscleboundness
You gain 166 Magicalness
You gain a Mysticality point!
You gain 155 Smarm
Basement level 160: Stat reward
You can't wear that outfit.
Maximizing...
420 combinations checked, best score 8.5
Putting on chef's hat...
Equipment changed.
Wielding giant cactus quill...
Equipment changed.
Holding charged magnet...
Equipment changed.
Putting on hardened slime pants...
Equipment changed.
Putting on energy drink IV...
Equipment changed.
What do I need to do to fix that?
 
account_manageoutfits.php can be checked to see if the outfits exist. You would just need to see if value="Mysticality" exists, for example.

EDIT:

Code:
string page=visit_url("account_manageoutfits.php");

string[int] outfits;
outfits[1]="Mysticality";
outfits[2]="Muscle";
outfits[3]="Moxie";
outfits[4]="Gauntlet";

boolean outfit_exists(string page, string o) {
	return contains_text(page,"value=\""+o+"\"");
}
	
foreach i in outfits {
	if ( outfit_exists(page, outfits[i]) ) print("You have an outfit named "+outfits[i]);
}

ouputs:

Code:
You have an outfit named Mysticality
You have an outfit named Muscle
You have an outfit named Moxie
You have an outfit named Gauntlet

EDIT 2 @ tgetgel

on lines 268-270, change

Code:
outfit("MPRegen");
cli_execute("maximize .5 MP Regen min, .5 MP Regen max, switch Disembodied Hand");
cli_execute("outfit save MPRegen");

to

Code:
outfit("MP Regen");
cli_execute("maximize .5 MP Regen min, .5 MP Regen max, switch Disembodied Hand");
cli_execute("outfit save MP Regen");

(add spaces in "MPRegen")
 
Last edited:
Alternately, in the function maximize_mp_regen(), take the space out of "MP Regen". slyz's suggestion is earlier in the code, though, so it's probably easier to find.
 
If you take out the space in maximize_mp_regen(), you need to take them out in lines 271-272 too. I'm starting to know this code by heart =)

I've already added cost effectiveness of a buff in preparation for finding the most cost effect way to buff to a set goal

Since only one of each potion is used, meat per stat isn't as appropriate here as in Bale's recovery script, for example, where the best meat per mp item is used until the condition is filled (simplifying things).

On the other hand, using a potion of gr8tness, for example, will pay off because it will certainly help for all the tests that you will encounter while you have the effect (5/10/15 turns). Maybe the duration should be taken into account in the cost, as well as the fact that potions of gr8tness and tomato power buff more than one stat.

EDIT: equalizers also have benefits to all stats
 
Last edited:
Since only one of each potion is used, meat per stat isn't as appropriate here as in Bale's recovery script, for example, where the best meat per mp item is used until the condition is filled (simplifying things).

On the other hand, using a potion of gr8tness, for example, will pay off because it will certainly help for all the tests that you will encounter while you have the effect (5/10/15 turns). Maybe the duration should be taken into account in the cost, as well as the fact that potions of gr8tness and tomato power buff more than one stat.

EDIT: equalizers also have benefits to all stats
Both the duration and multiple stat effects are already taken into account. It's basically stat points increased per meat times duration times the number of stats it affects.

Code:
float cost_effectivness(_item value)
{
    return ((value.percent_mod * my_basestat(my_primestat()) + value.absolute_mod) / value.cost * value.duration * value.effective_stats); 
}

I'll add the custom outfit check and fix the misnamed MP Regen outfit name.
 
Last edited:
Where is the logic in having the script abort once you reach Level 30? Simply modifying the 'setvar("autoBasement_break_on_level"' variable doesn't seem to alleviate the problem either.
 
I guess some players continue basementing past level 500 until they reach level 30 for the trophy.

To modifiy autoBasement_break_on_level, do not edit the script, simply type this in the gCLI:
Code:
zlib autoBasement_break_on_level = 50
 
When I try to run the script, I just get:

["humorous" t-shirt] has no matches.

Then mafia turns red and nothing happens. What gives?
 
Back
Top