Page 1 of 1

Better control over damage taken, via mitigation stats.

Posted: Sat Jul 20, 2019 3:40 pm
by Nasrudin
Hey guys, I've been looking into creating a more complex stat based damage & mitigation system, RPG-esque (but still working with original factorio damage/armour/mitigation types, and most imporatantly existing armor items).

I've gotten to the point in my mod where I'm wanting to modify the damage about to be applied to the player's entity each tick, but have noticed there is no such direct capability... A lot of what I'd like to do could be done with the ability to override resistances, however some things (like evasion) can not.

The problem is to do this right now, you need to implement a completely custom armor or entity (to override the resistances they provide) - when I'm aiming to work 'with' existing armor and entity prototypes (still being relatively new, I'm not even sure I can override EntityWithHealth resistances at runtime / I assume it's read-only).

I've also noticed this seems to have been raised quite a lot in the forums and shot down every single time, however all of the requests have 1) been very broad (wanting a generic on_pre_entity_damaged event) to the point of having performance issues if misused, and 2) seem to want to be able to hook into every instance of a damage occurrence (eg: on-hit level granularity).

My proposal is much cheaper and simpler: Add the ability to override Resistances of a LuaEntity, in the form of per-damage-type resistance modifiers.
  • final_flat_resist = max(0, flat_modifier_offset + original_flat_resist*flat_modifier_coefficient)
  • final_percent _resist = max(0, percent_modifier_offset + original_percent _resist*percent_modifier_coefficient)
  • This gives people the ability to post-process entity resistances to implement custom damage-mitigation systems, without editing armor/entity prototype resistances.
The technical cost of this would be along the lines of:
  • Relatively low storage overhead (basically doubling the size of Resistances by adding an extra 2 optional numbers for the override modifiers)
  • Low computational cost of 2 adds, 2 muls, and 2 max's per damage-type, ONLY when the entity original resistances change, or the modifiers change (far lower frequency than per-tick or on-hit, unless someone changes the resistance modifiers on_tick (which is on them)).
The end result of this would be the ability of mods to implement the following without mutating armor/entity stats directly (thus being able to work cleanly with standard factorio armor/entities, as well as modded ones)
  • Capability to implement custom mitigation stats (eg: mitigation stats based on additional mod-specific stat systems)
  • Capability to implement concepts like buffs/debuff/auras (eg: damage amplification field buildings, or weapons/turrets that reduce the resistances of hit enemies).
Alternatively, if the memory overhead is too much - having the same modifiers in resistance modifier 'groups' that can be applied to an entity (eg: entities share a reference to the the same set of modifiers) is also workable - it makes some things (like auras) a little harder, but it would all still be possible with enough effort (eg: one group for every possible combination of modifiers).

As for proper evasion... that requires per-instance-of-damage (eg: on-hit) level granularity (one random sample per hit, per damage type, plus a comparison). I can understand if that's not acceptable, depending on the kind of PRNG used internally it could be as cheap as some XNORs & shifts, or it might be something as slow as mersenne twister - so if there's no workable solution there, I understand.

P.S. thanks for this awesome game, you have no idea how many countless nights of entertainment you've brought - I can legitimately see myself playing this game for the next decade easily.

Edit: clarified my thoughts (since this was written up at 2am local time), including the realisation this calculation would only need to be updated infrequently.