A simple story engine

I'm planning to create a linear adventure game. Or at least that's the current blurry vision in my head.

I've done one "select your own adventure" -style game a long time ago, so I know a bit what to expect. Here are my thoughts on what I'm going to create:

The spec

The story will be linear without any branching. Why not? Well, at this point every additional feature will multiply the development time. If I create multiple timelines that may interfere with each other, I'd assume something like n2 growth.

I want to load a static world from the get-go, where I'd swap objects on and off as the story progresses. It may become a problem later if I have a lot of audio clips that I'll need to load at the start, but I'm pretty confident I can optimize that with a few different techniques (additive levels, asset load deferring or audio streaming from disk) if needed.

Now the most important thing when putting together an adventure game is, that you'll need to be able to jump into a specific point in the story many times around. So this needs to be a really central feature of the story engine.

Stating the state

So onto the big questions: How am I going to store the game state? To know that I'm going to model my state a bit.

Since I'm having a linear story, I'll need to have a pointer to a certain time at my storyline. In-game events happen that move that pointer one step towards the end.

I should be able to recreate the world to any given state in the time without side effects. So my model is somewhat like this:

Game progresses in steps when an event occurs

So basically I only need to store one little piece of information: The pointer to the current state of the world. And then all objects in my world can adjust themselves to that state. For this I chose a simple enum value that represents a list of all possible states my world can be in:

enum State {
  WakeUpMiddleOfTheBattlefield,
  GetToTheChoppa,
  SayAFamousMovieLine,
  KillTheBadGuy,
  SaveThePrincess,
  TheEnd
}

What's the thing you're not supposed to do?

Ah, singletons. Let's slap one of those in to hold the state. Then my world can subscribe to any changes of that singleton, and voilà: We have a way to control anything based on the game state.

Noooo you can't just use global value to hold your state you need to use dependency injection or actor model to make implementation-independent interfaces — Haha singleton go brrr.

I added a couple of simple helper scripts that automatically subscribe to the state changes and turn the object's functionality on or of based on the game state.

A script that enables the object based on the current state

Resisting the urge to create a custom editor for that component is pretty hard, but I've managed to do avoid it for now 😅