Inform6 command echo & invisible commands

Good! I apologize for not replying sooner, but I didn’t have any idea what was going on.

I appreciate your perserverence in pushing a bunch of software modules (whose interaction isn’t always that well documented) into a brand-new arrangement. Using Quixe in this way was always a possibility, but now we know it works.

No, thank you for helping me get here. I really need this to work for my game.

The last thing I’m wrestling with is not losing any typed input before the event occurred and putting it back in place so the player can continue typing. Turning out to be a tricky one…

It’s possible! But you’ll have to modify KeyboardPrimitive().

When you call glk_cancel_line_event(), the number of characters the player has entered (so far) is left in gg_event-->2. Copy these out to another array.

Then, on the next turn, when glk_request_line_event() is called, copy those characters back into the buffer array. Pass the number of characters in the fourth argument. (In parserm.h, the fourth argument is always zero, but you need to change that.) This starts the line input with those characters pre-filled-in.

(Regrettably, you lose the player’s cursor position. The interpreter will restart input with the cursor at the end of the prefilled line.)

There should essentially be three different cases, depending on what you want to do:

  1. If you just want to run some logic to update the world state or global variables (that does not involve printing anything), then just do it, and then return 0 from HandleGlkEvent.

  2. If you want to run some logic that involves printing something (but not issue an actual command), you can glk_cancel_line_event, do your logic, then glk_request_line_event (passing the same parameters as the original cancelled request, except for the number of cancelled characters in the final parameter as zarf said above); finally still returning 0.

  3. If you want to execute a command as if the player entered it, then you glk_cancel_line_event, fill abortres with your desired command, and return 2.

Doing #2 safely requires intercepting glk_request_line_event so that you can capture the original parameters used and then restore them afterwards (this is what my I7 extension does). You can’t quite get away with assuming it will always be buffer – while that’s true most of the time, if the player is in the middle of disambiguation then it might sometimes be buffer2 instead, and getting this wrong will confuse the parser.

If you don’t want to do #2 the safe way then you can handle that case by doing #3 with a dummy command like your nullinput instead, but this may have other consequences (such as disrupting turn counts, undo, and the aforementioned disambiguation).

I think I tried this with bad results but I’ll try it again and see if I can pin down what went wrong.

EDIT: I just reread your last paragraph, yes, I think I may stick with my nullinput. It doesn’t seem to be affecting move counts and these external events shouldn’t really be undone except, perhaps, by another external event.

Are you really far from EST or do you also have insomnia? :stuck_out_tongue:

Unless there’s some weird code running, the correct call should always be one of these two:

  • glk_request_line_event(gg_mainwin, buffer+WORDSIZE, INPUT_BUFFER_LEN-WORDSIZE, num_canceled);
  • glk_request_line_event(gg_mainwin, buffer2+WORDSIZE, INPUT_BUFFER_LEN-WORDSIZE, num_canceled);

The trick is that one and only one of these is correct at any given moment (and the other one is wrong), and I don’t think there’s any good way to tell which is which, without just capturing the original call.

Of course, if your story makes use of character input at all (even just of the “press space to continue” kind; but not counting MORE prompts since those are outside of the VM) then you may need to worry about character input being pending, not just line events, and make changes accordingly.

I’m running on NZDT, so it’s not even late yet. :wink:

A Kiwi!

Since it’s declared as meta, it won’t add onto the turn count, but there might still be some other rules that get run. I don’t recall exactly how I6 behaves in this regard.

What I had particularly in mind regarding undo etc is, for example, something like this:

> take aple
I don't see that here.
> oops apple

The resulting behaviour of this will be quite different depending on whether the nullinput happened just prior to the oops command or not.

I believe this will also occur when using the undo command, if they wanted to undo their previous actual command but there’s a surprise nullinput in the way. (I don’t recall if meta verbs add onto the undo stack or not, but I assume they do.)

That is a VERY good point. I’ll have to test it out. I’m sure my beta-testers will also have a field day with figuring out all the things I’ve done poorly :smiley:

It turns out, as is on brand for me, that I was making it more complicated than it needed to be.

I was already collecting the current input in my GlkOte re-implementation, so I just appended the input whenever a new “input update” came through my update() implementation.

This solution would probably not work for someone who was using Quixe plain or some other interpreter but I will leave those solutions to their particular contexts. I don’t think this is a one-solution-serves-all situation.