Soulfused Devlog #4
I've been talking about Soulfused as being feature complete for a while now and I stand by that. Still, I've found myself more often than not working on new features, polishing, tweaking and bug fixes rather than the more immediate work that remains: Bringing the story over from various flow charts and into the game. In this devlog I thought we'd take a look at my setup, the work that remains, and my plans to wrap it all up.
What do you mean procrastinating? I'm not procrastinating. Well, maybe just a little...
Flows and charts
When I first started mapping out the story for Soulfused I opened a new Miro board. I've used Miro many times in the past and I've gotten used to working with it so it felt like a natural place to begin. Miro is a sort of online whiteboard app which has many different tools for planning and mapping. It is intended to be a cooperative tool but it works just as well solo. I used the flowchart tools to create the overarching narrative with its twists and branches, which is something Miro is quite good at. The problem came when trying to go into more detail about each mission such as characters or even player choices.
Unfortunately, it also requires a constant internet connection, and will quickly become painful to work with if it gets even slightly spotty.

The screenshot above shows an example of a mission in Miro. It shows the map, details of each room, and finally details for all different types of content that might exist in a room. This worked great for getting an overview over the pieces that exist within a mission, but updating it became a hassle.

Arcweave solved some of the issues I was experiencing with Miro. It is less flexible than Miro, but makes up for that in features more relevant to writing stories for games. For example, it allows adding components that can be assigned to several elements. This lets me create locations, NPCs and items that exist beyond the scope of a single mission, having them accurately update through the story as they change.
Arcweave is a tool designed to handle branching storytelling and it worked well for my use case. It also allows me to track variables through the scenario and then "play" it to see what the outcomes would be.
It even supports exporting to various game-friendly formats, including into editor plugins. That could have been a great help, but by the time I started using the tool I was already too deeply into my own setup. Like Miro, Arcweave is also an online tool, but I found it's a bit more lenient even when the connection isn't the most stable.
All the objects!
I started using ScriptableObjects as the building blocks for the Soulfused narrative relatively early in the process. There are pros and cons to this setup, the biggest pro being that it would be relatively easy to serialize a mission into a single data file. (I say "easy," but there's a couple of exceptions from third party dependencies. We'll talk a bit more about this later.)
On the other hand, the biggest downside is that it's tedious to work with. Maintaining an overview over the scriptable files and their connections is tricky, and I find myself losing track. I've lost track of the number of times I've sat down to bring data over from Miro and Arcweave only to hit a motivational brick wall after a short time.

In this picture you can see an overview over the different Scriptable Objects in the game. Most of them are based out of the Base Scriptable, which is an abstract class that handles all the shared data types and behaviors. This is mostly things related to IDs and naming.
The Library on the top of the chart acts as an access point for all Scriptable Objects within the game. It loads and maintains an overview of all the Scriptable Objects available at any given time, making the them easily accessible where they are needed within the game. All data in the Scriptable Objects are treated as read-only at runtime, hiding all data in serializable private variables behind public getters. In simple terms, this prevents the game from accidentally changing the raw data.
Building the Missions
Initially I was doing all the editing of the missions directly on the Scriptable Objects. While that is a fast and easy way to work, it also gets out of control really quickly. As I mentioned, keeping track of them gets more complicated as the project grows. Already by the 4th mission I could feel like I was spending too much time navigating folders and trying to remember how to correctly link everything. I can't imagine how it would be once I started working on the endgame.
So instead I took a step back and built a Mission Editor!

The Mission Editor isn't a perfect solution, but it's a game changer. It's able to handle about 80% of the mission construction and saves me the organizational nightmare of continuously jumping between folders, remembering filenames, forgetting links, and so on. It is able to handle the creation of (almost) all objects listed in the graph above, as well as editing them on the fly and deleting them. It lets me link objects by type and will alert me if something is suddenly missing. It's even able to do a little "spring-cleaning" and delete objects that are no longer used. It lets me quickly mock something up, jump over into the game, play it, and delete it again without fearing that I'm cluttering the project unnecessarily.
The one thing I haven't been able to pull into the editor is the NPC dialogs. They are created using a separate editor tool and must still be linked after a mission is created. The reason for this is a reliance on third party editor tools, which gives a nice visual view of the dialog. It's a fair tradeoff, in my opinion.
Next steps
Okay, so there are two parts to this. The main goal right now is to actually bring all the data over into the game and wrap up all the mission content. Of course, that's an oversimplification. There's still a lot of work remaining in putting all the pieces together, but this editor should make it less tedious.
I do also have to admit that part of me wants to go fully serialized, and have each mission be it's own self-contained file. As all data is already serialized in Scriptable Objects, this is in no way an unreasonable goal! It would mean that I would need to find another solution for the dialog, but other than that I feel like I'm already almost there! Doing that would also enable me to separate the Mission Editor as a standalone tool that could be bundled with the game. Imagine players creating and sharing their own text adventures using Soulfused almost as a text adventure engine! Wouldn't that be awesome? It's the kind of "easy" that looks great on paper but is probably much harder once I start working on it. I'm already feeling way behind on finishing the game since (as you might know if you've been following along) my priorities took a sudden shift in December. So for now, I'm settling for putting the serialization task into the "After Release"-backlog and staring at it longingly occasionally.
Join us on Discord if you want to chat about the game, or find me on Bluesky if you want to follow along.