Development Progress Report, week 31

This update is running a couple of days late, I know. I’ll try to blame the public holiday at the beginning of the week for that.

Alright, where are we at? Once again, a good week for development, though more on the narrative side than has happened in recent weeks.

Still, let’s start with the code.

Effects

Effects are now fully-integrated with the story-log (exception: full-screen fades). That is, when triggered, they become a part of the scrollback history, and will trigger again when you are scrolling back and forth through the portion of the story you’ve read so far.

This, however, doesn’t make sense for the full-screen fade-in/fade-out effects (which are two separate effects, and don’t exactly make a lot of sense if they take place in reverse order).

Visual and sound effects can now also be triggered either as discrete actions, or embedded in the narrative in the same inline way that text-substitution tags are. Logistically, that’s usually simpler, from an authorial perspective, as it eliminates the need to provide a list of characters to whom the effect applies.

Which leads me to:

Simplification

Writing the engine is one thing, but writing games/stories for it is another. You want that to be simple for the author, because the task of producing branching/combinatorial narratives is tricky enough already, without having to fiddle about with a lot of moving parts.

So, with that in mind, I set about simplifying certain aspects, including the new inline effects.

Colours are now easier to specify, using the names from the HTML colour table that I added in during week 29. Additionally, you can specify the alpha-value for the colour as colourname/[0-255] (eg: black/128). You can specify custom RGBA values as well, but most of the time the name/alpha syntax does exactly what you need.

Not satisfied with that, I added simple text definition macros, so that you can define a sequence, name it and insert it wherever you need to, by name.

In practice, that looks a bit like this:

$proc:gunshot:{effects:sfx:gunshot.wav}
text:*:{$gunshot}*BANG*

That saves a heap of typing, since effects (and groups of effects) can be tagged with a friendly name, and just applied where you need them. The Feature Creep Fairy is suggesting that I can make them parameterised templates as well, but that’s for another day.

This led me straight on to another feature, which involved simplifying an annoying necessity: Repeated blocks of narrative.

Occasionally it is necessary to repeat a block of narrative, usually with some custom alterations. A character may have some explanation of some part of their background, or some other story-relevant information that does not appear in every branch, and you need that (or something almost identical to it) later on, if the player hasn’t already seen it.

Or, characters might have character-specific narrative/dialogue for a scene, but you don’t know which of several roles in a scene a character might have been assigned to (that sounds wierd, perhaps, but it absolutely happens). So, you put in a couple conditionals, and write the same narrative several times, juggling the identities of speakers/enactors around.

That was a right pain, especially if you then needed to go back and alter something – because you’d have to change it in more than one place.

“Why not handle that during story-compilation?” I thought.

So I did.

I can now mark a section of narrative as a block, name that block, and insert a compiler directive to repeat that block elsewhere, with a list of text substitutions (changing enactors, words, or phrases, as needed).

I was able to shave a couple thousand words out of the total word-count that way, and make the narrative easier to edit and maintain.

Minor problematic consequences: It is increasingly difficult to figure out what the total word-count of the narrative actually is, given compile-time and run-time substitutions of authorial simplifications.

The actual story

So, armed with a new slew of visual effects that I can deploy, I’ve gone about using them to highlight the narrative in certain ways. An overall sepia tint for sections of the narrative which constitute flashbacks, a dark tint for narrative asides, and a bluish tint for a character thinking to themselves in the present tense (as opposed to the past-tense, in which most of the rest of the narrative is written in).

That means going over all of the narrative and refitting; essentially revisiting more than 23,400 lines of narrative, and pasting in certain predefined effects markup, and doing some editing and polishing to go along with it.

The side-benefit of this is that it’s given me an opportunity to do some other work as well.

One item involves breaking up some of my larger scenes into more manageable sub-scenes (narrative scenes can be embedded in each-other, or even embedded recursively). That makes some of it easier to find and easier to work on. Scene 208, for example, was nearly 800 lines, but was easy to break up into four logical scenes (a main scene and three embedded sub-scenes). That made it a whole lot easier to work with.

I’ve still got some monster scenes that are much less tractable.

Note to self: Don’t put all eleven playable characters in the same place at the same time and then have important things happen… Unless it is absolutely necessary for the story.

Another benefit has been reviewing each line and polishing and extending the material. While I’ve been saving word-count on one hand, with a bunch of technical tricks, I’ve been adding material on the other, fleshing out and reworking some parts of the narrative. It more or less balances out, but the results are an improvement, I believe.

Cosmetics

I’ve finally gotten rounded rectangles worked into the widget-code, and they look nice. I already had what looked like rounded-rectangles for various button controls, but they’re actually button images that are loaded and blitted, not created on-the-fly.

There’s a shot at the top of the post, showing off the new curves. I don’t use it in a lot of places, but where I do, it’s improved the overall look of things.

I also decided to make the background colour of the narrative area a beige, instead of the stark white. It’s a fair bit easier on the eyes. A few pixels of drop-shadow on the widget helps it pop as well.

When choices appear on the screen, the buttons are no longer full-width, but are set to the width necessary to accomodate the choice that takes up the most horizontal space in text. I’m not sure it is as attractive, but I’ve gotten positive feedback about the change, so it stays for now.

Story files can now also offer alternative font sets. In the case of SNAFU, I’ve included a dyslexic-friendly font that can be enabled through the Argus display preferences.

I find it a bit hard on the eyes, myself, but then again, I’m not the person who needs it. So consider that an additional accessibility option.

While I’m on fonts, I’ve iterated the kerning system a few more times.

Problem: My kerning system worked just fine for non-italic fonts, but italic fonts had all sorts of crazy spacing between characters. f and i were jammed too close together, while j and y had far too much padding, just to name a few. It was fairly ugly.

Solution: Since the story-file is providing the fonts, the story file can contain a manually-defined kerning table, allowing specified character pairs to have their own positive or negative kerning offsets, on a per-font basis.

That looks something like this:

|Narrative/italic:dd:-1 // Too far apart
|Narrative/italic:od:-1
|Narrative/italic:on:-1
|Narrative/italic:Ca:-1
|Narrative/italic:fi:4  // Too close together.
|Narrative/italic:hi:1
|Narrative/italic:is:1
|Narrative/italic:jo:1
... etc

I haven’t caught every single case where it looks wrong, but I’m working on it, as I see them.

Other stuff

A large part of my intended audience for SNAFU/Argus is comprised of people who aren’t (or who don’t think of themselves as) gamers, but instead, people who enjoy a good read, and might be enticed by a story that can be read from multiple perspectives, and can contain a variety of surprising twists and turns, even on subsequent readings.

That’s a bloody tough target demographic, right there.

That means, for some people, the whole CYOA part might actually constitute a turn-off, so I’ve added an option to the engine to actually disable it.

If you turn it off, what you get is a kinetic novel – that is, you read, but do not make choices. Instead, the choices are made for you by the character, the same way that they are made by the other characters – a little random number generation, weighted strongly by opinions, knowledge, and individual preferences.

It’s still a choice-based narrative, but you’re not making the choices anymore.

That’s going to appeal to some people and not others, but the option is there. If all you want to do is read, then that’s all you have to do. If you want more input into the story, well, that’s the default case.


That’s all for this week. I need to go back to editing/polishing/tagging narrative. There’s a lot I want to get done this week, and the clock is ticking.