C# - Generic Configurable Condition checker at Runtime - Achievement System
I'm writing a "generic" achievement system for my MMORPG project, it needs to be friendly & efficient for my game designers (without having to write code to add new achievements). If anyone got some suggestions about good alternatives, I'll be glad to give it a check. (Lua, C# scripting...), many things I've not yet done and I'm feeling more "comfortable" on that option. For that, I thought about a solution, which is a basic configuration file that is linked to an enumeration of "eventType" and provide a list of optional args (based on the Event properties) Here is an example name: ACHIEVEMENT_NAME event_type: ITEM_USAGE # enum as a string, there is a list of event types count: 30 # 30 item usage args: # every args are optional item_vnum: 1127 # vnum - optional map_id: 1 # on map id 1 only - optional public enum AchievementEventType { ITEM_USED, MONSTER_KILLED, } public interface IAchievementArgument { AchievementEventType EventType { get;} } public class MonsterKilledAchievementArgument : IAchievementArgument { public AchievementEventType EventType => AchievementEventType.MONSTER_KILLED; public long MonsterVnum { get; set; } public short? MapId { get; set; } } public class AchievementConfiguration { public string Name { get; set; } public string EventType { get; set; } public long Count { get; set; } public Dictionary<string, object>? Args { get; set; } } public delegate bool AchievementFilter(IAchievementArgument achievementArgument); I thought about generating an expression tree to build a delegate (AchievementFilter) for my "Achievement incremental condition" (Basically, the function that will check if the player's specific achievement counter can be incremented or not) There are two solutions I thought, both have their pros/cons, but I'm looking for external point of view, what do you think about it. (or maybe, another kind of solution that you could present me) 1 expression tree per achievement I generate 1 expression tree per achievement that will compare the IAchievementArgument given as parameter with the achievement configuration. Pros : faster at execution time (each achievement condition have their own delegate) Cons: Memory footprint 1 expression tree per args type I generate 1 expression tree per IAchievementArgument type that will fetch and compare achievement configuration one by one Cons : More execution time (needs to check all key/value equality of each achievement configuration) Pros : Lighter memory footprint
I'm writing a "generic" achievement system for my MMORPG project, it needs to be friendly & efficient for my game designers (without having to write code to add new achievements). If anyone got some suggestions about good alternatives, I'll be glad to give it a check. (Lua, C# scripting...), many things I've not yet done and I'm feeling more "comfortable" on that option.
For that, I thought about a solution, which is a basic configuration file that is linked to an enumeration of "eventType" and provide a list of optional args (based on the Event properties) Here is an example
name: ACHIEVEMENT_NAME
event_type: ITEM_USAGE # enum as a string, there is a list of event types
count: 30 # 30 item usage
args: # every args are optional
item_vnum: 1127 # vnum - optional
map_id: 1 # on map id 1 only - optional
public enum AchievementEventType
{
ITEM_USED,
MONSTER_KILLED,
}
public interface IAchievementArgument
{
AchievementEventType EventType { get;}
}
public class MonsterKilledAchievementArgument : IAchievementArgument
{
public AchievementEventType EventType => AchievementEventType.MONSTER_KILLED;
public long MonsterVnum { get; set; }
public short? MapId { get; set; }
}
public class AchievementConfiguration
{
public string Name { get; set; }
public string EventType { get; set; }
public long Count { get; set; }
public Dictionary<string, object>? Args { get; set; }
}
public delegate bool AchievementFilter(IAchievementArgument achievementArgument);
I thought about generating an expression tree to build a delegate (AchievementFilter
) for my "Achievement incremental condition"
(Basically, the function that will check if the player's specific achievement counter can be incremented or not)
There are two solutions I thought, both have their pros/cons, but I'm looking for external point of view, what do you think about it. (or maybe, another kind of solution that you could present me)
1 expression tree per achievement
I generate 1 expression tree per achievement that will compare the IAchievementArgument
given as parameter with the achievement configuration.
- Pros :
- faster at execution time (each achievement condition have their own delegate)
- Cons:
- Memory footprint
1 expression tree per args type
I generate 1 expression tree per IAchievementArgument
type that will fetch and compare achievement configuration one by one
- Cons :
- More execution time (needs to check all key/value equality of each achievement configuration)
- Pros :
- Lighter memory footprint