Temp effects (slow, damage, boost, etc.)

Godot Version

4.3.rc3

Question

20 people shoot you applying different effects. Burn, poison, slow, stun, rate of fire change, gold earned change, scale changed, etc. Things stack, they last for different amounts of time, etc.

There are lots of ways to make this work. The most obvious is a lot of hard coded code and a lot of timers (or collapse effects into a timeline histogram or process an array of effects with a single polling timer on a fix poll cycle, etc.)

on_hit(hit: Hit):
if hit.effects[0].trait_affected = rate_of_fire:
    create timer(hit.effects[0].time)
    rate_of_fire *= hit.effects[0].value_change
elif hit.effects[0].trait_affected = health:
    blah
elif hit.effects[0].trait_affected = range:
elif hit.effects[0].trait_affected = scale:
elif hit.effects[0].trait_affected = movement_speed:

i can do this but it’s a lot of boring code. i thought i heard a rumor that GDScript has more elegant ways of handling this sort of thing. Maybe:

on_hit(trait_name, change, duration):
self.modify_property(trait_name, self.get(trait_name) + change)
create timer stuff

Buffing, debuffing and DoT are common enough i figure a bazillion people have come up with clever, elegant, efficient ways to do this. Anyone here know some?

I would have said you create a base class for all DoT effects (damage over time)
that has variables like name, ticks, strength and init_dot(), apply_on_hit() and _process() method.
Whenever an enemy applies an effect to the player, instantiate the DoT to the player and add it to a node_container (like %DoTs) and activate the DoT via init_dot().

  • init_dot(): Sets all the variables and activates the process() method
  • _process(): Will count the time up and call apply_on_hit() method once per second
  • instead of _process() you can also just use a timer and reset the timer when _on_finished signal
  • apply_on_hit(): Will damage or heal the player and count the tick variable down by 1. If tick reaches zero, queue_free() the entire dot

Of course you can then think about creating deeper mechanics. Like the decision if multiple dots are applied of the same type (like poison).

  • Do the dots stack?
  • Do the dots refresh upon reapplying?

Upon being applied a dot, you can loop through the dot container and see when a dot of same type is already applied. If yes, then call that node and _refresh_dot(). Or maybe you want to disregard that and treat each dot of same type as a separated entity.

1 Like