Feature - Implemented Tracking Combat Monster Level

Theraze

Active member
I'm actually looking into trying to do some of the Monster Level tracking. The problem is that most of the items delevel for a range...

According to the Drowsy Sword wiki page, Jick confirmed that delevel on hit weapons reduce ML by 10-20 percent of weapon power per hit. So we can know what the ranges are, but not the specifics...

Here's the question... mid-point or bottom of the range for when it's not clear? There's no way to know exactly what it's doing, unless they actually make it display the ML on the page. It's somewhat important for things like the NS, where it'll wipe delevel if you go down too far. Then again, most people won't try to do delevel on those guys...

Edit: The 20101109 patch should now properly track the new modifiers. It should do the following:
Tracks monster attack and defence in processNode using image matching.
Tracks monster healing for the NS, +125 per healing, no cap. Also added a pattern for the NS2 to match properly.
Tracks monster healing for the ghuols, +10 per healing, no cap.
Tracks monster healing for the NSN, +90 per healing, caps at HP max.
Tracks monster healing through mana drain for NS and Lord Spookyraven, same amount healed as drained.
Tracks monster healing for Dr. Awkward, +50 per healing, no cap.
Tracks monster healing using the healing bang potion, +16 per healing, no cap.
Removes the old delevelling hacks.
Tracks expected_damage using the new attack modifier. Made a public function for both attack and defence modifiers.

Edit: The legacy version of the patch is here for if the listed information is removed. The 20101029 legacy patch does the following:
Overloaded the function named KoLCharacter.getMonsterLevelAdjustment, to request fight-data be included instead of static information if you give it a positive boolean. Non-overloaded, it still defaults to not include fight data, to not break any functions that call it.
The function is currently called with monster_level_adjustment. The static information can be given if you give either 0 or false to monster_level_adjustment.

Tracks delevelling for weapons with the WEAKENS mod by using weapon power / 8 in a new function called processMonsterLevel that executes during the round update, just after monster special effects happen. This is now done using regex so we only need to do a single check instead of the two it was doing before.
As well, this function now should have the NS weakening reset properly detected. NS2 does not have a listed message on its page, but if it's the same as the NS1, it should work for both. If not, then the Wiki needs to have that updated and we can put it into the system.

Tracks monster healing for the NS, +125 per healing, no cap. Also added a pattern for the NS2 to match properly.
Tracks monster healing for the ghuols, +10 per healing, no cap.
Tracks monster healing for the NSN, +90 per healing, caps at HP max.
Tracks monster healing through mana drain for NS and Lord Spookyraven, same amount healed as drained.
Tracks monster healing for Dr. Awkward, +50 per healing, no cap.

Tracks successfully insulting pirates for a delevel.

Tracks combat item usage in various ways using an existing function, payItemCost. This allows both checking the specific item and verifying that the message needed exists, in the cases of items like the Spectre Sceptre with multiple possible effects.

Added delevelling tracking for the 2 bird delevels, the haiku delevel, and spray sap.

Added psalm of pointiness monster-hit delevelling tracking.

Converted delevelling items to use modifiers.txt as its data location, using 3 new modifiers - COMBAT_DELEVEL_MIN, COMBAT_DELEVEL_MAX, and COMBAT_DELEVEL_TYPE. This makes payItemCost much less complicated.

Added develling familiars using modifiers.txt as its data location, using the modifiers as above. This should work properly as well.

Tracks familiar action delevelling in the existing function payActionCost. This seemed to be the proper place for familiar actions to be checked, as I was told that payItemCost was the place for items, and 3 familiar actions were already noted in here.

Moved the actual delevel handling into a new function, processCombatDelevel(final Modifiers mods, int min, int max, int type). This allows me to just hand the function the series of Modifiers and lets it process them, whether by int or Modifiers.

Bang potions give their override information to processCombatDelevel properly, including on initial identification.

Pasta Guardians are now tracked for delevelling as well, in payActionCost, similar to familiars.

Fixed a (new) bug with Cunctatitis stopping familiar delevelling from being tracked.

Added unspaded items with minimal (1) delevelling.

Added limitations to delevelling for attack and defense; now they can't go below zero.

Added a new global preference named mlDangerPercent that defaults to 25. This allows people to set how dangerous they want it to be.

Tracks Crown of Throne familiars for delevelling using payActionCost, like Familiars and Pasta Guardians.
 

Attachments

  • LegacyFightMonsterLevel.patch
    52 KB · Views: 45
  • TrackFightMonsterLevel.patch
    25.6 KB · Views: 44
Last edited:

StDoodle

Minion
I, for one, would prefer mafia assumed that the ML was at the highest value possible. Knowing the possible range would be great too, but having mafia report a ML too low is quite dangerous, at least to my play-style.
 

Theraze

Active member
Sounds good to me... Yeah, I somewhat prefer if items with ranges gave the most conservative estimates. Personally, I'd prefer to purchase an extra KGS on initial restoration instead of switching outfits twice more. But, to each their own. I'll plan on working on conservative ML numbers, 10% of weapon power, for delevel instead of using the average of 15% of its power. Same for items that have a range... if you're using a CCS that will decide based on the numbers, you can track things however you'd like... 3 rounds of X item means that it should be roughly here... but for tracking purposes, to keep people alive, low is probably best. :)

Not sure... does the code currently have support for tracking monster attack and defence modifiers? Should it? I believe currently it's only currently only done during combat, but the actual modification thereof should be easy... similar to hobo-dance, do Modifier.overrideModifier( "fightMods", "Monster Level: XX" ); and toss in the recalculateadjustments and updatestatus... fightmods gets wiped when the fight ends, so it should just last for that fight. Easy.

Interestingly, Funk Bluegrass Fusion has a combat ML modifier currently in... 20 ML delevel, does FightRequest.levelModifier -= 20 and that's it, no recalculate or updatestatus. Head + Knee + Shield combo also does -= 5 for ML, eyepoke is stealthmistletoe *3, DDoD is SM * 5, DD2EB is SM * 7, DDFS is SM * 10, and the list goes on and on... nothing currently otherwise, but it looks like that's the current 'best' method for doing this.

Thought... anyone know if the ML variance is based on damage done? Psalm of Pointiness does 4-8 damage and delevels by 1-5... same range. I'm mainly just wondering if anyone has worked through the spading on that... Since it's known at which point the NS will reset ML modifiers, it should be possible to use that information to see if they correspond.

Another interesting bit... the "delevel" command runs DEP, DDoD, DDEB, ToT, and DFS. It skips Suckerpunch, the Shieldbutts, and Funk Bluegrass Fusion. Should it?
 
Last edited:

StDoodle

Minion
Yeah, for seltzer purchasing, I agree. I'd prefer either an extra was purchased, or KoLmafia said "good enough" after using the estimated requirements. But that's an issue of page loads & increased wait time. For combat & ML, if you estimate ML too high, you may throw more resources into the fight than necessary. However, if you estimate wrong the other way, you'll likely get beaten up, which is much, much worse.
 

Theraze

Active member
So, it appears that the standard "you just used a weapon to delevel" message is this:
Your opponents look weaker...

If anyone knows if there's a different message that gets used at times, let me know. Same with how things work for dual-wielding...

Interestingly, it appears that in-combat ML modification doesn't appear visible in any way... I'm sort of tempted to convert all of the current ML modifier points to the fight modifier system.

Ah... that's just for multiple (they) combats. Standard apparently look like:
Your opponent looks weaker...
 
Last edited:

Theraze

Active member
Okay... here we are with a weapon-ML bit. It checks first if the WEAKENS modifier is set on the equipped weapon, and if so, if it finds one of the two weakening messages I've found. Also made monster_level_adjustment() display in-combat ML, since it didn't before.
 
Last edited:

slyz

Developer
If it was possible, I think seeing the range would be interesting. There is a natural monster ML variance to start with (+/- 5), and the difference between min and max can become important I guess. Not all combat strategies need the conservative value: V-Crisis might be quasi-extinct, but who knows what people can come up with.

Another question: the initial monster HP depends on the initial ML modifiers, but does not go down during combat when you further modify the monster's ML. What happens if you add FightRequest.getMonsterLevelModifier() to getMonsterLevelAdjustment()?

EDIT: Does Mafia take into account the fact that Actual defense is equal to 90% of (base defense + ML Modifiers + Random Variation), rounded up.?

Maybe someone who knows about ML and game mechanics should weigh in =/
 
Last edited:

Theraze

Active member
Well, we can't use a RANGE, as it's a single int... either we use low, average, or high. I've elected currently to use the low value, as it means that you're much more likely to be safe if the code is calculating that for safe statis checks and so on... I don't want the code to decide after 5 rounds that I'm safe and statis for 20 more, when I'm actually getting torn to ribbons because instead of having ML get dropped by 75 or 100, it dropped by 50, and I'm still deeply in danger for extended combat. Safe for fast killing, not so safe for wasting time.

Far as I saw, it didn't affect the displayed HP... it just affected the calling command. Once combat starts, the HP is set as a part of that FightRequest. Until the combat starts, FightRequest.levelModifier is set to 0. So... it shouldn't affect a thing, besides that you can actually detect the real modifier.
 

zarqon

Well-known member
Ha, didn't see this discussion taking place. So I thought I would step in and complicate matters. :)

Saying we must use low, middle, or high is a false dilemma. We could use a result anywhere within the range, perhaps even weight it torwards low vs. average using some formula or another (perhaps factoring in your survivability, for example). Of course, the proof's in the pudding, so if low works well for everyone, then low is great.

BatMan is using averages for everything, but that's because it's adaptive, and any given number can be tweaked for best results. For mafia's tracking, it seems that using something closer to the highest possible ML value is best (which means smallest value for deleveling, largest value for +ML -- I assume this is what you meant by "low value"). It makes me feel a bit uneasy to use these values though, especially for anything with a large range.

On a related note, mafia should also have range checking wherever possible, using whatever clues may be available to adjust tracked ML into a valid range if it's outside the range. Does mafia already do this for spading gear? Spading gear messages show in the CLI but that might have been added purely as information for log parsers. Seems like adjusting the relevant stats within acceptable ranges there would be really handy if it doesn't already exist.

Aside from spading gear, are there any other not-too-involved ways to detect valid ranges for the current monster's stats? For example, if the monster is not dead, it has at least 1 HP (currently, it's possible for monsters to have negative HP). If you miss the monster (non-fumble), the monster's defense must be at least (your attack stat - 5). If you hit the monster (non-crit) its defense cannot be higher than (your attack stat + 6). And so forth. Any ideas for adjusting monster attack within range (In other words, an easy way to tell a monster's crit from a regular hit, or a monster's miss from a fumble)? It would be very nifty to make mafia smart about this.

Also, even for monsters with unknown att/def, it's still useful to track these changes, but we may have to look again at how we access monster stats from within ASH. Presently we can access both the current monster's adjusted stats and the static +/-ML, but if you delevel (or level) a monster with original stats of 0 (unknown), how would you know the original values were unknown?

Also also, for what it's worth, getting Beaten Up is not always worse -- purely from a meat perspective, if you have a massager in inventory you may be out less than the cost of the skills/items you would use to smack down the monster. Likewise if you have cheap MP (maybe via starfish or regen) and Tongue.

Random thoughts -- hopefully at least one of them was helpful. Thanks much for working on this, Theraze. I'm very pleased to see progress being made.
 

Bale

Minion
We could use a result anywhere within the range, perhaps even weight it torwards low vs. average using some formula or another (perhaps factoring in your survivability, for example).

I like that idea. Perhaps (3*low + high)/4 to produce a more use-able value? For a deleveling range of 2-10 that'd produce a value of 4; safely on the low side without quite being at bottom.

Also also, for what it's worth, getting Beaten Up is not always worse -- purely from a meat perspective, if you have a massager in inventory you may be out less than the cost of the skills/items you would use to smack down the monster. Likewise if you have cheap MP (maybe via starfish or regen) and Tongue.

What's the meat value of the stats you are losing by getting Beaten Up that adventure? The possibility of missing out on those stats is a potent incentive to win the fight.
 
Last edited:

Theraze

Active member
What the uploaded version of the code is currently using for weapon delevelling is weapon power / 10 which offers 10% as its terminus. If we wanted a slightly higher, but still low estimate, we could go to weapon power / 8, which should offer up 12.5% as its endpoint instead.

The true range for weakening weapons is 10-20% per hit which is chosen randomly for each hit, I believe... Does the 8 provide a better end-result for safety estimates, or do we prefer 9 or the most conservative 10 for weapons?

Regarding ways of detecting things... there ARE in fact a few internal safe-combat-checks. willUsuallyMiss, willUsuallyDodge, isAcceptable (which uses both and returns false if either is true)... those do use the monster in-combat delevelling for their safe checks... so if you're using/able to use those, they'll be based off our estimate of which side of the range happened. If we use the /10, we'll know 99.5% that we're safe. If we use /8 (low-mid average) or /7 (mid average), we'll be somewhat less certain.
 
Last edited:

lostcalpolydude

Developer
Staff member
For psalm, I didn't look for any correlation between damage and deleveling when I spaded the range.

If you hit the monster (non-crit) its defense cannot be higher than (your attack stat + 6).
It's actually attack stat-9, or -10, I can't remember which number came from RT's spading. Also, don't forget gremlin juice making you auto-hit.
 

zarqon

Well-known member
@Bale: stats are next to worthless in most aftercore play. My point was that Beaten Up is not always the worse option. I know this because I coded up the cost of getting Beaten Up for BatMan. :)

@lostcalpoly: I pulled that right off the Wiki, but it's been known to be wrong before. And surely you mean +, not -?

@Theraze: 8 gets my vote for deleveling weapons, given that if you decide to stop deleveling and start attacking, you'll still be deleveling! :)

Also, I don't think you quite got what I was saying about detecting and range-checking. I'm fairly sure willUsuallyMiss, willUsuallyDodge, and isAcceptable use mafia's knowledge of the monster stats. I was talking about using deductions from fight.php to fix mafia's knowledge if it is known to be off.

For example, let's say you delevel a much stronger monster using something with a broad deleveling range. New ML-Tracking Mafia™ would, correctly, assume fairly minimal deleveling. Now let's say that according to mafia the monster now has a defense stat 14 higher than your attack stat. Then, you attack and actually hit the monster! This is impossible if the defense were really 14 higher, so Mafia should see that and automatically adjust defenseModifier to within the valid range.

Or, for example, you attack a ghuol several times. It heals itself several times (not currently tracked). The monster's HP according to mafia is now -13. A consult script would be fairly confused that all of its options will do 0 damage. Clearly, monster HP should be capped on the lower end at 1. Ideally, monster HP would be tracked more thoroughly as well.

Monster HP

I explained this in greater detail elsewhere, but a few searches didn't turn it up. I think it must have been lost when the forum changed bugtrackers. So, for starters, several monsters have healing moves which are not tracked. For monsters where their healing move also drains your MP, the amount of healing is the same as the MP drain. For naughty sorority nurses, their healing amount can be found on the Wiki. For ghuols, that number was narrowed down decently well in that other thread, which is now possibly lost. For the others, I have forgotten what was said, but there are others.
 

Theraze

Active member
The problem with using the system to spade the stats is that most develling is on a range, and while we could try to track min-delevel/max-delevel possibly, I don't think that the current data-files allow for delevel range on items... I believe that while Memory of Aggressiveness is +30 ML true, the scrolls all do -1 to -3 ML, but would be averaged to -2 ML with the datafiles... Barbed wire fence is -1 to -7 at an average of -4, but so is the plot hole with a range of -3 to -5 which also averages to -4 ML...

If a range is allowed in data files, we could track minimum and maximum delevelling and try to use that to spade, but otherwise we're looking at things being difficult to guess-spade at. Though of course, there are the items like MoA, Suckerpunch and the other DB skills, Shieldbutt, and a few other items... but anything with a range being involved basically makes good accurate spading fairly painful.

Of course, that's not to say that we couldn't have something like the auto meat spading flag that's semi-hiding in KoLmafia... Output a message or adjust the variable if it thinks that the miss/dodge shouldn't have happened. Criticals will still throw this off... but if you hit 2-3 times in a row, that suggests that your delevel was great enough to succeed. Could even do it that you can set how many anomalies it takes before it adjusts the variables. Though if you have anything above 1-2, it's likely to continue delevelling before it actually gets to where it matters. :)

That's where the issue comes in. Criticals screw up all these lovely checks, and if we can't easily detect for every possible critical (can we?) then adjusting it based on guesses will involve in the value being adjusted up/down/up/down/up/down as you crit hit and delevel, they hit, you crit hit and delevel, they hit, you (regular) hit and delevel, they crit hit, etc...

If I can find the proper healing stats and messages, I can try to put that in, either here or into another function... Question on mob healing, can it pass max, or does it cap like it does for players? If it's capped, as long as I can pull ML without round modifiers... or does heal-max-hp get affected by fight ML?
 

Bale

Minion
Question on mob healing, can it pass max, or does it cap like it does for players? If it's capped, as long as I can pull ML without round modifiers... or does heal-max-hp get affected by fight ML?

Monsters cannot heal past their maximum HP. Thank goodness, or some characters would never be able to kill the Naughty Sorority Nurse.
 
Last edited:

Theraze

Active member
Least that's something... do we know if their max hp is affected by delevelling in combat? Not that it drops their current health if it's above max, but if you delevel the NSN to level 1, is it possible to kill her with a drowsy sword or knob bugle, for example?
 

Bale

Minion
I'm not sure if combat ML reduction reduces HP cap for healing. Experiments with the Naughty Sorority Nurse would be useful in order to verify.

I know that ML reduction before a fight reduces max HP, but in combat ML reduction is a bit different.
 

Theraze

Active member
The common wisdom, at least as I've picked up, is that in-combat ML doesn't affect monster HP... but I've only specifically seen that referring to current HP, not max healable. If I remember next time I come up to them (will probably be at least a few more days... my BM TT aren't exactly deadly yet) I'll try to check it out. Or if someone else can do/has done this...
 

Bale

Minion
It might be very entertaining and educational to see if you can kill a Naughty Sorority Nurse with a 7-Foot Dwarven mattock...
 

Winterbay

Active member
Monsters cannot heal past their maximum HP. Thank goodness, or some characters would never be able to kill the Naughty Sorority Nurse.

I've found quite often that the best thing I can do with NSNs is to run away and hope that I don't find another one. I generally don't have the damage output to kill one if I'm a moxie class (one of the reasons I hate Moxie classes).

That said I was under the impression that the NS could heal herself above her original max.
 
Top