Accessing the player's previous command

Can I, within Inform, store what the player typed last turn in a text variable? My attempts to program it have prompted ‘you can’t store snippets in text variables’ kind of messages.

Also, I’d also like to get access to (or make my own version of) the ‘again’ mechanism, where instead of ‘again’, I could have the player’s actual last bit of typing appear at the prompt and be entered, perhaps in response to a particular other command I set up which they would type.

So if last round they typed ‘jump’, and the codeword is ‘zowie’, if they type ‘zowie’, JUMP appears at the prompt and is entered.

I think you have to store snippets in indexed text rather than text.

Cool, now I’ve got this much working:

the_last_command is an indexed text that varies. After reading a command: now the_last_command is "[the player's command]".

After that I can ‘say the_last_command’ to print the previous command out.

Edit: Actually I don’t need the square braces. This works for the 2nd line:

After reading a command: now the_last_command is the player's command.

The ‘Xot’ example from the manual helped me out, though it wasn’t one I found initially in my searching of the manual.

Offhand, I’m thinking this technique might be a nice addition to Aaron’s Neutral Messages extension, as it would allow the extension to quote the text that can’t be processed (in situations where it needs to do so).

Although I do like that Neutral Messages is indexed-text-free. Aaron said he’s still trying to make his extensions z-friendly, so it might be the sort of thing he would put in a glulx-only section.

To me it sounds more like Smarter Parser’s domain, though.

the_last_command is an indexed text that varies. After reading a command: now the_last_command is "[the player's command]".
Er, shouldn’t that rule be a before reading a command? Else it’s giving you the command typed in that turn, not the previous turn.

OK, this might be what you want? Getting the last input to appear again is easy once you’ve stored it, but redoing the last command seems non-trivial. You can store it as a stored action, but sometimes the last input will yield a parser error, which won’t give you an action to store. So I just decided to trap that case by setting the last command to a dummy action whenever a parser error happened. (You could give different responses to different parser errors, depending on how much you like typing, I guess.)

There may be problems with this. Also, note what happens when you try “xyzzy” after “again.” (If you want to paste this into the IDE, hit “reply,” copy the text within the code tags, and then cancel your reply – that’ll preserve the tab stops.)

[code]“Force Command” by Matt Weiner

Include Basic Screen Effects by Emily Short.

Holodeck is a room. “It’s a holodeck. A screen reads, ‘Type XYZZY to repeat your last command.’” Engine Bay is north of Holodeck. “It’s an… engine bay?” A wrench is in Engine Bay. Airlock is north of Engine Bay. “It’s an airlock, I guess.”

Erring is an action applying to nothing. [No understand grammar, no rules, no nothing; this is a dummy action that keeps track of whether the last thing entered was a parser error.]
The last input is an indexed text that varies. The last input is usually “”.
The last command is a stored action that varies. The last command is usually the action of erring.

Rule for printing a parser error:
now the last command is the action of erring;
continue the action.

To force command:
say the command prompt;
let N be the number of characters in the last input;
repeat with M running from 1 to N:
wait for any key;
say character number M in the last input; [This means whatever the player types turns into the last input]
wait for any key;
if the last command is the action of erring:
say “[line break]That won’t work this time, either.”;
otherwise:
try the last command.

Before reading a command:
now the last input is the player’s command.

xyzzying is an action applying to nothing. Understand “xyzzy” as xyzzying.

Every turn while the current action is not the action of xyzzying:
now the last command is the current action.

Carry out xyzzying:
if the last input exactly matches the text “xyzzy”:
say “You try to repeat repeating the last command, and get thoroughly confused.”;
otherwise:
say “OK, let’s try that again.”;
say line break;
force command.

Test me with “sing/xyzzy/xyzzy/n/xyzzy/get wrench/xyzzy/n/xyzzy/s/get wrench/xyzzy/go north/again/xyzzy”. [If you try “test me” the commands in the test will appear automatically, but you’ll have to enter the fake commands that are prompted by “xyzzy” yourself.][/code]

Matt, you might have an easier time with using “change the text of the player’s command to the last-input-used” rather than using stored actions.

Sounds like a good idea, but do I have a hook for it? At this point I’ve already parsed the player’s command as “xyzzy” and am in the midst of the carry out rule; do I have the chance to change the text of the player’s command and re-parse it at that point?

Thanks all for the observations. I agree that I’ve realised what I was trying to do is non-trivial. As such it’s on the backburner, but as usual I learned stuff in the process.

Oh, I wouldn’t have allowed it to go as far as action processing. After reading a command when the player’s command is “xyzzy”: now retrying previous is true; reject the player’s command. and appropriate Before & For rules on the same activity.
I guess it depends if severedHand wants his AGAIN to be in-world or out-of-world.

Ah, I see. This is much simpler. It does change the behavior when you input xyzzy twice in a row – it now retries the previous command again – but that’s probably not a bad thing. (And it turns out what severedhand really wants is something to do with overwriting the command line, which requires an extension of yours that I don’t want to mess with.)

It’s very provoking that the syntax required is “change the text of the player’s command to,” when “change” is deprecated everywhere else.

[code]“Force Command” by Matt Weiner

Include Basic Screen Effects by Emily Short.

Holodeck is a room. “It’s a holodeck. A screen reads, ‘Type XYZZY to repeat your last command.’” Engine Bay is north of Holodeck. “It’s an… engine bay?” A wrench is in Engine Bay. Airlock is north of Engine Bay. “It’s an airlock, I guess.”

The last input is an indexed text that varies. The last input is usually “”.

To force command:
say the command prompt;
let N be the number of characters in the last input;
repeat with M running from 1 to N:
wait for any key;
say character number M in the last input; [This means whatever the player types turns into the last input]
wait for any key;
say line break.

Before reading a command:
now the last input is the player’s command.

After reading a command when the player’s command matches “xyzzy”:
change the text of the player’s command to the last input; [“now the text of the player’s command is” doesn’t work!!!]
if the player’s command matches “xyzzy”: [which should probably never happen; since when “xyzzy” is entered the command gets changed, and so “xyzzy” can never be stored as the last input]
say “You try to repeat repeating the last command, and get thoroughly confused.”;
reject the player’s command;
otherwise:
say “OK, let’s try that again.”;
say line break;
force command.

Test me with “sing/xyzzy/xyzzy/foo/xyzzy/n/xyzzy/get wrench/xyzzy/n/xyzzy/s/get wrench/xyzzy/go north/again/xyzzy”. [If you try “test me” the commands in the test will appear automatically, but you’ll have to enter the fake commands that are prompted by “xyzzy” yourself.][/code]

Agreed. And the “text of” makes it look like a property or relation or something when it isn’t. The dev team’s stated many times they like to remove odd exceptions in the language like this, so perhaps eventually it’ll be replaced with a “now (snippet) is (indexed text)” or something.