NOTE: I am currently not using any frameworks or other game dev tools like Unity - this is purely written using c# 6.0 in Visual Studio 2015. I would be interested to learn about any frameworks or tools that have an implementation of this system for learning purposes, but ultimately I wish to design my own system.
For the past several weeks, I've been working on building (the engine for) an RPG game. The work done has purely been based around things like what happens when a player attacks an enemy, etc. More recently, I've been trying to figure out how to implement the stats system.
If you're familiar with EverQuest, this is the sort of system I'm going for, namely:
- Players and enemies share the same common stats.
- Stats are capped (based on level or otherwise). Example: crit chance cannot exceed 100,
Stamina
cannot exceed 250 at level 40. - Stats are calculated into the basic
Damage
,Defense
andHealth
stats. Example:Stamina
increases theHealth
stat byX
per point. - Stats are affected by things like potions, friendly spells, debuffs, item effects, etc.
- There is a maximum number of effects that can be used at one time (ex. 10)
- Item effects may increase a stat past the cap
There are other details that I'd ultimately like to consider, but this is the primary goal: A player (or enemy) has a set of statistics that, at any given time, can be changed by a (maximum) number of statistic effects.
Consider the following example:
A player with 100 Health
and 10 Strength
has a calculated Damage
stat of 18 (arbitrary). He then receives a buff, increasing his Strength
to 14. If he then drinks a potion that gives Strength + 2
, his strength should be recalculated to 16 (base strength + buff + potion).
The system I am trying to design should be able to calculate the Damage
stat to its new value, regardless of the source of the stat change. Whether it's a potion, spell or otherwise that changes the stat, the stats should ultimately be represented as one single calculated value.
Similarly, when the timer on an item effect expires, the buff should be removed and its effects should fall off.
What I have so far
I have created a base class, holding the individual statistics, and using OnPropertyChanged()
to recalculate base stats when a secondary stat changes:
public int Defense //base stat, no change event fired
{
get { return this._defense; }
set { this._defense = value; }
}
public int Stamina //affects health
{
get { return this._stamina; }
set { this._stamina = value; OnPropertyChanged(nameof(Stamina)); }
}
This works for the time being, but I've already run into snags trying to add item effects into the equation. At this point, I'm simply stuck on the implementation and am not sure about the "proper" way to proceed further.
Edit:
Based on comments to the question, I'm narrowing the scope to be less broad. I would like assistance designing the Statistics
class to facilitate the requirements given above.
public void ApplyStatEffects()
{
Statistics playerStats = new Statistics
{
Health = 10,
Damage = 3,
CritChance = 20
};
Statistics buffStats = new Statistics
{
Health = 5
//only declare properties that are changing
};
//apply a blanket update to the base stats based on current effects
//playerStats += buffStats;
}
Ultimately, what I would like to do is take one Statistics
object (base
) and apply the effects of other Statistics
objects to base
. It should also support things like buff timers and stat caps, BUT:
I'm not sure how to design the properties to make this easier. A few thoughts:
- I could use a
KeyValuePair<>
with anenum
to represent the stats - Make every
Statistic
it's own object with propertiesstring name;
andT (object?) value
. - Roll the current properties into a
List
orArray
.
However, some properties are int
, where others are double
. Additionally, some may be capped in a range 0-100
while others might be capped at x * level
.
How should I implement my Statistics
class to make it easier to apply one or many stat changes like Health + 10, Damage - 2
from multiple sources?