Sto creando un gioco (beh, un plugin) in cui ogni giocatore ha una lista di abilità, ognuna delle quali ha un unico type object , ognuno dei quali ha un elenco di azioni che devono essere eseguite quando un giocatore esegue le sue abilità. Ho disegnato un diagramma per mostrare le mie classi: link
Ed ecco un rapido mockup in pseudo-python:
class Player:
    def __init__(self):
        self.skills = []
    def execute_actions(self, **event_args):
        for skill in self.skills:
            skill.execute_actions(player=self, **event_args)
class Skill:
    def __init__(self, type_object, level):
        self.type_object = type_object
        self.level = level
    @property
    def name(self):
        return self.type_object.name
    def execute_actions(self, **event_args):
        if self.level > 0:
            self.type_object.execute_actions(skill=self, **event_args)
    # more type_object properties
class SkillType:
    def __init__(self, name, max_level):
        self.name = name
        self.max_level = max_level
        self.actions = []
    def execute_actions(self, **event_args):
        for action in self.actions:
            if action.event == event_args['event_name']:
                action(**event_args)
class Action:
    def __init__(self, event, callback, group=None, cooldown=None):
        self.event = event
        self.callback = callback
        self.group = group
        self._cooldown = cooldown
   @property
   def cooldown(self):
       if self._cooldown is not None:
           return self._cooldown
       if self.group is not None:
           return self.group.get('cooldown', None)
       return None
# Usage
player = Player()
fireball = SkillType('Fireball', 5)
def fireball_deal_damage(skill, player, target, **event_args):
    player.damage(target, skill.level)
fireball.actions.append(
    Action('player_attack', fireball_deal_damage, cooldown=5)
)
player.skills.append(Skill(fireball, 1))
Quindi, questi tipi di abilità e azioni sono effettivamente analizzati da JSON:
// skills.json
[
  {
    "name": "Fireball",
    "max_level": 5,
    "actions": [
      {
        "event": "player_attack",
        "action": "deal_damage",
        "data": {"amount_base": 3, "amount_per_level": 1},
        "cooldown": 5
      }
    ]
  }
]
 L'azione sopra ha un cooldown di cinque, che è abbastanza facile da implementare, basta dare ad ogni azione un dizionario di tipo   {Skill: time_when_last_used}    in modo che segua ogni cooldown dell'istanza   Skill    per quella particolare azione. 
Il problema è che a volte ho bisogno di avere più azioni che usano tutte lo stesso cooldown (forse l'incantesimo palla di fuoco ha bisogno di infliggere danno e accendere il nemico, quindi sono due azioni separate), così mi è venuta l'idea di " gruppi ":
// skills.json
[
  {
    "name": "Fireball",
    "max_level": 5,
    "actions": [
      {
        "event": "player_attack",
        "action": "deal_damage",
        "data": {"amount_base": 3, "amount_per_level": 1},
        "group": 0
      },
      {
        "event": "player_attack",
        "action": "ignite",
        "data": {"duration_base": 0, "duration_per_level": 1},
        "group": 0
      }
    ],
    "groups": [
      {  // Group 0
        "cooldown": 5
      }
  }
]
Ora alcune azioni useranno il cooldown di questo gruppo, quindi non è più così semplice come dare ad ogni istanza di azione un dizionario. Tuttavia alcune azioni useranno comunque un tempo di recupero individuale piuttosto che un tempo di recupero di "gruppo". Come potrei continuare a implementare questo?