Restricting certain keypresses

Hi, I am new to Inform and have met a difficulty with my first project (which might be too ambitious). I am wishing to restrict certain key presses as inputs before being read by the parser. I would also like to be able to alter these restrictions at will. For example, making it so that if a player typed any of the number keys nothing would happen.

I still want the parser, but I wish to restrict input prior. I have found some things vaguely in the direction I want for this, but not quite what I am after. Would anyone be able to point me in the right direction?

Thanks.

In my first (current!) Inform 7 game I’ve got a child’s toy that does something similar - including that you can only type alphabetic keys when using it. Do you want to give more details of what you want to achieve in your game/story/project? It might be that my code could be amended for your purpose. Having the code reviewed here could help me too.

If you’re asking about line input, rather than character input, then this isn’t possible. You can’t stop the user from typing anything in, or even from pasting in some text.

Is the example of wanting the number keys to not do anything a real example? What would the purpose behind that effect be?

Couldn’t the digits be set up as terminating characters on the Z-machine? Not necessarily a good solution, as it would complicate everything else, but it seems technically possible at least.

Nope, for the Z-Machine only the function keys, numpad, and cursor keys are allowed to be terminating characters. The Glk spec also says printable characters shouldn’t be made terminating characters. Maybe you could find some work around, but it would take a lot of messy hacking, and I’m not sure what the benefit would be.

1 Like

I know there’s a segment of Taco Fiction by Ryan Veeder where the parser interrupts whatever the player types key-by-key and types something else. That may not at all apply here, and situationally it is sort of a “cutscene” style moment that only occurs once. I don’t know if that can be done normally during open play.

§18.33. Reading a command

There may also be a way if you specifically use the Vorple interpreter, but Vorple might be more than you need and requires a game to be hosted online.

1 Like

The Taco Fiction trick is just a fake command prompt and a series of “wait for any key” moments enabled by Basic Screen Effects by Emily Short.

3 Likes

Thanks for the quick responses! To give further details of what I want to achieve: in my game, I want a parallel development to the standard moving between locations and discovering things by unlocking greater vocabulary through the ability to use alphabet characters that were previously unusable. So lipogramatic writing also where, for example, ‘A’ might be learnt at some point.

I hope this is in the right direction! The only really relevant part is the “After reading a command” sentence. The rest was just practice (and I would welcome comments). You can get rid of the laptop of course and - I expect - store a regular expression in a variable which changes according to which letters are currently allowed/disallowed.

"Broken Keyboard" by Jonathan

Your Office is a room. "This is your hiding place. Your secretary's office is to the west."

A desk is a supporter in Your Office.

A laptop is carried by the player. The description is "This is the laptop you are typing into now[if the laptop is broken]. There is a hole near the top left, where a letter is missing[end if]." Understand "keyboard", "hole" as the laptop. The laptop can be fixed or broken. It is broken.

A key is on the desk. The description is "[if the laptop is broken]It is black with faded, and unreadable, white lettering[otherwise]The 'W' key is now in the keyboard where it belongs[end if]." 

A wristwatch is on the desk. The description is "This is a Casio F91W, a classic watch." Understand "watch" as the wristwatch.

After reading a command when the laptop is broken:
	if the player's command matches the regular expression "W|w":
		let C be "[the player's command]";
		replace the regular expression "W|w" in C with "";
		change the text of the player's command to C;
		say "[italic type]You manage to type '[C]'[roman type]: "
	
Instead of inserting key into laptop:
	if the laptop is broken:
		now the key is part of the laptop;
		now the laptop is fixed;
		say "You squeeze the letter into the laptop's keyboard, and it snaps into place.";
	otherwise:
		say "You've already done that."
		
Instead of tying key to laptop:
	try inserting key into laptop.
		
The Secretary's Office is west of Your Office. "This is where the real work is done."

Test me with "examine desk / examine key / examine wristwatch / go west / inventory / examine laptop / put key into hole / examine wristwatch / go west".
Your Office
This is your hiding place. Your secretary's office is to the west.

You can see a desk (on which are a key and a wristwatch) here.

>test me
(Testing.)

>[1] examine desk
On the desk are a key and a wristwatch.

>[2] examine key
It is black with faded, and unreadable, white lettering.

>[3] examine wristwatch
You manage to type "examine ristatch": You can't see any such thing.

>[4] go west
You manage to type "go est": You can't see any such thing.

>[5] inventory
You are carrying:
  a laptop

>[6] examine laptop
This is the laptop you are typing into now. There is a hole near the top left, where a letter is missing.

>[7] put key into hole
You squeeze the letter into the laptop's keyboard, and it snaps into place.

>[8] examine wristwatch
This is a Casio F91W, a classic watch.

>[9] go west

Secretary's Office
This is where the real work is done.
1 Like

Ahh, that could indeed be interesting. I think Vorple will be the best option for you, you can then write a filter in Javascript that checks for acceptable keypresses.

Thanks, Jonathan. That does work, but I am hoping to intervene before the command is entered. I will look into Vorple.

It looks like I could have javascript commands for various filters of key input which could be called when required. There is already an example for rejecting key input.

From the section of the documentation that reads:

When the player types a command and a filter changes it, Inform receives the changed command but the original, unchanged command remains in the prompt . If the prompt should reflect the changed command, we can change it with vorple.prompt.setValue()

does this mean that by default it just filters the data it sends to inform and there would need to be something additional so that the player also sees the filtered result?

Input filters apply after the player has already typed the command, so they’re not suitable for this specific task. What you can do is add a “normal” keypress listener to the prompt that restricts the keypresses. Here’s a quick proof of concept:

Javascript:

// list of all letters that are restricted initially
let disallowedLetters = [ "t", "d" ];

// function that removes restricted letters from the list
function allowLetter( letter ) {
    const index = disallowedLetters.indexOf( letter );
    
    if( index > -1 ) {
        disallowedLetters.splice( index, 1 );
    }
}

// the keypress listener that blocks pressing those keys
window.addEventListener( 'load', () => {
    $(document).on( "keydown", "#lineinput-field", (e) => {
        if( disallowedLetters.includes( e.key.toLowerCase() ) ) {
            e.preventDefault(); 
        }
    });
});

Inform:

Include Vorple by Juhana Leinonen.
Release along with the "Vorple" interpreter.
Release along with JavaScript "inputlimiter.js". [The name of the Javascript file in the materials folder]

When play begins:
	say "Letters T and D are restricted. Pull the lever to learn T and push the button to learn D."

The lab is a room. The lever is in the lab. The button is in the lab. The diamond is in the lab.

To allow letter (L - text):
	execute JavaScript command "allowLetter('[L]')".

Instead of pulling the lever:
	say "You learn the letter T!";
	allow letter "t".
	
Instead of pushing the button:
	say "You now know D!";
	allow letter "d".
	
After taking the diamond:
	end the story finally.

You can try it here: https://vorple-if.com/tmp/inputlimiter/

2 Likes

I had to double check the username! Thanks so much. This is absolutely fantastic. I added a switch which taught you B. So the player would initially only be able to type ‘lever’, ‘uon’ and ‘swich’; after pulling the lever, ‘utton’ and ‘switch’; after pulling the switch, ‘button’.
The only problem now is having to compile each time I want to test it. Would working in Borogove be any faster?

Borogove was made (partly) to make it easier to compile the games, but you can’t include external Javascript files there yet. When making longer games personally I test the normal gameplay in the Inform IDE as usual and any Vorple-specific stuff in the browser with release–switch to browser–reload.

This is impressive. I like the sound of Vorple. In the final version you’ll have to fight against iOS predictive text, as the iPhone will shoehorn in “take diamond” and spoil the puzzle.

You’ll need a separate handler for cases where the input doesn’t come from a keypress (autocomplete, copy-paste etc.) that checks the entire input after it has changed and removes the restricted characters.

I’m not great at JavaScript, but I think you could use an oninput handler that removes any disallowed characters. This will get around not just predictive text but also pasting and (theoretically) any other method of putting characters into the input field.

I hadn’t considered copy and paste or autocorrect getting around the filter. I don’t know javascript, so this is a little difficult for me at the moment, but for prototyping purposes it is not necessary anyway until later on. I will post back here later if I have a solution, but I will also watch the thread in case anyone else takes an interest. Thanks all for your help.

I’ve just let my 7-year-old daughter have a go at this and she found it really funny…