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?
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.
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.
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.
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.
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.
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.