Window has pending line request error when asking yes or no

I could do with some help with this Counterfeit Monkey bug.

Quoting from the linked issue report: Lectrote will hang with the error “Quixe run: gli_put_char: window has pending line request” if the player resizes the game window while the game is asking the player to answer yes or no. It won’t happen during the initial questions, but as soon as the game proper starts this bug can be reproduced by typing QUIT and then resizing the window while the game is asking “Are you sure you want to quit?”

Obviously, the problem is that the main window is redrawing while there is pending line request. But this does not happen when the game is waiting for standard input, only when waiting for a yes-or-no reply. I’ve tried cancelling the line request before resizing the window and then restoring the request afterwards, but it seems I’m not doing it in the right place.

This would happen if you try to print something to the main window during the status-line activity. Or the map-redrawing code, I guess.

If you open the web browser console (“Toggle Developer Tools” in Lectrote) you’ll see a VM stack dump at the point of error. This is just VM function addresses, but if you compare it to the I6 debugging output you might be able to tell what functions are involved.

Right, this is the VM stack dump from typing QUIT after the initial questions and then resizing the window by dragging the bottom right corner when the game is asking “Are you sure you want to quit?”:

VM stack dump: 0x3c, 0x9d1c, 0x10cd50, 0xcb911, 0x9f32, 0x106d07, 0x106d74, 0x2a30, 0x14f45, 0x10743f, 0x10cd50, 0xcdef8, 0x1e039, 0x10cd50, 0xec093, 0x26f3, 0x9932, 0x5720, 0x18c4, 0x742, 0x13990e, 0x10cd50, 0x10ceb2, 0x108a55

Translating these to functions gives me this:

0x3c, <Function $3c “Main__”>
0x9d1c, <Function $9d1c “Main”>
0x10cd50, <Function $10cd50 “FollowRulebook”>
0xcb911, <Function $cb911 “B1_turn_sequence”>
0x9f32, <Function $9f32 “GENERATE_ACTION_R”>
0x106d07, <Function $106d07 “BeginAction”>
0x106d74, <Function $106d74 “ActionPrimitive”>
0x2a30, <Function $2a30 “DESCEND_TO_SPECIFIC_ACTION_R”>
0x14f45, KeyError: 85829 “QuitSub”?
0x10743f, <Function $10743f “GenericVerbSub”>
0x10cd50, <Function $10cd50 “FollowRulebook”>
0xcdef8, <Function $cdef8 “B11_specific_action_processi”>
0x1e039, <Function $1e039 “R_28”> (A specific action-processing rule ( this is the carry out stage rule ):slight_smile:
0x10cd50, <Function $10cd50 “FollowRulebook”>
0xec093, KeyError: 966803 “B318_carry_out_quitting_the_”?
0x26f3, KeyError: 9971 “QUIT_THE_GAME_R”?
0x9932, <Function $9932 “YesOrNo”>
0x5720, <Function $5720 “KeyboardPrimitive”>
0x18c4, <Function $18c4 “VM_ReadKeyboard”>
0x742, <Function $742 “HandleGlkEvent”>
0x13990e, <Function $13990e “PHR_875_r0”> (To decide what number is the value returned by glk event handling ( this is the handle glk event rule ):slight_smile:
0x10cd50, <Function $10cd50 “FollowRulebook”>
0x10ceb2, <Function $10ceb2 “RulebookParBreak”>
0x108a55 <Function $108a55 “DivideParagraphPoint”>

Note that some addresses produced errors (KeyError:) when using the “functions[]” function in profile-analyze.py, so I had to search for the address manually in the gameinfo.dbg instead. But that seemed to work fine.

Unfortunately, this is still not a lot of help, mainly because I still don’t understand what is going on. None of the map-drawing or window-size-adjusting code in Multimedia.i7x seems to be directly involved, nor Simple Graphical Window or Flexible Windows, the other obvious suspects. Rather the problem seems to manifest somewhere in the replacement HandleGlkEvent function in Glulx Entry Points or in VM_ReadKeyboard and YesOrNo from the standard template code (Glulx.i6t and Parser.i6t, respectively).

Right, so this seems to be caused by commit 6c59e5e, from pull request #91. This bug was present in older versions of Counterfeit Monkey, but it was apparently fixed by a new version of Glulx Entry Points by Dannii Willis (in combination with his Glk Events extension).

However, this new version did not implement some functionality needed by graphic links (used when clicking on the compass rose, see discussion of issue #76) so I reenabled some commented-out code in Glk Entry Points to make it work again, which seems to have reintroduced this bug.

As I mention in the Github issue report, older versions of Kerkerkruip have this bug as well, and it actually seems to be fairly common. Some other games that have it: Alabaster, Andromeda 1983, Being There, Blue Lacuna, Dead Cities, Transparent, Scroll Thief. A common feature of many, but not all of them, is a graphics window.

Sorry, I should have responded earlier…

The stack trace makes clear that the problem is the “handle glk event rule” in Glulx Entry Points. This checks a number of rulebooks to decide what to do with a given input event. However, the rulebook mechanism has an arcane set of rules to decide when it should throw in a line break. Throwing in a line break during HandleGlkEvent is fatal.

My suggestion is to update that rule in GEP and change all the “follow the FOO rules” statements to “follow the FOO rules without linebreaks”, where this phrase is defined as

To follow (RL - a rule) without linebreaks: (- FollowRulebook({RL}, 0, true); -).

You don’t have to touch the line “follow the glulx input handling rules for the current glk event”; that already operates without linebreaks. No, I don’t know why “follow RL” uses linebreaks but “follow RL for V” does not.

I have not tested this idea!

Thanks a lot! That worked!

I immediately noticed a closely related bug though: clicking on the compass rose, which generates a command like NORTH, causes the same error (“Quixe run: gli_put_char: window has pending line request”) during “Are you sure you want to quit?”. I fixed that with a corresponding line break-suppressing variation for “abide by the FOO rules.”

Now there is only one small annoyance remaining: ordinarily, if I answer the question “Are you sure you want to quit?” with, say, NORTH, I will get the response “Please answer yes or no.>”. This was also what I used to get if I clicked on the North compass direction in a less strict interpreter such as Gargoyle. But now, after the latest fix, the session will just end instead, as if I had typed YES.

Somehow the graphic link action seems to make the YesOrNo routine return the wrong result. I’ll have to investigate this some more.

I pushed these changes anyway and opened a new issue. This behaviour is certainly better than crashing.

It would be interesting to know why the YesOrNo input causes these problem while the normal input does not, and whether there is a universal fix, e.g. by replacing the YesOrNo routine.

Github commit 54d5b5d, Make the glk event handling rules not print linebreaks. Fix #121
Github commit 8ea1016, Make the legacy glk event handling rulebooks not print linebreaks

Now I found this old thread about the exact same problem. Not that it would have helped much.