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

Jan 26, 2025 - 18:20
 0
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