CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.25k stars 4.11k forks source link

Effective engagement ranges #17643

Closed mugling closed 7 years ago

mugling commented 8 years ago

Summary

Effective range of guns is too low and unaffected by weapon type, skill, gunmods or aiming

If we define effective range as a 50% chance of a good hit on the first shot then effective range for the following guns used at different stages of the game is:

item early mid late
Glock 19 3 3 3
MP5 3 3 3
AR-15 4 4 4

This explains why in DDA everyone walks around with a shotgun and a big handgun and engages targets at point-blank range. Rifles in particularly are especially useless.

The algorithm (with code sources) is set out below or otherwise skip to Plan.

Proof

Dispersion (σ) is expressed in minutes of arc and is the sum of penalties from the player and their weapon. Player penalties are calculated as follows:

# Weapon and marksmanship skill 
(10 - WEAP) * 45  # Character::skill_dispersion()
(10 - GUN ) * 15  # Character::skill_dispersion()

# Player stats
(12 - DEX) * 15   # Character::ranged_dex_mod()
(12 - PER) * 15   # Character::ranged_per_mod()

# Clothing encumbrance
EYES  * 6         # player::get_weapon_dispersion()
HANDS * 6         # player::get_weapon_dispersion()

An additional penalty applies for recoil. The default is MIN_RECOIL of 150 with lower values achieved by aiming and higher values resulting from recoil.

We can calculate player dispersion (σ) for some typical survivors:

description GUN WEAP DEX PER EYES* HANDS^
S1 early game 2 2 8 8 5 0 630
S2 mid game 4 4 8 8 10 5 570
S3 late game 6 6 9 9 15 10 510

* safety goggles, light survivor mask, heavy survivor mask ^ fingerless leather gloves, light survivor gloves, survivor gloves

Weapon dispersion (Wσ) is simply the sum of the gun and ammo dispersion:

description GUN AMMO
G1 Glock 19 240 140 380
G2 MP5 150 140 290
G3 AR-15 5 80 85
G4 700NX + scope 60 15 75

Chance to hit (k) is calculated in Creature::projectile_attack as:

σ = Pσ + Wσ + recoil 
t = π / 180 / 60 * 0.745
k = range * σ * t

Excluding monster dodges this is applied in Creature::deal_projectile_attack:

k result multiplier
< 0.1 headshot 2.45 - 3.35
< 0.2 critical 1.75 - 2.30
< 0.4 good hit 1.00 - 1.50
< 0.6 0.50 - 1.00
< 0.8 grazing 0.00 - 0.25

Dispersion is applied randomly so resuming an even distribution the typical effective dispersion (x̄σ) will be half and is calculated as follows:

x̄σ = ( Pσ + Wσ + recoil ) / 2

The below shows average dispersion (x̄σ) for some combinations:

description recoil* S1 S2 S3
G1 Glock 19 380 150 579 550 525
G2 MP5 290 150 536 506 476
G3 AR-15 85 150 432 402 372
G4 700NX + scope 75 0 352 322 292

* G1-G3 'from the hip' whereas G4 is after maximum aiming

If we define effective range as a 50% chance to yield a good hit (k<0.4) on the first shot each of the following combinations has the following effective ranges:

description S1 S2 S3
G1 Glock 19 3 3 3
G2 MP5 3 3 3
G3 AR-15 4 4 4
G4 700NX + scope 5 5 6

These values are of course all (much) lower on subsequent shots due to the effects of recoil. I've included G4 as it illustrates both gunmods and aiming having very little overall effect.

Plan

Comments as to the following or alternative suggestions:

TODO

Firestorm01X2 commented 8 years ago

Finally someone pointed on this issue.

TempestMaiden commented 8 years ago

Hold on. Isn't "sight dispersion" a cap on how low the player can reduce recoil, not an additional source of fixed dispersion of its own?

But in general I'd have to agree that gun ranges leave something to be desired - throwing daggers shouldn't have significantly longer lethal ranges than SMGs.

mugling commented 8 years ago

Hold on. Isn't "sight dispersion" a cap on how low the player can reduce recoil, not an additional source of fixed dispersion of its own?

Good point - I've updated the above charts to represent this

mugling commented 8 years ago

Using the following definitions:

effective range As 50% chance of a good hit (k<0.4) on the first shot at S2

maximum range A 50% chance of any hit (k<0.8) after maximum aiming at S2

The current situation is as follows:

example effective maximum
pistol Glock 19 3 7
SMG MP5 3 7
carbine M4A1 4 10
rifle M1 Garand 5 11

Note this is for the first shot only - subsequent shots will be much worse due to recoil. Also at maximum range many hits will do only 1-2 points damage even for otherwise good ammo.

What should these values be?

DeadLeaves commented 8 years ago

Not sure for the close range weapons, but for the longer range weapons its straight out silly that you cannot hit at longer distances. 15-20 squares at least for the rifles. I once ran a bionic sniper just to try it out, and trying to snipe was still useless even when taking into account the massive bonuses you have as that profession. With like 5 marksmanship and 5 rifles and I still have a hard time hitting STATIONARY turrets at military outposts with a scoped M82 and doing precision shots at distances like 20 squares

mugling commented 8 years ago

but for the longer range weapons its straight out silly that you cannot hit at longer distances. 15-20sqaures at least for the rifles.

One possible route is to bump MIN_RECOIL up and then allow rifles to aim more than pistols. Requiring them to aim to achieve long distance shots is both realistic and helps maintain balance as after the first shot your recoil is too high for you to take a second (long range) one any time soon whilst still allowing some shorter range use

nikheizen commented 8 years ago

Pistols are probably fine as is. SMGs could do with either slightly increased range (5/10?) and/or heavily reduced recoil effect. You should be able to go full auto with an SMG, multiple rounds in a row and ream anything which isn't heavily armoured up close. Rifles should definitely have an effective range of 15-20 squares and a max range of 30-35. Carbines should have maybe 70% of this range.

Making aiming considerably more effective on longer ranged weapons is another good way of handling this. At 20 squares or so you have enough time.

mugling commented 8 years ago

max range of 30-35.

That's nearly a 10-fold increase on the current values and possibly too much although at maximum range your typical damage output is only 20% of effective range

nikheizen commented 8 years ago

10-fold increase

35 / 11 ~= 10 ?

Agree that it is probably too much though. My terminal wouldn't even be big enough to see what I'm shooting unless I displace my screen horizontally all the way. You should definitely be able to hit mobs ~20 or so tiles away with aiming an a good rifle though.

mugling commented 8 years ago

10-fold increase

Sorry my bad, I had compared the wrong numbers

Firestorm01X2 commented 8 years ago

Maybe high skilled shooter should have effective range equal to maximum range (but only if shooter have time to aim).

I mean maybe it will be easier and much more logically to just increase effect of weapon skill on ability to hit target and at the same time increase aiming time.

kevingranade commented 8 years ago

In general I agree, but I think you're "overshooting" a bit, in particular you're treating firing "from the hip" as a valid use case, it isnt. A 50% chance to get a "good" hit at a range of roughly two meters sounds about right for a beginner (skill levels at 2) irl, but since our shooting distances are (intentionally) compressed, if anything it's too good.

The balance point should be around "aimed" shots (potentially also considering "careful" and "precise").

The raison d'etre for the current aiming system is to limit firing rate, especially the time between movement and firing, because previously "run and gun" tactics were way too good.

Use cases (and ideally unit tests) around firing accuracy/range/etc should include: Target parameters (size, dodging) Distance to target Shooter abilities and penalties Gun parameters Shooter starting state (standing, moving, running, weapon holstered, weapon out, in shooting stance, braced, prone) Time to aim Desired outcome (definite hit, good hit, crit, high DPS, etc)

If we're making any comparisons to real-world distances, we also need a scaling factor for converting between irl and in game distances.

This is a lot of parameters, but neglecting some if these is going to result in an incomplete rebalance meaning the whole thing will have to be revisited later anyway. A lot of them can be specified with in-game entities, which cuts down the configuration space. Some more can be handled like you have already by specifying early/mid/late game survivor templates.

A basic example: Target: zombie Distance: 5 tiles (orthoganal) Shooter: early game Shooter (slvl 2, OK stats, light encumbrance) Weapon: Glock 19 (unmodded) Start: standing, gun ready but not aimed Time to aim: 2 seconds Desired outcome: 50% chance of good hit

Target: brute Distance: 40 tiles Shooter: late game Shooter (slvl 8, OK stats, light encumbrance) Weapon: browning blr (hunting rifle with scope) Start: weapon ready, prone Time to aim: unlimited Desired outcome: 99%+ chance of headshot

Increasing max aim and requiring much more time to aim for long distance shots sounds like a good idea for handling rifles. Also I'd be fine with dismantling my goofy multi-sight handling logic, which would mean guns configured for sniping would be even worse for close quarters, which is good. I was trying to avoid the situation where "upgrading" a gun makes it worse in critical ways, but in retrospect that was a bad idea.

mugling commented 8 years ago

Use cases (and ideally unit tests) around firing accuracy/range/etc should include:

This is the intention behind the definitions S1, S2, S3 etc and effective and maximum range. I'd like to work out agreed definitions...

Use cases (and ideally unit tests)

...then connect these to the stats dumper - especially as it can output to TSV for spreadsheet-fu. This should allow us to quickly identify any regressions as we work on this. Once it's worked out I might look at doing formal unit tests.

The balance point should be around "aimed" shots (potentially also considering "careful" and "precise").

in particular you're treating firing "from the hip" as a valid use case,

It's probably one of the most common use cases - a zombie suddenly appears. One possible option to maintain sane balance is to make more use of aim_speed. It's reasonable that a pistol should be quick to aim versus a rifle?

If we're making any comparisons to real-world distances, we also need a scaling factor for converting between irl and in game distances.

Might be best to avoid to avoid absolute distances as tiles vary in scale if their indoor vs outdoor. We can try and maintain relative proportion between different guns though.

Also I'd be fine with dismantling my goofy multi-sight handling logic, which would mean guns configured for sniping would be even worse for close quarters, which is good.

I don't think it's actually the cause of the problem. It's reasonable to have both a rail laser and scope. The issue is that the system isn't very intuitive to the player. It might be worth converting a lot of our display units from arc minutes to tiles or something of that nature

TempestMaiden commented 8 years ago

One obvious use case that should be considered:

It should be entirely possible for a gun-armed player to kill shockers or spitters from beyond their special attack range, at some level of skill; for throwing daggers this is possible at (and probably a bit before) throwing 7.

What requirements (in skills and equipment) should there be for firearms to do the same?

DeadLeaves commented 8 years ago

That really depends on the weapon. A survivor with relatively good weapon. say a rifle with a scope, should clearly if given time be able to take out such zombies. In fact this might be one of very few reasons I'd ever chose something like a rifle at all. And also one of the reason I only ever use sniper-ish weapons at immobile targets like turrets as it is now.

kevingranade commented 8 years ago

Use cases (and ideally unit tests) around firing accuracy/range/etc should include:

This is the intention behind the definitions S1, S2, S3 etc and effective and maximum range. I'd like to work out agreed definitions...

Yep, just trying to clarify things.

Use cases (and ideally unit tests)

Connect these to the stats dumper - especially as it can output to TSV for spreadsheet-fu. This should allow us to quickly identify any regressions as we work on this. Once it's worked out I might look at doing formal unit tests.

Unit tests should come first. It validates our assumptions about how stats interact with the game code, provides a way to specify our end goals in an unambiguous way, and sets the priority of completion correctly (i.e. more important than the actual change, which it is). If you make changes and then write unit tests that pass, you're just documenting how it works now, which is entirely different from setting goals and then making changes to meet them.

The balance point should be around "aimed" shots (potentially also considering "careful" and "precise").

in particular you're treating firing "from the hip" as a valid use case,

It's probably one of the most common use cases - a zombie suddenly appears.

Just because players want to react immediately doesn't mean they should be able to. Taking time to aim is one of the biggest disadvantages of guns vs melee weapons in close quarters, and we should preserve that.

One possible option to maintain sane balance is to make more use of aim_speed. It's reasonable that a pistol should be quick to aim versus a rifle?

Absolutely, pistols should mitigate the aim speed penalty somewhat, but guns should never be as fast as melee weapons in general (there are outliers on both sides). Another thing we could adjust is how quickly aiming increases aim, currently it increases by a fixed amount per tick (adjusted by sight type), but to make fine aiming harder to achieve, we could for example make the improvement per tick reduce based on the current aiming level.

If we're making any comparisons to real-world distances, we also need a scaling factor for converting between irl and in game distances.

Might be best to avoid to avoid absolute distances as tiles vary in scale if their indoor vs outdoor.

Tile sizes do not vary, ever. Yes our map features have wacky sizes, but we do not treat indoor tiles differently from outdoor tiles.

We can try and maintain relative proportion between different guns though.

The only reasonable way to do this I know of is to link weapon ranges to their irl counterparts and then scale it. Having said that, there's no pressing need for this set of changes to do this, I just wanted to mention it because people are very likely to provide irl based use cases.

Also I'd be fine with dismantling my goofy multi-sight handling logic, which would mean guns configured for sniping would be even worse for close quarters, which is good. I don't think it's actually the cause of the problem. It's reasonable to have both a rail laser and scope. The issue is that the system isn't very intuitive to the player.

I don't think it's a cause, but it's a confounding variable and it reduces the distinction between pistols and rifles.

It might be worth converting a lot of our display units from arc minutes to tiles or something of that nature

I'm against, MoA is a standard when talking about gun accuracy, and it translates directly into the game with no adjustment.

It should be entirely possible for a gun-armed player to kill shockers or spitters from beyond their special attack range, at some level of skill;

Yes, but this should happen by scaling shocker/spitter ranges, not gun ranges.

mugling commented 8 years ago

Unit tests should come first.

To clarify these would be failing unit tests that we then adjust the code to pass? If so that could work well.

I'm against, MoA is a standard when talking about gun accuracy, and it translates directly into the game with no adjustment.

Sure but I can't do that amount of trig in the preamble without a calculator. MOA is a good comprative unit for guns, gunmod and ammo but perhaps an additional display along the lines of 'this gun has an effective range of x and maximum range of y' would be very helpful for new players.

kevingranade commented 8 years ago

Unit tests should come first.

To clarify these would be failing unit tests that we then adjust the code to pass? If so that could work well.

Yes, precisely this, the tests would be assertions of how we think it should work.

I'm against, MoA is a standard when talking about gun accuracy, and it translates directly into the game with no adjustment.

Sure but I can't do that amount of trig in the preamble without a calculator. MOA is a good comprative unit for guns, gunmod and ammo but perhaps an additional display along the lines of 'this gun has an effective range of x and maximum range of y' would be very helpful for new players.

I thought you meant replacing it, effective and maximum range derived stats would be great.

Coolthulhu commented 8 years ago

Reminder that this exists:

if( !gun.ammo_effects().count( "SHOT" ) ) {
    const item *parent = gun.is_gunmod() && has_item( gun ) ? find_parent( gun ) : nullptr;
    dispersion *= std::max( ( ( parent ? parent->volume() : gun.volume() ) / 3.0 ) / range, 1.0 );
}

This means that any gun with "expected range" of 4 must have volume no larger than 12.

Also, the biggest problem here is not absolute accuracy being too low/too high. It's the fact that accuracy itself is a sum rather than a product (or result of some other kind of accumulation) and is then multiplied by range (linearly). As a result:

We really need a dodge penalty on ranged attacks vs. dodgy critters. The one that calculates off bullet speed doesn't count, it isn't implemented properly yet since it is calculated off bullet speed.

mugling commented 8 years ago

What is the magic constant 0.745 in Creature::projectile_attack?

Coolthulhu commented 8 years ago

A way of preserving balance when changing units. Before, it was there in an implicit form, only indicated in a comment. Now it's explicit.

mugling commented 8 years ago

What was the change from and to? I'm trying to rework it as more standard isosceles trig so I wanted to either drop or rename that constant.

Coolthulhu commented 8 years ago

Not sure, it "was always there". It might also have been a way of approximating the tangent (badly).

If you want to drop it, make sure the results don't get worse (less accurate) in the process. They're wild enough as it is, so magic constant is better than replacing it by 1.

mugling commented 8 years ago

It might also have been a way of approximating the tangent (badly).

It approximates a² = b² + c² - 2bc cosθ but the extra obscurity doesn't seem worth it versus just using the cosine formula

kevingranade commented 8 years ago

On Jul 11, 2016 5:22 PM, "Coolthulhu" notifications@github.com wrote:

Reminder that this exists:

if( !gun.ammo_effects().count( "SHOT" ) ) { const item parent = gun.is_gunmod() && has_item( gun ) ? find_parent( gun ) : nullptr; dispersion = std::max( ( ( parent ? parent->volume() : gun.volume() ) / 3.0 ) / range, 1.0 ); }

This means that any gun with "expected range" of 4 must have volume no larger than 12.

I'd be perfectly happy with this being replaced by something more sensible like aim speed being modified by weapon weight or volume.

Also, the biggest problem here is not absolute accuracy being too low/too high. It's the fact that accuracy itself is a sum rather than a product (or result of some other kind of accumulation) and is then multiplied by range (linearly).

Need an alternative that still makes sense, "it shouldn't be a sum" by itself doesn't help. I'm not trying to reject your point outright, just start a conversation about it.

As a result:

Point blank attacks are nearly always the best

This should be the case. The only down side to firing at point blank is the risk of letting yourvenemy get close. The only sensible way to correct for this is to accentuate the risks of letting monsters get close.

Accuracy rises sharply near the endgame, but will never be enough for sniping by midgame (unless we count 6 tiles shotgun attacks as sniping)

To snipe, you need: A low dispersion gun (most rifles will qualify)

Gunmods have an extremely disproportionate effect on accurate guns (shotguns) compared to inaccurate guns. This is both bad for balance and for realism (a good grip should help more with a gun that "kicks", not less).

This is because grips and some other gunmods have gotten a pass on the general principle that everything contributes to dispersion, and all you can do is eliminate sources of it. Grips are allowed to compensate for arbitrary sources of dispersion. If we can add a heuristic for how much dispersion in a particular gun stems from bad grips, and only allow improved grips to compensate for that portion of it.

Aiming only really makes sense when you aim to 100% achievable accuracy. There are no snapshots, except when counting moves. To fix this, aiming speed would have to depend way more heavily on current recoil (of the player), possibly linearly

You're saying make aiming slower with higher recoil, or faster with higher recoil? The latter is what I meant by, "one thing we could adjust is how quickly aiming increases aim". Now that I read that again, it's really unclear, what I mean is spending more move points per point of dispersion as dispersion gets small. Basically more diminishing returns for finer aiming, and it also extends the range of useful times that can be spent aiming. At the other end of the scale, this implies that going from, "holding gun" to, "gun pointed in general direction of target" is nearly instantaneous (but not instantaneous to overcome automatic fire).

We really need a dodge penalty on ranged attacks vs. dodgy critters. The one that calculates off bullet speed doesn't count, it isn't implemented properly yet since it is calculated off bullet speed.

Agreed, I thought we had one based on monster speed too, as an analogue for dodginess.

BTW, it's laundry lists of issues like this that make me want to base any rebalance on acceptance tests, discussion just breaks down for an issue this complex, and details get lost.

Coolthulhu commented 8 years ago

This should be the case. The only down side to firing at point blank is the risk of letting yourvenemy get close.

A moving target close up needs faster movement to keep the aim on the target, can predict where you aim and avoid that and makes it impossible to rely on sights. This isn't adequately represented in the current system, where a rifle scope improves the odds of scoring a headshot at point blank.

Point blanks shouldn't be the best thing around vs. dodgy enemies that, when up close, move faster than you can aim. For example, manhacks.

If we can add a heuristic for how much dispersion in a particular gun stems from bad grips, and only allow improved grips to compensate for that portion of it.

Even something as simple as "25% of base dispersion" would be fine. The problem is only really bad for very accurate guns, such as shotguns.

Now that I read that again, it's really unclear, what I mean is spending more move points per point of dispersion as dispersion gets small.

This would work if it got really high by the end. The problem with current aiming is that you're almost always better off aiming perfectly.

I thought we had one based on monster speed too, as an analogue for dodginess.

We have/had it in 3 different "incarnations":

kevingranade commented 8 years ago

This should be the case. The only down side to firing at point blank is the risk of letting your enemy get close.

A moving target close up needs faster movement to keep the aim on the target, can predict where you aim and avoid that and makes it impossible to rely on sights.

My mistake, I was over focusing on dispersion from gun/skill versus aim dispersion. I agree that aiming should have a mechanic where monster movement/dodging interferes with it.

This could either be an effect acquired when moving, or a passive property of the monster.

If we can add a heuristic for how much dispersion in a particular gun stems from bad grips, and only allow improved grips to compensate for that portion of it.

Even something as simple as "25% of base dispersion" would be fine. The problem is only really bad for very accurate guns, such as shotguns.

Yeah, simple is fine, and it's certainly not worth a new gun stat.

Now that I read that again, it's really unclear, what I mean is spending more move points per point of dispersion as dispersion gets small.

This would work if it got really high by the end.

Yeah, it could get all the way out to a turn or more to extend effective range by another square, which is perfectly fine if it allows you to take shots effectively outside of combat.

mugling commented 8 years ago

it's laundry lists of issues like this that make me want to base any rebalance on acceptance tests,

Agreed, I have a near-working branch I'm hoping to push today that wraps some of the trig math into the startings of unit tests

mugling commented 7 years ago

Done