QuollAlpha
Quoll
Quoll

2022-12-14 22:30: Ecce Ada

Hello,

It's been about four months since I last wrote one of these dev diary entries, judging from the previous entry. That makes it about ten months since the last release. And guess what? Remember those reality modification mechanics? I discuss those mechanics in abstract here in this dev diary, but that's not what this entry is about.

That is, rather than the mechanics themselves1, it will instead be about the effects of the reality modification. Or more specifically, it is about how I wrote the code that handles how Ada describes herself when the Playerr2 enters the command "EXAMINE ME" or as I usually do, "X ME"3. It actually takes quite an effort, as we'll see!

(WARNING: This Dev Diary entry contains spoilers for the content in the Apartment and Glitch's Non-Breaking Space Levels. This includes discussion of the solution to one of the puzzles. Otherwise, there's nothing too major, but it may ruin some of the surprise.)

The Part in which Ada Takes a Walk on the Wild (Dog) Side

So being an unabashedly furry game about my fursona, who is a rat, you probably could have easily guessed that Ada will turn into a rat and not just stay human as she is in the Apartment Level. But in addition to being a rat, she can also turn into 12 other interesting critters while in Glitch's Non-Breaking Space (GNBSP). Well, and she can be a boring old human, I guess.

Each plushie that could possibly be found in the Seattle Apartment Level represents a different species she could be. There are 13 plushies that are available, though only a subset, seven of them, are seeded into each playthrough in a semi-random fashion as you can read in the diary entry before this one.4 The manifestation of the properties of reality are represented by the Manifestation Altars, one of which, the Onyx Pawn Altar has a sacrificial platform that requires a plushie sacrifice like the altar in the apartment does.

As you might guess, an empty platform makes Ada human, but any of the plushies change her species to be an anthropomorphic animal in the same vein as the animal the plush is. I say "same vein" because it's not exactly what the animal the plush is in all cases. For example, Autumn the Mouse makes Ada a rat, not a mouse, and Malachi the Panther makes Ada a lynx, not a panther.

Ada's species, as you might guess, is handled by the species Property on the player Thing5. That is, species can be one of 14 values6, which I named after their scientific names:

Note that to reflect Ada being black and thus of African descent, I tried to find particularly African breeds where I could. Though, I made some choices just because I liked other animals better. For example, like cat Ada being a lynx.

But wait, there's more! One of the propositions that can be altered also changes Ada's "body plan". That is, is she anthropomorphic, with two arms and two legs (which I'll sometimes shorten to "anthro"), or is she "tauric"8 with an animal's body instead of legs like a centaur or our fluffy skunktaur tutor Glitch. I don't let Ada be tauric when she's human9, but any of the other species can be tauric.

For the most part the only effect this has on the game (right now, at least) is how Ada self-describes. I have already fully implemented how Ada describes herself the first time she responds to the "EXAMINE ME" command, so now, over this entry I am working on what she says the second time.

To start out, rather than trying to write narratively while also writing the code to adjust what she says based on the current game settings, I first wrote out what she says just for one state, that is, when she is a tauric painted wolf:

Huh? OK, not that it's likely to be relevant or anything, but I can like, uh, totally describe myself through "present me", I guess.

In some sense, with the scrawny flat body, the shortness, the thin arms and legs, I do look like I usually do; that is, a 38 year-old... Well, I guess this is my 22 year-old body... But... that is I look like a black woman!

Sorry, I'm still adjusting to having basically travelled back in time...

Anyway, I'm mostly-humanoid shaped, at least. At the same time, I'm also most definitely an animal person, or I guess the top half of me is... The bottom is... I'll get to that. I don't know what your frame of reference is, playerr, but a common term is "furry". Rather than skin, my body is covered in tri-colored splotchy fur. My ears are pointed and stick out over my head. The fingers on my hands are pretty thick..., with claws at the fingertips. But despite that, I still have a good deal of manual dexterity.

On top of that, or perhaps on the bottom of me, rather than a single pair of legs, my person-shaped torso connects to the entire four-footed body of a painted wolf. Except for, like the head? That's where my torso connects? That part is perpendicular to the rest of my body, and stretches out over a meter behind me.

Yeah, this is kind of not "normal" for me, either. But as Malia might say, "it is what it is." Normally, I feel being transformed like this would inspire joy, but... there's the thing about editing reality, and why I've never... Well, not never... Why I have only done this once before... There is just this feeling of... "normal" that makes what I'm looking at feel... well... "normal".

Oh my god, I'm just like, totally satiating the syntax of "normal". What I mean, is that to change reality is to change the past. And to change the past means to change my entire experience of, like, everything that came before... before the moment we connected to each other. A part of me is saying "these are just your paws, Ada, why are you staring at them?", while another, the seed of the present... Well, she's the one that's telling you that she is not normally a painted wolftaur, but a human being...

Oh, maybe you don't even know what a "human being" is... It's a sort of naked ape who is sometimes, just sometimes, too smart for her own good.

I guess that's like a long way of saying: my tail is very much not wagging right now. This feels very "wrong" to me as those two parts collide. I'm not "set" correctly. There's literally some Bul that is manifesting into me as my current species, and it's wrong. I can feel my ears pressing back into my head in fear as I try to understand... but not that bad of fear... I'm fine, really.

Let's get back to work, OK?

Whew! That's actually a pretty hefty response just on its own. Note that I am writing this dev diary "live" as I make these changes since I want to show how I am going to make this static text handle all the possible variations. But that also likely means I may end up editing or altering this text from when it finally makes it to release beyond what I talk about in this diary10.

However, I think it's also important that my example be as full as possible. As you can read, this instance of Ada describing herself includes a lot of narrative impact, but it also helps to give the Playerr a better description of what these "anthropomorphic animals" actually look like, since, crazily enough, non-furries might play this game. But even more, the description of the body ends up being quite an important part of most transformation fiction, so I'd be letting down my fellow transformation sickos to not include it11.

My work would be easier if I limited the amount of text I have to possibly alter, but then the narrative would be much less rich. Let's see if I can't save both!

The Sequel is Always Bigger

As I said, the text written above is what's written when Ada examines herself a second time. It's pretty long: 506 words, which is much longer than the 188 words that are written out the first time Ada examines herself in the same case of Ada being a tauric painted wolf:

OK, It's not too weird, I guess. Ah, let me see if I can get "past" me to describe myself... Should just show up in italics for you...

I'm wearing a plain teal t-shirt, and like some super cute blue jeans, my hair done up like always in braids with pink beads? And like, I have the same old brown-black fur with white splotches. Y'know, as expected. Oh though, and this is so cool, there are some bright teal streaks in the brown fur connecting the splotches like distant space trade routes from, like, a few months ago after losing a bet with Malcolm! And like it took forever to get galaxies connected, but the effect is great, it's like an effect... or something...

Anyway, I'm pretty relaxed! I guess...

Oh yeah, and I got a couple of pairs of cute pink sneakers on my paws, just picked them up a week ago!

Yeah, see? I myself am aware that I was not a painted wolftaur, but a human, but not my past self. Listen, I know that can be confusing, so I'll defer to past me sparingly.

However, you might be surprised that the 506 words of the second description takes up only 34 lines of code12, while the 188 words of the first description is the result of 104 lines of code! Now obviously some of that is due to the second description currently just being static and not changing when Ada's species changes in the game. However, The first description is implemented to handle that change. For example when Ada is in her "canon" anthro rat form, the first description becomes a different 185 word description:

OK, It's not too weird, I guess. Ah, let me see if I can get "past" me to describe myself... Should just show up in italics for you...

I'm wearing a plain teal t-shirt, and like some super cute blue jeans, my hair done up like always in braids with pink beads? And like, I have the same old brown-cream tapering fur. Y'know, as expected. Oh though, and this is so cool, there are some bright teal streaks dyed through creamy part of my fur near my ropy tail from, like, a few months ago after losing a bet with Malcolm! And like it took forever to get all the streaks dyed, but the effect is great, it's like an effect... or something...

Anyway, I'm pretty relaxed! I guess...

Oh yeah, and I got a pair of cute pink sneakers on my paws, just picked them up a week ago!

Yeah, see? I myself am aware that I was not a rat anthro, but a human, but not my past self. Listen, I know that can be confusing, so I'll defer to past me sparingly.

But another aspect of this is that the first description was the first one of these descriptions where I fully implemented all 14 different species Ada could be, as well as all of their tauric variations. Before I got to this point, I worked with a very basic description that only handled the subset of these species that I actually changed Ada to in my tests.

That is, I didn't really have a good idea of how to organize my code around this, which is what I'm hoping to fix with the second description, and I started doing that by refactoring the first one a little...

The Art of Not Repeating Yourself

There's a very popular coding principle called "Do not Repeat Yourself" or DRY for short. It's meant to counter a pretty common, yet sub-optimal pattern of writing code: copy-and-paste coding. Copy-and-paste coding is exactly what you might guess, and while it's sub-optimal, it's often good for when you're just getting started. For example, when I wrote the website code for generating the Dev Diary Index Page, I copied my code for generating the Release Note Index Page. They work exactly the same and I was very desperate to be done, so I just copied them.

The downside of this method for writing code is also pretty easy to guess. Though I have fixed it as of the time of writing, I released with the Dev Diary Index Page calling each entry a "Release Note". That's why you don't repeat yourself. As you make small changes, you end up having your copies drift apart and have to put in extra effort to maintain the multiple slightly different copies.

A common way to avoid that is to extract the shared code into a helper function that can be called in both places, possibly passing in different arguments. That's also a useful tactic here, as parts of my first description can definitely be reused in the second description. For example, Ada mentions being a "painted wolftaur" in both descriptions, we can put that in a text substitution, [gnbsp-ada-species-description]:

To say gnbsp-ada-species-description:
  let S be the species of the player;
  if S is:
    -- b-taurus: say "cow";
    -- l-victoriae: say "hare";
    -- r-norvegicus: say "rat";
    -- d-draco: say "dragon";
    -- a-squamigera: say "[if the player is tauric]lamia[otherwise]snake[end if]";
    -- e-quagga: say "zebra";
    -- c-hircus: say "goat";
    -- l-catta: say "lemur";
    -- g-gallus: say "chicken";
    -- l-pictus: say "painted wolf";
    -- p-porcus: say "hog";
    -- l-lynx: say "lynx";
    -- m-mephitis: say "skunk";
  if the player is anthropomorphic:
    say " anthro";
  otherwise unless S is a-squamigera:
    say "taur".

Note that I didn't include a branch for when Ada is human because in both cases13, Ada remarks on it being odd that she's a human, so the phrasing is completely different beyond just these words. Well, not that her being a human is odd, But that being a human while in the incredibly furry realm of Glitch's Non-Breaking Space is definitely unexpected. Glitch drops way too many hints that that's going to happen.

In the same way, the description of Ada's "pelt" (that is, her skin or fur or hair or feathers or scales) can be pulled out into [gnbsp-ada-pelt-description]:

To say gnbsp-ada-pelt-description:
  let S be the species of the player;
  if S is:
    -- h-sapiens: say "caramel-colored skin";
    -- b-taurus: say "orange and white speckled fur";
    -- l-victoriae: say "brown-gray fur";
    -- r-norvegicus: say "brown-cream tapering fur";
    -- d-draco: say "bright purple scales";
    -- a-squamigera: say "dusky orange scales";
    -- e-quagga: say "black and white striped hair";
    -- c-hircus: say "white fur with brown and black splotches";
    -- l-catta: say "gray fur";
    -- g-gallus: say "mostly black feathers with a few white one speckled about";
    -- l-pictus: say "tri-colored brown-black fur with white splotches";
    -- p-porcus: say "orange hair with a white stripe running from my head down my back";
    -- l-lynx: say "spotted tawny fur";
    -- m-mephitis: say "dark black fur with a few white stripes running from my head all the way down my back and
    tail".

And the last useful bit to pull out of the first description, which was not originally part of our first stab at our second description, is the description of Ada's current footwear (or lack thereof when she's a tauric snake, AKA a lamia). This was pulled out into [gnbsp-ada-feet-description]:

To say gnbsp-ada-feet-description:
  let S be the species of the player;
  if the player is anthropomorphic or S is h-sapiens or S is l-catta or S is g-gallus:
    say "a pair";
  otherwise if S is a-squamigera:
    say "a set";
  otherwise:
    say "a couple of pairs";
  say " of cute pink ";
  if the player is tauric and S is a-squamigera:
    say "designer tassels off";
  otherwise:
    say "sneakers on";
  say " my ";
  if the player is tauric and S is a-squamigera:
    say "tail";
  otherwise if S is h-sapiens or S is a-squamigera or S is l-catta:
    say "feet";
  otherwise if S is b-taurus or S is e-quagga or S is c-hircus or S is p-porcus:
    say "hooves";
  otherwise if S is d-draco or S is g-gallus:
    say "talons";
  otherwise:
    say "paws".

(We'll see why I felt like pulling this description out in the next section on writing human Ada.)

These three helper text substitutions show my general pattern for handling so many variations. In some cases, I can use the very concise syntax that you see that begins with if S is:, which is the Inform 7 equivalent of a switch-case block. But in a lot of other cases, I didn't have much choice but to use pretty complicated chains of if-otherwise if-otherwise blocks (as well as blocks using if's negative sibling, unless).

This could definitely be written in a much clearer way with some helpful phrases. For example, I could have a phrase to decide if Ada currently has hooves that would be equivalent to S is b-taurus or S is e-quagga or S is c-hircus or S is p-porcus (where S is the species of the player, obviously). However, for right now, I stuck with this as-is because there's a lot of times where I need to slightly handle things differently14. I actually had to write all of the foot options out on a piece of paper to keep track of them, because, for example, chickentaur Ada and lemurtaur Ada both only have two legs15, and tauric snake Ada is instead treated as a lamia with a snake's tail for her legs, so she has zero legs.

For the other sections of the first description that I wasn't intending on re-using or was intending on writing in a different way, they remained. But with the helper text substitutions pulled out, and me converting some of the if blocks with only one line in them to inline if statements16, I was able to get the code of the first description down to 46 lines from the original 104. That's some big savings!

Humanness, the Boring Default That Is Treated Specially

Even though I describe Ada's species and body plan as having 27 different variations, I can't deny that of these variations, human Ada is treated a bit special. For starters, as I mentioned above, human Ada is never a taur, she always has two legs. But in another way, since Ada starts as a human, and my players are going to be human17, they in theory need less introduction than all the various shades of "animal people" do.

This also reflects the puzzle set up. There are two factors that affect Ada's species, the setting of the Spades Propositional Bul and the plushie placed on the sacrificial platform of the Onyx Pawn Manifestation Altar, which holds the Spades Propositional Bul. I already talked about the effect of the plushie above, but I didn't mention that the plushie only has an effect if the Spades Propositional Bul is set to Ful, which it is when I load the level. That is, if the Spades Propositional Bul is set to Trul, Ada will be her normal human self regardless of the plushie.

There are also narrative reasons for this! As you can read in my static starting response above, the "seed of the present" within Ada knows she's supposed to be human, and thus would not describe her current state as "not normal". So at the least this part has to be rewritten, and that's where I began introducing my actual code to handle variations:

if S is h-sapiens:
  say ". Which makes sense, because I'm just, like, my normal human self.
  [paragraph break]Oh, that's right! It's possible that Playerrs don't have any context about things like that. So,
  anyway, that's what I am: a human being. I am a naked ape, with most of my tan skin exposed rather than covered in
  hair. Except for the top of my head, which [italic type]is[roman type] covered in hair. My ears are small, rounded,
  and close to my head, pierced by a couple of cute dangly hoop earrings. My fingers are long and well designed for
  grabbing branches as well as performing fine tasks of manual dexterity, and are decorated with teal polish on the
  nails to complement the teal streaks in my hair, tied in tight braids with pink beads at the end.
  [paragraph break]I have the normal single pair of legs, wearing some very dated, somewhat baggy jeans. My rather tiny
  feet are wearing a pair of pink sneakers, sadly hiding even my toenails, which are also done in teal nail polish like
  my fingernails.
  [paragraph break]As normal as all that feels, it almost feels [italic type]too[roman type] normal. Like, there's a
  reason that I have never... No, not [italic type]never[roman type]... I mean, there is a reason why I've only done
  this once before... This overpowering feeling of 'normal' that can make, like, even the most [italic type]not[roman
  type] normal things feel perfectly 'normal'. And once you've experienced that, and have been informed of the
  exceedingly [italic type]not[roman type] normal things that you could have sworn [italic type]were[roman type]
  'normal'... Well, even the most 'normal' things feel '[italic type]not[roman type] normal'. Y'know? ... I guess it'd
  be unlikely [italic type]you[roman type] would know...[no line break]";

The writing here was me deciding that it would be funny, given that while I as a game dev know my Playerrs likely know what a "human" is, that Ada has been warned that Playerrs may not know what a human is. It's called dramatic irony, and plus it's endlessly fun to describe the familiar in unfamiliar ways. However, note that Ada also describes a lot of other "features" in this: particularly her hair, her earrings, her nail polish, her jeans, and her sneakers. These features didn't appear in my original starting description above!

While I want these two paragraphs to be different, I generally do want them to describe all the same features where they can. The absence of features can be just as stark as the presence of different ones. None of these features are actually represented in the actual game world, so I wanted to avoid the Playerr thinking that Ada needed to put her earrings back on if they were particularly deep in the throes of frustration. Another reason to address this is that there's an issue regarding narrative cohesion: that is, Ada still should be Ada, regardless if she's furry or human! If human Ada would think it important to describe these, then a furry Ada that currently believes that she is normally a furry would describe them too.

So that was definitely going to be a set of changes I did while expanding out the passage above to cover the other species, which I'm going to talk about next...

Adding More Animals to the Zoo of Ada

I decided to start with the painted wolf form of Ada mainly on a whim. I started with the skunk form of Ada for the first description because I was going to force it to be that, but most likely, the first time the player sees the second description, Ada will actually be human, since as part of the tutorial Glitch takes away the Null the Skunktaur plushie for reasons that will be revealed in future parts18. Glitch then suggests to the Playerr that they command Ada take a look at herself, in hopes that the tie of the plushie to Ada's species is made clear.

But I couldn't start from the human one for most of the reasons that I explain in the last section. the human description was always going to be very different from the rest. So out of knowing it probably wouldn't be a skunk, and having personal preferences for the painted wolf19 I chose that.

However, if you examine it, little of what I wrote actually describes features that need to change when Ada's species changes. To make this clear, I've marked the necessary changes in bold in this quote block (I've also skipped some parts without changes):

[...]

Anyway, I'm mostly-humanoid shaped, at least. At the same time, I'm also most definitely an animal person, or I guess the top half of me is... The bottom is... I'll get to that. I don't know what your frame of reference is, playerr, but a common term is "furry". Rather than skin, my body is covered in tri-colored splotchy fur. My ears are pointed and stick out over my head. The fingers on my hands are pretty thick..., with claws at the fingertips. But despite that, I still have a good deal of manual dexterity.

On top of that, or perhaps on the bottom of me, rather than a single pair of legs, my person-shaped torso connects to the entire four-footed body of a painted wolf. Except for, like the head? That's where my torso connects? That part is perpendicular to the rest of my body, and stretches out over a meter behind me.

[...]

Oh my god, I'm just like, totally satiating the syntax of "normal". What I mean, is that to change reality is to change the past. And to change the past means to change my entire experience of, like, everything that came before... before the moment we connected to each other. A part of me is saying "these are just your paws, Ada, why are you staring at them?", while another, the seed of the present... Well, she's the one that's telling you that she is not normally a painted wolftaur, but a human being...

[...]

That's right, most of the description doesn't change! This is purely to make my job easier, and fits how little changes in the first description (here, the parts that change are also in added bold):

OK, It's not too weird, I guess. Ah, let me see if I can get "past" me to describe myself... Should just show up in italics for you...

I'm wearing a plain teal t-shirt, and like some super cute blue jeans, my hair done up like always in braids with pink beads? And like, I have the same old brown-black fur with white splotches. Y'know, as expected. Oh though, and this is so cool, there are some bright teal streaks in the brown fur connecting the splotches like distant space trade routes from, like, a few months ago after losing a bet with Malcolm! And like it took forever to get galaxies connected, but the effect is great, it's like an effect... or something...

Anyway, I'm pretty relaxed! I guess...

Oh yeah, and I got a couple of pairs of cute pink sneakers on my paws, just picked them up a week ago!

Yeah, see? I myself am aware that I was not a painted wolftaur, but a human, but not my past self. Listen, I know that can be confusing, so I'll defer to past me sparingly.

But it's also because really, you just don't usually go into much detail about your various body features when you're describing yourself. Ada in fact, gets mostly distracted talking about the whole "pressurized normality" of editing reality.

This is the first secret of interactive fiction writing: a little variation can go a long way. You don't often need to have radically different passages for different paths, so limiting them can really make the work manageable without hurting the narrative too much. You usually only need enough variation to reward a Playerr by showing that their choices had an effect.

I'm not going to share all the code I wrote to handle the differences, because they're not really too different from the various patterns you saw me pull out into the helper text substitutions. But, for example, here's how I handled the first part of the description up to the hands:

say ". At the same time, I'm also most definitely an 'animal person'[if the player is tauric], or I guess the top half
of me is... The bottom... is... I'll get to that[end if]. I don't know what your frame of reference is, playerr, but a
common term is 'furry'. Rather than skin, my body is covered in [gnbsp-ada-pelt-description], though I still also have
my braided hair, which has teal streaks in it, with pink beads at the end. My ears are ";
if S is:
  -- b-taurus: say "shaped like a broad leaf, sticking out from";
  -- l-victoriae: say "very long and tall, rising far above";
  -- r-norvegicus: say "like big round satellite dishes sticking out from";
  -- d-draco: say "short, three-part fins, sticking out from";
  -- a-squamigera: say "little more than small ridges around a small hole in the side of";
  -- e-quagga: say "tall scoops rising above";
  -- c-hircus: say "like a furry flipper flowing down the side of";
  -- l-catta: say "small fluffy triangles on top of";
  -- g-gallus: say "barely detectable except for a hole above a fleshy dangling lobe in the side of";
  -- l-pictus: say "large pointed spades sticking out over";
  -- p-porcus: say "tufted triangles sticking out from";
  -- l-lynx: say "tufted triangles rising far above";
  -- m-mephitis: say "like small round satellite dishes sticking out from";
say " my head,[if S is a-squamigera] the ridges[end if] pierced by dangly hoop earrings. The fingers on my hands are ";

Note that I use my new [gnbsp-ada-pelt-description] helper text substitution here, as well as an inline [if ...] statement to handle the [if S is a-squamigera] case, where I wanted to write something a little different from everything else. The snake form tends to have the most differences like that, but that's just from me eyeballing how many times I had to handle something special as I look at the code.

You might also notice that I handle a slight variation for when the player is tauric using [if the player is tauric]. The player being tauric also gets an extra paragraph going into more detail (this part is in the otherwise block of an if the player is anthropomorphic block):

say "[paragraph break]On top of that, or perhaps on the bottom of me, rather than a single pair of legs, my
person-shaped torso connects to the entire ";
if S is d-draco:
  say "winged and four-legged";
otherwise if S is a-squamigera:
  say "long, sinewy";
otherwise if S is l-catta:
  say "two-armed and two-legged";
otherwise if S is g-gallus:
  say "winged and two-legged";
otherwise:
  say "four-legged";
say " body of a ";
if S is:
  -- b-taurus: say "cow";
  -- l-victoriae: say "hare";
  -- r-norvegicus: say "rat";
  -- d-draco: say "dragon";
  -- a-squamigera: say "snake";
  -- e-quagga: say "zebra";
  -- c-hircus: say "goat";
  -- l-catta: say "lemur";
  -- g-gallus: say "chicken";
  -- l-pictus: say "painted wolf";
  -- p-porcus: say "red river hog";
  -- l-lynx: say "lynx";
  -- m-mephitis: say "skunk";
say ". Except for, like, the head? That's where my torso connects? That part is ";
if S is a-squamigera:
  say "parallel";
otherwise:
  say "[if S is g-gallus]nearly [end if]perpendicular";
say " to the rest of my body, and stretches out ";
if S is a-squamigera:
  say "for a few meters";
otherwise if S is b-taurus or S is e-quagga or S is m-mephitis:
  say "for a meter and a half";
otherwise:
  say "over a meter";
say " behind me, quite bizarrely covered in the blue denim of somewhat baggy and dated blue jeans? I have no idea how I
got these on";

Note that I could not use my [gnbsp-ada-species-description] text substitution as that has the additional "taur" or "anthro" ending that wouldn't apply in this case. Plus, I wouldn't want to say "lamia" instead of "snake" in this case. It's likely I refactor them to work together better in the future, but for right now it's fine. There's also the addition of Ada describing her blue jeans. I hear taurs wearing pants are something that we sickos get pretty excited for, so I had to include it.

That's pretty much it for handling all the variations of furry Ada, but I want to mention another trick of interactive fiction writing that I use...

Branching and Gathering

When writing interactive fiction, your main additional task as a writer is to handle all the variations. There are a few different techniques to handle this, both in Inform 7 and in other systems for handling interactive fiction. For example, in Inform 7, if your variation is particularly small, it can be easily handled by inline [if ...]...[otherwise]...[end if] blocks, as I do at the start of the "furry" section of writing:

say ". At the same time, I'm also most definitely an 'animal person'[if the player is tauric], or I guess the top half
of me is... The bottom... is... I'll get to that[end if]. I don't know what your frame of reference is, playerr, but a
common term is 'furry'. Rather than skin, my body is covered in [gnbsp-ada-pelt-description], though I still also have
my braided hair, which has teal streaks in it, with pink beads at the end. My ears are ";

Here, I don't change things much when the player is tauric so I use an inline [if the player is tauric]...[end if] to handle it. Additionally as mentioned above, when the variations get particularly complicated, it becomes useful to wrap them up in a helper text substitution like [gnbsp-ada-pelt-description] in this same passage.

Despite that, there's still plenty of cases where I use normal if-otherwise blocks, particularly for the parts of the writing that I don't intend to repeat. A common term for these two (or more!) separate paths is "branches". The idea is that the text "branches" off into its variations. But, often, after branching off, the variations are "gathered" back at some point. Obviously, how Ada describes herself while being human versus how Ada describes herself while being furry are the branches, given their need to be handled differently.

However, Ada then goes into a point about how editing reality changes her sense of "normal" that I wanted the player to see regardless of the other paths. I needed a "gather point":

if S is h-sapiens:
  say "[... human Ada text...]
  [paragraph break]As normal as all that feels, it almost feels [italic type]too[roman type] normal. Like, there's a
  reason that I have never... No, not [italic type]never[roman type]... I mean, there is a reason why I've only done
  this once before... This overpowering feeling of 'normal' that can make, like, even the most [italic type]not[roman
  type] normal things feel perfectly 'normal'. And once you've experienced that, and have been informed of the
  exceedingly [italic type]not[roman type] normal things that you could have sworn [italic type]were[roman type]
  'normal'... Well, even the most 'normal' things feel '[italic type]not[roman type] normal'. Y'know? ... I guess it'd
  be unlikely [italic type]you[roman type] would know...[no line break]";
otherwise:
  [... furry Ada code ...]
  say ".[paragraph break]Yeah, this is kind of not 'normal' for me, either. But as Malia might say, 'it is what it is.'
  Normally, I feel being transformed like this would inspire joy, but... that's the thing about editing reality, and why
  I've never... Well, not [italic type]never[roman type]... Why I have only done this once before... There is just this
  feeling of... 'normal' that makes what I'm looking at feel... well... 'normal'.[paragraph break]I mean, I even have
  [gnbsp-ada-feet-description]. That's [italic type]normal[roman type], right? Isn't it? Do you know? You should know,
  right?[no line break]";
[gather point here!]
say "[paragraph break]Oh my god, I'm just like, totally satiating the syntax of 'normal'. What I mean, is that to change
reality is to change the past. And to change the past means to change my entire experience of, like, [italic
type]everything[roman type] that came before... before the moment we connected to each other, that is. A part of me is
saying 'these are just your ";
if S is h-sapiens or S is r-norvegicus or S is l-catta or S is a-squamigera:
  say "hands";
otherwise if S is b-taurus or S is e-quagga or S is c-hircus or S is p-porcus:
  say "hooves";
otherwise if S is g-gallus and the player is anthropomorphic:
  say "wings";
otherwise if S is d-draco or S is g-gallus:
  say "talons";
otherwise:
  say "paws";
say ", Ada, why are you staring at them?', while another, the seed of the present... Well... ";

This type of branching and gathering is so common to interactive fiction that I stole the term "branching" from the documentation of a different interactive fiction system that I've used before20 called Ink. And I am pretty sure their documentation also used to refer to "gather points", but I may be misremembering.

You should keep an eye out for this pattern in other interactive fiction games, as well as this one. In this case, I used ending paragraphs that primed the gather point by having Ada never shut up about the word "normal", but there's other cool tricks writers use to make the transition into gather points more subtle.

Narrative Puzzles: Please Make My Fursona Happy so that I Can Make Her Sad

But what are adventure games without puzzles? The puzzle around Ada's species in Glitch's Non-Breaking Space is the first one of my "purely narrative" puzzles in that rather than the focus being interaction with game mechanics, the real focus is interaction with the characters and plot of the game. It's a wavy distinction because part of good puzzle writing in these types of games is making puzzles actually feel like they're part of the story.

As a contrast, I do not consider the apartment level puzzle with the plushies to be a narrative puzzle, despite my sense that the framing of the the puzzle is, indeed, well integrated into the game's narrative. Yes, she needs to open the portal and to open the portal she needs to sacrifice a plushie, to satisfy the corporate overlords that provide her with Chi Energy for casting. And she ends up having to deal with "fixing" them in the eyes of that corporation due to an over-zealous skunktaur21. So, there's a good plot explanation for the actions the Playerr and her need to take. That's just part of writing a good puzzle.

However, solving the puzzle itself does not really require Playerr comprehension of those plot elements. Even the cute stories that Ada has about all the plushies have no real effect on the puzzle. Except for Autumn, who is an especially beloved plushie and thus, Ada is unwilling to sacrifice her.

Most of the puzzle involves looking at the color of the plushies, the cleanliness of the plushies, and the spells Ada has in her spell book. Those plot points may motivate the puzzle, but they certainly don't determine it. Instead, it's all determined by these rather arbitrary game mechanic elements of the puzzle. As an example of this arbitrariness of those elements, the color is completely random, and the cleanliness is semi-random22. Further, Ada's descriptions of the spells are pretty barebone and lack plot implications, which is partially by design23.

That's the Apartment Level puzzle, but comparatively, I consider this puzzle around Ada's species in Glitch's Non-Breaking Space to be "purely narrative". Yes, the Playerr and Ada will need to play with game mechanics, the plushies and the sacrificial platform, but the solution is actually dictated by the narrative, not those elements. This point will likely be clearer if I show you how I use Ada's self-description here to signal that. It'll spoil the solution to the puzzle, obviously.

After the gather point I mentioned in the last section, we get this code:

say ", Ada, why are you staring at them?', while another, the seed of the present... Well... ";
if S is h-sapiens:
  say "[italic type]she[roman type] agrees that it's 'normal', but even that doesn't really calm me against the
  pressurized 'normal' I can feel.[no line break]";
otherwise if S is r-norvegicus:
  say "[italic type]she[roman type] feels... Oddly at peace... This is familiar to her, too... Somehow she's been a rat
  for a while[if the player is tauric]...[paragraph break]Well, except for this whole 'taur' thing. She is still weirded
  out by that... We should probably do something about [italic type]that[roman type], but otherwise, this is pretty
  cool![otherwise]. I guess what I'm saying is... that I [italic type]like[roman type] this form.[no line break][end
  if]";
otherwise:
  say "[italic type]she's[roman type] the one that's telling you that she is [italic type]not[roman type] normally a
  [gnbsp-ada-species-description], but a human being...
  [paragraph break]Oh, maybe you don't even know what a 'human being' is... It's a sort of naked ape who is sometimes,
  just sometimes, [italic type]too[roman type] smart for her own good.[no line break]";
unless S is r-norvegicus:
  say "[paragraph break]I guess that's like a long way of saying: this doesn't 'feel' right [italic type]at all[roman
  type]. This[if S is h-sapiens] [italic type]still[roman type][end if] feels very [italic type]wrong[roman type] to
  me[unless S is h-sapiens] as those two parts collide[end unless]. I'm not 'set' correctly. There's literally some Bul
  that is manifesting into me as my current species, and it's [italic type]wrong[roman type]. Or maybe it has to do with
  the sacrificial platform, or something?
  [paragraph break]I'm managing to keep cool, but there's a rush of emotions in my head that is making it a bit hard to
  think. It's not too bad... I'm fine, really.
  [paragraph break]Let's get back to work, OK?";
otherwise unless the player is tauric:
  say "[paragraph break]We should look around and decide if we want to change other things, but I'm feeling pretty good
  right now. I can stand to be my rat fursona Psyche while I'm here in Glitch's Non-Breaking Space.";

In this code, unless Ada is a rat anthro (that is, non-tauric), she will mention one of the bits about how she doesn't think things are set correctly. And as you may expect, she will eventually stop the Playerr from advancing the timeline. (I say eventually, because I haven't written this code yet at time of writing.)

The solution of this puzzle is arbitrary in a completely different way from the Apartment Level plushie puzzle. It's enforced purely by my authorial intent regarding Ada's self-image. My intention is that most of the puzzles in Quoll will be more on this narrative side. The plushie puzzle is a bit of an exception.

Also compared to the plushie puzzle, this puzzle has only one acceptable solution. I definitely don't intend that to be the case for all of my narrative puzzles. I do want the Playerr to be able to make some meaningful choices, after all. However, on the matter of what body plan Ada has for rest of the game24, as well as her species for the rest of the game25, I'm putting my foot down as an author.

Yes, this is also because, as you can see in this dev diary entry, maintaining these variations takes a lot of code. At the time of writing, it's 190 lines of code to handle the second description. That's definitely a lot compared to the 34 lines I started with, but that's because there's a lot of refactoring that I am saving for when I write the third and fourth descriptions later on.

But she who puts down her foot also has to spend some time working through the code fixing small syntax errors as well as editing, which is what I did after all of this work in making my interactive fiction actually interactive. For example, one of the more annoying "features" of Inform 7 is that sentence-ending punctuation at the end of a piece of text automatically causes a line break. Which is often not desired and must be overridden using the [no line break] substitution. This also includes updating all the tests. Not just the tests I have on these rules for handling Ada's response when examining herself in Glitch's Non-Breaking Space, but also other tests where Ada examines herself twice in a spell of time.

Tedious work, and I don't have much more interesting to add here, so I'll end this entry there! My hope is that this gives you some insight on some of my interactive fiction tricks. Though I admit, I am a bit disappointed that my main trick seems to be "haha if-otherwise blocks go brr"...

Your Not-so-humble Dev,


  1. Which, said mechanics are working great! At the time of writing, I've written the entire zeroth tutorial except for a few loose ends. This work required a few nuggets of unplanned work further refining the mechanics to support actual content and not just the stuff I wrote during my initial implementation.

  2. Normally in these dev diaries, I break kayfabe and just call the person playing the game "the player" but there's a reason this could be a bit confusing to use in this particular dev diary. Because, within the code, the player refers to the player character, that is Ada, so I am going to follow the same convention of the game and refer to the person playing the game as "the Playerr".

  3. I'm realizing that with the Playerr being referred to directly, it may eventually make sense to expect that "ME" could refer to the Playerr instead of Ada... But that can wait for now, as I would rather get some playtesting of the main mechanics first.

  4. Though of course one of those seven was used as a sacrifice in the Apartment level, so she only has six in GNBSP. And then Glitch ends up taking another for a different reason that I won't spoil, so she really only has five choices. And the narrative will force her to choose the one that makes her a rat, so really she has no choice. But none of that is that important for this dev diary, which is why it's in this footnote.

  5. Don't confuse this with "the Playerr", the person playing the game! the player refers to Ada, not you. There's not usually such a stark distinction between the two in interactive fiction, but it's kind of a big distinction in this one.

  6. If you're wondering where I drew such a motley crew of animals from, it's the 12 Earthly Branches of the Chinese zodiac (Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Goat, Monkey, Rooster, Dog, Pig), with the additions of humans and skunks. Several of the Earthly Branches animals got replaced with similar animals I liked better. The order I give the Earthly Branches in this footnote is their canonical order, but for whatever reason, this is not the order I follow in the code, which is the order of the list of species I give in the main entry. Mistakes were made.

  7. Note that Glitch is a spotted skunk, Spilogale putorius, not a striped one!

  8. I think I made this term up myself, but I've seen other furries use it before, so maybe I read it somewhere! I could spend reams and reams of pages talking about the furry fandom concept of a "taur", but I'll save it for Glitch's constant propaganda on the glory of being tauric.

  9. Sorry, human-taur fans. I'm not even adding it to my project spellcheck dictionary which is why it has a hyphen in this footnote.

  10. In fact, I have already changed it once so far while writing this footnote.

  11. Heck, I'd be letting myself down.

  12. Always take "lines of code" with a grain of salt as a measurement. The number of lines used to write something out in code can vary based on stylistic choices, just like the number of words in prose. For example, I didn't minimize the number of lines I wrote the static paragraph with because I used extra line breaks to make the text easier for me to read and edit, such as always starting a new paragraph on a new line of code so that the code has breaks in the text that will match where the paragraph breaks will be. Even in the real code, I often use blank lines to organize my code into sections (though not as much in Inform 7 as I do in other programming languages).

  13. I'll talk more about approaching writing human Ada for the second description in the next section...

  14. For example, in the second description I have Ada describe her hands, and I adjust the number of fingers she has when she's an even-toed ungulate (that is, cow, goat, or pig) versus an odd-toed ungulate (when she is a zebra). I don't count her thumb as a "toe", because the human thumb seemed more analogous to dewclaws.

  15. Yes, this means that lemurtaur Ada has four arms technically. It was just too cursed an idea to not include it.

  16. For example, I'm wearing [if the player wears the Glitchtech collegiate hoodie]my big bulky purple college hoodie[otherwise]a plain teal t-shirt[end if] was originally written out as a full if block.

  17. At least on the surface. I see you, my therian cousins. :3

  18. I do greatly fear I've hinted much too hard at these reasons already. There's even hints on this website!

  19. If you read my social media posts, when I want to distinguish, uh, myself from Chimmy and Ada, I often imagine myself as painted wolf. It finishes the cat-mouse-dog holy trinity handed down upon us from Tom and Jerry cartoons. Yes, my fursonas are just gay female versions of Tom and Jerry.

  20. I used Ink for a visual novel project that is sort of a spiritual predecessor of Quoll, Object-Oriented (Warning: contains adult content). Sadly, I gave up on that project, but I still find the writing fun. Look, I can write infinite stories about disaffected programmers turning into their fursonas. There will likely be an Easter egg or reference in Quoll to it. If you'd like to see how I used Ink there, check out that project's repository.

  21. The subtext is thick here...

  22. Once again, more information on how the plushies are randomized in the diary entry before this one.

  23. Namely, I wanted to signal to the Playerr that sometimes Ada may not find something important that is actually important to solving the puzzle. I will probably actually update the response there to have Ada also realize the usefulness of those spells. In fact, I went ahead and added a TODO for it while writing this footnote.

  24. Sorry, Glitch. It's not happening.

  25. There's a possibility that right now, you're putting some pieces together about what that will means for certain especially beloved plushies. All I can say is: Sorry, Ada. It's happening.

Jayce Mitchell