I’m not perfectly sure that I get your meaning, and it might well be that you’re not at all asking about something quite as simple as what I’m going to say, but nevertheless – here goes …
You can create the goal kind and the achievement kind and give achievements the property of having a list of goals.The lists of goals for each achievement can start empty and be manipulated at will (removing a goal from it when completed, or giving goals a boolean completed/uncompleted property that can be set by some other code when the player does what is needed to meet the goal, etc.).
[code]A goal is a kind of thing. [A goal can be completed or uncompleted.]
An achievement is a kind of thing. An achievement has a list of goals called to-do-list.
The F-grade is an achievement.
The A-grade is an achievement. [The to-do-list is {alpha, beta, gamma}.]
This is reminding me of a problem with the Jira issue-tracking system. Jira has relations between issues and it also has “subtasks.” Subtasks can’t have subtasks, but relations are always directed and many-to-many. I’m not sure if you actually want to deal with a dependency tree, but if you did, you wouldn’t have to deal with lists and you’d have more flexibility.
Events can be just any kind of condition, right? You can’t put such a motley crew into an I7 table column. To do that all your events need to be of a kind (all actions, say, or all truth states).
If you just want the conditions for completing the different goals collected at one place in your code, you could put them all inside an every turn rule.
Every turn:
if the dragon is dead, now slaying the dragon is completed;
if the player carries the blue bird of happiness, now finding the blue bird is completed;
if the Riverbed is visited, now finding the Riverbed is completed;