Strange error when playtesting

Hi, I’ve started working on a new game in Inform 7 but are getting a strange error I didn’t get before.

Here is my code:

include Basis Screen Effects by Emily Short
include Real-Time Delays by Erik Temple

When play begins:
say "placeholder1";
Wait 4000 ms before continuing;
clear only the main screen;
say "placeholder2"

placeholderRoom is a room

It compiles my code fine, but when playtesting, I get this:

placeholder1
(4 second wait)
Fatal Error: Printing text to a window that is waiting for line or character input is not allowed.

Does anyone know how to fix this?

1 Like

Are you using Version 1/100607 of the extension?

Yes, I am using that version.

I tried this and didn’t see any problem. Code below. This is with Inform 6M62.

I tested it with Lectrote, which should detect errors of that sort. (The built-in interpreter in Inform is lax about them, which is a known problem.) Also with the web-release option.

"Test Case" by Andrew Plotkin.

Include Basic Screen Effects by Emily Short.

Include Real-Time Delays by Erik Temple.

Release along with an interpreter.

The Kitchen is a room.

When play begins:
	say "placeholder1";
	Wait 4000 ms before continuing;
	clear only the main screen;
	say "placeholder2"

Strange… That’s the exact same code as me but it won’t function properly.

I have Inform version 6L38 installed. I pasted zarf’s code in and got this in the IDE:

placeholder1Fatal Error: Printing text to a window that is waiting for line or character input is not allowed.

Oh, and I seem to have version 10/140425 of Glulx Entry Points installed.

Should this not be include Basic Screen Effects by Emily Short ?

ie. Basic not Basis

Whoops, I typed it correctly in my code. I just must have not done it in the question.

I’ve just had this happen as well, also from using Real-Time Delays. All the extensions I’m using are the versions from the github.

Oddly, the error only occurs in the Windows IDE’s interpreter – using standalone Glulxe or Git it continues on without issue.

Also oddly, in my case it’s a sequence of alternating say/wait/say groups and it very reliably only issues the error at the end of all of them. After some experimentation, I found that this appears to be the magic trick:

Reliably crashes:

say "foo";
wait 4000 ms before continuing;

Reliably works:

say "foo[paragraph break]";
wait 4000 ms before continuing;

Note that it does have to be a paragraph break, for some reason. A line break doesn’t work. I don’t know why this is.

Also reliably works (and prevents the delay being skipped by a keypress):

say "foo";
wait 4000 ms before continuing, strictly;

(Possibly also of note is that unless you explicitly [run paragraph on] then you get a paragraph break across the wait regardless, so it probably doesn’t hurt to explicitly add the [paragraph break] anyway.)

2 Likes

Thanks, @mirality that worked fine!

Without deep investigation, here’s what I think is happening: I7’s rulebook mechanism has some logic for adding a line break between rules. (For example, if you have several “every turn” rules that print text, the rulebook mechanism makes sure they appear with blank lines in between.)

This is the right thing 80% of the time. 18% of the time you have to fudge around it by adding [line break] or [run paragraph on] or some other phrase until you get the spacing you want. And then there are cases like this, where it’s actually illegal for the game to print anything at a certain point, but the rulebook mechanism doesn’t know that.

Sticking [paragraph break] before the call is reliable because the mechanism never tries to turn a blank line into two blank lines. You can get the same effect by poking some internal I6 variables, but I don’t have an example of that handy.

2 Likes

Yeah, that makes a certain amount of sense, but … why does it only affect the IDE interpreter and no others? And how could the rulebook mechanism insert extra output lines inside an I6 method call, which is where all the pausing occurs?

I said I hadn’t investigated it deeply. :)

In Flexible Windows I had to use this phrase to stop mysterious line breaks, so I think say__p and say__pc are the only I6 variables you need to handle. But I haven’t look at what’s going on with the timers so I don’t know how you’d handle them in this case. (I think for FW it wasn’t producing crashes, just unwanted linebreaks in the wrong windows.)

[ Fix spurious line breaks from being printed in the main window after running the refreshing activity ]
To safely carry out the (A - activity on value of kind K) activity with (val - K):
	(- @push say__p; @push say__pc; CarryOutActivity( {A}, {val} ); @pull say__pc; @pull say__p; -).

The interpreters in the Windows Inform front-end are much more aggressive about error reporting than many other interpreters, most of which tend to silently ignore at least some illegal operations, such as printing to a window waiting for input.

Without doing detailed debugging it’s hard to say what’s going on. But waiting for a length of time will involve a call to glk_select(), which will run event processing. Depending on what events occur, all sorts of code could be running within that.

You’re Zarf, even your cursory investigations have good/excellent depth :wink:

Best regards from Italy,
dott. Piergiorgio.

I’ve done a bit of debugging on this. The story file definitely attempts to print a carriage return while input is still active on the window, suggesting that Lectrote isn’t strict enough in its check for this. That the offending character is a carriage return support’s Zarf’s analysis, too.

Lectrote is strict about that error. I think your guess about order of event generation may turn out to be correct.

Unfortunately, I’m now not so sure! Looking at the events being generated, once the pause starts there are no events until a timer event, and it’s that that seems to trigger the error.

Oddly, if I skip over the error, entering any command triggers the error when it prints the entered command line. As yet I’m not sure what to make of that.