Method of implementing effects for all attributes respecting 4E stacking rules
Opened this issue · 4 comments
Because I've had this rolling around in my head for a while.
I do not think this is a good idea, I do not think it is super practical to implement now, it would need one hell of a migration script.
But it fulfils the following objectives:
- All character attributes have a well defined shape with a "this is what you edit"
- It allows any of them to be altered by an an active effect
- It fully implements the 4e stacking rules
- It requires no change to the active effect system, it does not even /require/ a change to the active effect UI, but the overall UX would be made much better by a 4e specific Active effect UI.
But it would require a big alteration to the Actor data model :'(
I write it up to get it out of my head, and in case it sparks further thoughts.
All attributes that are effect modifyable have the following json structure defined in the system model.json. This is important as this defines what gets persisted to the db.
{
base: 10
bonuses: {
manual: []
}
}
bonuses.manual
are the explicit bonuses you can add though the UI without using the effect system.
So not much is actually persisted. Everything else is dynamic, including the value
attribute, which is the eventual total value. value
is never saved and so is always computed on the fly by the prepareData()
method.
All effects that are modifying an attribute are in the form of attributeName.bonuses.bonusType
. All bonus types that are not untyped
are set as effect type UPGRADE
because they do not stack, while untyped
are set as ADD
because they do. (this is where some nice UX would come into play and do that for you.
So assuming we wanted a feat bonus to fort defence it would be form system.defences.fort.bonuses.feat
type UPGRADE.
prepareData()
would go over each attribute, grab the base value, then iterate all the non-manual
entries in the bonuses object and add them. Manual bonuses would have to count as untyped and stack I think, since the player has manually put them in, so they each get added on as well. the result becomes the value
for that attribute.
So we would have in memory something like this:
{
value: 17
base: 10
bonuses: {
feat: 2
power: 1
untyped: 4
manual: []
}
}
(Obviously some things such as AC or NADs have a slightly more complex formula where they are also pulling in other things on top of the bonsues, but they follow as extensions on top of this base system for modifiable attributes.
The weapon/power effects that I wrote could be rewritten easily to operate in a similar manner.
Anyway, it's not a very elegant solution to the problem and I don't think its worth the effort (I definitely wouldn't do it), but written up as /a/ solution.
random aside, you get the best json syntax colouring by tagging the code block as yml
:D
I've gone and done the first part of this, where now all ( or at least most) attributes should have feat
, item
, power
, and untyped
as the keys that should be used while creating active effect moving forwards. Currently the change modes do still not properly respect the systems stacking rule. Currently it's up users to manage their own stacking for feats, items and powers.
Love this! It's exciting to be making some progress on this front.
Could we add heritage
/race
/racial
to the list as well, it being the other common bonus type that's relevant across all attributes?
Can we do we specific types for specific attributes? I ask because I'd like to see shield
available for AC and Ref, given there are a surprising number of non-shield things that interact with it.
It occurs to me that if we can do specific type/attribute combos, we could probably use this to solve the resistance/vulnerability issue too. Since those values don't use bonus typings (pretty sure that never happens? I could be wrong) we could instead use types of "resistance" and "vulnerability", and the upgrade/downgrade modes to apply the rules correctly.