For the last two weeks, I have been working on a new feature for Tinselfly.
You’ll be able to play most of the game in this little window. You see text descriptions of the areas you’ve unlocked, see all dialogue as text on screen, and interact with the world by pressing buttons representing objects in the scene. There’s not a single graphic.
It’s basically a text adventure.
And I’m incredibly excited about this.
* * *
Ok, ok, this isn’t a feature really. It’s a development tool. What this allows me to do is not do anything at all whenever my partner Marie needs to write a new scene with new props, new environments and new characters. With a few button clicks, Marie will be able to create new things for the player to interact with, and new places for them to explore. She’ll be able to test dialogue trees and play through whole scenes containing multiple dialogues and puzzles, without ever running the game. She won’t have to wait on me to create art assets or scripts, which always takes a dreadfully long time. She can write text descriptions of yet-to-be made assets, which will help me, you know, make them.
As someone who’s already accustomed to writing both traditional text-only stories and text adventures in things like Twine, I’m hopeful that this will be a natural workflow for her.
* * *
For this to work, there has to be a clear separation between the content of Tinselfly and its presentation.
Right now, my Tinselfly scenes — like many Unity scenes — are this soup of things that do stuff… you click on an interactive object, it runs a little script that affects other objects, or variables, or plays animations, or whatever… it works but it’s very unorganized.
For example, imagine the simple act of opening a door in a spaceship hallway that leads to your cabin. Currently:
- There is a 3d modeled and textured hallway the player may walk though.
- There is a 3d modeled and textured cabin that the player cannot see yet.
- There is an invisible physics barrier where the door is, preventing the player from passing through the door.
- The player clicks on the door.
- An animation plays, showing the door opening.
- The physics barrier is removed, allowing the player to pass through.
There’s not that much here, but there’s an uncomfortable combination of visual updates (the door opening), physical scene updates (the physics barrier being removed), and conceptual updates (the player’s new ability to walk through the doorway).
Thing is… the most important part — the conceptual update — isn’t expressed in any direct way in the door script. The player can pass through the doorway by virtue of the invisible wall being removed, but the game has no awareness that a new area has been unlocked.
To make the text version of the game, I need formalized blocks of data for things like unlockable areas, interactive objects and characters that exist completely separately from their visual representation. These data blocks can even exist completely outside of game scenes. They’re just… data.
And then I also need a more limited concept of game scripts, that can’t operate on objects in game scenes at all; scripts that can only operate on the data.
(Many problems in application development can be solved by limiting what things can do, rather than expanding it.)
The flow then becomes:
- The spaceship hallway area is currently unlocked.
- The cabin area is currently locked.
- The player interacts with the door.
- The cabin area is marked as unlocked.
None of the steps above deal with visuals or physical walls at all. They’re just dealing with concepts. The presentation layer of the game then takes care of the visuals. It can detect when an area is unlocked, and play an appropriate animation, and disable the appropriate physics barrier.
Or, if the game is in text adventure mode, it can show a text description of the new area, with a new list of buttons representing the objects in that area that the player can interact with.
* * *
Now here’s the fun part: if every interaction in the game is expressed as simple instructions that operate on pure ideas, you don’t need to actually play the game to play the game.
I can now write some testing scripts that ‘play’ the game just by looking at all the data, and go through every conceivable combination of player interactions with the world, and tell me if the game can ever reach a state where a puzzle can’t be solved, the player gets stuck, or certain important events can happen out of their intended order. I’m sure this will be incredibly helpful moving forward, for both me and Marie, as we make sure the player experience is what it’s supposed to be.
* * *
Moving Tinselfly from a solo-dev project to a multi-person project has been… a complicated process. It’s not just a matter of delegating tasks; the project has to be structured in such a way that tasks can be compartmentalized meaningfully. And so far, they really haven’t been.
While Marie has been taking a break from the project during these updates, this has already helped me fixed other bugs. Which brings me to the moral of the story here: solo-dev or not, this sort of work makes the project more maintainable, and stable, and testable. I started this so that Marie could do her job more efficiently, and it’s making everything about the project better.