Software Architecture designed to handle events in Angest
(Disclaimer: Victor is now Unity Engineer at Touch Press Inc. but worked as Project Lead Engineer at Black River Studios during the development of Angest)
This article will cover how we planned to manage both Take & Event Systems to meet the need of having multiple arrangements in the same scene. Also, how these systems made scripting and debugging easier for both GDs and QA team.
Angest while keeping high performance. Angest is narrative-driven game made by Black River Studios (Finding Monsters Adventure, Rococo VR, Rock & Rails) that has been recently released for GearVR.
The game has lots of events to respond to the player's input and they follow certain gameplay rules on how and when to be triggered. They have to happen at different states of the game and persist between scenes. Since Angest has alternative paths regarding player choices, there was a lot to consider.
In our game we have a system of “takes”. Take is a custom configuration for a scene. In one scene we can have multiple takes which handles its own events that need to be consistent between other takes and scenes. This requires a robust event management system.
As seen in GIF above, when the play button is pressed and the scene starts, inside the Takes Game Object hierarchy only the Take1 Game Object (which represents the current take descriptor being used at the moment) will be active. After the screen fades, an event will be triggered to notify the game that scene is ready to respond to a player’s input and other objects can start its behaviors and set default states.
For example, the system of takes allowed creating a setup of way points different from the scene in completely different moments in the game. With this, it is possible for the player to try different pieces of history and enjoy unique experiences.
This is what the Take Inspector looks like. It contains some information that will be presented to the player in the form of an entry card inside the game scene.
Until now the take system isn’t enough to take care of the different events that we have in any given take inside a scene. It only gives us a good approach on how to organize the objects and activate and de-activate what will be needed for the current take. Here’s where the Event System shines.
Event System & Playmaker
Basically speaking, our event system works based on event states. An event will have a default state when a take starts and its state will be modified by the player’s choice during the gameplay. The image below shows how the events and states are organized in the descriptor’s custom window.
There is a class in the game that is responsible to manage these events under a dictionary which contains a string referred to it and a data structure named as Event Record. The Event Record contains the current state for the event and all listeners attached to it. Once the event is triggered each object will behave accordingly.
It’s important to notice that we used Playmaker (*) to serve as an Interface between Game Objects by using the FSM Plugin. Each object will stand at its default state until all events in which it is registered triggers. This means that if you are using a prefab you can have the same object to behave differently for each take in your scene with different rules. Playmaker is also used to dispatch and trigger the events with a custom action. By mixing together these systems plus a couple more custom actions, we allowed our Design Team to visually create the sequences for the entire game.
[SPOILER ALERT – Contains gameplay spoiler]
In this section I will show one practical example used in our game based on the Take and Event System. When you reach the Aeroponics for the first time, you can use wrench to open the aquarium duct as illustrated in the image below.
If you do so, Konstantin will ask what you’re doing because he didn’t expect you to be that smart. Using the duct check-point with the scissors in the hand will open a new branch of the story that was not in the main flow of events. You will be placed at the Habitat where it is possible to cut the network wires of the computer to access hidden messages and logs to understand more about the story of the game.
But how do we guarantee that all these events are happening during the gameplay? And what happens if we scale to thousands of objects in the same scene? Could we keep track of them? The answer is yes, we can. We also created an Inspector that allows both Game Design and QA Team to understand what’s going on the current scene. By navigating or using the filter field, we can find all the events that were created for the game, its current state and enumerate all the listeners. Clicking on an object in the drop-down menu will highlight the object on the scene hierarchy. The GIF below demonstrates it.
This article got a bit longer than I was expecting! I hope it is useful to someone out there. There is a lot of similarities when developing systems when it comes to Game Development. I doubt that our approach by far is the best for dispatching messages and keeping constancy between objects and scenes, but the big deal was considering Unity plus the usability and freedom to our Design Team to script their own ideal. I hope that this article can help further implementations and game architecture when it comes to event management. Everything was possible due to other engineers on the team, as George Nunes, @Rodrigo Pegorari, @Bruno Croci, @Germano Assis and Kleverson Santana.