Things I wish I'd known writing my first ChoiceScript game (+ add yours)

I’m still new-ish to writing ChoiceScript and crowd-sourcing organization best practices. What helped you muscle through your first game, or what have you learned and adopted to make the process easier for yourself?

Here are a few things I learned, please add your own!

1. Sublime Text with the ChoiceScript mode on is better than a plain .txt file for drafting (and trying to draft in Word will bite you later.)

2. Pick short variable names you can reliably spell without typos for your key stats.

3. Have your startup.txt file open in an alternate screen for reference and to easily add new variables.

4. Create a syntax cheat sheet with syntax reminders and house style items for easy reference and copy/paste (em-dash, I’m looking at you.)

5. A whiteboard that lists your primary stats, goal stats, key NPC names, and any other reminders you need readily visible is helpful.

6. An outline (per the COG guidelines) is gold, but I’ve also built myself a broader beat sheet description of game mechanics.

7. Keep an XLS to track wordcount per chapter, an edit checklist, and possibly add story bible pages for characterization notes and other details you want for easy reference. <Thing I didn’t do but plan to do for game 2: track actual stat movement potential by chapter, would love to see other author’s examples of this.>

8. Doing a full text randomtest read for multiple seeds is the easiest way to see/understand your continuity issues. <This thread helped me.>

9. If you’re writing spicy romance, clothing variables are your friend! While some people are totally cool being magically naked or having Schroedinger’s wardrobe, I write contemporary and it doesn’t fly with close readers. lol

10. Searchable placeholders like TBD or <> can help you stay in flow and you can fix it later.

Plus one: multireplace. My enemy, now maybe my friend? My if/then brain balks but it is useful. (Somewhere, Mary is cheering.)

YMMV, but what other sage wisdom is out there?

37 Likes
  1. I just use plain text!
  2. skill issue
  3. Yeah you can drag and drop windows to the left and right so you can write on one half of the screen and display startup.txt on the other. I use Notepad++ which allows half-and-half mode (right click on tab, “move to other view”) which I use pretty much 100% of the time.
  4. I did this and it was super useful. Highly recommend making your own cheatsheet because the act of making it is a good learning tool.
  5. Just stick your notes in startup.txt as *comments instead.
  6. Notes app on my phone is good for this. Include a searchable keyword for later.
  7. I don’t think this is useful. It’s work-coloured but it’s not work.
  8. skill issue
  9. This is a tonne of extra work for an insignificant payoff IMO.
  10. I use [UNDER CONSTRUCTION] because no chance of that ever coming up organically as I write.
  11. Multireplace is very powerful.
9 Likes

I’m not a writer, but I’ve read enough code that I don’t think I could emphasize enough what a great tool multireplace is, and I was surprised when I realized that almost no Hosted Games writers use it. It makes it possible to add so much nuance to the narrative, creating a truly custom experience, without having to copy and paste and modify large chunks of code. And once you get the hang if it, it’s a lot less hairy than it appears at first glance. I wish more HG writers would give it a try.

21 Likes

Wait, really? How come? I just started my first work and it’s already been handy a bunch of times.

Er, not to brag? It just mimics some of ink’s text substitution features and it’s handy for QOL. Is there a downside I’m not aware of?

6 Likes

Do you know of any WIPs with visible code that are good examples of utilizing multireplace? I learn best by example, and I’d love to see some.

10 Likes

I was also going to say multireplace, until I saw it at the end, but I have one of my own to add: CSIDE!

I can’t say enough good things about this development environment. Great for a newbie, but still powerful enough for an expert. It just makes writing so much more convenient. I’m currently writing my first ChoiceScript game, and I started out using it. I can’t imagine trying to do it without it. And those built-in testing tools are great!

12 Likes

A lot of people are intimidated by it, since it is pretty hairy-looking. A lot of HG code looks a lot like a Choose Your Own Adventure book: there’s a block of text, and then you make a choice, only instead of a page number there’s a *goto. (I exaggerate only slightly - most are a bit more complex than that, with variables and if/thens, but still, for the most part, it looks like a text document.) Multireplace looks like computer code: curly brackets, often some parentheses inside the curly brackets, throw some variables in the mix and now you have curly brackets inside the curly brackets. And pipes. A lot of people don’t even know that | is called a pipe, let alone how to make one.

It’s probably an unfortunate reality that some HG writers don’t want to streamline their work. I don’t get the sense that people are being deliberately inefficient to boost their word count, but it’s a lot easier to meet that 30K-minimum word count if the major scenes are all in there four or five times each.

As for disadvantages, the only one I can think of is that, since there are a lot of small moving pieces involved in multireplace, there are that many little mistakes you can make. Forget one of the necessary typographical characters, and the ChoiceScript engine spits it out on screen as text rather than processing it as code. Entering the text variants in the wrong order leads to continuity errors. If you’re not very careful punctuating around the brackets, you might end up with weird punctuation errors. Even experienced writers make these mistakes now and then, and they’re usually worked out in testing or copyedit, so it isn’t actually much of a disadvantage in practice.

19 Likes

This is a sample snippet where you choose your partner and it sets a partner_id, then there are different responses by partner_id throughout the scene. I’ve been using it to vary RO responses/pronouns/actions/details as the scene progresses. It’s more concise and flexible than an if statement on partner_id, and the sections can be super long in between the {||} for each option. (In the example below, partner_id 1 you know, so you ask Luc if he can cook. The others you’re meeting for the first time.) Note: I didn’t quicktest this and it’s been a minute since I drafted in CS, so this may have typos.

9 Likes

Is this a sequel?

3 Likes
  1. *comment is your friend. Use it liberally. Think you’ll forget what a stat (usually one-off booleans) does? Put a comment above or below it that explains just that. Don’t want your searchable placeholders visible to readers? Put it in a *comment. I used to not see the use of it way back in high school programming classes, but it’s so much easier to have this kind of information embedded in the code rather than (only) in a loose document, because this way you can see exactly where those things apply.
  2. Mind the capital letters. When it comes to stats, labels, variables, and other code parts, CODE is not equal to code.
  3. Consistently use either spaces or tabs for indentations. Don’t mix and match. So many coding errors are caused by just these two things.
13 Likes

If you use Notepad++ (which I love), the Choicescript language plugin is gold, and you can pre-code a lot of your code with macros! I’ve got all my pronoun variations, names and other commonly used code down to just a single ALT+[key] stroke. That speeds it up SO much!

28 Likes
  1. Short, unique and descriptive variable names.

As tempting as it is to use ‘*temp a 30’ for a throwaway variable, and whilst you could add a comment to explain what it is for, using ‘*temp cave_en_health 30’ is far more obvious, and is less likely to cause a variable naming conflict.

16 Likes

I am literally only on chapter 3 of my first ever game, so take my words with a pinch of salt, but here are the things I have subsequently gone back and changed/intend to change because I just think they work way better than the way I did it at the start:

  • My best friend, multireplace. When I started, I thought I needed different storylets and scenes for variables in relationships, but now I do most things with multireplace.
  • The VSCode ChoiceScript plugin. I find it the friendliest option of the ones I’ve tried. It even creates a multireplace template when you type @{, which saves me a lot of time because most of my main characters have variable genders.
  • Simple, reusable variables I can use for adding flavour. For example, I have one called “clothes” that I use quite often - it can sometimes affect how other characters see the PC, and affect stats that way, but sometimes it just adds a bit of flavour to the description. I like having one variable I can reset for something like this, rather than making up a new one each time, which I find a bit messy.
  • I want to second what @CodedQuill said about using unique and descriptive variable names, and also add that this should apply to labels too. In my first chapter, I gave things labels like “next 1”. When that didn’t work, I changed to using a format like “Ahmet chat 1/2/etc”. But this was also chaotic because I would change the orders around when I edited things, or even delete labels, so the sequence never made any sense. Now, I pick a couple of key words from the first line after the label, and use that to name it. “*label you_dress_for_dinner” or whatever. It means I can cut and paste sections, or remove them, and it also makes it much easier to remember which label I want each bit to go to. Sometimes labels can be on the long side (up to five words, maybe), but I usually copy-paste them so I don’t mind that.

But as I say, I am mainly on this thread as a learner, so pinch of salt!

16 Likes

As usual, the first and last thing I’d say is that ChoiceScript is for everyone, and that people not ready to bite off learning some new technique can write a great game with clumsy and inefficient code. To anyone reading this and having an allergic reaction to anything suggested, my response wouldn’t be a Will-esque “skill issue” but “come to it in your own time.” :slight_smile: I’m not a good coder myself, and anything I say below might be obvious-to-others bad advice.

I wrote my first game just fine without multireplace, but am a big fan and constant user now. Definitely agree that it’s worth it for HG writers to take the time to get their heads around it, whenever they feel ready. It makes it so much easier to texture the story in response to reader choices.

A lot of people coming here from CYOAs or VNs mentally model their stories as sizeable blocks of text linked by code (hence all the “do you write before you code, or at the same time?” threads). But for my money, the distinctive power of CS text games is in moving away from that model toward stories shot through with a continual degree of responsiveness and variability that would be impossible in any other medium – variability levels that no human-generated graphics or voice acting could keep up with.

When I realize I’m going to reuse a chunk of text, I usually make my gosubs by jumping to the end of the document and putting the gosub block there, after the *finish. That keeps them from getting in the way of the code. Most of my gosubs end up getting called from pretty different places in the document, so I’d need to use CTRL-F on the gosub labels to take me to the text anyway. As a consequence, I usually use gosub labels that aren’t words/names appearing in the text, so I don’t have to jump through extra CTRL-Fs to get there.

Like Malin, I use Notepad ++ macros to save me typing time. I’ve got some common variables like the ${xhe} pronoun loaded up, but also a bunch of nice long ones like:

ALT-I ((ird_focus = 1) or (ird_subfocus = 1))

ALT-S @{sim ${simon}|other}

ALT-C @{cerl_here Cerlota|not}

When I want to pop a multireplace into the code, I’ll usually start with ALT-S and then edit the contents for whatever variable I’m actually checking. (The macro is especially helpful here since my laptop with a UK keyboard layout doesn’t give me an easy way to type a pipe character.)

For syntax requirements around em-dashes and ellipses, I’ll usually go a couple months writing three dots and double hyphens before doing a find/replace with the correct unicode character.

I keep a XLS sheet as a reference for key numeric stats, that lets me quickly remind myself what different values/ranges mean:

I guess my mildly hot take would be that while QT and RT are essential tools, so is manual playtesting. You’ll never really know how your game is flowing as a story if you don’t read through it a whole lot, down all the major paths. RT can help you track a lot of stuff, but not the feel that makes the most difference to a reader.

So contra some of the things said in the writer thread:

I’d say do it again, a bunch of times. :slight_smile: You can’t do it comprehensively for a big complex game, which is probably what Paul meant. But if you want your work to feel like a good story, not a stats-first gaming experience, there’s no substitute for seeing how well it reads down all the main routes.

Start writing from wherever you are, with whatever vision excites you. ChoiceScript is for everyone.

30 Likes

No, actually, it’s a common feature of most programming languages. Not original to ink or choicescript.

Really? :astonished_face: It’s usually to the left of Z, together with the back-slash symbol. Else, it’s somewhere around the Enter/Return key. I mean it’s a very common character in programming, regardless of programming language. I can’t believe UK devs don’t have access to a pipe character. :sweat_smile: Sometimes, the character on the keyboard looks sectioned, like a smashed colon, but that’s to distinguish from the I key.

I’d say it probably makes it easier to skip initial chapter you’ve already tested. Either by commenting them out from the scene list or skip to them with goto at the end of startup. It’s also important to pre-set values to variables simulating a play through up to that point.

5 Likes

I wasn’t aware one could feel imposter syndrome even with three full games published, one of which did pretty well. But here we are. I don’t do most of this. I only understand about half of it.

23 Likes

Happy cake day!

4 Likes

Having autoreplace replacing them automatically as you write is great too, although whether or not that’s possible depends on the program you’re writing in.

You can’t use multireplace inside another multireplace. That’s a downside.

10 Likes

I also regret putting underscores in some of the common (e.g. pronoun) variables. I hate typing {b_he} instead of {bhe} but I’m committed now.

I just made snippets in vscode so I don’t have to copy-paste. I just type .em followed by tab and I get an em dash. Or .el for ellipses, or .var for a variable or .Var for capitalised variable. After reading some of the other comments I should add one for multipreplace too.

I use it for story mode, to highlight romance options and skill changes and checks, thanks to some thread on the forum. Example:

She…

*fake_choice
#Had a sharp mind, though her tongue often got her into trouble.@{sm [+2 RSN, -1 DIP]|}

Another example use:

You place your @{injured bandaged hand gingerly|hand} in his and allow him to @{injured carefully |}pull you to your feet.

I’d offer my own code as an example but I am still newbie and it’ll be hidden until next update, but Powell-Smith does some elegant coding worth diving into. You should be able to easily access code for the first few chapters of CoG titles without paying for them. The Earth Has Teeth is also available on CoGDemos and probably has some good examples.

I think maybe partly because of that people just don’t know it exists. I would of used it way earlier in the process had I known, but iirc it’s not in the CSIDE tutorial or other beginner documentation (I think on the CS wiki it’s listed under advanced uses, which makes it seem scarier than it is, and also harder to find). So the only way you find out is by being pretty active about code diving, asking questions, or talking to other authors.

9 Likes

So far, examples here have been for descriptive text. In choices, I believe people mostly use it to show or hide certain indicators (a heart for romance options, for example) and/or stat changes. Additionally (and I am certain I’m not the first one to do this, but I cannot think of an example), it can be used to vary choices according to a player’s stat(s).

An example from my own WIP, N01R:

#@{skill_indicators_on [INTELLIGENCE ${intelligence} / 2.5] |} @{(intelligence >= 2.5) "Who is this lover you're talking about?"|"Wow! That must have been a [i]really[/i] special friend. I never kiss [i]any[/i] of my friends."}
Explanation because that's a LOT of text that might be unfamiliar.

The “[INTELLIGENCE X / 2.5]” will only be shown if “skill_indicators_on” is true. In the second multireplace instance, the player only realizes that a character means “lover” when they say “special friend” if they have at least 2.5 intelligence.

8 Likes