RPG Effects
by Gareth Fouche · 03/26/2007 (5:20 am) · 4 comments
Well, its been a while since my last post, but I haven't been idle (well, most of the time ;) ). Indeed, I have made significant progress.
For those of you who have been following my posts, you might remember that I was working on upgrading my items system. Thats done. To recap, an item is generally built from a base template.
For example, "Steel Longsword" is a base template. You then apply modifiers to this template, which affect the items stats. So for instance, "Rusted" is a modifier, which, when applied to an item decreases the damage by 1 and drops the items durability. On top of this you can add enchantments to the item.
So I got that all working, and its groovy, except for the enchantments. Enchantments were just text entries in the "enchantments" field of the item, but that didn't correspond to anything, since I had been putting off working on them.Deciding it was time to bite the bullet, I moved on to tackling "Effects".
Now, what exactly are Effects? Well, pretty much any effect that can be applied to a Player. Damage over time, Poison, "Buff" spells, Curses, etc. It requires a very flexible framework, to handle all the possibilities. So I set out to design a powerful and flexible framework. It needs to be able to track all active effects on a player, removing them when their lifespans expire. More than that, it needs to be able to save out the effects and load them back in. There are also issues involving effects stacking. For instance, when a player casts "Enhance Strength" on himself twice, what happens? If both effects took place it would be a bit of a cheat, wouldn't it? You could just cast 10 buff strengths on yourself and walk around beating the living daylights out of things. So effects have to overlap, in some cases. You can't just overwrite the previous effect. Think about what happens if, for example a player has a strength buff (+2) effect lasting 10 minutes on them, and then they get a short lived 2 minute buff of +10? For most players, you would expect 2 minutes of +10, followed by 8 minutes of +2, right? So this framework has to keep track of all effects that overlap, and only apply the "best".
So thats what I built :D. All my effects are loaded from a database table, and if their stack type is "overwrite" then it manages the effects as I mentioned above. Of course, you can specify that the effect stacks, so that in the case of poison for instance, the more poision effects you are afflicted by, the worse off you are. I also have a field for "exclusion group". If an effect is a member of an exclusion group type, then when it gets applied to a player it ends all other effects that are also part of that exclusion effect. This is useful for example with mental spells. You could have a "Crushing Despair" and a "Berzerker Rage" spell both as part of the "Emotion" exclusion group. This ensures that you cannot be enraged and despairing at the same time ;). Its also useful for say combat stances. If you have a defensive stance and offensive stance effect, it makes sense that you can't have both at the same time.
As to the effects themselves, there are 3 components to them : Modifiers, Events and Properties.
- Modifiers are what you'd expect from Buffs/Debuffs. Basically they alter one of your stats for the duration of the effect. Enhance Strength is an example of a Modifier, but it could be anything, enhancing your Fire Resistance for example.
- Events are, well, stuff that happens on an event. There are 3 types of event at the moment : Tick, OnHit and OnDamage. Every effect has a tick rate, and at every tick interval it calls its Tick script. Perfect for effects which apply over time, such as regeneration or DoTs. When a player gets damaged by something, every effect on him gets their OnDamage event script called, with the attacker being passed in. So you can have effects which damage anyone hitting you ;). OnHit gets called in the reverse case, when the player hits something, and again, the victim is passed into the call. I have tested with with a vampirism effect, so you drain the life of whoever you whack! Glee. :D
- Properties are special boolean flags. So for example "Stunned", or "Underwater Breating". When they are active, the player gets certain benefits.
Now, all effects can also have upkeep, which gets payed every tick or the effect ends, where the upkeep can be Mana, Health, or Stamina. So, for example, I made that Vampirism effect have health upkeep, so the player had to drain the life from others or he would slowly die! Great fun.
Effects also can have a radius defined. When the script processes, it applies its effects to everyone in that radius. So for example I made an effect creatively called "Death Aura" which damages anyone in a 10 unit radius around the player. You can set the effect to exclude the player if you wish, which in this case is a good thing, but you might not want to if you have the reverse, and Aura of Healing.
When you create an effect instance, you assign it a duration and a level value, which determines the magnitude and range of the effect. So that Death Aura I mentioned didn't actually have a range of 10 units. It had a range of 5 + 1/level units. And it did a base damage of 5 + (1-3/level). All easily defined in the DB :D
All of this is great, but not so amazing without some graphics. The first aspect of this is the Arcane Effects tie-in. Basically, for anyone who has the pack, I have split the spells into two conceptually different parts. The "spell" part is what applies an effect, the effect itself is my custom built RPGEffect described above. Which, itself, has reference to a Afx Effectron which it creates when it is applied, and ends when it dies.
That might be a bit difficult to understand, so let my use an example. The Spirit of roach spell. When you cast it originally, the player raises his hands, there are particle effects and whatnot, and a cool spinning energy shield shell appears around the player. In Afx, this is one spell. Now, I am splitting it. The animations and initial particle effects are the spell, and at the end of this spell it uses Afxs ability to make script calls to apply one of my RPGEffects. The RPGEffect has no graphical aspect itself, but it starts a Afx Effectron which creates and spins the energy bubble around the player. This Effectron has an infinte duration, but the RPGEffect will end it programmatically when its done.
The other graphical aspect of my RPG effect is an "Active Effect" list. Basically, for those of you who have played WoW, think that little list of icons at the top of your screen showing you the effects applied to you. Not only does my framework track and manage the RPGEffects, it ghosts some of the details across to the player, where it then uses those details and the super cool StackControl gui to create a list of icons with duration details (Note, still programmer art though ;)) :


So sweet, the taste of victory! Its all working, and working well. This is a major component of my game that I had still to do, and it feels good to have it done. I can now add in the code which translates item enchantments into actual effects!
On the design side, I have also been doing something I should have done a long time ago, fleshing out the plot and setting details, building a list of game locations etc. I have a "vague" idea before, but with a more concrete target to aim for, I'm much happier. Although, a good name for my game still eludes me....
For those of you who have been following my posts, you might remember that I was working on upgrading my items system. Thats done. To recap, an item is generally built from a base template.
For example, "Steel Longsword" is a base template. You then apply modifiers to this template, which affect the items stats. So for instance, "Rusted" is a modifier, which, when applied to an item decreases the damage by 1 and drops the items durability. On top of this you can add enchantments to the item.
So I got that all working, and its groovy, except for the enchantments. Enchantments were just text entries in the "enchantments" field of the item, but that didn't correspond to anything, since I had been putting off working on them.Deciding it was time to bite the bullet, I moved on to tackling "Effects".
Now, what exactly are Effects? Well, pretty much any effect that can be applied to a Player. Damage over time, Poison, "Buff" spells, Curses, etc. It requires a very flexible framework, to handle all the possibilities. So I set out to design a powerful and flexible framework. It needs to be able to track all active effects on a player, removing them when their lifespans expire. More than that, it needs to be able to save out the effects and load them back in. There are also issues involving effects stacking. For instance, when a player casts "Enhance Strength" on himself twice, what happens? If both effects took place it would be a bit of a cheat, wouldn't it? You could just cast 10 buff strengths on yourself and walk around beating the living daylights out of things. So effects have to overlap, in some cases. You can't just overwrite the previous effect. Think about what happens if, for example a player has a strength buff (+2) effect lasting 10 minutes on them, and then they get a short lived 2 minute buff of +10? For most players, you would expect 2 minutes of +10, followed by 8 minutes of +2, right? So this framework has to keep track of all effects that overlap, and only apply the "best".
So thats what I built :D. All my effects are loaded from a database table, and if their stack type is "overwrite" then it manages the effects as I mentioned above. Of course, you can specify that the effect stacks, so that in the case of poison for instance, the more poision effects you are afflicted by, the worse off you are. I also have a field for "exclusion group". If an effect is a member of an exclusion group type, then when it gets applied to a player it ends all other effects that are also part of that exclusion effect. This is useful for example with mental spells. You could have a "Crushing Despair" and a "Berzerker Rage" spell both as part of the "Emotion" exclusion group. This ensures that you cannot be enraged and despairing at the same time ;). Its also useful for say combat stances. If you have a defensive stance and offensive stance effect, it makes sense that you can't have both at the same time.
As to the effects themselves, there are 3 components to them : Modifiers, Events and Properties.
- Modifiers are what you'd expect from Buffs/Debuffs. Basically they alter one of your stats for the duration of the effect. Enhance Strength is an example of a Modifier, but it could be anything, enhancing your Fire Resistance for example.
- Events are, well, stuff that happens on an event. There are 3 types of event at the moment : Tick, OnHit and OnDamage. Every effect has a tick rate, and at every tick interval it calls its Tick script. Perfect for effects which apply over time, such as regeneration or DoTs. When a player gets damaged by something, every effect on him gets their OnDamage event script called, with the attacker being passed in. So you can have effects which damage anyone hitting you ;). OnHit gets called in the reverse case, when the player hits something, and again, the victim is passed into the call. I have tested with with a vampirism effect, so you drain the life of whoever you whack! Glee. :D
- Properties are special boolean flags. So for example "Stunned", or "Underwater Breating". When they are active, the player gets certain benefits.
Now, all effects can also have upkeep, which gets payed every tick or the effect ends, where the upkeep can be Mana, Health, or Stamina. So, for example, I made that Vampirism effect have health upkeep, so the player had to drain the life from others or he would slowly die! Great fun.
Effects also can have a radius defined. When the script processes, it applies its effects to everyone in that radius. So for example I made an effect creatively called "Death Aura" which damages anyone in a 10 unit radius around the player. You can set the effect to exclude the player if you wish, which in this case is a good thing, but you might not want to if you have the reverse, and Aura of Healing.
When you create an effect instance, you assign it a duration and a level value, which determines the magnitude and range of the effect. So that Death Aura I mentioned didn't actually have a range of 10 units. It had a range of 5 + 1/level units. And it did a base damage of 5 + (1-3/level). All easily defined in the DB :D
All of this is great, but not so amazing without some graphics. The first aspect of this is the Arcane Effects tie-in. Basically, for anyone who has the pack, I have split the spells into two conceptually different parts. The "spell" part is what applies an effect, the effect itself is my custom built RPGEffect described above. Which, itself, has reference to a Afx Effectron which it creates when it is applied, and ends when it dies.
That might be a bit difficult to understand, so let my use an example. The Spirit of roach spell. When you cast it originally, the player raises his hands, there are particle effects and whatnot, and a cool spinning energy shield shell appears around the player. In Afx, this is one spell. Now, I am splitting it. The animations and initial particle effects are the spell, and at the end of this spell it uses Afxs ability to make script calls to apply one of my RPGEffects. The RPGEffect has no graphical aspect itself, but it starts a Afx Effectron which creates and spins the energy bubble around the player. This Effectron has an infinte duration, but the RPGEffect will end it programmatically when its done.
The other graphical aspect of my RPG effect is an "Active Effect" list. Basically, for those of you who have played WoW, think that little list of icons at the top of your screen showing you the effects applied to you. Not only does my framework track and manage the RPGEffects, it ghosts some of the details across to the player, where it then uses those details and the super cool StackControl gui to create a list of icons with duration details (Note, still programmer art though ;)) :


So sweet, the taste of victory! Its all working, and working well. This is a major component of my game that I had still to do, and it feels good to have it done. I can now add in the code which translates item enchantments into actual effects!
On the design side, I have also been doing something I should have done a long time ago, fleshing out the plot and setting details, building a list of game locations etc. I have a "vague" idea before, but with a more concrete target to aim for, I'm much happier. Although, a good name for my game still eludes me....
About the author
Recent Blogs
• SoW Weekly Update 10• SoW Weekly Update 9
• SoW Weekly Update 8
• SoW Weekly Update 7
• SoW Weekly Update 6



Associate Tom Eastman (Eastbeast314)
Can't wait to see it in action :)