-
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
"Flinch", a mechanic for making speed penalties less deadly and annoying #73050
Comments
It looks like
It can also be noted that the higher flinch_threshold is set, the harder each flinch hits as it's a higher value being divided, although it occurs with a lower frequency. It seems to me that you'd want to control the threshold for when to trigger it separately from the severity. |
That was supposed to say chance, yes. However, running the numbers, I realized what I actually want is for it to be based on how much your flinch_chance rose this turn. Probably the best way to do it is to have flinch length be affected by the number of turns since last flinch, so that if your symptoms are mild your flinches are shorter too. The only trick there is that the math should ensure that we don't get too geometric in the rising rate. I have some ideas for how to do that, just gotta open desmos. Alternatively we might just make flinches always 50 ticks and only play with the frequency. This makes them feel more serious at minor pain but means you can always predict exactly how bad they are. edit: added those to the OP. For now I kept the simplest version, setting flinch duration to be based on the amount of flinch you gained this turn. I like doing it that way instead of as an average because if you're flinching but your symptoms are improving fast, it shortens the duration. |
I'm not sure I got that right. So take it as an alternative. graph TB
text1 --> text2 --> text3 --> |Calculating flinch|text4 -->|Comparing| text5
text5 --> |Yes| text6.1 --> text6.2 --> text6.3 --> text8 --> |go to|text9
text5 --> |No| text7.1 ----> text8
text1("flinch = 0")
text2((*))
text3([Start of turn]):::c_green
text4("flinch_pain = (current_pain - 10) * pain_flinch_mod
flinch_stamina = 100 - 100 * current_stamina / stamina_max * stamina_flinch_mod
flinch = flinch + flinch_pain + flinch_stamina")
text5{"flinch >= flinch_threshold"}
text6.1["flinch_power = flinch_pain / 5 + flinch_stamina / 5
note: You can make different contributions to the power.
And, if necessary, limit to a maximum and minimum value. "]
text6.2["Display message"]
text6.3["flinch = 0"]
text7.1["flinch = flinch - flinch_threshold / 10
flinch = max(flinch,0)"]
text8([end of turn]):::c_green
text9((*))
classDef c_green fill:#00FF00
What's going on here.
These are separate values depending on pain and stamina. Calculated for convenience. In case you need to use them separately.
The total value, is the sum of these two parameters and the value for the last turn.
A flinch event occurs. For which the power And also a little bit of calculus magic. As I said, you can play with coefficients so that stamina and pain affect with different power. And choose them so that at "limit" values they give 50 ticks. For example, 2 and 5. (I'm oriented on pain = 110). Or just introduce restrictions min(10) & max(50). I'm not sure, maybe it's necessary to operate directly with pain and stamina.
If the value I should note that this is a moot point. The alternative is flinch = 0.9*flinch. That is, we should focus on the current flinch value. The higher it is, the higher the number by which it is reduced.
We do not need to remember when the "flinch" event occurred. The frequency of this event directly depends on the current value of pain and stamina. It cannot be more than once per turn. With the current values, you need to get pain = (flinch_threshold - flinch_stamina) / 0.6 + 10 = (300 - 100) / 0.6 +10 = 343. I'm not sure if this is possible in a normal situation. Because that's equivalent to 686 HP damage taken at a time. Or 114 for each body part. Anyway, you can change the The power of flinch also depends on pain and stamina. In general, the higher the pain and lower the stamina, the more often and more powerful you flinch. P.S. I used Deepl. And I'm sure I made a lot of mistakes. |
Isn't this what the stumble function does? |
Stumble is move loss when missing with a melee attack that scales with weapon size. Flinch would be move loss that kicks in when you are at high pain and exert yourself, mostly with melee attacks, which would replace speed penalties from accumulating pain. A flinch would trigger independently of hit or miss. |
I was thinking of opportunities for code reuse. But true, stumbling is based on physics and flinching is based on physiology. I was going to nitpick what body parts are flinching but I see that's been discussed in #72851 and is waiting on the wounds system. |
Is your feature request related to a problem? Please describe.
Speed penalties are a necessity in the game. Lots of things, like pain and breathlessness and muscle strain, should lower your speed when doing things like swinging weapons... There's no easy way around this because there are only so many ways to alter character abilities as their resources change. However, speed penalties are disproportionately punishing and frequently lead to hard-to-understand failure cycles where you're getting hit by enemies more and more for each attack you make. This is not just frustrating but generally unfun, as it requires a lot of foreknowledge of the game engine to allow players to make logical assessments about their avatar's capabilities. One turn they seem to be on top of things, then they make a too-slow attack because of slight misjudgment and are now not one turn later, but two or three.
Solution you would like.
Let's stop penalizing attack speed. Instead, anything that penalizes speed only affects movement speed (if it should even do that). Instead of penalizing attack speed, we get a new mechanic, Flinch.
Anything that could be susceptible to a speed penalty, such as melee attacks or smashing objects, makes a call to Flinch() instead. When your character Flinches, they delay for some short amount of time (10-50 ticks) and get a message about it. This means they now can make another decision based on knowing they are slowed down. It also means that faster attack weapons don't have as strong an advantage over slower, the flinch mechanic is the same no matter what.
Some ground rules.
flinch_chance
score that builds up right before eachflinch()
check, and if it passesflinch_threshold
, we get a flinch. The duration of the flinch is based on how highflinch_chance
is.The algorithm
flinch()
to start would increment when attempting a melee attack, by an amount equal to:(current_pain - 10) * pain_flinch_mod
(pain_flinch_mod is a global JSON setting, default 0.6)100 - 100 * current_stamina / stamina_max * stamina_flinch_mod
(stamina_flinch_mod is a global JSON setting, default 1.0)flinch_threshold
is another global JSON setting, default 300.flinch_chance_gained_this_turn / 5
ticks, max 50, min 10. Then flinch_chance resets to 0.When I finish adding strain I'll redo these numbers to work it in but this should work for now.
In this model, you start flinching every two turns pretty often, but the duration only caps out if you're both tired and in pain. To get to the full 50 ticks of flinch per turn, you have to be accruing 250+ points of flinch_chance, which most of the time requires you to be in both a lot of pain and also out of breath.
The message given for flinching should probably suggest the things that are causing the flinch, eg:
you flinch for an instant as you push past the pain.
you take a fraction of a second to gather your energy.
Probably if you're both breathless and in pain, we should just randomly select an appropriate message? That way we can have alternative texts too. Or we could implement logic based on which of these is contributing the most to flinch_chance.
Describe alternatives you have considered.
I am not sure about the 'every other turn' limit, but I don't want to keep flooding the player with flinch messages as they get more common. This keeps the spam down
Speed penalties are the other obvious alternative, and I hate them.
Additional context
The effect should be subtle, but give the player a lot more control over their avatar's actions.
I think it's fairly easy to implement, but my time is limited again so I'm sort of hoping someone will get to it before I have a chance; It seems like it might help me to get the first pass of strain working, after testing it out
The text was updated successfully, but these errors were encountered: