Reworking Percent-Based Spell Effects

Feedback on past, current, and future development.
User avatar
Greywander
Posts: 119
Joined: 04 Dec 2014, 07:01

Reworking Percent-Based Spell Effects

Post by Greywander »

Let me tell you a little story to give a bit of context to this topic. You guys like stories, right?

So a while back (before I discovered OpenMW), I decided that I wanted to mod in Restore Magicka as an enchantable effect. Now, I already had magicka regeneration from using GCD, and I raised the price of Restore Magicka such that you could only fit 1 point constant effect on an exquisite ring or amulet, so it's not like I really needed it or that it was game breaking. I just felt like it should be there for the sake of completeness.

In order to enchant an effect, though, you first need to have a spell with the effect. (I should note that with the price increase, you couldn't even break even with a custom spell.) I wanted these spells to be actually useful, though, rather than simply to fulfill a requirement. So I made two spells: The first was called Blood Pact, and would essentially convert health into magicka using a Damage Health effect in conjunction with Restore Magicka. The second was called Meditation, and would paralyze and blind the player for 30 seconds while restoring some magicka. Seems fair, right?

Well, when I went to test the spells, I ran into some issues. You see, I was playing a Breton (50% Resist Magicka), and I was wearing the Cuirass of the Savior's Hide (60% Resist Magicka). You can probably see where this is going. I had a total of 110% Resist Magicka, and either spell essentially gave me free magicka without any negative effects. I partially fixed the Blood Pact spell by splitting the damage between Damage Health, Fire/Frost/Shock Damage, and Poison Damage, but Meditation remained thoroughly broken.

The point of this is to illustrate how the percent-based spell effects are kind of broken. And that's without even bringing up things like 100% Chameleon or Sanctuary.

Now, I understand that we want to replicate Morrowind gameplay as faithfully as we can, and that this is more of a design flaw than a bug. However, a post-1.0 feature could give the option to change how these percent-based effects are handled.

First off, it's kind of ridiculous that Resist Magicka will resist Weakness to Magicka. If you have 100% Resist Magicka, then you become immune to Weakness effects. A better behavior would be to have them cancel, so for example 100% Resist + 50% Weakness = 50% Resist.

Another possible way to handle these is to move away from a raw percent-based system. Consider the following simple formula:

% effect = x / (x + 50), where x = spell value

So, for example, Resist Magicka 50 pts would give you 50 / (50 + 50) = 50%, while 100 pts would give you 100 / (100 + 50) = 67%, and 25 pts gives you 25 / (25 + 50) = 33%. Even with 999 pts you'd only get 999 / (999 + 50) = 95%. Just 1 pt gives you 1 / (1 + 50) = 2%.

This way, it becomes impossible to ever reach 100%, which is were most of the exploitable design flaws are. You could complement this by adding new spell effects that have the same effect as reaching 100%. For example, % Resist and Immunity, % Darkness and total Blindness, % Sanctuary and Ethereal, % Chameleon and, er, Invisibility (I realize that Invisibility breaks on actions while Chameleon does not, so not quite the same). I'm not sure Weakness effects should be treated the same way, as 100% Weakness has no where near the same game breaking effect as 100% Resist or Chameleon (and Weakness beyond 100% actually does something).

Finally, it would be nice to have a way to bypass Resistance and force a spell effect, even if this means using a script.
onionland
Posts: 68
Joined: 29 Jul 2014, 00:43

Re: Reworking Percent-Based Spell Effects

Post by onionland »

Whilst in a way being a part of the Morrowind experience, the spell system really is broken. :lol:

I like the idea of changing how spells and effects are computed, let's hope that Zini or someone else with big plans for post 1.0 pops up to tell us if there are any plans to make that de-hardcoded in the future.
Chris
Posts: 1626
Joined: 04 Sep 2011, 08:33

Re: Reworking Percent-Based Spell Effects

Post by Chris »

I've had the thought of modulating percentage-based magnitude effects (at least, effects that have 100% as max, like weaknesses, resists, chameleon, etc). That is, rather than adding percentages together like:
25% + 75% = 100%
it instead modulates with the remaining amount, so:
25% + ((100% - 25%) * 75%) = 75%
or in pseudo-code form:

Code: Select all

float cur_magnitude = 0; // [0...1]
for(each effect source)
    cur_magnitude += (1-cur_magnitude) * effects[i].magnitude;
This means that more sources you have applying a given effect, the less each will contribute. It also makes it practically impossible to get 100% unless you have an item that specifically gives 100%, since even an extra 99% magnitude when you're already at 99% results in (1-0.99)*0.99 < 1. This also has the interesting side-effect that if you have an item that gives >100% magnitude, the other contributors will cause the result to lower back down toward 100% instead of increasing it further (like nullifying an overcharge).

I believe I've done the math correctly and it should result in the same value regardless of the order effects are accumulated (the fp rounding/precision error should be undetectable given the RNG testing), but it would be best to double-check that.
User avatar
Greywander
Posts: 119
Joined: 04 Dec 2014, 07:01

Re: Reworking Percent-Based Spell Effects

Post by Greywander »

Putting some more thought into this, clearly the solution is to turn all spell effects into scripts, so that they can be freely changed, and so that new spell effects can be added effortlessly. This way, modders would be able to come up with their own solutions to issues like this (and a whole host of other spell effect issues), and players could pick and choose whichever ones appeal to them the most. De-hardcoding the spell effects is likely to take some time, though, and who knows what the OpenMW team will want to address before that, even once they reach 1.0.

Still, de-hardcoding spell effects is going to vastly increase modding potential (particularly since potions, racials, vampirism, and, well, almost everything in Morrowind runs on spell effects). If I was familiar with C++ I'd want to join and help out, but sadly I am not.
onionland
Posts: 68
Joined: 29 Jul 2014, 00:43

Re: Reworking Percent-Based Spell Effects

Post by onionland »

Greywander wrote:Putting some more thought into this, clearly the solution is to turn all spell effects into scripts, so that they can be freely changed, and so that new spell effects can be added effortlessly.
I don't think that the way effects are calculated is stored with the individual spells, as it is a part the game's internal logic, meaning that to change it one would have to change part of the logic of the game, which I would think is yet to be de-hardcoded.
While I'm not entirely up to date when it comes to the progress of openmw-cs, I belive that changing spells and effects, as well as adding new ones is already well within its capabilities.
User avatar
sjek
Posts: 442
Joined: 22 Nov 2014, 10:51

Re: Reworking Percent-Based Spell Effects

Post by sjek »

What have read the code the research page effects are kinda directly placed into game logic with c++

Would imagine it's matter of directing the handles to sethealth / gethealth, setmagicka / getmagicka scripts for armor and weapon eaters and maybe give warning if it's missing that mods are free to replace those. What kind of commands would be good .?

Global script which handles the health changes in relation to dmg with armors is kinda neat as mod example but in vanilla it executes every frame and can be heavily laggy.... It was endurance health mod and vanilla was trying to change the health back.

How's that float variable works as if remember correctly it possible to write

Timer = (getsecondspased + 3)/2 as separate definition at least

Something similar in form of "ischanged" cript command to check any value would be nice moving the per frame checkings to engine or is there a way to make interfering with game mechanic more real time althought rng nature itself prohibites that more or less
Cramal
Posts: 186
Joined: 19 Sep 2014, 13:37

Re: Reworking Percent-Based Spell Effects

Post by Cramal »

Maybe a possibility is to make effect from different spell to multiply instead of add.

Exemple :
50% resist + 60% => 80% resist (just 40%*50%=20% of the effect is applied) vs 110%
50% absorb + 25% absorb => 62,5% (0.5*0.75=0.375) absorb vs 75%

In that way it is still possible to achieve a 100% resist or a 100% chameleon but you have to have it on a single effect
And in any other case each new effect improve the situation without any cap
User avatar
Okulo
Posts: 672
Joined: 05 Feb 2012, 16:11

Re: Reworking Percent-Based Spell Effects

Post by Okulo »

Cramal wrote: Example:
50% resist + 60% => 80% resist (just 40%*50%=20% of the effect is applied) vs 110%
But when you first have the 60% resist, and then add the 50%, you get: 60% + (50% of 60) = 90%.
Same with...
Cramal wrote:50% absorb + 25% absorb => 62,5% (0.5*0.75=0.375) absorb vs 75%.
If you first have the 25% absorb and then add the 50% absorb, you now have 37.5% absorb.

It really shouldn't matter in which order you apply the spells.
Cramal
Posts: 186
Joined: 19 Sep 2014, 13:37

Re: Reworking Percent-Based Spell Effects

Post by Cramal »

Okulo wrote:
Cramal wrote: Example:
50% resist + 60% => 80% resist (just 40%*50%=20% of the effect is applied) vs 110%
But when you first have the 60% resist, and then add the 50%, you get: 60% + (50% of 60) = 90%.
Same with...
Cramal wrote:50% absorb + 25% absorb => 62,5% (0.5*0.75=0.375) absorb vs 75%.
If you first have the 25% absorb and then add the 50% absorb, you now have 37.5% absorb.

It really shouldn't matter in which order you apply the spells.


You have to multiply the part of the effet that is applied and not the resist% :
so 60 % resist => 0.4*effect. This 0.4*effect + 50 % resist => 0.4*0.5*effect=0.2*effect
This is the same result in the other order :
so 50 % resist => 0.5*effect. This 0.5*effect + 60 % resist => 0.5*0.4*effect=0.2*effect
For resist i means that the total resist i calculated by :
1- (1-resist_1)*(1-resist_2)*(1-resist_3)....(1-resist_n)

Same with absord
25% absorb => you are hit 75% of the time } + 50% absorbb => you are hit 50% of 75% of the time ie 37.5% of the time
50% absorb => you are hit 50% of the time } + 25% absorbb => you are hit 75% of 50% of the time ie 37.5% of the time
For absorb / reflect it means that you have one random number in [0.1] for each absorb/reflect effect and each one is tested successively


In both case the order of the application of the effect from the same kind has no impact on the final result
User avatar
Okulo
Posts: 672
Joined: 05 Feb 2012, 16:11

Re: Reworking Percent-Based Spell Effects

Post by Okulo »

Ah, I see what you mean now.
Post Reply