Thai text display analysis – Rockman X DIVE

Let’s talk about another Capcom’s title, Rockman X DIVE. This title is developed by Capcom Taiwan, using Unity 3D.

If you’ve already read my State of Thai in Unity 3D post before, you probably have an idea of what is coming down below. For those who haven’t, and doesn’t want to spend too much time reading, let me give you a TLDR; this game is a TOTAL DISASTER.

In fact, for those who know some Thai, you should probably notice by now what’s wrong in the feature image. All of the tone mark in that screenshot are misplaced (well, there’s only 2 of them.). Here’s an example of what went wrong.

In this button, the text is actually “หมุน 1 ครั้ง”. However the tone mark is misplaced and it totally obstruct the Mai Han-Akat. Mai Han-Akat is now missing.

Now let’s take a look at the configuration screen.

These buttons are all text and looks like they are localized very well, but again most tone marks are miss the mark (pun intended).

Regarding the font, this looks like it is Noto Sans Thai, although it might be a different variant or weight. This font is pretty well designed and should work on OpenType-aware applications. Unfortunately Unity 3D is not one of them. I’ll simulate the text render using my test tool. Notice that the text itself is pretty similar, however there are no text effects implemented yet so it looks a bit bland.

The top is what similar to how the game render currently, and the bottom is what it supposed to be.

Suggested Workarounds

Given that these problems are in the text rendering of the engine, there are a few thing we can do with it. For those embeded in the textures, the textures has to be edit using OpenType-aware application (eg. Photoshop).

Tone mark is the most obvious problem here as they can be placed directly over base character, or floating vowels (like Mai Han-Akat in this example). The easiest method to mitigate the issue is to push those tone marks up in the air, to avoid the floating vowels. Basically adjust the glyph metrics of those tonemark so the glyph is pushed upward.

This does not totally eliminates all problem, if there’s no floating vowel underneath it, the tone mark is too high. However I think in this case readability is more important than correctness (as Unity can’t do proper Thai text rendering anyway). Just leave it high in the sky then it would be fine.

Using adjustment pair might help, but there’s a lot of cases needed to handle, given how many vowels and tonemark we have. Testing can be a nightmare.

I’ll be updating the post about Unity 3D with the new version of the site (still under development). That should includes more details of the fix you can do to make Unity 3D displays Thai text better. Without feature like mark-to-mark anchor it won’t look right, unfortunately.

Thai text display analysis – Resident Evil: Village

Resident Evil: Village is the latest installment of the successful series Resident Evil/Biohazard. With this sequel, it returns with Thai support. I’ll be analyzing how it perform in the area.

Please keep in mind that the quality of the translation is not part of this article. I can easily say it leaves a lot to be desire, but that’s not what we are going to discuss here.

The Good

Overall I think this game has a very good support of Thai text display. Below is the image I take from the settings menu.

Each glyph looks good with no visible artifacts. The tone marks are place correctly (eg. “การสะท้อนพื้นที่หน้าจอ” (lit. “screen-space reflection”)) which is pretty rare in today’s games. Usually you’d find tonemarks floating too far atop the base character, or clash with the vowels mark underneath it. Here are example of bad positioning.

Arundina Sans @64px

Noto Sans Thai @64px

In RE Village, these positioning are perfect.

In the main game, the subtitle looks good as well, no artifacts or overlaps whatsoever. The tonemarks are perfects.

So how did they manage to do this? Capcom implemented this by combining appropriate fonts with the right technology. I will start with the actual font (or, in the correct terms, typeface) first. From the information I can gather it appears the Thai typeface are all from Linotypes foundry.

  1. Neue Frutiger Thai Modern Regular for the UI Texts
  2. Neue Frutiger Thai Traditional Light for the subtitles.
  3. SST Thai Meduim for the main menu text.

Now I haven’t really tested these fonts so I can’t be 100% certain. These are basically a guess based on the asset file names. The actual content doesn’t appears to be the TrueType/OpenType files but rather the custom file format oft. Also the licensing fees is too expensive for me just to test my hypothesis. If you happens to have access to these fonts may be you can share your results with me, that would be appreciated.

Next lets talk about the technology. Capcom incorporate two famous opensource libraries here on the text rendering. This is based on their copyright screen (which is taken from the PS4 Demo version).

  1. FreeType 2 for glyph render/font file handling.
  2. Harfbuzz for text shaping/glyphs layout.

They are pretty much the common library uses in major Desktop Environments on Linux, Web Browsers, Android OS, etc. Getting the right results is kinda a given. Anyway it’s also possible that Capcom only uses these library to extracts necessary information to make the asset files, and use entirely custom rendering/layout code.

Nonetheless let’s applaud the afford it takes to implements these features.

The Bad

Apart from the translations and typos (a lot of both of them) problems, one thing that seems to be so problematic about Thai text display in Resident Evil: Village is line spacing. Basically the line spacing on Thai text is too tight, so tight that in some circumstances glyphs from below line can overlap with the glyphs on the line above.

For example. Notice the character Mai Tho is now above the baseline of the line above.

Now compare to this.

Laksaman @64px

There is significant space above the Mai Tho tone mark. This space is for some of characters that stay below the baseline, like Sara U in this example which clashes with Maitaikhu from the line below.

It’d be better if they stay apart from each other.

Laksaman @64px

So what happens with these? At this point I can only guess. Given that the two fonts (out of three) are from the same family Neue Frutiger, I think this font family has the same decender (space under the baseline) problem. It looks like descender is 0 which leave no spaces to the under-baseline characters. It’s also possible that the under-baseline glyphs are place outside the descender area as well.

Another guess I can think of is Capcom completely ignore the descender value. However after comparing multiple languages it doesn’t seems to be the case.

The Ugly

Let me start with our infamous Duke shop.

Just in case you can’t see the where it goes wrong, the word “ปืน” has Sara Uee overlaps with the tails of the character Po Pla below. Also Mai Chattawa is hitting Po Pla as well in the word “กระเป๋า”. What happens ?

At a first glance this looks to be a texture created from some DTP program. However, I doubt Capcom would use anything other than Photoshop, and Adobe Photoshop usually has a very good support for Unicode. Then if it’s not texture, it’s the real-time render text just like above.

Here’s another example of this problem. This is right in the beginning, but it can be easily dismissed as a merely typos.

Most people would think, Mai Ek is missing. That might be true, but one possible problem is that the font requires Thai Script shaping algorithm. I have seen this problem before but cannot replicate with fonts I have at hands. Anyway, in Harfbuzz there’s a function to set the script of the buffer to be a certain script (Hiragana, Katagana, Thai, Arabian, etc.).

hb_buffer_set_script(buffer, HB_SCRIPT_THAI);

Most script will use the common shaping algorithm, but Thai is one of the exceptions. In most fonts I have encountered the common algorithm works fine, but again there are some exceptions (eg. Cadson Demak’s Prompt). So maybe the Neue Frutiger Thai font family requires Thai-specific shaping algorithm? I don’t know (remember I don’t have these fonts). Anyway I think if the character is there, then this settings is something worth investigating.

Closing

It’s been years since I’ve seen video games has this level of Thai text support. Even games made by Thai developer has some kind of shortcoming (especially those made with Unity). I’d like to again applaud to Capcom for their afford of implementing Thai localization in Resident Evil: Village.

Now as I mentioned, there are problems with line spacing (and possible characters with long tails). This is something that people with lesser proficiency in Thai language might not be able to spot right away. I can’t be blaming them I think (I won’t be able to point out if there’s something wrong with Japanese rendering, will I ?). This is something that is certainly possible to be fixed.

However, localization is partly about displaying text correctly. The major problems with this title are in the actual text itself. Let’s hope that Capcom will come up with a fix in the future.

Finally, please let me says this with my broken Japanese 🙂 カプコンさん、タイのローカライゼーションをどうもありがとうございました。楽しかったです。

Appendix

The following fonts are used for illustration (using my font-render-tester.

  • Arundina Sans Copyright (c) 2003 by Bitstream, Inc. All rights reserved. Copyright (c) 2007 by Software Industry Promotion Agency (Public Organization) All rights reserved.
  • Noto Sans Thai Noto is a trademark of Google Inc. Noto fonts are open source. All Noto fonts are published under the SIL Open Font License, Version 1.1. Language data and some sample texts are from the Unicode CLDR project.
  • Laksaman Laksaman, based on TH Sarabun New. Copyright (c) 2014 Theppitak Karoonboonyanan. TH Sarabun New: Copyright (c) 2010-2011 by Software Industry Promotion Agency (Public Organization) (SIPA). All rights reserved.

Thai character names are based from Unicode standard.

State of Thai in Godot Engine

And today here we come at Godot Engine. Godot Engine is an open source game engine which gains more and more popularity among game developers. Part of the reason is it’s an open source, another part would be it is good enough for many indie games.

When it comes to Thai in Godot Engine, one of the pioneers is LeftWay from Tongson. Tongson is actually a friend of mine whom I chat with almost everyday. He is quite onto Open Source and discovered Godot very early on. He is even one of the first developer who publish games made with Godot in Steam. And that’s a shoutout to him, mavhod.

Enough with the introduction.

In-Game.

Godot Engine supports two kinds of font, the bitmap fonts, and dynamic fonts. Dynamic fonts is in fact TrueType fonts, backed by FreeType library.

First of all, bitmap fonts does not work with Thai, period. Just skip it.

Regarding Dynamic Fonts. Since FreeType has advanced layout feature removed when it was transitioned to the version 2, you can assume that necessary feature for Thai text is also removed as well. I have no experiences with FreeType 1, but FreeType 2 does not supports those features. That also the reason why Dynamic Fonts does not support these features as well.

So yes, its support for Thai text is pretty much on par with Unity 3D. No mkmk nor mark supports. For the time being, you’ll be stuck with older fonts, designed a decade ago. I won’t go into details for now, but it’s pretty similar to Unity 3D version I made. Please check it out.

And here it plays out in-game:

As you might have guess, if you read the link I’ve mentioned before, the above text is Loma from TLWG, and below is Sarabun from Cadsondemak. Loma is older font, which was designed at the time there were no OpenType, so the designer took extra care to make sure it is read-able when the combination of character can lead into problem. These design decision is not present with Sarabun, which was designed much later. Comparing the output of these two fonts, you might notice the missing ticks on Sarabun, and also the tail of one character is overlapping the tail of the above vowel character. That’s the trait of newer fonts.

Similar to Unity3D, you can also do glyph substitution technique to solve the floating tonemark and the floating vowel problem. The feature image I took from LeftWay shows the in-house implementation made by the developer. Please scroll up a little bit :).

However, after I do some more investigation, I come up with the conclusion that it will be come a waste of time in the near feature.

Someone in the Godot Engine community has already proposed to do OpenType shaping based on Harfbuzz library. In fact, a pull request is already been reviewed and should be merged to the main trunk very very soon. The PR originated by a needs to do LTR text layout which is required by Arabian language, but we are also benefitted from the PR as well (they even have screenshots contains Thai text as well). I’d like to express my gratitude to the user bruvzg on github. Thank you.

Here’s the test screenshot, taken directly from that PR. Credit to bruvzg as well.

I’m expecting this to be merged into the next major release of their, but well don’t hold your breath.

Editor

The game engine’s editor runs on top of the game engine, like Unreal Engine 4. So since the engine could not display Thai perfectly (yet), then the editor also suffer from the same problem.

Anyway, Godot ships with Thai font, NotoSansThaiUI, so at least it can display Thai (unlike UE4). And since they ship with older version of NotoSansThaiUI, the font has older design that based on the constraints we had in the past. Thus, Godot Engine can display Thai text pretty well.

So, out of the box, Godot has one of the best Thai support.

Appendix

Here’s the font I uses in above example.

Feature Image taken from LeftWay by Tongsun. I’m not associated nor affiliated with the company nor the title in anyway.