Game effect architecture

11 posts

Flag Post

Hello,

I am making an effect similar to the damage over time elemental effect in borderlands. I can accomplish the effect, my question is how you would accomplish it. I am not asking anyone to write the code or classes for me, just asking how some of the more experienced programmers would construct it, my thoughts so far:

Gameloop: I could simply put a boolean flag that if true registers the damage per every couple of frames. Simply but very limited and given that I plan a few different damage types could get convoluted quickly.

Gun Class: I could have the gun have the information about the element type and the damage, and even the function. flagging an effected unit, but this still leaves the actual damage dealing and registering portion in the gameloop when I iterate through the enemies.

I could even make the elemental damage over time effect its own class, but again the only way I can think of actually executing the function is with a flag in my main enemy iteration loop :(. I was hoping for something that didnt rely on a conditional statement in my main loop, but that is what I keep coming back to. Thoughts?

 
Flag Post

How do you deal regular damage? That could be a starting point.

 
Flag Post

Main game loop iterates through projectile list, checks to see if the line formed from the projectiles previous position and new position passes through an enemy, if the true the enemy is dealt damage based on the weapons min – max damage.

 
Flag Post

Here’s how I deal with damage over time effects:

Shot hit tests happen (of course) and if successful, deal damage to the enemy. Additionally, if the projectile is flagged to apply any status ailments (such as DOT effects), generate an appropriate status ailment object. This status ailment object should come with a reference to the affected target, counter to track the duration, a damage value to indicate the amount of damage per tick, and if necessary, flags to indicate damage type (fire, ice, poison, etc) and optional removal methods (antidote, dispel magic, etc) if necessary.

Then, push it into a vector to be cycled through in the framehandler, where it will deal damage and, if necessary, apply a visual (such as burning or poison bubbles) to the affected target, then decrement the timer variable. Upon reaching 0 or if flagged as removed, it expires and is removed from the vector, “curing” the target.

Something like that.

 
Flag Post

In a TD game I made, I would simply apply the effects to the enemy that was hit. Then, in its update phase, a check would be made to see if it was poisoned/slowed, and the appropriate response undertaken.

All I think I had was duration and power of the effects which were passed to the enemies.

 
Flag Post

You should just make a general purpose debuff system that can do bad things over time, and use that for the extra elemental damage.

 
Flag Post

If you only have vary limited number of conditions and they always behave the same (‘poison’ deals the same amount of DoT whatever its source and whoever it’s applied to, for instance) then you can probably get away with applying the condition directly on the target as fearteh describes. Otherwise, Aesica’s explanation constitutes an excellent basis for a general buff/debuff system, easily expandable and customizable.

 
Flag Post

I should add that it might actually be better to push the effects into a vector on the affected target. Then, for the target’s framehandler, loop through the vector to also execute effects for things like periodic damage. It would certainly make stat buffs/debuffs easier to manage.

 
Flag Post

Really? On the contrary, one of the aspects of your first explanation I found particularly compelling was that I imagined all effects were centralized in a single vector, and each effect kept track of who their target was. Imagine a tower defense game. There could easily be hundreds of enemies on the screen at once but only a handful of them poisoned at any given time. Cycling over the debuffs would be much more efficient than cycling over the enemies to locate the few that have a debuff on them.

You’d just have to check before applying an effect that the effect’s target is still a living enemy, as it might die of something else between two applications of the effect damage, and nobody likes flash crashing because of a reference to a property of a null object reference.

 
Flag Post

Well since each enemy has its own do-this-every-frame function, including it in that would be trivial enough. (I wouldn’t make a secondary loop-through-all-the-enemies pass just for effect checks!) The advantage to this approach is that it (in theory) would make stat modifying effects less sloppy since the enemy has a list of what effects are on it. The separate creature/effect approach would work fine for damage over time, but what about things which reduce movement speed, attack power, defense, healing, etc?

If the creature doesn’t know what effects it has, then the effect has to destructively alter a property on the creature. On the other hand, if a creature does know what effects it has, it can simply cycle through its effect list and apply any modifiers to its outgoing damage, movement, etc on the fly, without actually altering any of its base stats directly. Then, when the effect vanishes, there’s no need to reset any stats to their defaults—the effect is simply removed from the list, and any modifiers it contributed go away with it.

 
Flag Post

What I had was:

Tower: (damage, range, rateoffire, slowingpower, slowing duration)

fires a bullet (speed, angle, damage, slowingpower, slowingduration)

hits an enemy. (maxSpeed, HP, colour)
health-=damage
if(health<=0)destroy().
if(slowingpower>0){slowed=true; movementSpeed*=slowingpower; slowDur=slowingduration;}

enemy’s update function:
move:(x+movementSpeed…)
if(!slowed)if(movementSpeed<maxmovementspeed)movementspeed+=maxmovementspeed*.05 (Makes sure it doesn’t go over maxmovementspeed)
if(slowed){ movementSpeed*=slowingpower; if(—slowDur==0)slowed=false; }

Basically, the enemy checks if it is being slowed(slowed=true).
If so, it decreases its movement speed by multiplying its speed by the slowing power of the bullet (0-1) and decreases the duration remaining of the slow.
if not, it checks if the movement speed is less than what it should be, and if so, increases it until it reaches its proper amount.

I could probably dig up the class if anyone’s interested.

It would have probably been better, if I had more effects and multiple were being applied to the same enemy at once, to give each enemy an effects Array, which it checks each turn to see if it has any buffs/debuffs, rather than having all of the checking and action being done in the update function.

But keeping track of each enemies’ effects in the main class would be difficult (for me at least).