remaining resistance balance issues
Moderator: Forum Moderators
-
- Retired Developer
- Posts: 2633
- Joined: March 22nd, 2004, 11:22 pm
- Location: An Earl's Roadstead
a possibilityott wrote:Getting back to the topic at hand, anyone have ideas for what to do about the huge day/night swings that remain?
Based on the huge amount of changes and balancing since 0.7.1 I think it's too late to go back to multiplicative modifiers before 1.0. We are stuck with additive calculations for the moment.
The only way to restore sanity to out-of-whack additive calculations is to
- * reduce resistances to more reasonable values, as was done with undeadspirit (60% down to 40%),
I don't know that I like this, as chaos/neutrality/order to me is an expression of what environment the unit thrives in.
* to make the relevant units neutral, or
I really don't like this. Restricting non-neutral units to not have a small number of big hits is a bad idea.* to change the affected attack from a few damaging swings to more swings each doing less damage but retaining the same overall damage potential.[/list] and of course to then counterbalance these changes.
-
- Retired Developer
- Posts: 2633
- Joined: March 22nd, 2004, 11:22 pm
- Location: An Earl's Roadstead
Ok, here is another possibility, which would require a little coding. All these effects are essentially where a is the attack and b is the absolute value of the boni/bogi. The problem is that with multiple boni rapidly gets large, so we currently use The problem with this is that if the b's are bogi, then this gets small quick. Well what if we try to get the best of both worlds and use where Bs are only boni and the Cs are bogi. Thus, boni would be additive, bogi would be multiplicative. The only other real alternative I can see would be to apply only the maximum boni and maximum bogi , but this has the undesirable effect that abilities would sometimes not make a difference for reasons that are not at first obvious.
Code: Select all
1: a*(1+-b)
Code: Select all
2: a*(1+-b1)(1+-b2)(1+-b3)...
Code: Select all
3: a*(1+-b1+-b2+-b3)
Code: Select all
4:a*(1+B1+B2+B3... - C1*C2*C3...)
What are some sample calculations with this one?Darth Fool wrote:Code: Select all
4:a*(1+B1+B2+B3... - C1*C2*C3...)
Hope springs eternal.
Wesnoth acronym guide.
Wesnoth acronym guide.
- Elvish_Pillager
- Posts: 8137
- Joined: May 28th, 2004, 10:21 am
- Location: Everywhere you think, nowhere you can possibly imagine.
- Contact:
How about a Thief backstabbing a Heavy Infantry during day?
a*(1+(1)-(0.5*0.75))
0.5*0.75=0.375, thus
a*(1+(1)-(0.375))
which multiplies the attack by 1.625. Clearly not correct. You probably meant this:
a*((1+B1+B2+B3...)*(C1*C2*C3...))
which yields
a*((1+1)*(0.5*0.75))
which multiplies the attack by .75, not a bad amount. Now let us examine the Ghost being attacked during an oppoing alignment to its opponent...
a*(1*.4*.74)
=a*.3, not bad at all.
Now for the bonuses, a Konrad-led holy watered Thief backstabbing a Chocobone at Night...
a*(1+1+1+.5+.25)
*3.75, 'not excessive' given the situation Switching the alignment,
a*((1+1+1+.5)*.75)
*2.625, which is not an excessive change.
The only problem I can see with it is complexity.
a*(1+(1)-(0.5*0.75))
0.5*0.75=0.375, thus
a*(1+(1)-(0.375))
which multiplies the attack by 1.625. Clearly not correct. You probably meant this:
a*((1+B1+B2+B3...)*(C1*C2*C3...))
which yields
a*((1+1)*(0.5*0.75))
which multiplies the attack by .75, not a bad amount. Now let us examine the Ghost being attacked during an oppoing alignment to its opponent...
a*(1*.4*.74)
=a*.3, not bad at all.
Now for the bonuses, a Konrad-led holy watered Thief backstabbing a Chocobone at Night...
a*(1+1+1+.5+.25)
*3.75, 'not excessive' given the situation Switching the alignment,
a*((1+1+1+.5)*.75)
*2.625, which is not an excessive change.
The only problem I can see with it is complexity.
It's all fun and games until someone loses a lawsuit. Oh, and by the way, sending me private messages won't work. :/ If you must contact me, there's an e-mail address listed on the website in my profile.
OK, I've implemented a modified version of this in dr (version 1.5 attached). Run the script with the -a flag to see theDarth Fool wrote:Ok, here is another possibility, which would require a little coding. All these effects are essentiallywhere a is the attack and b is the absolute value of the boni/bogi. The problem is that with multiple boniCode: Select all
1: a*(1+-b)
rapidly gets large, so we currently useCode: Select all
2: a*(1+-b1)(1+-b2)(1+-b3)...
The problem with this is that if the b's are bogi, then this gets small quick. Well what if we try to get the best of both worlds and useCode: Select all
3: a*(1+-b1+-b2+-b3)
where Bs are only boni and the Cs are bogi. Thus, boni would be additive, bogi would be multiplicative.Code: Select all
4:a*(1+B1+B2+B3... - C1*C2*C3...)
new calculations.
I've included the full output both with classic (dr.out) and new calculations (dr-alt.out) for comparison, for those who don't have perl installed. In short, the new calculations never yield a day/night swing of more than 2, which seems reasonable, but don't much affect the overall damage tables. The main effect is to increase damage during adverse time of day from 1 to 2 in many cases.
The code is fairly simple:
Code: Select all
$diff = 0; $factor = 1.0;
if ( $percent > 100 ) { # 120 -> 20
$diff = $percent - 100;
} elsif ( $percent < 100 ) { # 80 -> 0.8
$factor = $percent/100.0;
} # else do nothing
if ( $special =~ /backstab|charge/ ) {
$diff *= 2;
} elsif ( $special =~ /steadfast/ ) {
$factor *= .5;
}
if ( $_ > 0 ) {
$diff += 25*$_;
} elsif ( $_ < 0 ) {
$factor *= (1.0 + $_/4.0);
} # else do nothing
$finaldam = int( (1.00 + $diff/100.0) * $factor
* $damage + 0.499999 );
$finaldam = 1 if $finaldam < 1;
Code: Select all
$percent += 25*$_ - 100;
$percent = 100 + 2*$percent if $special =~ /backstab|charge/;
$percent = $percent/2.0 - 50 if $special =~ /steadfast/;
$is_neg = ($percent < 0) ? -1 : 1;
$diff = $is_neg * int( ($is_neg*$percent*$damage + 49)/100 );
$finaldam = ($damage + $diff < 1) ? 1 : ($damage + $diff);
the Elvish Fighter
Code: Select all
blade 5-4: Elvish Rider,Huntsman,Elvish
Fighter,Drake Clasher,Huntsman-Peasant
against -25 0 25 50 75 100
--------------------------------------
armoredfoot 2 2 3 4 4 5 <- 1.50
deepsea 3 4 5 6 7 8 <- 1.67
drakefly 3 4 6 7 8 9 <- 2.00
drakefoot 3 4 5 6 7 8 <- 1.67
dwarvishfoot 3 3 4 5 6 7 <- 1.33
elusivefoot 5 6 8 9 10 11 <- 1.60
float 4 5 6 7 9 10 <- 1.50
fly 4 5 6 7 9 10 <- 1.50
largefoot 3 4 5 6 7 8 <- 1.67
lizard 4 5 6 7 9 10 <- 1.50
mountainfoot 4 5 6 7 9 10 <- 1.50
mounted 3 4 5 6 7 8 <- 1.67
naga 4 5 6 7 9 10 <- 1.50
none 3 4 5 6 7 8 <- 1.67
orcishfoot 4 5 6 7 9 10 <- 1.50
scuttlefoot 3 4 6 7 8 9 <- 2.00
smallfoot 4 5 6 7 9 10 <- 1.50
spirit 1 2 2 3 3 4 <- 2.00
swimmer 4 5 6 7 9 10 <- 1.50
treefolk 4 5 6 7 9 10 <- 1.50
undeadfly 4 5 6 7 9 10 <- 1.50
undeadfoot 3 4 6 7 8 9 <- 2.00
undeadspirit 1 2 2 3 3 4 <- 2.00
woodland 4 5 6 7 9 10 <- 1.50
woodlandfloat 4 5 6 7 9 10 <- 1.50
Code: Select all
blade 5-4: Elvish Rider,Huntsman,Huntsman-Peasant,Drake Clasher,Elvish Fighter
against -25 0 25 50 75 100
--------------------------------------
armoredfoot 1 3 4 5 6 7 <- 4.00
deepsea 3 4 5 6 8 9
drakefly 3 5 6 7 8 9
drakefoot 3 4 5 6 8 9
dwarvishfoot 2 4 5 6 7 8
elusivefoot 5 6 8 9 10 11
float 4 5 6 7 9 10
fly 4 5 6 7 9 10
largefoot 3 4 5 6 8 9
lizard 4 5 6 7 9 10
mountainfoot 4 5 6 7 9 10
mounted 3 4 5 6 8 9
naga 4 5 6 7 9 10
none 3 4 5 6 8 9
orcishfoot 4 5 6 7 9 10
scuttlefoot 3 5 6 7 8 9
smallfoot 4 5 6 7 9 10
spirit 1 2 3 5 6 7
swimmer 4 5 6 7 9 10
treefolk 4 5 6 7 9 10
undeadfly 4 5 6 7 9 10
undeadfoot 3 5 6 7 8 9
undeadspirit 1 2 3 5 6 7
woodland 4 5 6 7 9 10
woodlandfloat 4 5 6 7 9 10
What are the feelings about this? Please also look at Knights and other units before drawing conclusions. There are some significant differences even for bonuses, where the penalties from resistances seem to pull the really high damage values back a little. My subjective feeling is that these calculations slightly squish the range of damage values, which is a good thing in my book. A lv-3 Highwayman from Liberty now does
Code: Select all
undeadfly 8 11 14 16 19 22 <- 1.75
Code: Select all
undeadspirit 2 4 7 10 13 15 <- 3.50
Before making any game code changes, could someone please also do some checking that my perl rendering of the existing code is a faithful rendering, by comparing with in-game damage. Looks good to me, but I'm not infallible.
I don't like this.The only other real alternative I can see would be to apply only the maximum boni and maximum bogi , but this has the undesirable effect that abilities would sometimes not make a difference for reasons that are not at first
- Elvish_Pillager
- Posts: 8137
- Joined: May 28th, 2004, 10:21 am
- Location: Everywhere you think, nowhere you can possibly imagine.
- Contact:
ott wrote:I think this would allow the defense reduction in CVS for undeadspirit to be reversed.
There has been no such change. If you are referring to the Wraith/Spectre change, it was necessary. The Wraiths didn't need invincibility in order to be overpowered; removing the invinvibility would only remove half the problem.webcvs.wesnoth.org wrote: [resistance]
blade=40
pierce=40
impact=40
fire=100
cold=30
holy=150
[/resistance]
It's all fun and games until someone loses a lawsuit. Oh, and by the way, sending me private messages won't work. :/ If you must contact me, there's an e-mail address listed on the website in my profile.
-
- Posts: 873
- Joined: July 4th, 2004, 9:14 pm
- Location: My imagination
- Contact:
Why are you multiplying the "boni"? Especially when you add to it both before and after. Shouldn't charge and backstab add 100% to it because they increase the damage rather than decreasing it?ott wrote:Code: Select all
if ( $special =~ /backstab|charge/ ) { $diff *= 2;
Play a Silver Mage in the Wesvoid campaign.
You are right, this causes the charge bonus to disappear when the resistance modifier is 100 (ie. no special resistance or vulnerability, very common).Invisible Philosopher wrote:Why are you multiplying the "boni"? Especially when you add to it both before and after. Shouldn't charge and backstab add 100% to it because they increase the damage rather than decreasing it?ott wrote:Code: Select all
if ( $special =~ /backstab|charge/ ) { $diff *= 2;
I think this should be
Code: Select all
if ( $special =~ /backstab|charge/ ) {
$diff = 2*$diff + 100;
}
I'll try to post a new version of dr and the damage tables as soon as possible. Since Friday I'm having to use lynx as the forum server is unreachable from my ISP, and this version of lynx doesn't allow file uploads.
- Elvish_Pillager
- Posts: 8137
- Joined: May 28th, 2004, 10:21 am
- Location: Everywhere you think, nowhere you can possibly imagine.
- Contact:
No, you don't understand. That mechanism is still 'multiplying the boni'; it should just add 100 without doubling.ott wrote:I think this should bejust like the old code. However, I'll also need to reshuffle the ordering, since the day/night bonus is not doubled either.Code: Select all
if ( $special =~ /backstab|charge/ ) { $diff = 2*$diff + 100; }
It's all fun and games until someone loses a lawsuit. Oh, and by the way, sending me private messages won't work. :/ If you must contact me, there's an e-mail address listed on the website in my profile.
-
- Retired Developer
- Posts: 2633
- Joined: March 22nd, 2004, 11:22 pm
- Location: An Earl's Roadstead
I'm not sure I meant that, but I should have as that does seem more reasonable.Elvish Pillager wrote:How about a Thief backstabbing a Heavy Infantry during day?
a*(1+(1)-(0.5*0.75))
0.5*0.75=0.375, thus
a*(1+(1)-(0.375))
which multiplies the attack by 1.625. Clearly not correct. You probably meant this:
a*((1+B1+B2+B3...)*(C1*C2*C3...))
The resistance modifier does need to be doubled somehow -- against a -20% resistant enemy one can't just add 10 onto damage for a unit doing 10 baseline damage, that would lead to charge adding the same amount of damage whether the unit was resistant or not. The current code does this, and I think we need to retain this behaviour.Elvish Pillager wrote:No, you don't understand. That mechanism is still 'multiplying the boni'; it should just add 100 without doubling.
Currently: -20% resistance (resistance modifier 120) against charging unit, becomes (100+(120-100))*2 = 240 (ie. 240% of baseline damage total) plus two times any daytime and leadership modifiers. We'd need to achieve similar values, which at 100 + 20*2 + 100 = 240 my suggestion matches exactly. The bonuses are not multiplied, simply the effect of bonuses is doubled. Adverse time of day (unled) modifies this to 2.4*0.75 = 180% instead of the current (100+(120-100-25))*2 = 190%. Favourable time of day (unled) would be 290% both old and new.
Resistance modifier 80 (resistance 20%) against charging unit currently becomes (100+(80-100))*2 = 160 ie. 160% total. The above suggestion is an attempt to translate Darth Fool's suggestion into something workable (with bonuses added, then penalties multiplied), in this case (1.00+100/100.0)*0.8 ie. 160%, again matching existing calculations. The difference is that adverse time of day (unled) modifies this to 2*0.8*0.75 so 120% instead of (100+(80-100-25))*2 = 110 so 110% total currently. Favourable time, unled would be 200% new, versus 210% currently.
This all seems innocuous. The big change happens with larger resistances, which currently are seriously messed up.
So for an unled charging or backstabbing unit doing 10 baseline damage, its adverse/neutral/favourable time of day damage, against
Code: Select all
-20% resistance: 19 24 29
20% resistance: 11 16 21
60% resistance: 3 8 13
Code: Select all
-20% resistance: 18 24 29
20% resistance: 12 16 20
60% resistance: 6 8 10
-
- Posts: 873
- Joined: July 4th, 2004, 9:14 pm
- Location: My imagination
- Contact:
Yeah, don't you understand how the system works? You're adding into the bonus, not the whole thing. Here are calculations using the correct scheme, with only +100% to bonus for charge.ott wrote:The resistance modifier does need to be doubled somehow -- against a -20% resistant enemy one can't just add 10 onto damage for a unit doing 10 baseline damage, that would lead to charge adding the same amount of damage whether the unit was resistant or not. The current code does this, and I think we need to retain this behaviour.
Damage multiplier = (100% + Bonus1 + ...) * (Penalty1 * ...)
Charge, no other modifiers:
Damage multiplier = (100% + 100%) * (no penalty) = 200%
Charge, 50% resistance:
Damage multiplier = (100% + 100%) * (50%) = * 200% * 50% = 100%
See, it does work appropriately with only +100% to bonus with charge, not multiplying the bonus itself.
Mathematically, distributing the bonus:
Damage multiplier = (100% * (Penalty1 * ...)) + (100%[from charge] * (Penalty1 * ...))
Every bonus is effectively multiplied by the penalties, so the penalties are fully effective. Multiple penalties don't reduce the damage in a ridiculous way (multiplying by below 0%, stopped only by minimum damage of 1, was caused by adding together penalties), and avoiding multiplying together the bonuses makes damages not become too huge. It is a very good scheme, IMO. Just try to understand how the formula really works and hopefully you'll understand...
Play a Silver Mage in the Wesvoid campaign.
I'm clearly failing to communicate my meaning, perhaps I can blame my poor phrasing on having to type into lynx via a high latency link.Invisible Philosopher wrote:Yeah, don't you understand how the system works? You're adding into the bonus, not the whole thing. Here are calculations using the correct scheme, with only +100% to bonus for charge.
A lawful charging unit currently does 250% damage during the day, not 225% as you seem to be suggesting. We should not change the current damage values too much, to avoid having to rebalance all the campaigns. I am proposing using Darth Fool's separation of bonuses and penalties, making bonuses additive and penalties multiplicative. However, we need to tweak this by ensuring bonuses are doubled for charging/backstabbing units, otherwise the current damage would be reduced. Are you suggesting that led charging units currently do too much damage?
This is a perl version of the kind of code I'm proposing (after corrections and more useful variable names):
Code: Select all
$bonus = 100; $penalty = 1.0;
if ( $percent > 100 ) { $bonus = $percent } elsif ( $percent < 100 ) { $penalty = $percent/100.0 }
if ( $_ > 0 ) { $bonus += 25*$_ } elsif ( $_ < 0 ) { $penalty *= (1.0 + $_/4.0) }
if ( $special =~ /backstab|charge/ ) { $bonus *= 2 } elsif ( $special =~ /steadfast/ ) { $penalty *= 0.5 }
$finaldam = int( ($bonus/100.0) * $penalty * $damage + 0.49999 );
$finaldam = 1 if $finaldam < 1;
Code: Select all
blade 10-3 backstab: Nightgaunt
against -25 0 25 50 75 100
--------------------------------------
armoredfoot 7 10 12 15 17 20 <- 1.71
deepsea 12 16 20 24 28 32 <- 1.67
drakefly 13 18 22 27 31 36 <- 1.69
drakefoot 12 16 20 24 28 32 <- 1.67
dummy0 30 40 45 50 55 60 <- 1.50
dummy1 1 1 1 1 1 1 <- 1.00
dwarvishfoot 10 14 17 21 24 28 <- 1.70
elusivefoot 19 26 31 36 41 46 <- 1.63
float 15 20 25 30 35 40 <- 1.67
fly 15 20 25 30 35 40 <- 1.67
largefoot 12 16 20 24 28 32 <- 1.67
lizard 15 20 25 30 35 40 <- 1.67
mountainfoot 15 20 25 30 35 40 <- 1.67
mounted 12 16 20 24 28 32 <- 1.67
naga 15 20 25 30 35 40 <- 1.67
none 12 16 20 24 28 32 <- 1.67
orcishfoot 15 20 25 30 35 40 <- 1.67
scuttlefoot 13 18 22 27 31 36 <- 1.69
smallfoot 15 20 25 30 35 40 <- 1.67
spirit 6 8 10 12 14 16 <- 1.67
swimmer 15 20 25 30 35 40 <- 1.67
treefolk 15 20 25 30 35 40 <- 1.67
undeadfly 15 20 25 30 35 40 <- 1.67
undeadfoot 13 18 22 27 31 36 <- 1.69
undeadspirit 6 8 10 12 14 16 <- 1.67
woodland 15 20 25 30 35 40 <- 1.67
woodlandfloat 15 20 25 30 35 40 <- 1.67
Code: Select all
blade 10-3 backstab: Nightgaunt
against -25 0 25 50 75 100
--------------------------------------
armoredfoot 5 10 15 20 25 30 <- 3.00
deepsea 11 16 21 26 31 36 <- 1.91
drakefly 13 18 23 28 33 38 <- 1.77
drakefoot 11 16 21 26 31 36 <- 1.91
dummy0 35 40 45 50 55 60 <- 1.29
dummy1 1 1 5 10 15 20 <- 5.00
dwarvishfoot 9 14 19 24 29 34 <- 2.11
elusivefoot 21 26 31 36 41 46 <- 1.48
float 15 20 25 30 35 40 <- 1.67
fly 15 20 25 30 35 40 <- 1.67
largefoot 11 16 21 26 31 36 <- 1.91
lizard 15 20 25 30 35 40 <- 1.67
mountainfoot 15 20 25 30 35 40 <- 1.67
mounted 11 16 21 26 31 36 <- 1.91
naga 15 20 25 30 35 40 <- 1.67
none 11 16 21 26 31 36 <- 1.91
orcishfoot 15 20 25 30 35 40 <- 1.67
scuttlefoot 13 18 23 28 33 38 <- 1.77
smallfoot 15 20 25 30 35 40 <- 1.67
spirit 3 8 13 18 23 28 <- 4.33
swimmer 15 20 25 30 35 40 <- 1.67
treefolk 15 20 25 30 35 40 <- 1.67
undeadfly 15 20 25 30 35 40 <- 1.67
undeadfoot 13 18 23 28 33 38 <- 1.77
undeadspirit 3 8 13 18 23 28 <- 4.33
woodland 15 20 25 30 35 40 <- 1.67
woodlandfloat 15 20 25 30 35 40 <- 1.67
I've added movetypes dummy0 and dummy1 representing 200 and 0 defense modifiers, respectively 0% and 100% defense, to show that the modified DF scheme gives sensible results even in these cases, whereas the current scheme results in large damage during the unit's favourable time of day, even against a unit with 100% defense against that attack.
I don't think the current pure additive scheme in 0.8.8 makes sense with high defense values, and I think it would be sad if all the high defense values in the game had to be removed because of a weakness of the damage algorithm that is easily fixed.
Could IP, EP or DF work out how your respective variations on DF's mixed additive/multiplicative proposal actually fare in this example? Nightgaunt is nice and easy to calculate with 10 damage per swing and backstab acting just like charge.
-
- Posts: 873
- Joined: July 4th, 2004, 9:14 pm
- Location: My imagination
- Contact:
You are correct about the current effects (for situations in which there are no penalties, at least), but who cares? That has only been true for a few versions, since we made charge and backstab multiplicative (0.8.4). The campaigns haven't even had time to be balanced with that, or if they had time, they weren't, mostly. Besides, this proposal is a somewhat big change, let's not leave hacky details in it that run counter to the goal of the idea. And 250% isn't so different from 225% that it would throw off balancing very much, assuming the campaign wasn't played with only horsemen.ott wrote:A lawful charging unit currently does 250% damage during the day, not 225% as you seem to be suggesting. We should not change the current damage values too much, to avoid having to rebalance all the campaigns.
Yes, that is the entire reason we made damage additive in the first place: units with too many bonuses did too much damage. If we don't care about them doing high amounts of damage, why aren't we just using multiplicative damage calculations for everything?ott wrote:Are you suggesting that led charging units currently do too much damage?
Contradictory. Either we use the scheme or we don't. Tweaks like that make the beautifully balanced scheme be wrecked and ruined beyond almost all use they had originally, sending them into a quagmire of complexity.ott wrote:I am proposing using Darth Fool's separation of bonuses and penalties, making bonuses additive and penalties multiplicative. However, we need to tweak this by ensuring bonuses are doubled for charging/backstabbing units, otherwise the current damage would be reduced.
Play a Silver Mage in the Wesvoid campaign.