I have completed the refactored procedural quest system for GearHead Caramel. Some of you might remember that this is the big thing I’ve been working on for most of 2023. Poor health, especially the severe brain fog I had for six months, prevented me from getting much work done. But now I am in Canada on vacation visiting my family, so I’ve finally got it done. You get a lot of free time in Newfoundland in winter.
Here’s how it works. You start by describing the potential outcomes for the quest- an Outcome is defined by a verb, an object of the verb, and some Lore which describes the outcome in more specific detail. The verb is selected from a list of standard options. The subject is usually a character or a faction. So, an Outcome might be something like “Defeat Aegis” or “Overthrow Frank”. So far so vague. The Lore describes this outcome in more specific detail, like “Aegis is trying to steal a shipment of impervium” or “Frank is a massive jerkface and we all hate him”. In addition to text descriptions, Lore also has a category and tags so the program can understand how to process the lore.
Each Outcome is then used to generate one or more Conclusions. The Conclusion contains the gameplay elements of the Outcome- usually a boss fight, or some other climactic encounter. The Conclusions then add a number of Tasks- actions which must be completed to unlock the conclusion. The Tasks and Conclusions are atomic; they don’t communicate with each other, and are only connected by Lore. In general, a Task will inherit some Lore from the Task/Conclusion it leads to. It will lock one piece of Lore, and add a new piece of Lore. A Task or Conclusion is activated when all of its required Lore is known by the player.
Take that, Frank.
For instance, the conclusion to Overthrow Frank might generate a Conclusion in which you have to blow up Frank’s house. To do this you need to know both “Frank is a massive jerkface and we all hate him” (inherited from the Conclusion) and “Frank is at home eating crackers like he knows the place”. A Task is added which locks “Frank is at home eating crackers like he knows the place” but adds the new Lore “Nobody knows where Frank is right now”. So to complete the quest, first you have to figure out where Frank is, then you have to go blow up his house.
Note how the mechanics of the quest are separate from the narrative of the quest. This should allow greater versatility and re-use of components. When creating a new procedural narration technique, those are very important things.
After the Quest is built, any “hanging lore” which doesn’t get revealed by a quest Task is handed off to a Lore Handler plot which will allow the player to learn the lore from rumors/conversations.
A Quest can have multiple Outcomes. For example, the Overthrow Frank quest might have a separate Outcome where you can “Help Frank become king of everything”. A single Outcome can have multiple Conclusions, so instead of blowing up Frank’s house you might be able to overthrow him by fighting him in a one-on-one duel or by bribing his bodyguard to stuff him in an envelope and mail him to Norstead. The first Conclusion to be completed ends the Quest. Multiple paths through the Quest will be generated naturally, whether or not there are multiple Conclusions/Outcomes.
The system seems to be working as intended (after a whole lot of testing and debugging yesterday). I need to add more content, then I’ll make a release as soon as possible. In the meanwhile you can read the source code for the quest system here.