Development Progress Report, week 32

 

A bit of a mixed week. A number of things (eg: double-casting, see below) have allowed me to cut the word-count without reducing the length of the narrative. So, I’ve shaved off a few thousand words here and there. Ongoing reworking and editing have pushed it back up, so it’s still hovering around the quarter-million word mark.

One final scene is refusing to write itself, but I expect it will work out once the narrative refit is done, and then I can move forward into chapter two.

There’s more interesting stuff than that going on, though.

Linux!

There’s now a Linux build that works!

Well, technically, I’ve had one that works for a little while now, but having a build that would work for anyone else, ah, now that was another matter entirely.

There’s a bunch of standard language features that I use from the 2011 C++ standard that were far from well-supported in g++.

This meant that getting the package to compile under (say) Ubuntu Trusty was mostly a futile excercise in pain. Up to now, I’ve been working with an experimental mish-mash (that’s a technical term). I could build it, and run it, but the odds that anyone else could were… slight.

Enter Ubuntu Xenial. The whole lot builds nicely on this platform, and I’ve created a .deb package, as well as a .zip bundle. It just works. (Though if you use the .zip you’ll need to manually add some packages [sdl2-mixer, sdl2-image, sdl2-ttf]. I should add a setup script for that. EDIT: I did.)

For now, the zip is getting uploaded to itch.io as an ongoing nightly build.

Installer funk

So … I have a bit of a tricky problem. I have tried zip files on end-users, they find the process of unzipping one and then finding and running the program inside to be complex and confusing.

There’s also some library dependencies that requires running a couple redistributables. For the average user, we’ve just crossed the line into Too Hard Country. Four steps constitutes too many steps, apparently. Two steps is marginal.

So, I’ve got an regular Windows-style installer (using NSIS), that does it all. Click through, and it does it all, including creating a shortcut and an uninstaller.

Well, Itch.io doesn’t like the installer. It interacts badly with the Itch app, either refusing to install properly, or doing the install but reporting failure. As for the Butler uploader, well it won’t touch it at all, meaning long manual Web-uploads to Itch.io. Also, Itch.io won’t accept anything like a .deb, except as an externally-hosted file.

Spiffy.

For the moment, I’m going to try doing this with zip files – so I can take advantage of Butler, and make updating a little smoother, but I’m not convinced that’s the way to go. I think I’ve got all of the dependencies built in right, but it’s hard to say. The first I’ll know is if someone tries it and it doesn’t work.

I’m going to temporarily hide the installers for now, and just leave the zips on the Itch.io page. So, we’re diving into the realm of nightly builds, as it were. We’ll see how that goes.

It’s an experiment that may or may not last the week.

Double-casting

The Argus engine casts actors (that is to say, characters) for scenes. Each scene has roles. Roles may have conditions. Actors that match the conditions for roles can be cast, and if a scene cannot be fully cast, then it can’t start, and is instead deferred in the hope its conditions can be satisfied later.

Within the scene, we generally don’t refer to our actors directly, but instead refer to them by their roles. While I could probably make the raw scene text much easier to read by using named roles, roles are currently numbered, because numbers make it much easier to write scenes.

One of the ‘interesting’ ways this works out in practice for SNAFU is that there are scenes where I know might know who all of the characters are in a given scene, but not actually necessarily know which role has been assigned to which actor for that scene (since some of the conditional casting assignments depend on choices or events that have happened earlier in the narrative).

That still leaves the issue that there may be a lot of quite stuff in a scene that is specific to a particular character (as opposed to a particular role), and for that I’ve used conditional blocks, along with an evaluatable function that can be used to determine whether a given actor was assigned to a specific role for this scene.

A couple days ago, however, I had a bit of an epiphany: I can actually cast actors to more than one role within the same scene!

Okay, actually, technically that wouldn’t work right because it could generate duplicate narrative coming out of the core engine at various points, but that was a one-line fixup (in two places) to prevent that from ever happening.

So, how does this work? Time to invent an example.

Let’s say we have three characters in a car. A driver, a passenger, and a hitchhiker. Three roles.

Our actors are Alice, Bob, and Christine.

Role 1 is the driver. This role is cast to either Alice or Bob, while role 2 (the front seat passenger) is either Bob or Alice. Which way round the casting happens for this scene depends on choices that Bob and Alice made earlier in the story. One wound up as the driver, and the other as the passenger.

Role 3 goes to Christine (for the sake of simplicity we’ll assume this is fixed casting, that is, the role is assigned to a specific actor, and not one one of a number of possibilities based on circumstances).

During this scene, each role has its own unique stuff (narrative, choices, or what-have-you). There’s stuff that’s specific to the driver. Stuff that’s specific to the passenger, and stuff that’s specific to the hitchhiker, in the back seat.

All of that stuff refers to the actors by their roles: 1, 2, or 3.

But Alice may have stuff specific to her, regardless of whether she is the passenger or the driver. Ditto for Bob.

Alice wants the radio on for the latest news. Bob doesn’t care for the news and would prefer a music station.

Up until Saturday, I’d have written a conditional:

#if:role:1:Alice

   // conversation and events assuming Alice is 1, and Bob is 2.

   END

#if:role:2:Alice

   // conversation and events assuming Bob is 1, and Alice is 2.

   END

(Yes, sometimes I would like to have a proper ‘else’, but I don’t)

The disadvantage here is essentially I have the same stuff twice, with different role numbers embedded in it. I’ve got a system where I can mark blocks to be repeated, with substitutions and variations, but even so, it makes authoring story harder, and (speaking as the current author) I don’t want that.

The new solution involves assigning Alice and Bob to the scene in additional roles:

Scene 101
Meta
 Summary: Alice and Bob give Christine a lift to the next town.
 Arc:The Mysterious Hitchhiker
 Follows:100
Roles
 Flagged:1,Alice,Bob;car-keys  // Whoever currently has the car-keys is driving
 Flagged:2,Alice,Bob;!car-keys // The other one is the passenger
 Fixed:3,Christine
 Fixed:4,Alice
 Fixed:5,Bob
Requirements
 None
Performance
...

Now, during the scene, instead of having to figure out who got assigned which role, we’ve got an additional option. We can simply refer to Alice or Bob directly as role 4 or role 5, independent of their roles as passenger or driver.

Though, if one role does influence the other, we can still opt to use conditionals or conditional substitutions to provide the necessary narrative richness.

Thanks for sitting through this rather long-winded bit of exposition.

Controller support

The first person to try out my early prototypes, outside of the family, was Damon Reece. Quoth he: “Are you planning on controller support? … [H]aving controller and assistive voice would make it playable for pretty much everyone.”

Well, I already had the assistive voice (at least, under Windows), and as of yesterday, Alpha 5 demo RC2, I’ve now also got working controller support.

Well, I assume it works. My Logitech F310 works with it under Windows.

Whether the controller works under Linux or whether other controllers work, I’m not sure. They should, but I don’t have a means of testing that right now.

Currently the D-pad is set for basic navigation. On the title-screen, left/right switches characters, and A/B/X/Y starts the story with the currently-selected character.

In-game, D-pad up/down scrolls back and forward through the narrative history, and A/B/X/Y advance the story.

In both cases, Start and Select toggle the options screen. The options screen remains mouse-driven.

Narrative refit

Still reworking and updating the narrative for recent engine features, which is taking a lot of time. I’ve probably got another 30 scenes to go before it is all done. That’s still a lot of work, and it is going much more slowly than I would like. Ideally, though, it should all be done by the end of Week 33.