Is there a tool to replace strings in a ZCode game?

Hello! Apologies if this has been already asked I coudn’t find an answer anywhere if so…

Is it possible to replace a text string in a Z-Code game?

I have a .Z8 game I made a few years back. I’ve lost the source…it has a dumb typing mistake that I really want to correct.

If I run txd on it then I can see all of its text strings. How can I recompile the game with that mistake corrected, please?

I just want to have e.g. apple replaced with banana in one string and then be able to play it!

I’ve tried using a binaryhex editor but none are showing me the strings…

Thanks!

I don’t think there’s a tool. It’s not trivial, but it can be done. It will generally be easier to go from a longer to a shorter text, so banana to apple is easier than apple to banana. With txd you can figure out the address of the string, and then you can modify the bits in a hex editor. It’s not one byte per character (see the Z-machine standard). You will also have to fix the file checksum in the header.

1 Like

If you don’t feel like doing the bit encoding manually, you could of course put the desired string in another Inform project, compile that, and then use txd to find the offset to the string. Then just copy those bytes over the old string (without overwriting what comes after) and fix the checksum.

1 Like

Thank you, Linus! Very informative. I will set aside some time to try that soon, starting with browsing the standards.

You can also run it through a decompiler (which produces horribly messy but hopefully technically correct code), change the string, and compile it again. I think Disinform is the best option out there, though I haven’t tried to decompile anything in a long time.

2 Likes

I was hoping it would be possible to do this, I don’t want to make any changes beside one string change. I’ll see if I can find Disinform, thanks!

The disinform/edit/recompile cycle will only work if the string winds up exactly the same length.

1 Like

Wait, isn’t the advantage of that method that it doesn’t depend on length?

1 Like

No, that’s why Linus said the problem was nontrivial!

In general, if you decompile and recompile a Z-code/Glulx game while changing code or strings, all the strings and functions will wind up with new addresses. This will break all the game references (like object properties or literals in code) which store string and function addresses.

You can do some analysis to try to figure out which values are string and function addresses, and match them up with their original values. Getting this 90% right is fairly easy. Getting it 100% right is very difficult.

The only safe course is what Linus originally suggested: replace a string with another string of equal length, either by recompiling or by byte-editing the game file. (You can also replace a string with a shorter string, by putting a terminator character in the middle. The details are different between Z-code and Glulx but it’s possible in both.)

5 Likes

If the string is a high string (i.e. it’s one of the strings listed last in a txd listing), you can probably create a longer version of the string which you place last in the story file, and change the reference(s) to the string in the program.

2 Likes

Good point; that’s easier than locating the references to every string. You’d still have to be sure to find and change all the references to your string, though. (There could be more than one; they might occur in global variables, array data, property tables, or function code.)