D&D 4th Edition RulesAsk questions about 4th-Edition rules and the like in here. General discussion about 4E or any other game belongs in General RPG Discussion, above.
There's been a lot of criticism of the 4e "math" lately. No biggie, really, but one thing has been bugging me. The analysis is incredibly shallow--nothing more than comparing one number (of dozens!) to another--and it's combined with this bellicose attitude and slapping down of anyone that dares disagree. Ptui.
The 4e math may be broken, or it may not be. The existing analyses don't prove anything. Play experiences back up the opinion of whoever's speaking. I'd like something more substantial.
Besides, I'm a programmer. This is my idea of fun.
Okay, so the purpose of this thread is to do a stochastic analysis of the 4e math, using something called a Monte-Carlo simulation. Basically, what we do is write a program that simulates a 4e fight, random dice rolls and all, and we run it a few hundred thousand times. From that, we get a complete view of everything that can happen. Not just the average case, but full range of possibilities. Because it's a simulation, we can incorporate a lot more variables than the typical DPR calculation.
This is a big project, so I'll be taking it one piece at a time. I hope you'll join in with your comments. First up: a look at how many rounds it takes to kill a monster.
Last edited by Truename; 1st November 2009 at 11:25 PM..
Reason: Corrected 'First up' preview
A tool for 4e fight simulations and statistical experimentation would be pretty cool, although take note that if you try to simulate everything that can happen in a fight, your program would have an exponential asymptotic time complexity. Also, you'd have to implement the whole 4e rule system, which would be very hard to say the least. But if you start small and build up, you could produce some very cool things, especially if this is undertaken as a collaborative effort. So, yay!
A tool for 4e fight simulations and statistical experimentation would be pretty cool, although take note that if you try to simulate everything that can happen in a fight, your program would have an exponential asymptotic time complexity. Also, you'd have to implement the whole 4e rule system, which would be very hard to say the least. But if you start small and build up, you could produce some very cool things, especially if this is undertaken as a collaborative effort. So, yay!
There's a lot to do, for sure! I think the model will have to make some simplifying assumptions, but I've made good progress so far. I'm definitely hoping this will attract a lot of collaboration--it's too much work to continue if nobody else is interested.
This is a big project, so I'll be taking it one piece at a time. I hope you'll join in with your comments. First up: a look at basic hit probabilities.
Unfortunately, there's no way to derive a "basic scenario" for D&D combat given the range of characters that could be played and tactics that could be employed. There's enough variation in characters that the choices here will drive the conclusion. Monsters have some variation as well.
The question "Suppose I have a party with hit bonuses H who will use XYZ abilities in a preset order against monsters that all have defense M and equal hit points (and sit there without attacking back). What will their overall chance of hitting be?" would be more reasonably answered.
Let's start by looking at the difference between a stochastic analysis and a DPR analysis. For this one, we'll start very simply. The question we're analyzing: How many rounds does it take for a PC to kill a monster?
The PC: a level 1 dwarf great-weapon fighter, using Character Builder's recommended stats, wielding a maul. No feats or powers yet--just basic attacks.
PC Attack bonus: 7 (4 stat + 2 maul + 1 greatweapon)
PC Dmg dice: 2d6 (maul) + 4 (stat)
Character Builder summary
====== Created Using Wizards of the Coast D&D Character Builder ======
Dwarf-Fighter, level 1
Dwarf, Fighter
FINAL ABILITY SCORES
Str 18, Con 12, Dex 14, Int 10, Wis 13, Cha 8.
STARTING ABILITY SCORES
Str 18, Con 10, Dex 14, Int 10, Wis 11, Cha 8.
A DPR analysis of this fight says the monster lasts 4.6 rounds on average.
DPR breakdown
Avergae damage for maul: 2d6+4 = ((2 + 12) / 2) + 4 = 11
Crit damage for maul: 2d6+4 = 12 + 4 = 16
Roll to hit = 17 AC - 7 att bonus = 10
Chance to roll miss = (roll to hit - 1) / 20 = 45%
Chance to roll crit hit = 1 / 20 = 5%
Chance to roll normal hit = 1 - miss chance - crit chance = 1 - 45% - 5% = 50%
Average crit damage = crit chance * crit dmg = 5% * 16 = 0.8
Average hit damage = normal hit chance * normal dmg = 50% * 11 = 5.5
The stochastic analysis shows us something completely different. It says the average fight lasts 5.5 rounds, not 4.6. That's a significant difference... big enough that, if correct, pretty much invalidates DPR as a trustworthy approach.
Source code (in Ruby)
Code:
REPS = 1000000
PRECISION = 1
DISPLAY_WIDTH = 75
MONSTER_LEVEL = 1
MONSTER_CON = 13
PC_ATT_BONUS = 7
PC_DMG_BONUS = 4
class Monster
def initialize
@ac = MONSTER_LEVEL + 16
@hp = 8 + MONSTER_CON + (MONSTER_LEVEL * 8)
end
def dead?
return @hp <= 0
end
def defend(att, dmg)
@hp -= dmg if att >= @ac
end
end
class Pc
def attack(monster)
att_roll = die(20)
att = (att_roll + PC_ATT_BONUS)
dmg = damage(att_roll)
monster.defend(att, dmg)
end
def damage(att_roll)
dmg_dice = die(6) + die(6)
dmg_dice = 12 if att_roll == 20
return dmg_dice + PC_DMG_BONUS
end
end
def die(size)
return 1 + rand(size)
end
def fight
monster = Monster.new
pc = Pc.new
round = 0
until monster.dead?
round += 1
pc.attack(monster)
end
return round
end
def analyze
results = {}
total_rounds = 0
max_value = 0
REPS.times do
rounds = fight
results[rounds] = 0 unless results[rounds]
new_value = results[rounds] += 1
max_value = new_value if new_value > max_value
total_rounds += rounds
end
results.keys.sort.each do |key|
value = ""
ticks = (results[key].to_f / max_value.to_f * DISPLAY_WIDTH).to_i
ticks.times do
value += "="
end
puts "#{key.to_s.rjust(2)}: #{value}" if value != ""
end
avg_rounds = total_rounds.to_f / REPS
format = "%.#{PRECISION}f"
puts "Fights simulated: #{REPS}"
puts "Average # of rounds per fight: #{format % avg_rounds}"
end
analyze
Why the difference? I'm not entirely sure. (Hopefully it's not a bug! That's why I included the source code.) I think it's partly because, in a real fight, some damage is "wasted" after the monster hits zero HP.
The Monte Carlo analysis also gives us a histogram that summarizes all of the fights. For this simulation, I ran a million fights. 'Cause I could.
Code:
LEVEL 1 SOLDIER VS. DWARF GREATWEAPON FIGHTER (no feats, no powers)
2 (2.3%): =======
3 (18.0%): ==================================================
4 (38.7%): ===================================================================
5 (57.8%): =============================================================
6 (72.6%): ===============================================
7 (83.0%): =================================
8 (89.8%): =====================
9 (94.0%): =============
10 (96.6%): ========
11 (98.1%): ====
12 (99.0%): ==
13 (99.4%): =
Fights simulated: 1000000
Average # of rounds per fight: 5.5
So, although the average # of rounds is 5.5, the majority of fights take 4 rounds. Over 80% of fights take 7 rounds or less to complete, although a very small fraction of this simulation's fights dragged on and on, presumably due to lots of bad rolls.
You can see how the Monte Carlo simulation gives us a much richer, more accurate analysis than the DPR approach. And we're just barely getting started. Next up: feats, powers, and monsters that actually fight back!
Let's start by looking at the difference between a stochastic analysis and a DPR analysis. For this one, we'll start very simply. The question we're analyzing: How many rounds does it take for a PC to kill a monster?
The stochastic analysis shows us something completely different. It says the average fight lasts 5.5 rounds, not 4.6. That's a significant difference... big enough that, if correct, pretty much invalidates DPR as a trustworthy approach.
As you say, that you can "overkill" the monster is the reason why HP/DPR doesn't equal average rounds to kill the monster. Average rounds to kill the monster must be weakly higher than this figure. You can see a lot more discussion of this here
As you say, that you can "overkill" the monster is the reason why HP/DPR doesn't equal average rounds to kill the monster. Average rounds to kill the monster must be weakly higher than this figure. You can see a lot more discussion of this here
Interesting stuff. Most of it went over my head, I'm afraid--I'm a programmer, not a mathematician, and I don't know much about statistics. I hope you'll contribute your expertise to this thread, too.
The stochastic analysis shows us something completely different. It says the average fight lasts 5.5 rounds, not 4.6. That's a significant difference... big enough that, if correct, pretty much invalidates DPR as a trustworthy approach.
No, no. The DPR analysis works just fine because its being compared to other DPR values. The relative relationship between two character's DPR calculations and the relative relationship between their "rounds of combat" calculations should be so similar as to be indistinguishable in casual discussion.
Try an example, done mathematically. You've got character A, and character B, with DPRs of 9 and 7, respectively. DPR wise, we expect character A to kill monsters approximately 28.6% faster than character B.
Now imagine they're each fighting a monster with 60 hp.
Using what you call the DPR approach, we expect Character A to kill the monster in 6.667 rounds. But if we were to make our analysis more specific, we'd determine that Character A expects to kill the monster in 7 rounds- 6 rounds to get to 54 damage, then one more to get to 63. The remainder is rounded up to the nearest whole number.
Using what you call the DPR approach, we expect Character A to kill the monster in 8.571 rounds. But if we were to make our analysis more specific, we'd determine that Character A expects to kill the monster in 9 rounds- 8 rounds to get to 56 damage, then one more to get to 63.
Well, lets check our ratios to see whether these forms of analysis generated significantly different outcomes.
For reference and full disclosure, lower hit points and higher damage (ie, fewer rounds needed to kill the monster) will generate more variability in the comparison of the DPR and Round analysis. This is because the remainder makes up a larger portion of the division of HD/DPR.
Using a mathematical expression for the round analysis instead of relying on DPR as an average will also introduce more variability. But that variability averages out and shouldn't affect overall conclusions.
There are some other possible sources of variability. For instance 2d6 vs 1d12 damage weapon, which Monte Carlo will show slightly different population standard deviation for in length of number of rounds.
Personally I'm not sure that Monte Carlo REALLY matters a huge amount, though it is true that the distribution is added information. However the really interesting stuff is going to be sets of opponents and then you get into the murky waters of what are the effects of tactics. You can reduce the battle down to the blows struck and abstract tactics in terms of simply opportunities to attack, etc, but how do you account for the fact that the evolving nature of the battle itself feeds back into how it plays out?
Even taking a simple battle with say 3 opponents on each side where they are all roughly similar creatures with basic melee attacks. Now you can pretty well model that abstractly, everyone is going to get to swing at somebody and who wins is likely to be decided almost entirely on which side focuses its attacks better. I don't think you'll learn a LOT more with this kind of scenario than with one-on-one fights.
But what would be a step up from that? Lets say one side has a creature that can deploy an area attack. How many of the enemy can it hit on each attack? Is this going to affect how much the other side groups its units together (presumably they need to be close to each other to all concentrate on one target). Exactly what is going to happen now is going to depend highly on exactly who moves where and when. So you can run that fight 1 million times and determine the effects of tactics randomly, but the veracity of the result depends on how true your "random effects of tactics generator" is to what happens in real games.
I kind of fear that by the time you get to something approaching the level of complexity of a level 1 party fighting a level 1 encounter with some typical monsters the number of guestimations required to do that "effects of tactics" is going to be large and nobody will ever know how accurate it is, except by actually collecting data from real combats.
And I think that is really the ultimate key. This is an area where nothing is going to beat real world data. Still, it could shed some light on certain very specific questions. I just think people would have to go back and do some sanity checking against real world data all the same.
No, no. The DPR analysis works just fine because its being compared to other DPR values. The relative relationship between two character's DPR calculations and the relative relationship between their "rounds of combat" calculations should be so similar as to be indistinguishable in casual discussion.
Good point.
Quote:
Originally Posted by Cadfan
Try an example, done mathematically. You've got character A, and character B, with DPRs of 9 and 7, respectively. DPR wise, we expect character A to kill monsters approximately 28.6% faster than character B.
Now imagine they're each fighting a monster with 60 hp.
Using what you call the DPR approach, we expect Character A to kill the monster in 6.667 rounds. But if we were to make our analysis more specific, we'd determine that Character A expects to kill the monster in 7 rounds- 6 rounds to get to 54 damage, then one more to get to 63. The remainder is rounded up to the nearest whole number.
Using what you call the DPR approach, we expect Character A to kill the monster in 8.571 rounds. But if we were to make our analysis more specific, we'd determine that Character A expects to kill the monster in 9 rounds- 8 rounds to get to 56 damage, then one more to get to 63.
I agree with your overall point. Just for fun, let's run it through my simulator.
First, I have to find real stats that give the DPR you're talking about. I chose a monster with AC 18 and 60 HP.
Character A: att +10 for 1d12 + 7 dmg = 9.05 dpr = 8.5409 rounds to kill
Character B: att +7 for 1d12 + 7 dmg = 7.025 dpr = 6.6298 rounds to kill
You can see how the Monte Carlo simulation gives us a much richer, more accurate analysis than the DPR approach. And we're just barely getting started. Next up: feats, powers, and monsters that actually fight back!
I think you should cut to the chase.
I don't know of anyone who is claiming that Level 1 math is bad.
Try Level 15, Level 20, Level 25.
See if the encounters last 5.5 rounds then.
__________________ The first sign of a broken rule is when someone suggests that the way to stop it is by readying an action.
I'm very interested in seeing your work on this, but I have to admit, that to my mind, the stochastic analysis will "simply" be giving a more accurate analysis of the same variables that a DPR calculation tries to analyze. While that more accurate analysis will certainly be more useful than DPR, I don't think it will (given the level of complexity you are likely to be able to model) be able to give us anything approaching a mathematically rigorous analysis of a whole D&D combat.
Even given a fight simply between two combatatants, the confounding variables of terrain, condition- and movement-inflicting powers, etc. will, I think, swamp the analysis.
Then, on top of all of those things, you have to consider the impact of player knowledge and judgement on tactics. Will the player use high-damage attacks at optimal times, when the damage will not be wasted, or will he use a high-damage power later in the fight, when it will result in wasted damage? Will a player recognize an optimal tactic, or use a suboptimal one instead? How would you calculate the chances of using suboptimal tactics in each fight?
Again, I think that the work you are doing (for FREE!) is going to be nothing but a very generous benefit for all (as I can't see any way in which it would do anything but give us MORE relevant data than a DPR analysis), but I also just don't see it as being an accurate model of a D&D fight.
I don't know of anyone who is claiming that Level 1 math is bad.
Try Level 15, Level 20, Level 25.
See if the encounters last 5.5 rounds then.
That's the ultimate goal, but it's going to take a lot of work to get there. The big question I want to answer is, "is the (year 1) math actually balanced across 30 levels?" But I can't answer that without simulating a lot of feats and powers, not to mention multiple characters, positioning, and conditions.
As a few people have mentioned, if all we're doing is a glorified DPR calculation, there's not much point. The real question is, how does each encounter consume the PCs' valuable resources?
To start answering that question, I first added the ability for the monster to fight back. So far, I haven't added initiative rolls, so the creatures act simultaneously--both the monster and the PC get an attack every round even if one of them is killed. (In other words, I only check if someone died at the top of the round.)
Same characters as before, but I added some new stats to the sim:
PC AC: 17
PC HP: 27
Monster attack bonus: 3
Monster damage: 1d10 + 3
Under these circumstances, the PC dies 21.6% of the time, and takes no damage at all 13.1% of the time. The fights are over a little more quickly because if the PC can't mop up the monster in a decent amount of time, the monster mops up the PC.
There's an interesting spike at the 14hp mark--for some reason, taking exactly 13 damage is the most common damage, if you're damaged at all. I presume that's because it's critical damage--it's not that criticals are more common, but that critical damage is non-random, making it jump out of the noise more.
Similarly, I presume hp of 11-13 and 24-26 is uncommon because the monster always deals at least 4 damage.
No, no. The DPR analysis works just fine because its being compared to other DPR values. The relative relationship between two character's DPR calculations and the relative relationship between their "rounds of combat" calculations should be so similar as to be indistinguishable in casual discussion.
This may be the case when working with simple examples, but as you hint at below, it's not going to hold when comparing, say, crit-centric builds to builds that deal miss damage. The miss damage builds look worse in dpr than they do in average rounds to kill an opponent.
Also, the average number of rounds to kill an opponent isn't all you care about. The players win almost every fight, so variance in general works against them. For example, you'd rather kill the monster in 5 rounds every time than an even chance of 3 through 7 rounds. This again favors builds with low damage variance, given the same dpr for each.
To repeat the link I posted above, there's a lot more discussion of this here.
Up until now, we've only been using basic attacks... no wonder our PC dies a fifth of the time. It's time to make things more realistic.
For my level 1 feat, I chose Dwarven Weapon Training, and also upgraded my maul to a mordencrad. This bumped my death rate down to 16.6% and helped bring down the amount of combat time as well. Now the most common combat is 3 rounds long, with an average of 4.3.
Next I replaced my basic attack with the at-will "Reaping Strike." I haven't bothered programming in the other at-will yet (I chose Cleave) because there's only one enemy.
Reaping Strike really helped. Survivability is way up (death happens 6.6% of the time) and combat time is even lower. I attribute this to Reaping Strike's fantastic 'miss' power, which helps reduce the variability of combat. The monster's going down eventually.
The final touch, though, was to implement Second Wind. Ready access to healing is one of the major things that separates PCs from monsters. Since second wind is a minor action for dwarves, it's essentially free (given that there's no other minor actions in play yet). I programmed the dwarf to spend the surge as soon as none of it would be wasted.
While I was at it, I also programmed in short rests. The dwarf tries to maximize his hit points during the short rest, but doesn't want to waste surges either. He's willing to spend a surge if he'll get at least 3/4 of the hit points from it. (In other words, he'll spend an 8-hp healing surge even if he only needs 6 hit points to hit max, but that's as far as he'll go.)
With the new healing ability, our hero is very resilient. He only dies 3% of the time, and easily heals back up to full after each encounter. Now the question isn't how long the fight took, or whether he'll survive, but how many surges the encounter consumed.
We have the dwarf's at-will abilities, but what about encounters and dailies? I programmed those next.
First, the encounter. I chose Steel Serpent Strike because it was the only PHB power that did additional damage. The others all apply conditions, and I'm not ready to simulate the effects of conditions yet.
I programmed the dwarf to use the encounter power right away, on the assumption that it didn't really matter when he used it.
Surprisingly, the encounter power didn't make much difference! The death rate is actually up slightly, presumably due to the lack of Reaping Strike's excellent miss effect. However, it does make fights go faster, and you consume fewer resources as well.
I also ran this scenario against higher-level opponents. When I did that, the encounter power made a much bigger difference, and the chance of death did go down.
Next was the daily power. I chose Brute Strike. To simulate resource hoarding, I decided the dwarf would only use his daily when things were "desperate"--in this case, when he was bloodied.
Again, it didn't make much difference--presumably because the level 1 opponent isn't much of a threat, and the power rarely gets used. (It's a reliable power, so low usage doesn't necessarily mean it wasn't actually attempted more often.)
Bottom line: the big guns don't make much difference against low-power opponents. They're much more interesting against higher-level opponents. More on that in the next post.