In this post, I’d like to talk a bit about displaying Thai text in Unreal Engine 4. I’ve been playing with this engine for months now. What I’ve seen so far is the engine does support Thai, but with a little bit of catch. I’ll talk about them a little bit later in this post.

Some might ask, what is so special about Thai? Well I’ve seen more and more awareness in getting games localized for Thai. AAA titles like Sekiro, Dying Light, or Jump Force ships with Thai localization. Many more are rumored to have one. Anyway Thai is also one of the difficult language to display due to its 4-level of glyph positions.

To give you some head ups, at a given horizontal position, there are 4 possible positions. These names are my madeups, which might different than other documents. Please keep this in mind.

  • Base character, which always stay on the base line. Part of the character might be under the base line.
  • Above base character, this can be either floating vowel character, or tone mark.
  • Above floating vowel character. In this position it can be only tone mark.
  • Below base character vowel.

For example ‘คนที่ไม่มีความกตัญญูกตเวที’

I won’t go further than these details. May be later I’ll write some article about that.

Because of these position, most game engine which only support TrueType layout (advance + bearing) won’t be able to render Thai string currently, let alone those only support fixed-width font.

Unreal Engine 4, in the other hands, support OpenType shaping. Things like mkmk, mark, etc. are directly supported, thanks to Harfbuzz, an open source OpenType shaping engine.

In-Game

As I mentioned before, support for Thai is pretty good out of the box. Just add a Thai font, create a TextBox with that font, and done, it’s ready.

But here’s the catch. Not all fonts are created equally.

The one on top is Sarabun, while the one on the bottom is NotoSans Thai. Notice that the above-vowel tone mark is not placed correctly. I don’t know why either. Since NotoSans Thai work fine on many software (including Android OS) my guess is UE4 has some problems with this font specifically.

Actually Sarabun is not perfect either, here’s why:

Sarabun has it’s ascender and descender too small to cover the lower vowel and above-vowel tonemark. If you have multi-line string, it’s possible that these characters will clash with each others, resulting in some nasty looking. This is something with the font. I’ve already contacted Cadsondemak on this matter, but they have yet to reply. May be I should visit Emquartier sometime, as their office is there :).

The one that looks better than those 2 above is Loma from TLWG.

The takeaway here is, you have to do some experiment to find which works and which does not.

Editor

Since the engine’s editor run on the engine itself, the editor is also capable to display Thai text as well as the game does. However, the game engine is not shipped with fonts that has Thai glyphs, every Thai character displays as ‘Tofu’s.

They are not ordinary Tofu, but still Tofu nonetheless. Anyway as I mentioned earlier, the editor itself runs on top of the engine, so if the engine can displays Thai, then what only missing is Thai fonts. Adding Thai fonts is not a difficult tasks to do, but it requires a little bit of coding. You have to then rebuild the engine from source. I hope that we could have Thai fonts shipped with the engine, but that’s up to the team at Epic to decide.

And here is the proof that it’s capable of doing that, after some modifications.

Anyway, in order to add font, firstly you have to get source code and build it. Please refer to this article for how to do that.

Secondly, after have all the code and build the engine, we needs some Thai fonts. I’m using Sarabun from Cadsondemak in this example, as the font looks amazing and render almost correctly most of the time by UE.

The path is /Engine/Editor/Slate/Fonts.

Finally, add some code to TSharedRef<const FCompositeFont> FLegacySlateFontInfoCache::GetDefaultFont() function to let the engine cache the fonts we’ve added.

// Thai (editor-only)
if (GIsEditor)
{
    FCompositeSubFont& SubFont = MutableDefaultFont->SubTypefaces[MutableDefaultFont->SubTypefaces.AddDefaulted()];
    APPEND_RANGE(SubFont, Thai);
    APPEND_EDITOR_FONT(SubFont.Typeface, "Regular", "Sarabun-Regular.ttf", EFontHinting::Default);
    APPEND_EDITOR_FONT(SubFont.Typeface, "Italic", "Sarabun-Italic.ttf", EFontHinting::Default);
    APPEND_EDITOR_FONT(SubFont.Typeface, "Bold", "Sarabun-Bold.ttf", EFontHinting::Default);
    APPEND_EDITOR_FONT(SubFont.Typeface, "BoldItalic", "Sarabun-BoldItalic.ttf", EFontHinting::Default);
    APPEND_EDITOR_FONT(SubFont.Typeface, "BoldCondensed", "Sarabun-Bold.ttf", EFontHinting::Default);
    APPEND_EDITOR_FONT(SubFont.Typeface, "BoldCondensedItalic", "Sarabun-BoldItalic.ttf", EFontHinting::Default);
    APPEND_EDITOR_FONT(SubFont.Typeface, "Black", "Sarabun-ExtraBold.ttf", EFontHinting::Default);
    APPEND_EDITOR_FONT(SubFont.Typeface, "BlackItalic", "Sarabun-ExtraBoldItalic.ttf", EFontHinting::Default);
    APPEND_EDITOR_FONT(SubFont.Typeface, "Light", "Sarabun-Light.ttf", EFontHinting::Default);
    APPEND_EDITOR_FONT(SubFont.Typeface, "VeryLight", "Sarabun-ExtraLight.ttf", EFontHinting::Default);
}

Feel free to change the font files to the one you’re using, if you’re not using Sarabun as I am.

Anyway I’ve came across some fonts that works fine in-game but not in editor, Loma is one of them. It just display ‘Tofu’ like this font does not exist. I don’t know why. If you happen to come across any font that works fine in both in-game and editor, please feel free to leave some comments.

Appendix

Here’s the font I uses in above example.

Feature Image taken from Home Sweet Home by YGGDRAZIL GROUP. I’m not associated nor affiliated with the company nor the title in anyway.