How to read input per keypress

So, I’ve got this game where I want a normal input (with backspace, etc, etc) but after every input, I can read what the character is that was pressed, and potentially print it or not. Like, you can be typing out HELLOin the input but it reads the letter L and decides it shouldn’t print it, leaving the player with only HEO in the command line.

I would make it so that the command line is done entirely through @read_char, but then you couldn’t really do things like backspaces and the rest of functionality stuff that a normal read command does, right?

This is trivial if you do all your input in a Glk text grid window. Otherwise I don’t know. Might be doable if you target Z-machine interpreters which support the garglk_unput_string() extension.

1 Like

I remember a little game which involved the computer keyboard having a missing “key”, which you had to find and put into the keyboard. I can’t remember whether it was from the Inform Recipe Book or something I wrote. Let’s say the missing letter was W - if you typed “go west” the game would only let you type “go est” and obviously not let you go west. Is that the sort of thing? I’d have to check whether backspace worked.

1 Like

Do you mean that as the player is typing the game would decide what to print? As you say you’d have to use @read_char, and then you’d have to manually implement backspaces etc.

Alternatively, if you only mean that after the player presses enter that it would then decide what to print, that is much easier accomplished, at least in Glulx. I’m not sure if it could be done for the Z-Machine.

Ah, fair enough! I can find a way to make it fit in, I guess. :sweat_smile:

Your problem is basically akin to the rather unique twist in Robert Patten’s Beat With and from your description of the effect you want, seems the solution is a variant of that twist. So, If Mr. Patten want to share with you his source (the twist alone should be worth of being amnestied…) this should be by far the best solution to your coding problem.

Best regards from Italy,
dott. Piergiorgio.

I checked and, as might have guessed, the game I had in mind didn’t work that way at all. Apologies.

The thing you’re talking about is kind of different, since there it doesn’t matter what you click, be that a backspace or any key, you always get the same forced text. It also doesn’t read the input afterward, as it knows what it is going to say.

I want the command line to read my input normally and actually look at what is pressed, and unless it’s a specific key under a specific in-game circumstance, it acts as normal. It also reads the input afterwards and translate it into a game command if possible.

It’s sort of possible, but it’ll be painful and won’t work as nicely as you’d hope.

You’ll need to split off a Glk text grid window for the input, so that you can move the cursor around it, then implement arrow keys, backspace, highlighting the letter under the cursor, insert and overwrite mode, and anything else you want the user to be able to do.

1 Like

Just a correction to what I suggested above: While in theory you should be able to call Glk extensions such as garglk_unput_string() from a Glulxe game, as far as I know it is not currently possible in Gargoyle, or any other existing Glk implementation, as those extended functions are not implemented in the dispatch layer (unlike, say, the Zcolor functions.) I suppose this is another candidate for an official extension of the Glk API.

1 Like

It’s not needed in this situation though. You’d just need to switch to manual line echoing.

That won’t work for character-by-character editing, though. Once a character is printed to a Glk text buffer, it can’t be deleted using standard functions, unless you delete everything in the buffer. Which is why garglk_unput_string() was implemented in the first place.

Oh, yeah if you meant the DIY line input you’d need to either do it in a grid window, or use that extension. Which you can’t use yet.

An alternative is to do regular line input, but with a timer that regularly looks at the input line and edits what’s there. This is not the same effect – it doesn’t operate every keystroke, but catches up maybe every 0.5 or 0.25 second. However, it could be a similar effect and it’s available in regular interpreters.

You’d also want to turn off input echoing and do a final edit when input is complete.

4 Likes

This is doable in vanilla z-machine if you are printing your input in the upper window. You can use set/get cursor to erase/overwrite previously printed characters.

It sounds like a lot of work, but it is possible.

1 Like

I just made a quick demo of how you could do this in the next release of Inform.

lipogram.ulx (632.3 KB) Parchment link

"Lipogram Demo"

Use manual line input echoing.

Lipogrammatic Workshop is a room.

A loaf of bread is in the lipogrammatic workshop.
The description of the loaf of bread is "This loaf of bread looks delicious!"

To request timer events every (N - number) milliseconds:
	(- glk_request_timer_events({N}); -).

When play begins:
	request timer events every 250 milliseconds;

Glk event handling rule for a timer event:
	suspend text input in the main window, without input echoing;
	let purified command be "[the current line input of the main window]";
	replace the text "e" in purified command with "", case insensitively;
	set the current line input of the main window to "[purified command]";
	resume text input in the main window;
4 Likes

For those interested, a solution to the puzzle (getting the loaf of bread) is:

>don loaf

Although obviously pick up loaf works as well.

Wow, the upcoming version of Glulx Entry Points looks so readable! I’m excited for it to release.

It’s built in and much improved! And usable now, for anyone who wants to go to the hassle of building Inform from source. Which isn’t actually that tricky (at least on Linux).

It’s not currently possible to use the upcoming version with the IDE, though, is it? Building the compiler isn’t too tough, but I’ve found using it from the command line to be a massive headache.