Real-time parsing I7 demo

I’ve put together a working demo of real-time parsing of input for Inform 7, which gives the player feedback on how the game will understand what they type as they type it, including spell-correction via suggestions.

I’ve written some notes about it on my blog, but you play the demo online here. The gblorb is also available.

Comments and feedback welcome here or on threeedgedsword.

Note, the system currently doesn’t do anything sensible when the player’s answering disambiguation prompts; I’ll look at this next.

The whole thing should available as an I7 extension eventually, which you can simply include to enable functionality.

cheers!
jon

This is bloody impressive. I usually find ADRIFT’s version auto-correction annoying, but this one if fine, and the feeling of added control is remarkable.

Much quicker than I expected, too, but I still wonder if it wouldn’t be a bit hefty for some web releases.

It looks like you’re using character input. It would be interesting to try using using normal line input and glk_set_echo_line_event()… it might be smoother.

How would that work? I need to run the parser repeatedly during input: doesn’t line input wait until the Return key is pressed before proceeding?

Not if you cancel it early. eblong.com/zarf/glulx/quixe/quix … est.ulx.js shows how the features work.

A-ha… that’s very interesting. Shouldn’t be too hard to put in, either. Thanks for the tip!

cheers
jon

Only special (non-alpha) keys are allowed as line terminators, so line input won’t be canceled early unless the player presses one of the function keys or the equivalent.

For your purposes, where you want the parser to check the entry as it is typed, character input seems to be the best fit.

Some brief looking into this over lunch makes me think,yeah, character input is the way to go, so that when the player presses the space key I can use that input directly without having to start and stop the line-input every few milliseconds to see if anything’s happened.

That said, what I was doing was just using VM_KeyDelay() and I can probably smooth the whole thing out a bit by writing my own version which doesn’t turn off the character input event when it goes off to do some parsing.

Expect v2 in a few days! :wink:

You could set up a timer with maybe a quarter-second interval, and re-parse if the input has changed since the last timer event.

The problem with using character input is that you’ll be emulating what interpreters do naturally, and you’ll never be able to emulate it perfectly. There’ll be some situation when it doesn’t work as people expect, maybe you won’t be able to select text, or move the cursor or copy a command. Using the Glk 0.7.1 features lets you use real line input while also intercepting it.

Line input has a couple of big wins - I like that the player could be continuing to type while in the background I’m doing some processing on what the last glimpse of the input line was. That feels smoother.

But I’m not sure how to best handle big changes between the old input line and the new, after a new “snapshot” is taken - particularly in handling the space-bar-to-accept-suggestions. What if they’ve deleted several characters and then pressed space? If I have to rerun the parser over the new input data it’ll be harder to optimise so probably slower; it might lead to the game making invisible suggestions because they’re only computed, and then written in, after the player has pressed the space key.

At the moment, I’m looking at using character input, and allowing command processing to be interrupted by the user pressing an additional key. Looking at it this way, it’s a real shame that glk_select_poll can’t recognise character input, as that would let me say “The user’s pressed something, get on with handling that” but without having the pause the gameflow to do that. (I can do something similar using a 1 millisecond timer and a normal glk_select call, but I can’t help feeling that introducing a deliberate delay is a weird way to speed things up.)

I’ll probably get the current version stabilised and out there, and then look at a line input rewrite and see how it goes. If checking for changes in the input line is really fast, then potentially I could use it as a glorified character input anyway…

You could also change from space to tab and setting tab as a line input terminator. I’m not sure why space can’t be a terminator too though.

Tab is not available for interrupt, is it? In any case, don’t most interpreters hijack the tab key to use to move focus between windows?

–Erik

I’m not sure.

Even if they do for character input, I think if a story file is specifically asking for tab to be a terminator they should do that rather than switch windows.

A quick update: I’ve released a version 2 of the example game, which should run substantially faster.

On Quixe I now get a few flickering/missed key-strokes, but substantially less, but running the native blorb is pretty seamless.

Let me know if you run into problems and please note, I still haven’t looked at how to handle disambiguation prompts!

Quixe
Gblorb

This is really cool. :slight_smile:

also, pressing the left arrow does something weird. It sticks a weird character onto the line and such. I’m on Google Chrome with your above Quixe link.

I get a multisecond delay and spinning beachball after pressing return when running this second version in Firefox 3.6 (I’ve tried it on two Macs, one running 10.5.8, the other 10.6). I don’t see that issue in Chrome on either machine.

This post discusses ways to ascertain whether you are disambiguating or answering a yes/no question from within VM_ReadKeyboard():

https://intfiction.org/t/glulx-inform-7-how-to-restart-line-input-after-canceling/1156/19

An aside: You’ve already got pretty much got this completed, but if you were just starting, you might have founf the Glulx Input Loops extension useful (it lets you change the behavior of VM_ReadKeyboard pretty easily using I7 code).

–Erik

I see the same character (the thorn) in Chrome, and also in Gargoyle. Odd characters are also added using the scroll wheel(!) in Gargoyle (latest release running on Mac OS 10.6).

–Erik

Gargoyle maps the scroll wheel to keycode_PageUp / keycode_PageDown during character input. The function keys produce similar anomalies.

Also, unsurprisingly, Delete gets remapped to keycode_Delete, which then works like Backspace.

I’ve never understood why Glk fails to distinguish the two. Maybe I’m showing my age, but I haven’t used a computer where both were available and they didn’t work as expected. Of course, the Mac keyboard calls backspace ‘Delete’, which muddies the waters a bit, but the underlying functionality is the same: there’s a key that erases input to the left of the cursor, and possibly a key that erases input to the right of the cursor. It seems like we could add a keycode_DeleteRight without causing too much trouble.

On a very much less technical note:

With commands addressed to others (like “Anthuk, up”), the first word (the name of the person you address, e.g. “Anthuk”), is mapped to a verb (“attack” in the case of Anthuk). Adding a comma and a blank space will replace the comma with that verb (so "Anthuk, " results in "Anthukattack ").

“Anthuk,up” (without the blank) works as expected, though.