Bug - Confirmed Maximizer didn't equip a weapon

MCroft

Developer
Staff member
I see your point. I would say that I consider it a bug because the outcome of using it is both unexpected and the worst possible result. We warn people if they are going to take 1-3 hp of damage from using a seal tooth, and this is a much worse outcome. However, I am open to considering it a feature request for a 'none-proof' effective keyword. (or even keyword property. 2 effective or effective nonnull...), but it seems that the reports I'm seeing in Autoscend (it's not just me) involve a number of people who don't understand how they got a no-weapon result or what to do to fix it.

Let me see if I can make a test case that isn't a full-blown Autoscend maximizer string. I will work on that and get back with (hopefully) a TC we can walk through in the debugger and see why it's doing what it's doing.

AFAICT, the melee weapon Turtle Totem was considered 1 of 3 times.

I have only a shaky grasp on the maximizer. But it seems like in the Weapon slot it did not consider melee weapons, but in the final pass where it re-considers weapons to deal with on-hand and off-hand (re-using accessory slots because it was written when memory was a real concern) it does consider them, and then it does not allow them in the equip phase.

To me, this is a catastrophic failure mode, as having an ineffective weapon is usually slightly better than having an ineffective empty slot.

TBH, it might be simpler if effective re-used whatever we're doing for "-melee" and resolved knives for Tricky Knivework as Ranged. Which is still slightly wrong, but not as wrong.
 

fronobulax

Developer
Staff member
the reports I'm seeing in Autoscend (it's not just me) involve a number of people who don't understand how they got a no-weapon result or what to do to fix it.

Autoscend could choose not to use the effective keyword or could try something different if no weapon is equipped.

There is, at the moment, no agreement that "no weapon" is always wrong or how to fix it. Sometimes the right answer for a low level character with Master of the Surprising Fist is to equip no weapon :) Personally my success criteria is day count, not turn count so I ignore autoscend's failure to equip message until I get Beaten Up once. Then "the fix" is that I try and run the same combat again, after manually choosing maximizer strings and equipment. Maybe I find resources to restore MP and sometimes I just manually run a few turns somewhere else that accomplish something useful but autoscend has chosen to defer.

There is always the non-Maximizer solution of having KoLmafia emit a warning if a user tries to adventure without a weapon and the associated preference to stop automation if that is true. But a simple - weapon - yes or no? - is going to be a problem for several special cases and implementing this might create more problems than it solves.
 

MCroft

Developer
Staff member
I've suggested privately to Loathers that they abandon the Effective keyword as radioactive and instead write their own "if" statement related to moxie > muscle and having Tricky Knifework.

I'm working on an enhancement instead to add Tricky Knifework handling to the melee keyword.

I'm not yet ready to submit it, but here's the code in Evaluator.java, starting at line 1253. My change is based on what I read in the wiki about Tricky Knifework. If that is successful, then I'd probably do what I was mentioning above and change "effective" to "if mox > mus, set -melee, else set +melee".

I'd like your opinion and how it works with your test cases.

Java:
        case WEAPON:
            int hands = EquipmentDatabase.getHands(id);
            if (this.hands == 1 && hands != 1) {
              continue;
            }
            if (this.hands > 1 && hands < this.hands) {
              continue;
            }
            WeaponType weaponType = EquipmentDatabase.getWeaponType(id);
            String type = EquipmentDatabase.getItemType(id);
            if (KoLCharacter.hasSkill( "Tricky Knifework" ) && type.equals( "knife" )) {
              // now it's a ranged weapon.  Good thing weaponType goes out of scope.
              weaponType=WeaponType.RANGED;

            }
            if (this.melee > 0 && weaponType != WeaponType.MELEE) {
              continue;
            }
            if (this.melee < 0 && weaponType != WeaponType.RANGED) {
              continue;
            }
 

fronobulax

Developer
Staff member
write their own "if" statement related to moxie > muscle and having Tricky Knifework.
If that is why they are using it then Effective is working as advertised.

But it does clarify that the desire is to use a knife rather than nothing.

Some things are clearing up for me.

Any character can use a knife if one is available and if the muscle requirement is met.

If Tricky Knifework is available then the knife will do damage based upon whichever is higher, adjusted moxie or adjusted muscle.

In some contexts a knife should actually be considered a melee weapon.

I'm getting some ideas for tests, possible ways to address and menus for crow since I might be eating some ;-)
 

MCroft

Developer
Staff member
Tests of code that is not covered are a good thing in themselves.

There are tests we can add to maxmizer's effective test class, such as...

Java:
public void useKnifeWhenMuscleIsHighWithTrickyKnifework() {
...
}
@Test
public void useKnifeWhenMoxieIsHighWithTrickyKnifework(){
...
}

However, we might consider a test of the scripting command maximize because the effective test class is checking recommendedSlotIs() and misses the interactions we're seeing.
 

fronobulax

Developer
Staff member
True. At some point we have to deal with the difference between what the maximizer recommends and what is actually equipped. I'm not getting the expected failures. I wonder if the Maximizer recommends a knife thinking it can be summoned and equipped and the failure is that it can't be summoned?
 

ziz

Member
My current ascension has a case where the effective keyword is not used, and nothing is equipped to weapon or off-hand, and also has different behavior (resetting on mafia restart) after a weapon is manually equipped. Session log attached. (Full skill list is in the session log.)

Mafia version: KoLmafia r27821 (Build main-58b0984 17.0.10 (Eclipse Adoptium 17.0.10+7) Linux amd64 6.2.0-1019-azure)

Maximizer string: 5item,meat,0.5initiative,0.1da 1000max,dr,0.5all res,1.5mainstat,-fumble,mox,0.4hp,0.2mp 1000max,3mp regen,0.25spell damage,1.75spell damage percent,2familiar weight,5familiar exp,10exp,5Mysticality experience percent,200combat 20max,+200bonus mafia thumb ring
(This is the autoscend maximizer string, but I have commented out the part ot autoscend that uses effective.)

weapons in inventory:
Code:
candy cane sword cane
pasta spoon
Rain-Doh violet bo
Rain-Doh yellow laser gun
saucepan
toy accordion
turtle totem

offhands in inventory:
Code:
psychic's crystal ball
Rain-Doh green lantern
stuffed baby gravy fairy
stuffed key
unbreakable umbrella (broken)

Stats:

Level 4 Pastamancer (in Shrunken Adventurer)
Mus: 2 (1)
Mys: 27 (17)
Mox: 1 (5)

Presence or absence of the knife skill and Master of the Surprising Fist: I have MotSF and do not have the knife skill.

The maximizer string equipped no weapon or offhand. 2 dump output inline in sepos_maximizer_analysis_20240210.txt marked with >>> [code1].

I then equipped weapons experimentally and retried the maximizer string after each. Equipping a pasta spoon did not change the behavior - it wants to unequip the pasta spoon. (>>> [code2])

but equipping a candy cane sword cane caused the maximizer to offer to keep the candy cane sword cane. (>>> [code3])

If I remove the candy cane sword cane, it went back to equipping nothing. (>>> [code4])

Equipping a Rain-Doh yellow laser gun, however, made the maximizer happy to equip the candy cane sword cane and the umbrella (>>> [code5])

and, bizarrely, to continue to offer to equip the candy cane sword cane and umbrella after I unequipped the yellow laser gun. (>>> [code5])

The maximizer then continues to happily equip weapons with this maximizer string while Mafia is running. If I unequip my weapon and offhand and restart Mafia, though, it returns to the earlier "not equipping anything" behavior.

Please let me know if there are additional debugging/reporting steps I can take to make this more useful for investigation.
 

Attachments

  • sepos_maximizer_bug_20240210.txt
    61 KB · Views: 1
  • sepos_maximizer_analysis_20240210.txt
    16.4 KB · Views: 1

fronobulax

Developer
Staff member
Java:
    public void ziz() {
      String maxStr = "5item,meat,0.5initiative,0.1da 1000max,dr,0.5all res,1.5mainstat,-fumble,mox,0.4hp,0.2mp 1000max,3mp regen,0.25spell damage,1.75spell damage percent,2familiar weight,5familiar exp,10exp,5Mysticality experience percent,200combat 20max,+200bonus mafia thumb ring";
      var cleanups =
              new Cleanups(
                      withEquippableItem("candy cane sword cane"),
                      withEquippableItem("pasta spoon"),
                      withEquippableItem("Rain-Doh violet bo"),
                      withEquippableItem("Rain-Doh yellow laser gun"),
                      withEquippableItem("saucepan"),
                      withEquippableItem("toy accordion"),
                      withEquippableItem("turtle totem"),
                      withEquippableItem("psychic's crystal ball"),
                      withEquippableItem("Rain-Doh green lantern"),
                      withEquippableItem("stuffed baby gravy fairy"),
                      withEquippableItem("stuffed key"),
                      withEquippableItem("unbreakable umbrella (broken)"),
                      withStats(2, 27, 1),
                      withSkill(SkillPool.MASTER_OF_THE_SURPRISING_FIST));
      try (cleanups) {
        assertTrue(maximize(maxStr));
        recommends("candy cane sword cane");
        recommendedSlotIs(Slot.WEAPON, "candy cane sword cane");
        assertTrue(KoLCharacter.hasEquipped(ItemPool.CANDY_CANE_SWORD));
      }
    }

The test above has the maximizer string @ziz reported as well as the skills and relevant equipment reported. Since withEquippableItem will silently adjust stats to make an item equippable I verified that the stats were unmodified by the equipment.

The mazimizer did suggest the candy cane sword cane but, if the test is correct, the maximizer did not actually equip it. Pondering. Stand by.
 

fronobulax

Developer
Staff member
By design the test speculates. I supposedly changed that so it equips and the recommendation is nothing but buffs. I'll stop reporting miniscule steps in progress but there is definitely something going on besides "effective".
 

ziz

Member
Side note: I very much appreciate the time and consideration going into this! (And also I'm always interested in minuscule steps in progress - a bug-hunting narrative, especially one I'm invested in, is a can of Pringles to my brain - but I appreciate that they take time and energy to write and not everyone is as interested in them as I am.)

[edited to add]

I'm not so much concerned about my own runs - similar to @fronobulax, if autoscend gets me Beaten Up once I run a turn or two manually and generally have no further problems, and I don't care if autoscend is doing turns with a weapon or without one; it's far faster than I am by hand still, and there's still plenty of optimization for me to learn. Likewise, in a practical sense, if the maximizer suggests no weapon and I know damn well I should be wielding a chefstaff or something, I'm going to assume that's on me for writing a bonkers maximization string and just equip the thing myself (or use a different maximization string for just that slot).

However, the situation of "well, if you equip this other weapon that you already own first, magically different behavior happens" gives me a raspberry-pip-stuck-in-the-tooth feeling in the same way "your sort isn't stable and things jitter if you re-sort repeatedly" does: it might technically be an outcome of the designed and intended behavior! but that behavior is only correct if you're a computer, and very, very few of us are.

As I said at the top: Thank you for the time and attention to help with this raspberry pip.
 
Last edited:

fronobulax

Developer
Staff member
Because public pronouncements are a way of keeping me accountable, at least to myself...

There are circumstances when using the effective keyword will result in not selecting and equipping a weapon and that is the right answer.

However there is definitely a bug where the user expects the maximizer to equip a weapon, a weapon is selected and it is not equipped. I have a test that seems to demonstrate this. I have not figured out why. It is possible that the test is flawed. It is possible that some keyword besides "effective" is implicated. It is possible that the various ways of invoking the maximizer are not consistent.

I have changed this thread to be a Confirmed Bug and will figure out what to do with the PR as I work on it.

My advice - if you use the effective keyword then you should be prepared for the possibility that no weapon is equipped. That advice will persist even after this bug is fixed.

Until the bug is fixed you should be prepared for the possibility that the Maximizer will not equip a weapon and take steps to work around that.
 

HippoKing

Member
First off, thanks a huge amount for your hard work on investigating this.

I want to make one remark: in the autoscend community, we have seen a lot of reports of this happening to people only happening per ascension, until it doesn't. What I have not seen reported, and why it's been so challenging to reproduce is that we've not seen it go back to empty handed *after* the maximizer has equipped a weapon once. So, I'd be tempted to look at things that depend on state.

I have never really understood the maximizer, and I've never investigated the code, but my wild speculation is that there is something that is keeping some state when it isn't supposed to.
 

fronobulax

Developer
Staff member
Well yesterday was a bust. My supposed failing tests turned out to fail because the test code didn't actually require the Maximizer to equip anything. My new tests all work. There is an internal parameter that controls whether things are to be equipped, or not, so an obvious path is to find if it is unexpectedly changed. That is not obvious with mere code inspection so I'm going to do some live runs and see if I can figure something out. I too wonder about "state" but I am not sure whether it is character state or code state. A lot of the relevant code is static which means things will persist from call to call. I have neither given up nor succeeded.
 
  • Like
Reactions: ziz

fronobulax

Developer
Staff member
Alas no failures to equip today so my added instrumentation did not find The Smoking Gun. More static analysis today and a hope for a new ascension tomorrow which, in the past, has triggered several failures.

Tangentially there were several cases where autoscend missed an opportunity to do better, at least when automation and not turn count was the success metric. One was the Oil Peak. autoscend stopped because of getting beaten up. I maximized (Turtle Tamer) on mainstat, accepted the equipment changes and cleaned the Oil Peak manually. I was still seeing barons so if what I did lowered ML it did not do so significantly. "My" weapon was one-shotting. autoscend's was barely hitting. I also noticed a case where a half-sized scalpel was equipped but doing less than 10 damage. I look forward to a time when the Maximizer will equip what it recommends so that autoscend can tune parameters with a goal of making sure the weapon can actually damage things :)
 

MCroft

Developer
Staff member
Because public pronouncements are a way of keeping me accountable, at least to myself...

There are circumstances when using the effective keyword will result in not selecting and equipping a weapon and that is the right answer.
Do we have any test cases where this is the case? Every example I've seen has a higher number value for some weapon other than [None] and a message that it is equipping something and not doing so.

Which is to say that I agree that there could be such circumstances, but I have not seen them demonstrated in this thread or in my logs.
 

fronobulax

Developer
Staff member
Do we have any test cases where this is the case? Every example I've seen has a higher number value for some weapon other than [None] and a message that it is equipping something and not doing so.

Which is to say that I agree that there could be such circumstances, but I have not seen them demonstrated in this thread or in my logs.

I believe I have seen exactly that case with a level one Pastamancer with Master of the Surprising Fist. If that is indeed the case - to be assessed when today's run finishes - then I will try it as a test.

I will also note that my understanding is evolving. I have seen examples where the speculation suggests a weapon but speculate and equip fails to equip. Sometimes effective changes this and sometimes not. Things get complicated since some tests are not repeatable and some behavior is currently only observed when using a debugger mid-execution.
 

fronobulax

Developer
Staff member
Java:
    public void noWeaponIsTheRightAnswer() {
      String maxStr =
          "5item,meat,0.5initiative,0.1da 1000max,dr,0.5all res,1.5mainstat,-fumble,mox,0.4hp,0.2mp 1000max,3mp regen,0.25spell damage,1.75spell damage percent,2familiar weight,5familiar exp,10exp,5Mysticality experience percent";
      var cleanups =
          new Cleanups(
              withSkill(SkillPool.TRICKY_KNIFEWORK),
              withSkill(SkillPool.MASTER_OF_THE_SURPRISING_FIST),
              withStats(2, 12, 1),
              withEquippableItem("toy accordion"),
              withEquippableItem("turtle totem"),
              withEquippableItem("saucepan"),
              withEquippableItem("stolen accordion"),
              withEquippableItem("seal-clubbing club"));
      try (cleanups) {
        assertTrue(maximize(maxStr));
        assertFalse(getSlot(Slot.WEAPON).isPresent());
      }
    }

Data extracted from real run from autoscend. No weapon is selected and that is the right answer since Surprising Fist is doing more damage than any of the available weapons. A similar test with "effective" added also does not choose a weapon. We have an Existence Proof for no weapon being the right answer. I probably have another from when the character hit level 8 because Surprising Fist was still killing a lot in the first round.

I'd like to move on.

Sometimes No Weapon is the Right Answer whether or not the effective keyword is used.

The problem currently being debugged is the case when a weapon is selected but not equipped. Note that because of the probable bug failure to equip does not imply failure to select.

A specific example of a case where the wrong weapon is selected (whether or not it is equipped) is certainly worthy of study but I am not going to search for such a case.
 

MCroft

Developer
Staff member
I bring it up because I think I see it in my log (from comment above)
[(none) (742), turtle totem (742), saucepan (742), candy cane sword cane (774)]
[candy cane sword cane]

SLOT STICKER3 [(none) (742), turtle totem (742), saucepan (742), candy cane sword cane (774)]
[candy cane sword cane, saucepan]

6 combinations checked, best score 1,139.35

Wielding turtle totem...

candy cane sword cane scores 774, more than "none" or "Turtle totem". It says "ccsc, saucepan", in the shortest shortlist, then it picks turtle totem, then it equips nothing. IT doesn't try to equip nothing, but nothing gets equipped.

The character was at that point not very high level; it may have been immediately after ascending.
 

fronobulax

Developer
Staff member
I bring it up because I think I see it in my log (from comment above)


candy cane sword cane scores 774, more than "none" or "Turtle totem". It says "ccsc, saucepan", in the shortest shortlist, then it picks turtle totem, then it equips nothing. IT doesn't try to equip nothing, but nothing gets equipped.

The character was at that point not very high level; it may have been immediately after ascending.

To be clear, why it failed to equip turtle totem is in scope of what I am working on. "Wielding turtle totem..." is the success message related to generating and submitting the equip command so it is not even clear that there was a failure to equip in your log.

Why it picked turtle totem and not something else is no longer in my scope.

If you would like to be helpful go to the PR, look at noWeaponIsTheRightAnswer in MaximizerTest and tell me why that test is wrong.
 

fronobulax

Developer
Staff member
No meaningful progress. I have no confidence that my tests are exercising the equip step and the cases where no weapon is recommended seem to be correct. I've gotten distracted by looking at the Equip requests. I have a test that passes when I run it alone and fails when I run it with other tests. The difference is the request doesn't have a PWD hash in the standalone but does in the multiple. That says to me there is some leakage but I I haven't addressed it yet.
 
Top