unicode/Gargoyle

Using a few Unicode symbols in my game mostly for UI elements. It seems, however, that Gargoyle doesn’t support them. (Was trying to follow this older conversation on the topic and I’m not clear on the conclusion: Which Unicode characters are "safe" in Glulx? - #8 by cas)

Is there a way I can help Gargoyle recognize these symbols (as opposed to something the user has to do), or is this just a symptom of different interpreters doing different things?

1 Like

Are you sure the font specified in the Gargoyle settings actually contains all the unicode symbols you are trying to display? Some text display systems will try to switch to a different font when a symbol is missing, but Gargoyle won’t.

Well, that’s a bit of what I mean when I say ‘is there a way I can help’. Tester reported that the symbols are showing up as ?'s and when I tried Gargoyle on my own, it does the same.

I personally don’t use Gargoyle so I’m not familiar with its settings. From your response it sounds like it’s something I could affect for my own Gargoyle usage, but not something I could affect on the behalf of the player.

True. This aspect of Gargoyle has made me think twice about using unusual code points.

Open the garglk.ini file, find the lines starting with monofont and propfont and change the default Baskerville Gargoyle Serif and Gargoyle Mono to one that contains the symbols you need.

Perhaps something like Noto Serif will work for the proportional text: Google Fonts: Noto Serif

Which symbols are you using? Some have wider font support than others.

The best thing to do in general is to substitute a fallback of some sort if the font doesn’t support a particular character.

I’m the tester in question so glad to mess around with my Gargoyle settings if it’s helpful!

FWIW the defaults I’m seeing are Liberation Mono and Linux Libertine O. I’m not sure which version of Gargoyle I’m currently running – I’m not actually seeing an easy way to check!

The current default fonts seem to be called Gargoyle Mono and Gargoyle Serif.

On macOS, you can see the version in the About Gargoyle menu item. There might be something similar on other systems. But it shouldn’t matter in this case.

There’s not actually a menu bar in the version of Windows Gargoyle I’m using, is the trouble – though turns out if you right-click the title bar a little “About Gargoyle” option does come up. Turns out it’s 2019.1.1, which is one release behind. I’m having the same issue in 2022.1, though.

1 Like

Haha. Mike, you didn’t need to out yourself. I doubt you’ll be the only Gargoyle user out there.

The best thing to do in general is to substitute a fallback of some sort if the font doesn’t support a particular character.

What would a fallback look like in practice for something like this?

say "[line break][unicode 9875]";

The only way I can think of to make sure that all unicode symbols show up is to provide your own custom font that you have added the symbols to, and ask the player to install it and set it as default.

If there are acceptable ASCII fallbacks for your preferred unicode characters, you can ask the player at the beginning whether to use special characters or not, perhaps displaying the unicode characters and asking the player if they can see the characters. Then use the fallback if not.

Unfortunately, it’s correct that Gargoyle doesn’t support fallback fonts for missing glyphs. It’s a feature that would be really nice to have, but it’s not simple, and there are three font systems (Unix {fontconfig}, Windows, and Mac) that would need to be updated. I’ve done some experimenting with Fontconfig but nothing anywhere near useable.

There is a possible approach, though, that may work some/most of the time. Gargoyle allows authors to supply their own .ini file to configure Gargoyle, with the idea being that you can override certain settings appropriate for your game. The config file also allows you to specify font files rather than font names. So, you can distribute an appropriate font with your game, and then point the config file to the font. If your game is named game.z3, for example, then the config file would be called game.ini, and be in the same directory. There are 8 config options associated with fonts:

propr ProportionalRoman.ttf
propi ProportionalItalic.ttf
propb ProportionalBold.ttf
propz ProportionalBoldItalic.ttf

And monor, monoi, monob, monoz.

The problem is this: you can’t, obviously, specify absolute font paths since you won’t know where the game file will be. So it has to be a relative path, as above. And that will only work if Gargoyle is running in the game directory. Whether it is depends on how the user launches it, so there’s no guarantee that it’ll work.

But this seems like a pretty useful use-case. I think it should be easy to add the ability to look in the game directory if the font paths are relative. That would make this much more robust. There is a 2023.1 release coming up, and I can ensure this feature makes it into that release. On that note, I also added a feature to allow users to disable these per-game configs (since it’s possible to abuse this feature and completely override a user’s config), so there’s no guarantee now, either, but at least that’s a conscious choice by the user.

Would this be an acceptable approach, at least until fallback fonts are properly supported?

4 Likes

Just to be clear, I wasn’t suggesting fallback fonts, but just substituting characters in the code.

1 Like

In the end the effect is the same: you need to find a font that supports the glyph you need. But now that I think about it, nothing’s stopping Gargoyle from shipping something like Noto, using it as fallback for missing glyphs. Expect maybe file size …

I’ll play around with this a bit and see if it’s feasible.

1 Like

It is, by the way, not hard to make your own fonts using free tools like FontForge. The tricky part is really to do it without infringing on anyone’s copyright, but there is plenty of open source fonts out there to use as a starting point.

1 Like

That would be U+2693, “anchor”? It depends what you’re using it for, really.

That one, and a couple others, are being used in straight text. The anchor is to have a themed symbol for my “wait for any key” moments, and I use others for things like my out-of-world action that tells the player what game goals they have and have not achieved ([Unicode 9746] switches to [Unicode 10003] for instance).

Would this be an acceptable approach, at least until fallback fonts are properly supported?

That’s a clever solution, but honestly, things like supplying font files starts to go beyond my technical ability and since it wouldn’t be a universal fix, I don’t see learning as a productive approach. And, I would be horrified to be the cause of any extra work for you.

In the end, I think I’m just going to strip any questionable Unicode from my game (I’ll never give up an em dash, though.)

I think I’ve crafted an ok “anchor” using regular symbols:

-|--)
1 Like

You can work around that with a batch/cmd file - just add a cd /d %~dp0 to change directory (and drive) to the batch file’s one before executing Gargoyle.

The Glk spec says that the game is supposed to be able to test whether a particular Unicode character can be printed. See section 2.2 Output:

A particular implementation of Glk may not be able to display all the printable characters. It is guaranteed to be able to display the ASCII characters (32 to 126, and the newline 10.) Other characters may be printed correctly, printed as multi-character combinations (such as “ae” for the one-character “ae” ligature (æ)), or printed as some placeholder character (such as a bullet or question mark, or even an octal code.)

You can test for this by using the gestalt_CharOutput selector. If you set ch to a character code (Latin-1 or higher), and call

glui32 res, len;
res = glk_gestalt_ext(gestalt_CharOutput, ch, &len, 1);

then res will be one of the following values:

  • gestalt_CharOutput_CannotPrint: The character cannot be meaningfully printed. If you try, the player may see nothing, or may see a placeholder.
  • gestalt_CharOutput_ExactPrint: The character will be printed exactly as defined.
  • gestalt_CharOutput_ApproxPrint: The library will print some approximation of the character. It will be more or less right, but it may not be precise, and it may not be distinguishable from other, similar characters. (Examples: “ae” for the one-character “ae” ligature (æ), “e” for an accented “e” (è), “|” for a broken vertical bar (¦).)

So it seems like you should be able to test whether, for example, the anchor character can be printed by the interpreter, and switch to the ASCII version if it is not.

2 Likes