[SDK] Lead from Behind

I guess it will be hard to get a very good fitting formula because of the huge jumps in odds when a single hit more or less decides the battle and small changes in strength can cause large jumps in odds. A fit that works well on average will probably be the best that can be done. If you have some software that can draw some graphs of the odds with higher strength or higher number of first strikes, then you could compare the odds better.
That's exactly the problem - those huge jumps due to the underlying combat mechanics make estimating based on strength alone impossible. I'm tempted to change the mechanics to reduce those anomalies ... but don't know that I want to change things that much ... ;)

When increasing strength from 10 to 10.01 (the smallest change possible) increases the odds by close to 25%, it makes it impossible to accurately estimate (through adjusting strength alone) the affect of a First Strike that should increase the odds by 13.6% ...

What I should be able to do though is essentially extrapolate it - assume 100X the HP (and 100 FS to balance it), and see what affect it has on odds. Requiring 100X as many hits to make a kill with greatly reduce those anomalies. Then I'll see how well I can fit a formula to that. It'll never be accurate with these anomalies, but it can at least be better than what's there now.

I've heard about that one. I think you should leave that one in. It's very important in making transport units not the stack defenders.
Agreed - though I'm not so sure about using asset value ... but really not worth tinkering with.

Wouldn't it make more sense to reduce the ranking of defenders (by the inverse of the factor which would be used if the defender had the first strikes) who aren't immune to the first strikes of the attacker while not changing the ranking of a defender that is immune. That would also work when the attacker has more first strikes than the defender. The left over first strikes would reduce the ranking of the defender.
Agreed - I was just letting you know how it works now. The end effect is the same really, but it's more confusing this way. All I can figure is the thought was immunity isn't so common, so you have to calculate the affect less often this way ...

You're right the effect is less prominent. Adding or removing first strikes cannot cause the well-known "jump points" like other combat modifiers can. Really this should make it easier to take into account the effect of first strikes.
Except that the basis for the algorithm is the strength, so the only way to estimate the affect of FS's is to adjust the strength ... which leads to these 'jump points'. I keep toying with basing it off of #hits needed to kill ... that's really a more accurate measure than strength (even takes damage into account). But that's tricky since the Attackers #hits will also vary with different defenders, so how to do the comparison of two defenders?

I fear there may be a problem here. I noticed you said it takes damage into account. How exactly? I would expect a mistake they have made is to assume the rank of a defender is proportional to its health (out of 100). This would be problematic because a unit that is half health is worse than a full health unit that is half the strength.
It factors it in the 'normal' way - a unit with say 75% health has 75% of their full strength. And yes, it's also a failing of this algorithm - though I think it's at least considerably more accurate than the FS code!

I'm not very good at coming up with appropriate formulae but the reduction in ranking of a unit should probably depend on something closer to the square of its damage rather than a linear factor.
I agree it's not going to be linear - but I'll worry about that when I have numbers to base it on.

I don't have that program set up at the moment but if necessary I could dig a bit to find it.
It's alright, I've already created my own - let's me enter the defender/attacker strength, hp, first strikes then calculates the odds. It doesn't apply bonuses or anything but that's irrelevant anyway (e.g: a strength 9 unit and a strength 6 unit with a +50% bonus are identical as far as combat goes)
 
The Ranking is pretty much just the Defender's current strength. That's taking into account any damage, fortification bonuses, Defender unit bonuses/promotions, Attacker unit bonuses/promotions (as a negative). It's the same calculation used when actually resolving combat (as well as computing the odds).

It does do some manipulation to the Ranking after that:

...

Hopefully, first defender is also taken into account? Take a look at this modcomp, which is pure XML. It uses the UnitClassDefender tag from the CIV4UnitInfos.xml to make destroyers defend first against submarine attacks.
 
It factors it in the 'normal' way - a unit with say 75% health has 75% of their full strength. And yes, it's also a failing of this algorithm - though I think it's at least considerably more accurate than the FS code!

I'm not sure that I agree. This is only based on experience but the way first strikes are handled only usually becomes a big issue when the defender is also injured. Full strength first strikers have their rank approximated fairly well, don't they? Like I said, this is purely based on experience - not theory.
It's alright, I've already created my own - let's me enter the defender/attacker strength, hp, first strikes then calculates the odds. It doesn't apply bonuses or anything but that's irrelevant anyway (e.g: a strength 9 unit and a strength 6 unit with a +50% bonus are identical as far as combat goes)
Nice work. That combat odds calculator is no simple task!
 
Hopefully, first defender is also taken into account? Take a look at this modcomp, which is pure XML. It uses the UnitClassDefender tag from the CIV4UnitInfos.xml to make destroyers defend first against submarine attacks.
That's modpack for the Rise of Mankind mod. I'd have to dig into to find out what they did - but I suspect its the RoM mod that added that capability, and this modpack is just using it. Certainly I don't have a UnitClassDefender tag in my CIV4UnitInfos ...

I'm not sure that I agree. This is only based on experience but the way first strikes are handled only usually becomes a big issue when the defender is also injured. Full strength first strikers have their rank approximated fairly well, don't they? Like I said, this is purely based on experience - not theory.
lol ... you're the one who gave me that link to the post by DanF5771 that had an Ironclad defending ... ;)

My guess is it's the linear issue - when defender is much weaker, the first strikes aren't nearly as effective, yet are still given the same weight. That applies whether they're weaker due to just being less advanced - or due to being damaged. Once we figure out how much effect the FS's should have we can see how big an issue damage actually is - but one thing at a time.

Nice work. That combat odds calculator is no simple task!
Well, I didn't have to actually write it ... just copy it and convert to C# (which mostly meant just changing -> to . and a few other syntax differences). So it was really pretty easy.
 
That's modpack for the Rise of Mankind mod. I'd have to dig into to find out what they did - but I suspect its the RoM mod that added that capability, and this modpack is just using it. Certainly I don't have a UnitClassDefender tag in my CIV4UnitInfos ...


First off, Silent Hunter is a modmod. (A mod for a preexisting mod.)

Secondly, Zappara, the coder for RoM doesn't have the capability to make SDK changes, and uses RevDCM's CvGameCore.dll. So, the UnitClassDefender tag must be in BTS's CIV4UnitInfos.

Do a quick search and you'll find it in BTS's assets, "<UnitClassDefenders/>."
 
Secondly, Zappara, the coder for RoM doesn't have the capability to make SDK changes, and uses RevDCM's CvGameCore.dll. So, the UnitClassDefender tag must be in BTS's CIV4UnitInfos.
You're right ... not sure how I missed it the first time (I did do a search, but must've had a typo I guess). Sorry about that.

Anyway, that falls into some code that goes before it even calculates a Ranking. It does some quick checks on the two possible Defenders - things like can it even defend (ruling out non-combat units) or can it co-exist with attacker (ruling out units belonging to player's who are not a war with the attacker).

It also does an 'isTargetOf' check, which is where the UnitClassDefender flag is used. It doesn't really come into the Ranking calculation since it's purely a yes/no - if you're flagged as a defender against the attacker, you'll always be picked over a unit that's not flagged.
 
I have a suggestion to find a strength approximation of the effect of first strikes.

We create a graph of a strength 10 attacker attacking a strength n defender with 1 first strike with the strength n of the defender on the horizontal axis and the odds of victory of the defender on the vertical axis. Then we try to find a graph of a strength 10 attacker attacking a strength n * FirstStrikeFactor that is as close as possible to the first graph with again the strength n of the defender on the horizontal axis and the odds of victory of the defender on the vertical axis. We vary the FirstStrikeFactor until we find a good match between both graphs. That would give an approximation of the FirstStrikeFactor that will be as good as we can do (assuming we want to find a simple FirstStrikeFactor that converts the first strikes into ranking adjustments).

So using mathematical notation, we compare the functions:

F: Strength of defender -> [0,1]
F(n) = the odds that a defender with 1 first strike and strength n defeats an attacker of strength 10

and the set of functions

G_s(n): Strength of defender -> [0,1]
G_s(n) = the odds that a defender with no first strikes and strength n*s defeats an attacker of strength 10

and try to find a value of s such that the area between both graphs is minimised for values of n between 5 and 20. (mathematically, the integral of the absolute value of the difference of the functions over the interval [5,20] is minimised)

This can be done by for instance plotting the graph of F and G_1.04, G_1.05, G_1.06 and G_1.07 and just look at them and estimate the best version of the function G_s with the naked eye. These graphs will all be non-continuous graphs and the jump points will not be at the exact same values of n. The graphs have to be calculated at some points close to the jump points in order to plot them correctly.

Due to the jump points at different values of n, there will be values of n where the approximation of F by G_s isn't great. This cannot be avoided by this approach. But given the impossibility to look at the true odds to create a ranking, I think it's one of the better things we can do.

The idea is then to approximate a single first strike for the defender by multiplying the ranking with s and to approximate for instance 2 first strikes and 3 first strike chances for the defender by multiplying the ranking by a factor (2 * s + 3 * 1/2 * s) and 1 first strike and 2 first strike chances for the attacker by dividing the ranking by a factor (1 * s + 2 * 1/2 * s). (I assume that only one side has first strikes as first strikes negate one another.)

It might be a good idea to also compare the situation for 2 first strikes in a similar manner to see if the same value of s is still a good approximation.

I personally don't have a good tool to plot graphs so I hope that someone with access to a combat calculator and a good plotting tool is willing to look at this approach. With a good plotting tool, it shouldn't be a lot of work.

The main reason (in my opinion) for errors concerning the ranking of units with first strikes is because the factor used by the Firaxian code is WAY too high.
 
lol ... you're the one who gave me that link to the post by DanF5771 that had an Ironclad defending ... ;)

lol true. I forgot what the exact circumstances for DanF's example, but now I check closely again I notice it's a unit with many first strikes that is also immune to first strikes. Except for Oromo warriors this is a pretty rare event. But anyway, maybe the reason I've noticed problems with only injured drill defenders and not injured non-drill defenders is that due to the existing problem with drill defenders often defending first, they are damaged already and then continue to defend due to their first strikes affecting their ranking. Fix this and then maybe damage might not be a problem as much - especially for drill defenders.

My guess is it's the linear issue - when defender is much weaker, the first strikes aren't nearly as effective, yet are still given the same weight.

I do agree with you, having thought about it a bit more. :goodjob:
 
I don't have any graphing tools either, so can't help there. I did do some rough estimates - basically looking at odds with defender having 1 FS then seeing how much I had to increase defenders strength by to get approx the same odds without the FS. Doing that for about a dozen different values, but ignoring any combinations where increasing strength would change the number of hits required (i.e: not going through a 'jump point'). I found the FS weight basically went from about 8% (at half the attackers strength) to 12% (at double the attackers strength).

So we could base it on that - but we'd always have the problem of those jump points. With multiple FS's, chances are good you'll end up crossing one of those points, and our estimate will be way off. I'm starting to think it's that (more than the flat 16%) that causes the problem. Same thing with damage - using current strength isn't a bad estimate in general, but you hit jump points at different health levels, making it way off in some cases - especially if the unit has a lot of damage.

I'm actually going back to looking at using combat odds ... yes it's slow, but what if we made it quicker? I'm thinking we could actually cache results (or actually sub-results) so that subsequent calls are much faster.

The calculation of combat odds consists of 4 nested loops - the first two of which are from low-high number of FS's for attacker and defender. Everything within those two loops is actually only dependent on four numbers (and then the results for the different FS combinations are simply averaged):

#FirstSrikes (AttackerFS-DefenderFS): from -6 to 6 (can you get more than 6 FS's?)
#HitsForAttacker (how many hits needed to kill defender): from 1 to 17
#HitsForDefender: 1 to 5 (explained below)
AttackerChanceToHit: 1-500 (explained below)

If AttackerChanceToHit>500, we can simply calculate Defender's chance to win and flip it, so we only need to be concerned with 1-500. That makes DefenderChanceToHit>=500, which makes DefenderDamage>=20, which makes #HitsForDefender<=5.

That leaves 552,500 valid combinations of those 4 numbers (at most). If we cached all those numbers, it'd use about 2.1M of memory, which isn't really that much (for comparison, I started a large map with 18 civs, and it was using around 230M - and that was still on the first turn). Plus a lot of those combinations would never actually come up (e.g: if #HitsForAttacker=17 you can be sure AttackerChanceToHit<20 or so) - allocate the memory in chunks as needed, and the memory requirement would be reduced a fair bit.

We can also store for intervals of AttackerChanceToHit (like every 16) and use a weighted average for numbers in between. That would cut down on memory use considerably (down to 138k) - and just experimenting a bit, I believe it'll still be accurate to +/-1 (i.e: you may get odds of 624 instead of 625), which is close enough for me (even for the displayed odds). Doing the weighted average would add a bit to the time, but still way faster than those two extra loops doing binomial and power calculations.

Should also note that the limits I've put on the numbers is of course dependent on other settings (namely the max FS you can have, COMBAT_DAMAGE, and COMBAT_DIE_SIDES) - so it would need to be flexible in case anyone changes those

So what do you think?
 
Should also note that the limits I've put on the numbers is of course dependent on other settings (namely the max FS you can have, COMBAT_DAMAGE, and COMBAT_DIE_SIDES) - so it would need to be flexible in case anyone changes those
I was about to mention that but then you did yourself. I personally am not in favour of changing the combat odds algorithm unless there is very strong reason to do so. Part of this unease I have is that if those values were changed it's quite possible there will be larger errors introduced. The existing calculator may not be the fastest there is but it's completely general (except for one or two mistakes that are in it).

One very small improvement that can be made on the existing combat odds code, which is built into my calculator is that some first strikes can be cancelled down (only guaranteed first strikes). As far as I can tell, the default calculator does not consider this.

So we could base it on that - but we'd always have the problem of those jump points. With multiple FS's, chances are good you'll end up crossing one of those points, and our estimate will be way off.
I want to say again, I'm pretty sure adding/subtracting first strikes cannot send combat over any "jump points". Jump points are always caused by a difference in either number of hits to kill attacker or number of hits to kill defender. These two values can be affected only by changing modified strength or number of hitpoints or amount of damage per hit. First strikes do not affect any of those.

Having said that, the effect (in terms of raw victory odds) of a first strike can become greater when a jump point occurs, but I'm not sure that it would ever complicate the "adjustment" caused by the first strike to the ranking.

It's true there are several things in the combat odds calculator that are calculated repeatedly and caching their results could improve speed, but I'm not sure that these are actually slowing the algorithm down by much in the first place?

Binomial and power calculations aren't necessarily very slow.
 
I was about to mention that but then you did yourself. I personally am not in favour of changing the combat odds algorithm unless there is very strong reason to do so. Part of this unease I have is that if those values were changed it's quite possible there will be larger errors introduced. The existing calculator may not be the fastest there is but it's completely general (except for one or two mistakes that are in it).
That's why I said it had to be flexible - e.g: I can't hardcode a max of 17 turns, because reducing COMBAT_DAMAGE would increase that. But I can easily make it flexible enough that it'll work for any settings (baring some mod that changes the underlying combat mechanics ... but then they'd have to rewrite the combat odds code regardless). The only real risk is some changes (increasing max number of FS, reducing COMBAT_DAMAGE, increasing COMBAT_DIE_SIDES) would increase how much needs to be cached, and could result in it ballooning way too high. But by making it dependent on a flag, anyone writing a mod like that could still include my code and just turn that part of it off.

One very small improvement that can be made on the existing combat odds code, which is built into my calculator is that some first strikes can be cancelled down (only guaranteed first strikes). As far as I can tell, the default calculator does not consider this.
The combat odds already only uses the difference between Attacker FS's and Defender FS's - is that what you mean by 'cancelled down'? It does loop on min-max FS, so it may not look like it's cancelling them out - but as I said, everything inside those two loops only looks at the difference.

There is an improvement that can be made regarding chance of FS's though - if both units have Chance FS's, it actually ends up duplicating some calculations (e.g: if attacker has 3-4 and defender has 1-2, it'll look at 3-1,3-2,4-1,4-2 or 2,1,3,2 - the case of 2 FS is calculated twice).

I want to say again, I'm pretty sure adding/subtracting first strikes cannot send combat over any "jump points".
I realize that - I meant that the existing best defender code tries to simulate the benefit gained by FS's by increasing strength - and increasing strength will take us through jump points. So as long as the best defender code is using strength to compare defenders, we're going to have that problem. (And same goes for damaged units)

It's true there are several things in the combat odds calculator that are calculated repeatedly and caching their results could improve speed, but I'm not sure that these are actually slowing the algorithm down by much in the first place?

Binomial and power calculations aren't necessarily very slow.
Slower than other calculations - but the real savings of the caching is that it completely removes the two inner loops (except of course the first time around).
 
Slower than other calculations - but the real savings of the caching is that it completely removes the two inner loops (except of course the first time around).
I actually tried it in my test app - variety of strengths (1-40), hp (10,20,...,100) and valid FS combos (none, Drill I/II/III/IV) for both attacker and defender (works out to 4 million combinations)

Running the standard combat odds took 177s ... running it with my caching code took 8.5s :D

The accurary though was kind of funny ... at first I was getting numbers further off than expected (even off by 4 or 5) - problem was I was being too accurate :eek: I was caching the results with greater accuracy since that's be used in my weighted average. Added the extra accuracy to the standard method 'fixed' my accuracy problem ;)

Basically, it calculates the odds of a number of distinct possibilies (winning with no damage, winning while being hit once, winning while being hit twice, etc ...). Each is computed as a float, but then converted (rounded off) to a number out of 1000, and they're added up. If most of the numbers get rounded up (or down), it can increase (or decrease) the final result by a few points.

Anyway, with the added accuracy (calculate odds out of 100,000 and divide the final result by 100), I got about what I was expecting - approx 2.5M of my answers matched exactly, 1.5M were off by 1, and 11 were off by 2. (This could of course be increased or decreased by changing how many results are cached).

If AttackerChanceToHit>500, we can simply calculate Defender's chance to win and flip it
This is another interesting tidbit - the above sounded perfectly reasonable to me ... but is actually wrong (as least with the calculated odds). For example, a strength 11 attacker vs a strength 10 defender has a (computed) 68.1% chance - but a strength 10 attacker vs a strength 11 defender has a 32.2% - I would expect 31.9%. I don't know why the discrepancy (though I haven't really looked into it yet).
 
Is there any reason to extend this concept to the attacker as well? I mean, the AI seems to usually attack with its best odds attacker (generally its most-promoted units), where it may sometimes make sense to send in some cannonfodder units first. Naturally, the AI should use it's collateral damage units first, which it also seems to do.

Just a thought. :)
 
This is another interesting tidbit - the above sounded perfectly reasonable to me ... but is actually wrong (as least with the calculated odds). For example, a strength 11 attacker vs a strength 10 defender has a (computed) 68.1% chance - but a strength 10 attacker vs a strength 11 defender has a 32.2% - I would expect 31.9%. I don't know why the discrepancy (though I haven't really looked into it yet).
I figured this one out - the problem is when it calculates the Defender's chance to hit, it always rounds down (same thing with damage btw). Change it to round off instead, and the discrepancy disappears. However, the actual combat resolution does the same thing, so the odds calculator is actually 'correct' - do we want to fix the combat resolution?

Is there any reason to extend this concept to the attacker as well? I mean, the AI seems to usually attack with its best odds attacker (generally its most-promoted units), where it may sometimes make sense to send in some cannonfodder units first. Naturally, the AI should use it's collateral damage units first, which it also seems to do.

Just a thought. :)
Sounds reasonable - I'll have a look.
 
Is there any reason to extend this concept to the attacker as well? I mean, the AI seems to usually attack with its best odds attacker (generally its most-promoted units), where it may sometimes make sense to send in some cannonfodder units first. Naturally, the AI should use it's collateral damage units first, which it also seems to do.
Sounds reasonable - I'll have a look.
In BBAI a while ago someone took a look into this, and the AI actually already saves it's high level level units, and attacks with cannon fodder first. Of course I'm sure the AI logic code here could be improved, but it seems to be pretty good. The person trying to adress this found the main issue was that the AI doesn't protect high level units. What frequently happens is that the high level unit gets stranded outside a stack, and the AI doesn't realize it needs to keep these units protected. They reported they had written some rudimentery protection code, and they were able to keep high level units in stacks better, and if stranded, able to get the AI to try to save the unit rather then just have it wander off like what happens now. Unfortunately this person never released their source code and dissapeared in the midst of development :sad:

What I'd really apreciate would be if someone reproduced this work. It would be awesome if the AI actually defended it's high level units, especially Warlords, and kept them burried in stacks, rather then send them off alone to die needlessly :deal:

Edit: here is the pertinent Better AI thread Keeping Particular Units Alive
 
Edit: here is the pertinent Better AI thread Keeping Particular Units Alive
Thanks - at least I can get some direction from his comments.

However, little point in even looking at the AI without first getting BBAI ... and there's a few other mods I'd want as well. What started as a 'simple little mod' is expanding, and I need to figure out what code base I should be using before I do any more ... I'm thinking RevDCM would be a good base to start with.
 
This is another interesting tidbit - the above sounded perfectly reasonable to me ... but is actually wrong (as least with the calculated odds). For example, a strength 11 attacker vs a strength 10 defender has a (computed) 68.1% chance - but a strength 10 attacker vs a strength 11 defender has a 32.2% - I would expect 31.9%. I don't know why the discrepancy (though I haven't really looked into it yet).
The discrepancy you are noticing could be caused by the discrete nature of the combat die. If you want to see some really weird results, try setting combat die sides to 2 and reversing attacker and defender roles in the same situation. If you want to understand why that discrepancy comes in have a closer look at how the game decides what combat die to roll when it is resolving combat.

If you are only talking about very small discrepancies it is of course also possible it is just rounding error.

EDIT...Oh, I see now you answered your own question. :lol: By the way, essentially the round down that happens always favours the attacker. When combat die sides is equal to 1, then the attacker never loses! :) By making the die have 1000 sides, most people (excluding yourself of course :P) would never notice this little asymmetry!

I'm thinking RevDCM would be a good base to start with.

Can I suggest keeping this modcomp relatively focussed? I'm not sure what you mean by using RevDCM as a base but if it will make it harder to put in mods that don't use RevDCM then I'd advise against it. Of course, making another modcomp that is based on this one but goes further is not a bad idea.

What I'm interested in is how this mod can relate to Advanced Combat Odds. In that modcomp I essentially expanded upon the original odds display to show other useful bits of information. The new code I wrote for calculating the odds was only very slightly improved but otherwise essentially the same. I did not attempt to "speedify" my code because it never got called by the AI and is fast enough for mouse over purposes anyway. However if yours is faster it might be worth linking it to your new odds function instead.

The other thing is, in ACO I have left the actual game rules completely unchanged for now (meaning I couldn't change things from round-down to round-to-nearest, for example). I even had to deliberately include what looks like an error in the code for using siege units attacking how their combats are resolved (the details are in the RNG link in my sig) but if you were to change these gameplay mechanics for one or some other mods I could adapt ACO for that change as well.
 
Can I suggest keeping this modcomp relatively focussed? I'm not sure what you mean by using RevDCM as a base but if it will make it harder to put in mods that don't use RevDCM then I'd advise against it.
Well, as I said, I can't see the point in looking at the AI without BBAI, so I'd need to use at least that as a base ... and I know I want to use RevDCM for myself, so really just trying to save myself some effort down the road ;) But ok, I'll keep it seperate and just merge it in. I'll also leave the AI changes off for now, just keep it focused on the best defender code - I may look at the AI changes in another mod, but not here (even if it is somewhat related).

The other thing is, in ACO I have left the actual game rules completely unchanged for now (meaning I couldn't change things from round-down to round-to-nearest, for example). I even had to deliberately include what looks like an error in the code for using siege units attacking how their combats are resolved (the details are in the RNG link in my sig) but if you were to change these gameplay mechanics for one or some other mods I could adapt ACO for that change as well.
Interesting - I hadn't noticed that bit with the siege units :eek:. I'd agree it looks like a bug, but I've decided I'm going to take the same approach - leave the combat mechanics alone ... at least for this mod ;)
 
I haven't had time to add to this thread, but I'll post a few short comments now.

I don't have any graphing tools either, so can't help there. I did do some rough estimates - basically looking at odds with defender having 1 FS then seeing how much I had to increase defenders strength by to get approx the same odds without the FS. Doing that for about a dozen different values, but ignoring any combinations where increasing strength would change the number of hits required (i.e: not going through a 'jump point'). I found the FS weight basically went from about 8% (at half the attackers strength) to 12% (at double the attackers strength).

So we could base it on that - but we'd always have the problem of those jump points. With multiple FS's, chances are good you'll end up crossing one of those points, and our estimate will be way off. I'm starting to think it's that (more than the flat 16%) that causes the problem. Same thing with damage - using current strength isn't a bad estimate in general, but you hit jump points at different health levels, making it way off in some cases - especially if the unit has a lot of damage.

Note that the jump points that you avoid in the above analysis will always be in favour of the strength increase. So valuing the first strikes as an 8-12% strength increase will be a (quite serious) over valuation of the effects of first strikes. So I do think that the present valuation of first strikes (as equal to a 16% strength increase) is a serious part of the errors with picking the best defender.

A good approximation of the first strikes by a strength increase will always deviate less (maybe almost half) the size of one jump in the graph. Before a jump point in the 'strength graph', the 'strength graph' will be below the 'first strike graph', after the jump point in the 'strength graph', it will be above the 'first strike graph' until the 'first strike graph' gets to its next jump point. (graphs of strength vs odds)

I'm actually going back to looking at using combat odds ... yes it's slow, but what if we made it quicker? I'm thinking we could actually cache results (or actually sub-results) so that subsequent calls are much faster.

Interesting, but the 8.5 seconds that you found later still seems way too long. Or am I missing something?

It would be great if a slightly simplified or compacted combat formula could be used so that the jump points are still accounted for.

BTW, I agree that the jump points are actually an ugly part of the formula and one that could have been avoided creating a more sensible combat model.
 
Back
Top Bottom