Chillu1 / ModiBuff

Buff/Debuff/Modifier library focused on feature set and performance, while maintaining 0 GC. Fully pooled
Mozilla Public License 2.0
139 stars 4 forks source link

Improved event recursion solution #13

Closed Chillu1 closed 10 months ago

Chillu1 commented 11 months ago

How event effects work Event effects are triggered on specific actions: when a unit gets attacked, attacks, hits, dies, etc. The problem occurs when there are two events that trigger each recursively. Example: Unit "player" and unit "enemy" have both event effects that work like thorns, essentially dealing 5 damage back when getting damaged. The thorns will keep recursively calling each other until a stack overflow.

How we currently fix the recursion issue Currently, we have an interface IEventTrigger that set's a private flag if an effect is "eventBased" or not. If it is, the event effect will not trigger any event effects.

It's a pretty limiting approach, for several reasons.

Other possible solutions

  1. Event recursion counting: Allow for a limited amount of recursion effect triggers. Problems with this approach, is that a recursive loop will eat up all the triggers, making other effect events not trigger.

  2. Single event effect trigger per tick Once an event effect has been triggered, it can't be triggered again on the same tick/frame. This approach allows other effect events to work together, but is against limiting in the amount of interesting interactions.

  3. Combining them, multiple standalone event effect triggers per tick, with source tracking Most complex and most performance-heavy solution, but we could also track which IEffect triggered it from what unit, limiting the recursion there, and allowing for multiple effect events calling the same effect event without recursions.

Ideally, we wouldn't limit any event interactions, while still solving the recursion issue, but I haven't thought of an ideal implementation yet.

Chillu1 commented 11 months ago

Source tracking approach might be next to impossible to do cleanly. Some initial testing has been done on the event-hash-checking branch.

https://github.com/Chillu1/ModiBuff/commit/8ed180d022c6221a505246e3d60cb63e75ec7b73

The problem is that we're not feeding the source effect hash when the modifier is not a stackable modifier. Since we're reusing the previous effect.

Chillu1 commented 10 months ago

Solved through counting how many times a primary event method has been called, then comparing that to our recursion limit, if lower on X event, trigger event. If lower on all events, zero out the counters.