[I7] Issue with movement commands in single-keystroke interface

So. I’m trying to work out whether it would be possible to implement a Bard’s Tale or Wizardry! style dungeon crawler with Inform 7 using Glulx. Right now I’m working out the implementation of a single-keystroke interface where the story tracks the direction the party is facing, uses the left and right arrow keys to turn 90 degrees in the appropriate direction, the down arrow to do a 180 degree turn, and the up arrow to move in the direction the party is facing.

For the single-keystroke interface I’m using Zarf’s Unified Glulx Input extension (3/160213) and the following code which is modded from one of the extension examples.

Handling input rule when handling char-event:
	let C be the current input event character;
	if C is special keycode left:
		say "[fixed-width on]TURN PARTY LEFT 90[degrees][fixed-width off]";
		handle the current input event as the action of turning left 90;
		rule succeeds;
	if C is special keycode right:
		say "[fixed-width on]TURN PARTY RIGHT 90[degrees][fixed-width off]";
		handle the current input event as the action of turning right 90;
		rule succeeds;
	if C is special keycode up:
		say "[fixed-width on]MOVE PARTY FORWARD[fixed-width off]";
		if the orientation of the party is 0:
			handle the current input event as the action of going north;
			rule succeeds;
		else if the orientation of the party is 90:
			handle the current input event as the action of going east;
			rule succeeds;
		else if the orientation of the party is 180:
			handle the current input event as the action of going south;
			rule succeeds;
		else if the orientation of the party is 270:
			handle the current input event as the action of going west;
			rule succeeds;
	if C is special keycode down:
		say "[fixed-width on]TURN PARTY 180[degrees][fixed-width off]";
		handle the current input event as the action of turning 180;
		rule succeeds;
	say "[line break]('[extended C]' is not a valid key.)";
	reject the input event.

When testing in the Inform 7 interpreter this behaves as intended:

However, when testing in Spatterlight or Gargoyle the up-arrow returns a response of “I beg your pardon?”

Is there something obvious here I’m missing?

1 Like

I’m going to assume there is a problem of some kind and that the IDE isn’t strict enough to catch it.

If C wasn’t matching anything, we’d expect your fall-through code to go off (say YADA is not a valid key). However, that we see ‘I beg your pardon?’ means the handling input rules returned no result.

We see the MOVE PARTY FORWARD message so it did match keycode up. But then for some reason it did not match any of the four subclauses.

The format of the output text is suspicious. The I BEG YOUR PARDON is immediately adjacent to the MOVE PARTY FORWARD message. I mean, we already know the rule returned no result – if it had succeeded, I might have expected a line break in there. That makes me look at the phrase [fixed-width off] which is immediately adjacent to MOVE PARTY FORWARD. Is there any chance that, in the context of moving forward, that phrase is saying something that is throwing this routine out? Even if it was, I then could not work out why your if-elses aren’t catching, unless the orientation of the party has become a non-matching value. It feels a stretch that that would happen in one interpreter and not another.

I also don’t personally use the ‘else’ construction (I use otherwise:) so maybe someone can see something structural there.

-Wade

If I were doing this, I’d declare the orientation of the party to be a direction, so that the rotation keys set it to ‘east’ or whatever as appropriate and the forward key just does ‘going the orientation of the party’. There’s a few other places where this sort of thing could be useful, such as printing descriptions of exits in the direction you’re facing.

But yeah, this probably doesn’t address your actual issue.

Have you tried explicitly printing the orientation of the party at each step? As severedhand said, perhaps it’s somehow being set to a value other than one of the four you’re checking. Perhaps some kind of initialised-to-random-value issue, if you’re not explicitly setting an initial value for it? I wouldn’t have thought that’d be terp-dependent, but it’s not impossible.

I just tried running the example I based by code on (“Maze of Keys 2”) in Spatterlight and it displays the same bug, so maybe it is terp-related?

A workaround I tried that didn’t work:

Summary

Put in this decide phrase:

To decide what number is the ordinal of (ch - unicode character): (- ({ch}) -).

Then you can do this for your input loop:

let C be the current input event character;
let key_number be the ordinal of C;
say "(key number = [key_number])";

The say line is just a test mechanism. Put this in your game and press a key. The number that’s printed is the number for that key. So press your up arrow key, note the number, then in your ‘if C is special keycode up’ clause, instead ask ‘if key_number is (the number for the up arrow key):’

You can actually use this mechanism to test for any particular key. I use it in general probably as a hangover from working that way with Basic Screen Effects, where the ‘special’ keys had particular numeric values you had to check for.

EDIT - My workaround doesn’t work! I tested it with Maze of Keys 2 and It actually reproduces the same problem. So there seems to be an interpreter-specific problem with UGI and the up key and Spatterlight, etc. The UGI docs say these special keys generate Unicode characters that are out of the official range, so maybe the up arrow value is falling foul of that, and being blocked.

-Wade

Update: It doesn’t seem to be the Unicode characters; I changed the code mapping the movement keys to alphanumeric, with the “W” key replacing the up arrow, and I still get “I beg your pardon?” in Spatterlight…

I haven’t tested this yet. But it’s worth adding a final “else” clause to the up-arrow stanza:

else:
    say "[line break]Forward failed.";
    reject the input event;

…just to see if you’re landing in that spot.

Hmm. Still not working.

Does the “forward failed” message appear?

It doesn’t.

Okay, so I discovered why it’s working in the Inform app interpreter but not in Spatterlight/Gargoyle/Lectrote…

I tried releasing for testing to see if the Inform debugging verbs could give me any information, and when I ran that version through Spatterlight, it worked fine.

So there’s something in debugging mode that’s allowing it to work that isn’t there in “release mode”. It’s not an interpreter issue after all.

Still can’t figure out what’s breaking it, though…