Help "fixing" Everybody Dies so it's playable online

Playing Everybody Dies on Parchment produces this error: “Quixe init: glk_put_jstring: invalid stream”.

This is very unfortunate. The most readily-accessible way to play games is via the browser.

The author no longer has access to the source code to rebuild the game.
I was thinking perhaps it’s possible to disassemble and fix the project.

I am not familiar with the internals of glulx to debug the issue and fix it. All I managed was to decompile it with Mrifk.
Is this a feasible task that anyone is willing to help with?

Reference issues:

1 Like

The thing that makes Everybody Dies die immediately is that it tries to write an empty string when the current stream is null. If glk_put_jstring_stream is modified to just return if val is empty, null, or undefined:

if (val == "" || val == null) {
  return;
}

before it tests whether it has a non-null, writable stream, the game starts and seems playable. This doesn’t seem like a regrettable choice, but then again this is the first time I’ve cracked open glkapi.js.

(Of course, I don’t know whether there are other times later in the game when it tries to write non-empty strings when the current stream is null.)

But I don’t know anything about hacking glulx assembly code.

2 Likes

My usual response to this is to apologise and promise that I’ll get around to updating Parchment soon. (Which I will… it’s my next priority after my secret project.)

But in this case it won’t help. If Lectrote can’t run it, then neither will an updated Parchment. It would actually need either substantial changes to GlkOte, or a new Glk library. But I’m not sure if we even really want that, because that would hinder other bugs from being detected.

However! My secret project will help with the decompiling part. So… wait a week or two?

2 Likes

I think the Glk implementation here is behaving correctly by erroring even given an empty string, but Quixe is not behaving in accordance with the specs when it passes that empty string to it.

The string being printed by the game is not empty (it’s part of a series building up the message “ *** Run-time problem P23: Attempt to look up a non-existent entry at column 9, row 2 of the table 'Table of User Styles'.”), but the current Glulx I/O system mode at the time of printing is zero, not 2 (Glk), so the correct behaviour as far as I can tell is to entirely ignore that output.

While Quixe identifies that the output is going to the null system, so discards all of the actual characters, it still ends up passing an empty string to Glk (as spotted by Zed above), triggering the error.

I think Quixe should be avoiding passing the empty string to Glk except when Glk was actually the selected I/O system mode - the change would be something along the lines of

--- a/src/quixe/quixe.js
+++ b/src/quixe/quixe.js
@@ -4659,7 +4659,9 @@ function stream_string(nextcp, addr, inmiddle, bitnum) {
         //qlog("### strop(" + addrkey + (substring?":[sub]":"") + "): " + strop);
     
         if (!(strop instanceof Function)) {
-            self.Glk.glk_put_jstring(strop);
+            if (strop || self.iosysmode == 2) {
+                self.Glk.glk_put_jstring(strop);
+            }
             if (!substring)
                 return false;
         }
2 Likes

Thanks for digging into this. I will look at that code more carefully when I have time. It may indeed be a bug.

(However, I’m pretty sure that fix is wrong. If there’s a bug, I think it’s in compile_string().)

2 Likes

Inspired by Eaten By A Grue mentioning this problem…

In the meantime, you can indeed binary-patch the game file to work in Parchment. Take EverybodyDies.gblorb, and change the four bytes at offset (hex) 234df from 23 1d 6c 05 to 00 00 00 00. On a Unix-y machine, you should be able to do this with:

dd if=/dev/zero of=EverybodyDies.gblorb seek=144607 bs=1 count=4 conv=notrunc

This works because the routine that prints the error message mentioned above starts with a jnz instruction then a return instruction; this replaces the jnz with nops, so it just returns immediately and doesn’t try to print the message.

3 Likes

Only a year late, I have fully investigated this error and checked in what should be a fix.

It’s basically what Zed said originally, except we check for “” in the Quixe interpreter rather than the glkapi.js layer.

4 Likes

Thanks - it’s good to see I wasn’t that far off on the fix.