Producing character replacement in any printed in-game text

Hello! I’m having a bit of a problem, and was wondering if y’all could offer some advice.

I’m looking for a way to substitute every instance of a particular character in all text produced in-game with another character. For example: every instance of the character “e” produced in any text (room descriptions, parser errors, item descriptions, everything) would be replaced with the character “é”. (The reason behind this is the PC’s decreasing sanity is depicted in part in an increasing degeneracy in in-game text quality.) I was looking at section 19.8 in the Inform 7 documentation, and trying to figure out if indexed text would help me out at all, but I was unable to come up with anything workable.

Any help would be greatly appreciated!

Use Text Capture by Eric Eve.

Indexed text can easily be manipulated like this, but most game text is printed without ever becoming indexed text.

Glulx has a feature that supports this kind of wholesale printing alteration. (That is, altering text as it goes by, which is not quite what the Text Capture extension does.) I’m not sure if there’s an I7 extension for it, but you can use it from I6 code:

The Kitchen is a room. "This place is not remarkable."

Instead of waking up:
	activate lunacy mode;
	instead say "Oh dear. You seem to have gone mad."

To activate lunacy mode: (- LunacyOn(); -).

Include (-

[ LunacyOn;
	@setiosys 1 printaltered;
];

[ printaltered ch;
	if (ch == 'e')
		glk($0128, $E9); ! put_char_uni
	else
		glk($0128, ch); ! put_char_uni
];
-).

Thank you for your help, all! zarf’s idea produces exactly the result I’m looking for, though working with I6 code is something beyond my abilities. I was hoping after learning how to produce these text replacements to be able to produce random replacements; something along the lines of (in I7) say "[one of]è[or]é[or]ê[or]ë[at random]" in place of any instance of “e” appearing in in-game text. (Or perhaps even more interesting Unicode shenanigans, if possible.)

I was hoping, ultimately, as the sanity of the player became lower and lower, to eventually substitute every letter in the alphabet with a random diacritic or Unicode “variant” of that letter, so that ordinary in-game text of “example” would appear, for instance, as something along the lines of “èχáɱp̪ɬë”. Doing that, I’m guessing, would require a knowledge of the correct I6 code for including a random character of a set list, and also knowing the correct codes for each character from which to choose (i.e. something along the lines of the I7 code above, but in I6).

Yes. It wouldn’t take much I6 code, but you’d need some. I do not have it for you right now, but perhaps someone else can help out.

The codes for characters (for the glk($0128, …) call) are just Unicode values. unicode.org/charts/PDF/U0080.pdf chart, for example. Many shȇ̶̹͕̇̈͢nanigans are possible.

You may want something like this (expanding on zarf’s sample game):

[code]
To activate lunacy mode: (- LunacyOn(); -).
To deactivate lunacy mode: (- LunacyOff(); -).
The degree of lunacy is a number that varies. The degree of lunacy is 0.
Every turn: increment the degree of lunacy.

Include (-

[ LunacyOn;
@setiosys 1 printaltered;
];

[ LunacyOff;
@setiosys 2 0;
];

[ printaltered ch;
if (random(100)< (+ degree of lunacy +) ) { ! This decides the chance of a character being substituted at all.
if (ch == ‘A’)
glk($0128, random($1EAC, $1EB6, $C6, $1FC, $1E2)); ! A is substituted randomly for one of Ậ, Ặ, Æ, Ǽ, or Ǣ (which the unicode characters corresponding to the hexadecimal numbers $1EAC etc.
else if (ch == ‘a’)
glk($0128, random($1EAD, $1EB7, $E6, $1EFD, $1E3)); ! … ditto, mutatis mutandis …
else if (ch == ‘d’)
glk($0128, random($1E13, $1EB6, $111, $18C, $221));
else if (ch == ‘e’)
glk($0128, random($1E17, $1EC7, $1E1D, $1DD, $25B));
else if (ch == ‘g’)
glk($0128, random($121, $1E7, $260, $123, $1E5)); ! … and so on
else
glk($0128, ch); ! put_char_uni ! Don’t substitute character that aren’t letters
}
else
glk($0128, ch); ! put_char_uni
];
-).[/code]

A warning (which is not important to this question, but may come up for something else):

Characters that are already Unicode characters in the text ($100 and up) do not go through the setiosys filter, so printaltered cannot affect them. (This is Mantis bug 845.) Also, bug 912 says that printing indexed text has the same problem.

You could catch those cases by replacing the glk_put_char_uni() function and applying alterations there as well.

Hopefully in the next release, I7 will steer all its output through @streamchar and @streamunichar.

Ah, this looks interesting! Thank you very much.

An alternative (and I don’t know how practical this would be, though it would probably be the ideal situation) is if we could set up a system wherein at below regular levels of sanity, random Unicode diacritics will appear on a few letters (the same stuff used in zarf’s

, and then appear more and more often as sanity drops lower, to the point where at lowest sanity, 1-3 random diacritics will appear on every single letter of text.

Something along these lines perhaps: [ printaltered ch counter; glk($0080, ch); ! print normal character for (counter=0 : counter < (+ degree of lunacy +) : counter++ ) { ! This decides the number of diacritics added. glk($0128, random($300, $311, $322, $333, $344, $355, $366)); ! Print a random diacritic } ];