'CYOA Framework for Glulx' extension - early tech demo

I’ve been working on an Inform 6L38 extension I’m calling ‘CYOA Framework for Glulx.’ It’s a framework (duh!) for making CYOA games in Inform 7 driven by keypresses and/or hyperlinks. The type-and-press-RETURN parser is turned off by default. (The thing that made this extension doable is Zarf’s experimental extension ‘Glulx Unified Input’.)

The extension is Quixe-compatible so it should be as easy to get a project online as with Twine. It has real undo support, quicksave saving if you want it (IE single keypress save and restore) and transcripting.

I’m trying to make it author and user-friendly. Each choice node takes the form of a single Inform rule. In most cases, that means everything to do with a node is in one place (physically and programatically) in the source.

Contrary to advance rumours, I did not incinerate the world model. Actually there are two modes in this extension - world model ON or world model OFF.

Say you want to write a game which is a two-header dialogue piece. You don’t want rooms or objects, you don’t care about them. Turn the model off and just use nodes. But even in this mode, the turn count is real, turn progression is real and UNDO is supported.

If you put the model ON, all the model stuff is there as usual (and people and objects are supported and appear in usual Inform ways) but the nodes are on top of this. Each room has a node that runs automatically when you enter the room, rather than a room description, but you can have all the other nodes you like.

You can flip options during runtime if you want, whether within a node or from node to node. This includes - hyperlinks in the prose, autolabelling links A-Z or 1-9, or giving them specific keys - including weirdo keys - having keypress choices automatically present as hyperlinks as well, clearing the screen every move VS retaining scrollback, etc.

I’ve put a tech demo online which has world model ON, uses the quicksave option and tries to show some variety. There are 4 rooms to walk around in a square, each with a corresponding node. Also, choose the Crumple into a ball on the floor option when you see it. That shows the 5th node.

There are two versions of the demo, one which clears the screen every turn and one which keeps scrollback. This is so you can see how it formats things in general either way.

aeriae.com/no/clearscreen/

aeriae.com/no/scrollback/

If you’re interested in this extension – either using it, or later playing something made with it – and have time, please have a look at the demos and let me know what you think. I’m interested in features or bits of presentation you like or dislike, or things you think are obviously missing, or obvious bugs. Thanks if you do!

(One thing I notice is a message that appears only in Quixe: “[stopped: success]” after a restore. This seems to be cosmetic only. It’s not present offline.)

As an example of how relatively easy it should be to program with this extension, in the rant tag is the code for the Home Room from the demo. Each node rule has a display phase, a list choices phase and then a react phase:

[rant][code]There is a room called Home Room. The node is home room rule.

Jim is a man in home room. Jim’s bowling ball is a thing in home room.

This is the home room rule:
if cyoa-node stage is “display prose”:
say “You are in the home room of the CYOA tech demo. A passage leads north to the Room Of Too Many Choices. Another leads east to the Room Of Quirky Key Assignments.[paragraph break]Because it’s in the spontaneous nature of the character you’re playing, you may wish to [hyperlink]DANCE[/hyperlink] by clicking this in-prose hyperlink. Or don’t.[paragraph break]”;
now cyoa-choice prompt is “(You can’t do anything with Jim or his bowling ball, but they’re just there to show you that real Inform objects and characters will appear in your game and be presented as usual in their location when world model support is turned on, as it is in this demo. If you want to make a game which requires no room, object or character models (eg a dialogue between two characters) you can turn the world model off and forget about rooms and all that stuff.)[paragraph break]If the dancing doesn’t appeal, select a more plebian course of action from below using the numbers of your keyboard:[line break]”;
continue the action;
if cyoa-node stage is “list choices”:
cyoa-present “Go north to the Room Of Too Many Choices.”;
cyoa-present “Go east to the Room Of Quirky Key Assignments.”;
continue the action;
if cyoa-node stage is “react”:
if cyoa-hyperlink choice is:
– 1:
say “You dance the night away. After the dancing, you’re still in this room.”;
if cyoa-choice is:
– 1:
try going north;
– 2:
try going east.[/code][/rant]

-Wade

Pretty awesome!

Out of curiosity - does your framework allow, theoretically, for…

…clicking hyperlinks instead of keypresses? (that’s easy enough to do anyway, so I’m guessing the answer is no)

…switching into parser mode at some point of the game, and vice-versa?

PS - before you say it, yes, in the northeast room, S is assigned to both ‘Save’ and ‘South’, so you can’t go south from there by pressing S, but you CAN by clicking the link, because in that room it’s also hyperlinked. This was an oversight resulting from a last minute change of my global SAVE key from G to S :wink:

-Wade

Thanks Peter.

Yes, you can make a list of hyperlinks down the screen (as the choices) or across the screen (as seen in the ‘crumbled to a heap on the floor node’) or put them throughout the prose (as in the DANCE choice in Home Room). And you can mix all these, and in addition to, or without, having keypresses assigned.

You could switch back to the parser but I haven’t considered all the ramifications. At the moment, ‘looking’ has basically become the node-activating activity. I haven’t even fully considered the ramifications of having the world model plus the nodes. For instance, you’ll probably need to program a little differently from usual to signiciantly mix the two, but the complexity of that would only get bad if the game gets really complex with the world model - at which point I’d suggest you’d have been better off with the straight parser to begin with.

-Wade

Thanks for the info.

BTW, I really appreciate how, in the scrollback version, clicking DANCE doesn’t do anything if you’re not in the appropriate room. Nothing gets by you! There are plenty of Twine games that fail to take that into account.

In the “Clear the screen” version, the text (as in, replying to DANCE or LOOK AT WATCH) appears at the top of the screen.

For some reason, I find that very unintuitive. I keep looking at the bottom of the screen. Possibly because I’m so used to it, but it doesn’t help that after the custom reply the game prints almost exactly the same text as before (room description), so for a few seconds I genuinely thought clicking DANCE was doing nothing at all.

Could this be toggleable? Either on the author or the player’s side?

Very cool.

If each rule is set up similarly (a say phrase for “display prose,” reactions for each option, etc.), is there a way it could be done with a table(s)? I don’t know if it’d work with whatever your approach is, but it seems like it could save typing the same conditions in each rule.

It’d be convenient if each reaction came right after/next to the choice itself in the code, to make it easier to keep track and make changes. As is, it looks like if you change the sequence of the choices, you will need to separately change the numbering of the reactions, and it might be easy to overlook something.

Any chance you could “release with source text” the demos so we can look at the full code?

The only thing that I don’t quite grok is you have a “dance” option which just presents a text, but then you have keypress reactions labeled 1 and 2 which actually are the 2nd and 3rd option in the game…in the code it’s labeled 1 and 2 with “dance” also being 1… Is it enumerating on its own with the actual physical order of the choices wired to the same order of “if input is 1…”?

Hehe, thanks. I discovered in early tests that old links in the scrollback would continue to ‘fire’ their event numbers into the current node if clicked. So then I set it up so that every hyperlink that’s printed has a new number. For now, I don’t start recycling hyperlink numbers until after 10000.

-Wade

Yeah, I realise what you’re experiencing is the cognitive gap between how we expect a parser game to react and how a typical Twine game reacts. This demo sits inbetween, because it has rooms, but it has no parser.

I set it up to have the response at the top of the screen because I thought about what it’s like when playing a Twine. In cases where the screen is refreshed every move, you never read a response to your action at the bottom. And if you did, either (a) the screen’s not being cleared, or (b) the game would make you click again to continue.

There is a problem for a game which has choices and rooms in that if we print a response at the bottom of the screen, we then need to add a moment where the player clicks or presses space to acknowledge that response before the screen is cleared. I actually experienced it as a bug when I first tried screen-clearing, saying to myself ‘where are the responses going?’… they were being printed and then immediately cleared before you could even see them.

But also, in a beta of this demo, the dance response printed on the current screen at the bottom, probably because I realised it was changing nothing. I think I changed it back to the top only because I was making sure that screen-clearing was happening at the right moment.

So overall, it seems it should be toggleable. People not using rooms won’t even need to worry about the concept of responses… such ‘responses’ are typically the prose of the nodes themselves.

Then if you have rooms, you will most likely want responses to typical Inform actions at the bottom in cases where you stay in the same room. If you don’t stay in the same room, you can still print it at the bottom, and add a ‘hit space’ or ‘click to continue’. Or you could, for that move, print at the top (at risk of confusion.)

Summarily - a tricky issue, but the best way to deal seems to be make a switch and let the author decide.

-Wade

Hi bg. I probably avoided tables at first because of the desire to go with the simplest option (everything in one place in one rule) but there would be modular advantages to using tables.

The prose and choices would be trivial to table-ise. To table-ise the reactions, I would store action names in the same table as the choices. So for instance, there could be a ‘go east’ action you could drop in anytime you wanted to add a ‘go east’ choice to a room. Whenever you wanted a unique response, you’d have to make and name a new action. This would also address you wanting reactions to be attached to choices, because they would share a line in the table.

The structure would probably then be: Instead of a rule per node, you’d have two tables, and the node itself would consist of pointers to those tables. I haven’t thought about how I’d deal with in-prose hyperlinks in this scheme… maybe one more table.

This would be a significant move away from the ease of everything-in-one-place, but I already acknowledge I need to do something more sophisticated with the choice presentation. At the moment, there’s no easy way to optionally add a choice to a room.

-Wade

Hi Hanon,

If you revisit the ‘scrollback’ version, you’ll find it’s now got source with it:

aeriae.com/no/scrollback/

The only difference between this version and the screen clear version is this truth state variable:

cyoa-clear the screen every turn is initially false. [DEFAULT IS TRUE]

Look in the Volume - ‘Core author-configurable variables’ to see all the options you can turn on or off.

I should also point out that because the demo project is built to run with or without screen-clearing, it has a few more if-then caveats in the node rules than a typical project would. Normally you wouldn’t be writing every node to format ideally in both modes, just the one you had picked for the whole game, or at least the one you’d picked for that node.

The way this works is that any hyperlinks in the prose are picked up in order by the extension and called ‘exclusive hyperlinks’ (exclusive as in - you can’t press a key to get at them and they’re not part of a list of choices). So it sees ‘Dance’ and says ‘here’s exclusive hyperlink 1’. If there was another hyperlink in the prose, it’d be exclusive hyperlink 2.

In the reaction phase, it then says ‘OK, did the player click Exclusive Hyperlink 1? Exclusive Hyperlink 2?’ etc. The important point is that these results are mutually exclusive from anything in the regular choices list that may or may not follow (where the first choice is Regular Choice 1, followed by Regular Choice 2, etc) so you don’t have to count your choices in an awkward fashion.

If your Regular choices after are ALSO being made into hyperlinks, that’s automatically handled by the extension. So mouseclicking Regular Choice 2 still returns Regular Choice 2.

-Wade

It sounds like tables would have their own complications. Please do whatever you think is best–I’m just tossing out ideas.

I wondered–for games that use hyperlinks–if there would be a built-in screenreader-friendly option for the player? An option at the beginning that players can choose if they want a number printed in front of each hyperlink, or something?

Just glancing through the source code, some of the default shortcuts here

cyoa-extended keys message is initially "( X = Undo, S = Save, R = Restore, Z = Credits, T = Transcript, Q = Quit )". [Change to whatever you need. Value is irrelevant if cyoa-show keys info in status window is false.]

seem unintuitive for me: X = Undo and Z = Credits. My associations with these shortcuts are

X = “examine” in IF, or the ctrl-X keyboard shortcut for cut.
Z = “wait” in IF, or the ctrl-z keyboard shortcut for undo.

Not a big deal though.

Yeah, a very good idea. Thanks for the reminder.

Yeah, I think I might set the defaults back to ‘all-intuitive’. What happened was, while testing, I was mucking around with keeping NSWEUD clear so they could easily be assigned to directions. But S is the most logical for SAVE, and U is the most logical for UNDO. I think it’s best to go all-intuitive as default. Because with any of the hardcoded keys, the author can (a) determine whether they want that function enabled in the first place, and (b) for options you do enable, you can reassign the keys to whatever you like, then just change the reminder text in the status window to match. And there are a lot of ways with this thing to enable moving in directions, but someone hellbent on using NSWEUD for movement in a world model project will have to work out what they want to do.

The arrow keys would be nice but as soon as you do that, you can lose mobile device / tablet compatibility. Something I do plan to stick to is make sure that on vanilla settings, a game will run online and on a mobile/tablet without problems.

-Wade

And kudos to you, my good sir.

Intuitive for what? Just a few posts ago you were telling me that screen-cleared-responses-going-to-the-top-of-the-screen is intuitive for Twine. :slight_smile: Trying to have the cake and eat it? Hmmm, cake. Hmmmmm.

Snapping out of the cake for a while, that is also relevant for NSEW directions. That makes a lot of sense to parser guys like most of us here, but little-to-no sense to the CYOA crowd.

But your extension provides so much customisation that I really don’t think that’s a problem. In fact, hey, don’t be afraid to create your own paradigm - neither Twine nor parser, something in between.

Now I’m going back to the cake. Hmmmm. Hmmmmmmmmm. I shall type (C) to eat (C)ake.

BTW, here are the reasons that I’d prefer to play a game using this default framework rather than most CYOA/Twine out there:

  • Savegame facility
  • UNDO support
  • Savegame facility
  • Runs on my terp without any missing features, like links to online resources
  • Is subject to all of my terp’s nice customisation, like font size, font colour, size of font, not having to resize-scroll all the time (don’t ask) and being able to change the size of all those letters
  • The facility for saving games
  • I don’t have to try and tap small letter in a small screen and wonder if I tapped the correct one (sheesh)

As a player, I would gladly trade all the nifty text effects on Twine for these usability issues. If it’s pretty and a chore to play, how can I enjoy it? If it’s vanilla but fully functional, bring it on!

Links are the way to go for touchscreens. Can links/keys be switched at runtime? Is mixed mode - keys and links - possible? What about automatic device detection?
If a game has a manual or help it might prefer invisible keys (unlabelled choices). The game should be able to specify labels.
On small screens minimum vertical (lines) and horizontal spacing is needed for easy link selection. The game should be able to influence spacing (it can be done by CSS).
Links in the scrollback remind of Undum. But they are dead.
Are inline links (like Twine) a small extension? Wishlist: image links.

I’ve added some code to Unified Glulx Input which handles UNDO more cleanly.

See github.com/erkyrath/i7-exts/blo … 0Input.i7x and the two Maze of Keyses. (I haven’t updated the documentation yet.)

During the setting-up-input rules, you can say “set input undoable”, meaning that this is an input event which should count as a turn. (This promises that the player will have a chance to enter an undo command!) Then you can either “replace the current input event with the line ‘undo’”, or add a rule to the new “checking undo input” rulebook.

The author can switch ‘links for everything’ on/off anytime while the game is running.

So are you saying maybe the player should be able to do this? It starts to make me think that a few of these functions could go in their own menu. This would potentially get me out of the ‘common keypress conflicts’ problem. I’d lose just 1 key to take the player to a menu where they can then use 1 key or click to save, restore, undo, transcript, look at the credits, turn all links on or off, etc.

I think I’d put in a boot question or two that would set things appropriately without the player having to think about them. eg ‘Are you playing on a mobile/tablet? Are you using a screenreader?’

I need to add a ‘use keys for everything’ mode for screenreaders, and this will cause a limit on the number of choices it can support per node (26 (alphabet) + 10 (1-9, 0) - maybe several hardcoded keys = about 32). 32 is OK 90%, of the time, but then you’ll have some game that suddenly want to show a grid of 60 links. And this limit would apply permanently in games that wanted to use keypresses from the start.

So… does anyone have any ideas about how to deal with this? One idea I can think of is to treat upper and lowercase keys differently if the game ever uses more than the max # of links, and if it does do that, tell the player that at the start. That gets the max up to about 58.

Sorry, I didn’t understand either of these ideas. Could you explain some more?

If you meant labels as in that choice nodes should be able to have names, that’s sort of in place already in the form of the rule. You get to name the rule whatever you want. Anyplace you want the player to be able to ‘move’ to, you name the rule for that place then drop in any prose, choices and reactions for that node.

Those things are beyond the power of Inform. As a minimum, if you’re playing in an interpreter, you control the formatting. If you play online, you should be able to hit a browser key to make all the text bigger or smaller.

After I had done everything on the extension itself, then I might consider looking into providing a basic CSS template of variability for online use. But I’m really just concentrating on the Inform extension. Solutions that involve two languages immediately up the difficulty and barriers for use. It’s like - there are a lot of things you can apparently do with Vorple and Inform, and no diss against Vorple per se, but because you need to know another language to use it, there are very few projects that have exploited the combination. I don’t want people to have to think about css before they can put a game online with this framework.

I deliberately killed them! It was a piece of programming I was quite chuffed to work out :slight_smile:

The thing about Undum is - doesn’t it mostly just keep going down the screen, moving things around before your eyes? It can reset the screen if you want, but with those text transformations happening before your eyes, and the idea that everything in the window is fair game, it’s a different paradigm. My framework operates on the assumption that you’re in the node you’re in and can’t choose/do things that aren’t in that node. Especially if the world model is on. The scrollback is there for history. And anyone emulating Twine is going to clear the screen on almost every turn, as well.

To add an eternal quality to links, the author would have to specify eternity or non-eternity for each link, and it enters an area of complications I’m not sure are worth it, and probably incompatible with easy generation of nodes. I mean, if lots of people feel differently about this, they should speak up, but I can tell it’s not a function I’m keen to add, mostly because I anticipate too much hurt to ease of use.

If you wanted a big Undum-like section, you could just print a big node with tons of links in it, and already be in the ballpark.

Whew, some easier questions!

Inline links are already in and easy to use.

Image links - hm, I have no idea if that’s easy or hard to pull off (probably easy, I hope - put a picture between hyperlink tags?..) but will investigate.

Thanks.

-Wade

Great, thanks!

-Wade