Saturday, September 20, 2014

Working with ChoiceScript (Creatures)

Note: This post deals with my game Creatures Such as We. As such, it will contain spoilers.

Working with ChoiceScript was not necessarily the easiest transition. It was my first time working with any CYOA scripting language, and ChoiceScript has a steep initial learning curve. It took some work to get past the initial hurdle, but I ended up really appreciating the tools and simple format that ChoiceScript uses, but I do have some thoughts on improvements.

Also, I'd like to say that while the game was assembled and tested with ChoiceScript, I storyboarded in Twine, wrote/programmed with OpenOffice Writer, and resorted to Notepad++ for interpreting automated bug reports.

Programming in ChoiceScript

ChoiceScript is actually deceptively simple of a programming system: it's all indent-based, so the main difficulty is keeping track of indent levels and GOTOs, and the automated testing is powerfully awesome about finding those errors. It was a little annoying needing to use Notepad++ to track them down, but that was all it was: an annoyance. My real complaint is that I would have appreciated better documentation on the commands themselves: there's some really basic instructions on the website, but they don't really cover as many common scenarios as I would have liked, and I had to do a lot of experimentation. I think a little rearranging of the documentation, and some more examples would have gone a long way.

For example, it took me a whole day just to figure out even where I was supposed to write game text. It would have been nice to have a clear description of the file structures in the online instructions. It would have been even nicer for the download file to have really detailed ChoiceScript game tutorial formatting, with all the different kinds of *choice and *fake_choice showing multiple levels of interactions along with text explaining what works and what doesn't. There's a tutorial there already, but it was a little too simple, and I kept running into weird programming problems. That said, once I got the hang of the programming and formatting, it went really smoothly. It didn't have weird curveballs or obscure commands to learn. It was simple to remember and quick to implement.

One of the more appealing features of ChoiceScript was its pretty powerful variable tracking system. Nearly every scene had a dozen or more variables that it was keeping track of (in addition to the permanent ones), and I can't emphasize enough how much I appreciated the simple, easy system that ChoiceScript had to create, set, and call stats.

The simplicity did have some drawbacks. One of the things that I would really like implemented with ChoiceScript is a more robust stat comparison system. Right now, I can compare two numbers against each other... and that's it. There was no way (that I could find?) to compare sets of stats and do something like pick the largest one (for instance, if you wanted to pick out the person with the most affection). So I had to brute force out an affection calculator system by chaining 1v1 comparisons (with appropriate safety precautions in case of a tie). I'd really like a ChoiceScript command that let you compare sets of stats, maybe with a choice either choose a tiebreaker randomly or give priority based on the order that each stat is listed within the set. I've been told this could be done with "arrays", which is a language feature that ChoiceScript doesn't currently support. (As an aside, ChoiceScript does allow you to display to the player stats and progress during gameplay, but I disabled that feature to allow for better immersion into the experience of a relationship unfolding naturally.)

One feature that I would have really liked during testing was the ability to make a Transcript. I asked my testers to manually create their own transcripts (thank you, testers!) but I felt I needed that info so I could get a feel for undesirable characters or choices, or so I could retrace steps if a variable had been set or called incorrectly. The ability to create transcripts seems like an important testing feature that ChoiceScript is lacking. Towards the end of the testing cycle, one of my testers gave me an edit to ChoiceScript datafiles that it would create a transcript. That was pretty cool, but it was definitely a feature that I, as writer-first-programmer-second, would have never thought of or known how to implement myself – it should just be a command that you can toggle on/off, that's part of the system.

I'd say that the main feature that I liked about the ChoiceScript presentation, and why I decided to write in ChoiceScript, was its clean and consistent choice-selection mechanic. It's intuitive and user-friendly, and I think that the structure really makes it easy to get into the groove and feel like the choices are going somewhere and make a difference. I considered Twine, but it felt too free-form, less inviting, and less like an actual game mechanic. I also think that Twine would have slowed down the game: many of the scenes would have needed to have examine points, which would have bogged things down, and there would have been liberal use of undo-and-re-choose exploration instead of getting connected to a path and committing to it. ChoiceScript's choice-selection mechanic was just exactly what I wanted to enforce keeping the game going at an enjoyable narrative pace.

That said, I do have one requested addition to the choice-selection system: an un-selectable choice. Something like how Depression Quest was implemented. For example, something like, "Shoot the zombie (no bullets)" would be a visible, but greyed out choice, if you had already used up all your bullets. They actually already have half that functionality with the "disable_reuse" command, so I don't think it would be too much of a stretch to have a "disable_use" command as well. I have a suspicion that this might be a feature I could implement myself if I knew much about how to tinker with programming, but it's a bit beyond my scope, and I think it should be just a part of the system.

Writing in ChoiceScript

Before I even touched ChoiceScript, I storyboarded the entire game out in Twine, so that I could get a feel for the size of the project, an idea for the setting and the characters, and suss out which sections would require more attention. Storyboarding the entire game was immensely helpful for researching the story before fully committing, and did help head off bad writing before tens of thousands of words were committed, but it still ended up being incredibly labor-intensive: nearly 50,000 words by itself. I could have definitely gotten away with something slightly more basic, if I hadn't let myself be so intimidated by learning a new game design system. It actually turned out that writing in ChoiceScript was fairly fast-paced, because once you get into the rhythm of their system, and if you know your paths ahead of time (storyboarding, yay!) it goes really quickly, and you can easily get into a flow and just focus on your writing.

When I got halfway into ChoiceScript writing, I discovered that I had to establish stylistic rules to give the game consistency. I really wish I had hammered these out from the beginning, because these rules accounted for a good amount of re-writing, but at least it's something I learned for next time.

My first rule was to hover the number of player choices somewhere around four: that number seemed to offer good variety without being overwhelming. I mostly limited fewer choices to obvious path splits, and reserved larger number choices to either NPC selections, or to more complicated emotional scales. The few times I allowed text-entry, I did so to allow greater player self-identification and control, or to evoke a feeling of parser interaction.

My next rule was to avoid page transitions that didn't offer the player a choice (in other words, I avoided the "Next" button). I wanted to keep a strong emphasis on player engagement and autonomy, so every opportunity I had to give players choices, set or call variables, even in small ways, I took them. I only ended up using a single "next_page" command and the few natural scene transitions. This rule actually had a really fantastic side effect: it really improved the pacing. Any time I felt like the scene was running long and needed a "next_page", I'd think about inserting a choice. But then I'd stop and consider: was that choice meaningful to the player? Did it make a different or feel engaging? If not, the scene was just running too long and needed to be trimmed down to what was actually important. I never wanted to implement useless choices that didn't affect the narrative.

I think that maintaining good narrative flow actually ended up being my most important writing directive.

Transitions between scenes were especially susceptible to being jarring: each scene tends to have a specific theme and focus, and that's as easy way to start feeling disjointed. I smoothed out scene transitions by referencing future events towards the ends of scenes, and past events at the starts of scenes. I made sure that scenes felt like they had an impact and a connection to the scenes around them. This made the time flow feel more contiguous.

One of the key ways that I maintained narrative flow was to never reiterate the text of the choice text from the previous page. So for example, if a player chose "Blue cake", I'd avoid, "You eat the blue cake. It's delicious." instead writing "It's delicious." Cutting out that repetition really helped maintain narrative flow. Unfortunately, it made for a very confusing experience if you ever left gameplay and then picked the game back up from where you left off. You'd just see, "It's delicious." What was delicious?

I would really like a systemic way to reiterate the "Blue cake" text at the top of that page. I toyed with manually implementing this in one scene of my game (see the screenshots), but it felt too risky and time-intensive for me to feel comfortable implementing everywhere, so I ripped it out. I got offered some files that allowed me to change the programming, but it was tied in with the testing transcript function, so I ended up not using it. Reiterating choices as a system change did beta test well though, as nobody noticed the transition when it dropped off (and most weren't sure what I was talking about when I asked about it) so I'm recommending it as something that should be standard with ChoiceScript, maybe with "ChoiceReiteration on/off" as a command if you don't want it in your game.

Choice picked by player
Picked choice displayed at the top of the page

The real hair-pulling transitions to get right were the more mundane between branches and merges, and those required a lot more work: specific attention towards line depth, actions, and any variable paragraphs. For example, the philosophical conversations were all based off of a basic system of split → split → merge → merge, which created a natural-feeling conversation with thousands of words that might ultimately boil down to maybe a couple hundred player-facing lines, but all those lines had to still feel connected and naturally flowing. To aid with consistency, I'd tie specific flavor actions or speakers to specific conversation depths and opinions. Testing the paths was crucial, but definitely its own big timesink. Getting transcripts from testers definitely helped with that.

My next rule had to do more with granting the player self-motivation: I avoided PC dialogue whenever possible. I only spoke for the player when referencing the character's internal motivations, never when actually speaking aloud to other NPCs. The few places I did say lines of dialogue for the player would only be clarifications on the choice lines, and those were rare because I was fairly careful to keep the choice lines fully self-contained. (I ended up making separate player voice rules for the in-game game: the zombie-PC is only ever referred to in third person, and that character could say things without the player's input.) I feel like this really helped not only the pace, but the player's ability to identify with and enjoy the character more.

All those rules really helped create what I feel is a more enjoyable experience for the player. It definitely took a lot of tinkering and getting used to, but I think I've enjoyed the process, and I feel well-poised if I ever wanted to do another ChoiceScript game: I won't have to do nearly so much stuff like storyboarding, and I can focus more on what I want to create and how to do it without having to re-write to a newly-formed guide.

Other Issues with ChoiceScript

I did run into one sticky issue with ChoiceScript, which was not with the language or the writing or testing at all. When I was soliciting feedback from the Choice of Games forums, I had someone on there be creepy towards me, and then switch to hostile when I asked that person not to be creepy. I then had to deal with a kind of apathetic response from the moderators, which all felt pretty terrible for someone just getting into the swing of the community and the system. I honestly felt fairly inclined to just cut my losses: release the game, and then never deal with Choice of Games again. But I did decide to give them a chance and escalate the issue and see where it went from there.

Happily, they were incredibly understanding and apologetic, and worked fast to promote better moderator education, clearer forum rules, and a firm stance against inappropriate behavior. It was all an amazing relief, and clearly showed great growth and positive company values. I really appreciated the way they made sure to help make me and others feel comfortable.

Overall, I enjoyed working with ChoiceScript: it has a steep initial learning curve, but once you get the hang of it, it's got a really easy and fast pattern to fall into, and it's created by a business that cares about doing the right thing and improving. I'd definitely recommend it.


  1. *selectable_if (false) #a choice that is always grayed out

    Will the above code work for your intention? The current ChoiceScript can do this.

    And sorry about your experience at the forum. I'm glad that you dug in and saw it through.

    Keep making games you want to play! :)

  2. Lynnea, I'm curious what informs your choice of scripting language to use and whether you have a restricted choice of potential options.

    I ask because I'm curious whether something like Lua or GM script is an option.