Bug Monsters with rejection in combat queue not accounted for properly

heeheehee

Developer
Staff member
Monsters with partial (i.e. between 0 and 1, exclusive; made-up term) rejection are not handled correctly, either with or without the combat queue.

Example: spend turns in the Hole in the Sky until you encounter an astronomer, then add up all the rates in appearance_rates($location[the hole in the sky], true) to get some number greater than 100. This does mirror what's shown in the location details.

The problem seems to be that the total zone weight as calculated by AreaCombatData is reduced by monster rejection rate, so the "denominator" in AdventureQueueDatabase.applyQueueEffects is smaller than the total number of monsters in the zone. The calculation ends up being incorrect in this scenario.

The approach is also simply incorrect in the case where multiple monsters with partial rejection appear in a zone (I don't think this currently happens; the only monsters I see with partial rejection are astronomer, amok putty, and wild seahorse; there may be others, though). For instance, I made a test zone locally where two of three monsters have 50% rejection. The current code expects that the two monsters with rejection show up 25% of the time, and the third monster shows up 50% of the time. In reality, for the third monster, we have three scenarios:
1) no monsters rejected, occurs 1/4 of the time. encounter rate: 1/3.
2) 1 monster rejected, occurs 1/2 of the time. encounter rate: 1/2.
3) 2 monsters rejected, occurs 1/4 of the time. encounter rate: 1.

Putting these together, the third monster actually appears 1/4*1/3 + 1/2*1/2 + 1/4*1 = 7/12, which is roughly 58.3%; the other two monsters appear with equal probability, about 20.8%.

So, two (maybe obvious) options:
1) accept slight incorrectness and just normalize so that the sum adds up to 100. This isn't as bad as it sounds in most practical cases, as it would yield results like 3.9263% when the expected is 3.9215% (specific case: looking at non-astronomer in queue; astronomer in queue, four other distinct monsters in queue).
2) Properly account for this, probably introducing more complexity.

I prefer the latter option, but I've been staring at it for the better part of a day and not coming up with a clean approach that doesn't involve cloning ArrayLists for every monster in the zone, so I'm open to input.
 
Last edited:
1/4*1/3 + 1/2*1/2 + 1/4*1 = 231/396
Not relevant to the discussion, but I was wondering how you calculated that. It's correct, but not the straightforward 7/12 I would have expected. Where'd the factor of 33 (in numerator and denominator) come from? Just curious.
 

heeheehee

Developer
Staff member
Not relevant to the discussion, but I was wondering how you calculated that. It's correct, but not the straightforward 7/12 I would have expected. Where'd the factor of 33 (in numerator and denominator) come from? Just curious.
Yeah, 7/12 would be a much more reasonable representation. I was quickly jotting things down, and I had a repl open on the side. Didn't feel like using a Rational number library, and I started with 99900 a base of 99900 (900 would've been adequate) before removing common factors.

Edited my original post, since the bizarre 231/396 isn't particularly relevant to the discussion.
 

Darzil

Developer
Does rejection remove the monster from the queue before evaluating it, or does it reroll if it hits rejection condition having chosen it? I am not sure whether the two result in the same chances ?
 

heeheehee

Developer
Staff member
Rejection removes the monster from the queue before evaluating. Depending on how you interpret this, this may result in different overall distributions.

If you read this as "if astronomer is rejected, every time astronomer comes up, reroll", then they're equivalent distributions; if you read this as "if astronomer comes up, roll anew for rejection; if rejected, roll again", then those are distinctly different, as can be seen from the infinite series that arises from the combat queue (which ends up reducing the relative appearance rate by less than 75%). Fundamentally, rejection of a monster only happens once, before populating the queue.
 

Darzil

Developer
Ok, so probably needs a complete re-write of rejection mechanics. We'll have to run queue effects twice to work out the encounter chances, once with rejected monster present, once without, then add the two together, weighted by non-rejection chance, and rejection chance respectively.
 

heeheehee

Developer
Staff member
Right. Ideally we'd want slightly more complication to deal with the possible eventual scenario of multiple monsters in a zone that can be rejected (i.e. possibility of A being rejected, B being rejected, A and B being rejected).
 

heeheehee

Developer
Staff member
I can't see a good argument for it to do so. In olfaction's case, iterating until stopping ended up being equivalent to looking at the expectation of a geometric random variable. In this case, we're looking at a mixture of simpler distributions, which doesn't lend itself to any nice telescoping or whatnot.
 
Top