-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Weakpoints #51305
Comments
Thanks for writing this up! There's a lot more depth to armor gaps than I first thought. I agree with much of what you wrote, and I have a few thoughts about the first pass:
Please let me know what you think, or if I misinterpreted anything. |
When they get hooked up to skills, I think it would be useful to add a |
Yeah I'm actually trying to write a new skill and weapon effect algorithm and would like that to be part of it. Even if coverage just accepted melee and range as separate arguments in fact. |
Adding separate melee / ranged coverage values shouldn't be too hard. Most of the wiring needed will be handled as a part of the "skill based hit chance" feature. I opened a separate issue (#51482) to discuss the hit chance formula. I have some rough ideas on what the formula should look like, but I'm not completely decided. |
I very much agree with the idea that weakpoints should exist, should make combat less deterministic, which is always a great thing. I am curious, however, why the existing coverage system was not applied to the armor of creatures, the same way it would be applied to players. |
Monsters don't have limbs (beyond some effect weirdness) or actual armor, and the consensus is that that also won't be a thing. |
Sorry, allow me to clarify. What I meant is not that items should exist on monsters, but rather that the concept of 'coverage' could be used to produce a unified conceptual framework that would apply to players or monsters. I guess I see a lot of value in a unified system, where attacking or being attacked occurs using the same basic rules. It also would seem to be much easier to create. Of course, I'm not the one doing the creating, so I suppose any shovel which moves dirt is a good shovel. |
Monsters are a lot simpler than characters. The coverage system assumes there is complex stuff being modelled under the armour to hit, but the attacker has no fancy targeting system. The weakpoints system assumes the target is modelled simply and the attacker has a lot of granular information about their skill level. Making coverage work for monsters would require adding a ton of infrastructure to it that isn't needed for players. |
Well, if it's actually less complex to do it this way, then that works well enough. Thank you for taking the time to explain. |
It looks like weakpoints are getting some attention on Reddit. I decided to run some numbers on the scenario described: Zombie Cops have a combined weak point coverage of 30% and a base stab armor of 6. Among the weak points, the maximum stab armor is 1.5 (a multiplier of 0.25). Makeshift wooden arrows fired from a short bow have 5 base damage. It can't damage a Zombie Cop when it misses a weak point. When hitting a weak point, it deal an average of 10 damage on a Good Hit!. Assuming 0 skill and 8/8/8/8 stats, it takes about 27 good hits to kill a Zombie Cop. With 3 skill, the weak point hit rate goes up to ~54% and it takes about 15 good hits. Note: these values are slightly conservative, because several weak points have no stab armor (head, eyes, etc.). |
That's sounding pretty correct. I think the main thing with cops and soldiers both is that they can probably get a bit of a buff to base armour now that they have so many weak points. |
I'm starting to add this to DinoMod. One thing I've wanted a long time is to set "the soft underbelly" as a weak point, but only available when the monster is knocked to the ground. This is how every apex dino predator appears to have hunted, especially against ankylosaurids and ceratopsians. Something similar could be interesting with sauropods, where only the knee is available, but once it's hit the monster is slowed and "the soft underbelly" appears |
So there are two things this makes me think of, they're not really the same.
Anyway for your dinosaurs I'd point out that a human-sized attacker can probably get the weak underbelly even when it's not knocked down... |
For what it's worth, I have plans to include "add an effect to yourself if you do this/hit with this" to monster special attacks, so keying weakpoint exposure from that would be nice. |
The C++ side of the weak points project is wrapping up! We've implemented the core features, and updated the documentation. All that's left is a few minor work items and possible bug fixes. @I-am-Erk Thanks for your guidance on this project! I've had a surprising amount of fun, and I'm happy to see people use a feature that I helped build. |
Is your feature request related to a problem? Please describe.
Monsters with high armour, which are quite common, have universal armour coverage. There are no holes for faces or arms, no soft spots over joints. We need gaps in armour. #51304 has begun implementing this critical feature, I am writing this issue to cover some of the ways we need to structure this for expandability.
Describe the solution you'd like
Gaps in armour, which are independent of your attack/critical roll but still based on skill. We'll call these
weakpoints
, because eventually this won't be just about armour but also about special hits that cause certain effects.These gaps should be individually listed in an array. Initially it's probably easiest to do it inline in the monster definition. Some day it might be nice to have json objects for these for easy moddability and for easily repeating some common basic patterns.
In the end, our JSON should look something like this. Don't be daunted, because I am going to layout a stepwise approach to implementation and the first step should be easy.
First pass
I'll write this part up and then take a break but I want this out so the PR can proceed.
A first pass only needs to support a name, an armour value, and a difficulty score. So, a first pass
weakpoints
array should look like this:name
: This is the string we use both to describe what this is for the content creators, and to generate an attack string, along the lines of "You hit the in its soft joints, doing 30 damage!".armour
: This is a multiplier for existing armour scores. By default it is 1.0, ie. the same armour as the base monster. An entry ofall
overrides that for all armour types, and individual values can be specified separately to override (not combine with) the value inall
. So:"armour": { "all": 0.2 }
- all the monster's armour is reduced to 20% of base value."armour": { "piercing": 0.2 }
- the monster's piercing armour is reduced to 20% of base value, the other armours are still full strength"armour": { "all": 0.2, "piercing": 0.5 }
- all the monster's armour is reduced to 20% of base value, except piercing armour which is at 50% of the base value."difficulty" is how likely you are to hit this weak spot. On a first pass, think of this as a percentage weight. Here is our starting algorithm:
difficulty
values, with "no weak point" filling the rest. We assume a max difficulty of 10, so the final weight is 10 - difficulty. So in the above example, with a difficulty 8 and 3 weakpoint, the list would be:93%: no weak point; 2%: narrow armour gap; 7%: soft joints
.Second pass: adding a role for skill to your chance to hit a weakpoint
See #51482 for a more up to date conversation on this issue.
~~Once we have a basic ability to hit weakpoints at random, we should add a role for skill to making you better at hitting them. There are a number of skill factors to consider:
These factors will combine with thedifficulty
of the weakpoint, to create a finalweight
value, taking the place of the difficulty score in the weighted list we built in part 1. I propose the following maths:weight = ( weapon_skill + weapon_class_skill + dex/8 + per/8 + proficiency_factors ) - difficulty, min
((10 - difficulty) / 2)`, min 0 on that second equation~~This makes it so that easy weakpoints can still be hit randomly even if you have no skill (that min 10-difficulty/2 bit) but harder-to-hit weakpoints require skill, and your skill will always have a significant role. ~~
once we calculate weight in this way, we can go back and do the same weighted ranking as before.addendum: I realized a day after writing this that I also really want the ability to define a weakpoint called
default
, which allows us to specify special data if an attack hits no weakpoints at all. Most of the time we don't need this, but after Part 3, it can allow us to do things like make monsters take reduced damage or not be susceptible to criticals unless they're hit in a weak spot. by Part 4 it would become an alternate implementation of #45142, in that we can make monsters immune to attacks on their main body and only get slowed down or knocked back.Third pass: Special damage and critical hit effects
Once we have a role for skill we can start getting into colourful stuff, specific data for each weakpoint. I really want this feature because it allows us to represent various types of critical organ and joint injury, especially in combination with part four.
"damage"
: This very self-explanatory field is a multiplier for incoming damage, applied after the armour is taken into effect. So first you hit the weak spot, reduce damage by the modified armour value, and then multiply your final damage by thedamage
modifier. This can represent specific points that are weak in armour but not particularly valuable spots (a weak point over the fleshy part of your arm, eg), or it can represent weak points where even if you didn't specifically roll a critical hit, it's going to do some extra damage off the bat (the eye, for example)."critical"
: This works exactly likedamage
, but is applied to critical hits. If this field is blank, thedamage
field is used for both regular and critical hits. If both this field and damage exist, usecritical
instead of - not as well as -damage
. This can mainly be used to represent weak points over top of vulnerable areas that still might be challenging to hit, like stabbing someone in the liver by reaching up from their abdomen. It could also represent areas which are less suscpetible to critical hits because they have no majorly important underlying structures. This multiplier should be applied to the final critical hit damage, it doesn't replace existing critical hit modifiers. However, if set to any value less than 1, this parameter should just downgrade all critical hits to regular hits.Fourth pass: Adding special effects
This is actually one of my favourites, but I have put less thought into how to implement it. As I currently see it, we should have an array of
effects
that may be applied if the weak point is hit. For example, hitting someone in the hamstring might not do much more damage but could knock them down or cripple their speed.The array would look something like:
"effects": [ "knockdown", "hamstring" ]
. Presently I am assuming that the severity, duration, and likelihood of those effects would be determined by the effects themselves. However we might also need some data on how to determine if the effect happens, so it might need to be more complex than that. Another option would be like:If we go with this more complex model then:
damage_percent
represents what percent of the monster's max HP the attack inflicted in damageintensity
determines how intense the effect is applied. Optionally, we might make it so higher damage is likely to inflict higher intensity, but personally I don't think that's needed... as you can see above, if we want that behaviour we can represent it by putting the same effect in twice.chance
is the percent chance this effect will occur if the conditions are metdamage_affect_chance
: if true, add the damage of the incoming attack (as a percent of the monster's base HP) to thechance
score before determining if it happens.In the above example, if an attack does, say 30% of the target's base HP, then it has a 30% chance of inflicting knockdown and a 10% chance of hamstringing the target at intensity 1 or 2.
This more complex implementation would probably be the ideal, but it's a lot more work and I'm not convinced we need it. That said, it would allow me to add headshots to Dark Days of the Dead, so PLEASE DO IT. Gah.
Fifth pass: determining if your weapon can hit the weakpoint
At this point we add that
"size"
attribute, which accepts "small", "medium", and "large", as well as no value. If there is no value, we assume any weapon can hit this weakpoint. Otherwise, this is for melee attacks only at this point, although later we may want to add the infrastructure to get something similar for ranged attacks.In very short this pass would look at the to-hit data of a weapon, and use that to determine if it can hit a small weakpoint. note that the size of the weakpoint here is completely independent of its difficulty: a weakpoint could be small but easy to hit, if there are a lot of them and they are near the center of mass, but a long broad weapon might just be too large to hit them.
Other features to consider
It would be nice if, while aiming, you had the option to toggle "aim for weakpoints" at a penalty to your to-hit chance but an increase to your "chance to hit weakpoints". I don't know the best way to do the same thing in melee though.
Describe alternatives you've considered
Something simpler?
Additional context
I think it's important these stats be in an attribute block just because of how many inline stats there already are in a monster entry.
The text was updated successfully, but these errors were encountered: