# a look into an RPG achievement system

april 2, 2021
#achievements #knowledgebase
Designing an achievement system without any octopus tangles.

## what does blessfrey consider an achievement?

An achievement is generally an objective used to create a metagame. They can vary in difficulty from an obscure discovery to repetitive use of mechanics to basic participation in the main story. Achievements can even be entirely external to the base game's system like The Stanley Parable's "Go outside" achievement, requiring you to not play for five years. Since achievements can be earned through any in-game system, the achievement system is closely tied to all other game systems.
Completing an achievement usually awards a trophy, gamer points, or possibly something more practical, like a new game mode or an in-game item.
Blessfrey feeds every in-game interaction through its achievement system, and its reward delivery is flexible enough not only to give a trophy but to cause anything to happen in response. Giving a trophy for finding a secret room is technically similar to gaining a Fire Resistance skill after standing on a bed of coals for 2 minutes or opening a new store after $1000 is spent at the mall. The only difference is actually notifying the player that an achievement was completed. Ironically, even though I ignore achievements in most games, Blessfrey's achievement system has become the backbone of player progression and world events.

## how to design an achievement system

Octopus-tangling is a major design concern for a system that is so interconnected with every other system. I could scatter achievement code through every other system, but that would be a problem if I ever need to make a fundamental change to the achievement system. Also, it will clutter the other systems if each system has a bunch of achievements tacked onto the bottom.
Instead, Blessfrey's achievement system, the Knowledge Base, looks more like a mailman between game progress and the achievement system. A mailman Each granular action or world event that contributes to earning an achievement is called a piece of knowledge, which is identified by a key id number. Knowledge is categorized into topics. Event handlers subscribe to topics, waiting for news that a specific piece of knowledge has been encountered. The Knowledge Base itself stores all knowledge and facilitates the learning and forgetting of pieces of knowledge. Event handlers subscribed to the "knowledge_learned" topic will pay out awards. The MessageBus is the mailman that receives information about encountered knowledge and passes it off to all event handlers subscribed to that topic. The event handlers allow me to freely make and delete achievements, and the MessageBus keeps everything separate.

## an example

Let's say you get an achievement for finding the Nurse's Office. The moment the player loads into the Nurse's Office, data will zip back and forth between the MessageBus and the nurse's office object, different event handlers and the Knowledge Base.

1. (Event Handler) At ready, event handlers call the MessageBus and subscribe to topics.
2. (Nurse's Office) The player enters the Nurse's Office. The room object sends itself to the MessageBus.
3. (MessageBus) Receives room object + sends it to all event handlers subscribed to the "place_entered" topic.
4. (Event Handler) NursesOfficeEntered receives room object. If the room is the Nurse's Office, send its corresponding knowledge key to the MessageBus. It can also verify pre-requisites and gather additional data for the Knowledge Base. This way, the system supports anything I'd like to track about when or how knowledge was learned.
5. (MessageBus) Receives the knowledge key + sends it to the Knowledge Base.
6. (Knowledge Base) Finds the knowledge identified by the incoming key. "Learns" by setting that knowledge to true and filling in additional fields if extra data was sent. Sends the knowledge key to the MessageBus.
7. (MessageBus) Receives the knowledge key + sends it to all "learned" event handlers.
8. (Event Handler) KnowledgeLearned receives the knowledge key + calls code for any changes resulting from learning this knowledge. Maybe you'll get a Steam achievement, but if the Knowledge Base was being to facilitate game progression, a quest could update, the dialog system could unlock the option to ask about the Nurse's Office, or you could gain a Codex entry about the new location. The changes can be conditional, too, so the handler can track whether all necessary keys have been received before enacting the change.

To use the achievement system for cyclical world events, you could trigger knowledge to be "forgotten" or ultimately set back to false in the Knowledge Base. This way, the phases of an event could begin anew.

## summary

Achievements can come from any combination of in-game actions, so an achievement system should be designed separately from the rest of the game. I achieve this through a couple of separate objects.

- Event Handlers: The tracking, verifying, and reward payout should be contained within event handlers, which can be generated and freed as needed. They subscribe to general topics and wait for their specific event to occur.
- The Knowledge Base tracks the status of all knowledge in the game and can be used to understand how far the player and world have progressed.
- The MessageBus is very light and only allows event handlers to subscribe to topics and for incoming message to be transmitted through that topic. It has absolutely no unique checks or code to execute, impartially delivering mail to the address on the envelope.
- Another set of event handlers is concerned about the outcome of encountering and learning knowledge and can prompt changes or directly impact other systems, depending on pre-requisites met.
Last updated April 2, 2021