So the theme for this month was "Rogue," and I figured that was a good excuse to be a little experimental.
I settled on two ideas for this month:
- Combine two things that have no business being together.
- Implement a Peter Molydeux idea.
1. Combine Unity and Twine
Unity, of course, is the increasingly-popular and learner-friendly 3D game engine. Twine is the also increasingly-popular tool for creating web-based "Choose Your Own Adventure"-style interactive stories. Twine is also, at a basic level, a graphical dialogue tree editor. The underlying source format for Twine stories, called twee, is a very simple text-based format. After some investigation and test code, I decided I could use Twine to create a large, complex conversation tree with minimal headaches, and the result could potentially be playable as a standalone Twine game while also serving as the dialogue tree data file for my Unity game.
2. The Peter Molydeux Idea
After some consideration, the idea that appealed to me the most was:
This works well with the idea of creating a dialogue-based game, and I thought the concept had a lot of interesting thematic ground, so, off I went.
(Update - after having several people ask me for more details about this part, I've put together a quick and dirty Twine/Unity tutorial with more specifics about how I handled this part of the game.)
This part was remarkably straightforward. Twee files have a basic format of:
:: Passage Title [tag1 tag2] Passage body [[This link leads to another passage|Another Passage]] :: Another Passage [tag3] More text goes here.
Writing a parser for that was trivial, after which my game could navigate the entire story easily. Piece of cake.
Right, except for the part where web browsers are built to display text that's clickable and links to somewhere else. Unity, not so much. So there was some functionality that needed to be written from scratch. I debated trying to get this working with UI text but eventually settled on creating a prefab that displayed a 3D text mesh of an individual word, clickable where appropriate, that used a collider and raycasts to react to mouse events, which allowed me to do mouseover highlighting as well as making text clickable. A clicked word sends an OnTweeNavigate(string passageName) event to a listener that handles the actual navigation.
With that working, I set up a standard format that I would use for all of my twee passages so I could include both parts of the conversation in each passage. Since twee allows passages to be tagged for convenience, but those tags are never shown to the user, I also settled on a consistent tag scheme so I could pass information to the game whenever a particular passage is displayed. In the end, the passages looked something like this:
:: Example Dialogue Passage [camera:one event:exampleEvent earth:24,topLeft] This is the text that the "Earth" voice speaks in this passage. ---- *[[One of the Asteroid's speech options.|Another passage]] *[[Another speech option.|Somewhere else]]
When this passage is displayed, the game:
- Tells the camera manager to move to camera target "one"
- Broadcasts the event OnTweeEvent("exampleEvent")
- Moves the Earth voice to a preset target position named "topLeft"
- Sets the font size of the Earth voice to 24pt
- Displays the text above the "----" in the Earth voice
- Displays the text below the "----" in the Asteroid voice
This is probably the part of this experiment I was most happy with. I could use Twine to visually plan out dialogue, and wherever needed I could set pre-determined parameters or, for complex events, raise specific event IDs that could trigger whatever code is appropriate.
I also had a decision to make here. If I used this feature for any mandatory game content, it would no longer be playable as a web-based story. And, while I was thinking about it, it meant I couldn't use any of the advanced code features of twee unless I wanted to re-implement that functionality in my code. I decided to limit myself to a simple dialogue tree setup with the special tags for Unity content, and see if I could keep the game playable both in Unity and as a web page. This has the added benefit of presenting the same game in two very different forms, but having identical content, to see if the added visuals and music add or detract from the story.
If you're just going to have one conversation in a game, it had better be a big one. This was definitely a point in favor of using Twine for planning out the dialogue - I would not have wanted to implement this conversation without a visual tool:
For the record, that's 109 content passages, with 238 links connecting them, containing over 8,000 words.
To me, the most interesting angle on the original Molydeux idea was the notion that everyone hates the asteroid, an object which presumably has no control over its course or its effect on those on Earth. As a result, several of the paths through the story focus on why the voice from Earth hates the asteroid, what it hopes to achieve through that hate, and how the people of Earth regard their own role in the events that are presumably about to occur.
Overall, there are five major areas of conversation that are largely independent of each other, and within those areas there are many paths you can take through them. All of them resolve in some way, and eventually lead to one of three conclusions. If there's a notion of "winning" in this game, that's probably where it is - of the 24 exit points of the conversation, there are five that go to a generally positive resolution, while five others lead to a much more negative resolution, and the remaining 14 go to a more neutral resolution that implies more could have come of this. At the end, the reader is given the chance to go back to a key point and try taking the conversation in another direction, which allows more exploration without requiring the reader to just replay the story from the start each time.
Is Twine Integration Worth the Effort?
Right now I'd give this a qualified "yes." There are definitely some benefits to using Twine for a dialogue tree planner, most notably of course the visual representation of the paths through story/dialogue sections, but there are some other features that came in handy along the way, like automatic detection and visual indication of broken links and a simple RTF exporter for spellcheck and proofreading.
Another big perk in a different type of project would be that if you're strictly using it as a dialogue planner and not trying to produce a playable Twine story, you don't have to worry about having a single entry point, so you could easily use a single Twine project to plan out a large set of smaller conversations. So far I haven't seen any reason why a game with appropriate dialogue requirements couldn't have its entire dialogue script implemented in a single Twine project.
There were some setbacks and issues, some of which I'm hoping will disappear as Twine gets more popular and has more developer interest. As of right now (version 1.3.5), there were several bugs and missing features I encountered along the way, ranging from minor inconveniences (syntax highlighter is a little buggy, exporting twee source isn't considered a common command for normal users so there's no keyboard shortcut) to annoyances (creating a new passage from the menu command more often than not placed the new passage several screens away in the workspace) to occasionally infuriating failures (the search function commonly did not work, telling me that even intentionally ridiculous searches like "and" didn't occur anywhere in my story). The search function was the only one that caused me to waste some time, because it made it nearly impossible to track down any specific issues in the text that I found during game testing - the game doesn't need to display passage titles, but I can't reliably search the body of passages in Twine, so I had to add some code to help me match those up.
So, yes, there are some kinks that need to be worked out, but if you just need a (free!) dialogue tree editor for a non-Twine project, you could definitely save a lot of time overall by just writing a twee parser and using Twine for your writing.
The Result - Is it a Game?
As expected, when the entire game consists of a single extended dialogue sequence which, since natural language processing and AI simulation are really outside of the scope of my 1GAM development time this month, is entirely pre-scripted, there's only so much "game" to be had. It's really more of an interactive story, as many Twine projects seem to be, with a Unity implementation that adds some visual flair and some very effective mood-setting music by Ben Freund, and while none of that is necessary to experience the story, I think it definitely adds to the mood and makes more of an impact.
I think what I'd hope for is that it's at least interesting enough to encourage a few moments of thought about when we hate, and why, and how particular we are about selecting the targets of our anger.
And I suspect this will not be the last time I base a 1GAM project on a Peter Molydeux idea. Not every game can be 100% unique, but the sea of games out there that never even aim for any degree of uniqueness just bums me out.
These builds are untested but should be playable: