Russian Griftlands font
Even though there was a similiar font picked in Russian translation, it’s notably differs from original.
Original uses Titillium font. Even though I’m not a fan of such fonts, it fits in the game pretty good.
Russian translation uses Exo 2 , since original Titillium has no support for Cyrillic. Luckily, there is a version with Cyrillic glyphs from certain Daymarius. And this is the version I’m planning to port.
But it’s not that simple. Even though Griftlands has mod system, where textures are loaded from PNG, fonts are still in TEX format, and you can’t load them from TGA or PNG. But I’ve managed to replace the font anyway.
Extracting original font
To understand how to replace the font, we need to identify original font format.
Fonts themselves can be found in Griftlands folder/data.zip/fonts
. Luckily, it’s a simple .zip and it can be opened with any archiver.
Original uses the last one, Titillium. So, this the font we will extract.
This screenshot spoilers a little that this file can be opened in Sublime Text. As you can guess, it’s a text file, or more specifically, XML.
But what to do with .tex file? Without thinking, I headed to Google search.
At first I’ve font .tex file tool for Don’t Starve . But sadly, a blank screen was shown when I’ve opened a file.
Next thing I’ve found is the way to export textures to PNG. In forum reply a function code has been posted but info about how to call it I’ve found later . In short:
- Enable debug mode. For that you’ll need to add
--debug
to game start parameters. - Open in-game console. It can be done by hitting
Ctrl+~
(tilde). - Call function from there. I did it by copy-pasting from text editor because it’s faster and more convenient.
After that texture will be saved in Griftlands folder to в user folder/Appdata/Roaming/Klei/Griftlands/steam-***
.
Font extraction code looked like this:
UIHelpers.SaveTextureAsPNG(
engine.asset.Texture("fonts/titillium_sdf.zip/font0.tex"),
"titillium")
Formatting was added for readablity sake, but it probably won’t work in console, so if you want to test it in-game, it’s better to use this one-line version:
UIHelpers.SaveTextureAsPNG(engine.asset.Texture("fonts/titillium_sdf.zip/font0.tex"), "titillium")
Result came out… strange.
Many questions arise momentarily:
- Why not symbols are here?
- Why the font is blurry?
- Why it’s rainbow-colored?
After that I’ve tried to extract Russian font. It defintely should contain more symbols. Extraction code wasn’t changed, only few arguments:
UIHelpers.SaveTextureAsPNG(
engine.asset.Texture("fonts/exo_ru_sdf.zip/font0.tex"),
"exo")
Formatting was added for readablity sake, but it probably won’t work in console, so if you want to test it in-game, it’s better to use this one-line version:
UIHelpers.SaveTextureAsPNG(engine.asset.Texture("fonts/exo_ru_sdf.zip/font0.tex"), "exo")
But result was the empty picture:
Right away it’s evident that something is lost during PNG export, so digging the format itself is required. That’s why i’ve opened it in hex editor and found an interesting thing.
First thing spotted is DDS
. Could it really be DirectDraw Surface? Well, there is a simple way to check: just trim all bytes before it.
And now is expectable question: how to open it? At first I’ve tried Paint.net:
My guess was correct: it is DirectDraw Surface. But there are still questions left: if it’s the original DDS, then how it works?
I’ve decided to search how else this file can be opened, and I’ve found very unexpected option: Visual Studio.
Eveything is same if not counting green background instead of checkered. But this was the place where I’ve found out what’s happening here.
Some time ago, when I was fiddling with Source engine textures with VTFEdit, they had alpha channel enabled by default. And commonly part of texture was hidden behind the same alpha channel. That’s I’ve decided to try: maybe it’s the same story here? And disabled alpha channel.
Jackpot.
Now it’s all made clear: letters are packed in different channels.
It’s clear now why only some symbols were shown and why they were rainbow-colored.
After that I’ve easily managed to convert it to TGA: it can be done in the very same Visual Studio. Why TGA? Just because it .fnt file said that.
By the way, as I’ve found out later, Paint.net also can convert DDS to TGA. So it’s a possible alternative if you don’t want to to install Visual Studio. But I’m sure there are other ways to do it.
Converted TGA works perfectly in Adobe Photoshop.
Then I’ve got curious how in-game Exo 2 looks.
Mostly the same, but it uses bigger texture and about 1.3 of channel is used in total. But mostly it looks the same.
Well, I’ve found the way to extract, now I need to find to create my own and pack it.
But there is still one question left unsolved.
Replacing of extracted font
As you can see, texture font is… a bit blurry. Not sure what’s the glowing border around it.
But luckily there is a hint right in font names.
Yes, you’ve got it correctly, we’re talking about SDF.
Without thinking I’ve started to search any information about it. And i’ve found out this article: UTF-8 text rendering with SDF font (in Russian) .
Not sure if there is an equal material or a translation of it on English, but I’m not going to tell what’s the SDF here. But here are the things from it that helped me:
- BMFont software. This app allows to generate bitmap font. Instruction in article wasn’t written for it, so I had to pick settings myself. Maybe UBFG would be easier, but I decided to avoid building.
- ImageMagick command. To get the result I need I’ve played with paramters a little.
First I’ve installed the font (since loading from file didn’t work) and opened it in BMFont. Also I’ve immediately selected all symbol groups that were there.
Font settings turned out to be easy: changed only the font itself and size. Font size was adjusted to approximate texture size though.
But export settings were a little pain, but in the end I’ve chosen something like this:
Important things here:
- Padding sets the padding from from symbol. It should be big enough since SDF border is not taken into account when generating.
- Texture width and texture height. I’ve tried to pick the size that will be not too big but can fit all symbols. Moreover, I’ve tried to not touch alpha channel.
- Pack chars into multiple channels. It allows to generate same font textures like in the game: packed in different channels.
- Chnl and Value. Here I’ve decided to pick the same values like in original: encoded glyph & outline is 2 (set for alpha channel in original font) and glyph is 0 (set for other channels).
But here’s the problem. The thing is that if Pack into multiple channels is checked then you can change either preset or alpha channel. In this case you can do the following:
- Choose in Presets “White text on black (no alpha)”.
- Set alpha channel to encoded glyph & outline instead of one.
And of course I’ve set Targa without RLE compression as type and XML as Font Descriptor.
You can see the resulted font in Options > Visualize
beforehand, but since the color is too eye-hurting (it’s bright red!), I’ll better show export result:
Now only thing left is to make it an SDF. For that I’ve used the following command from the article:
convert font.png ^
-filter Jinc ^
( +clone -negate -morphology Distance Euclidean -level 50%,-50% ) ^
-morphology Distance Euclidean ^
-compose Plus ^
-composite ^
-level 43%,57% ^
-resize 12.5% ^
font.png
I’ve used newer version of ImageMagick and adjusted some values, so it’s ended like this:
magick font.png ^
-filter Jinc ^
( +clone -negate -morphology Distance Euclidean -level 50%,-50% ) ^
-morphology Distance Euclidean ^
-compose Plus ^
-composite ^
-level 42%,58% ^
font.png
I’ve split the command to multiple lines for readability sake and since all things from article were done on Windows, its command line splitting is used. However, there is nothing specific for Windows’ command line, so it can be easily adapted to Bash by simply replacing ^
to \
:
convert font.png \
-filter Jinc \
( +clone -negate -morphology Distance Euclidean -level 50%,-50% ) \
-morphology Distance Euclidean \
-compose Plus \
-composite \
-level 43%,57% \
-resize 12.5% \
font.png
magick font.png \
-filter Jinc \
( +clone -negate -morphology Distance Euclidean -level 50%,-50% ) \
-morphology Distance Euclidean \
-compose Plus \
-composite \
-level 42%,58% \
font.png
Or it can be written in one line which should work in both shells:
convert font.png -filter Jinc ( +clone -negate -morphology Distance Euclidean -level 50%,-50% ) -morphology Distance Euclidean -compose Plus -composite -level 43%,57% -resize 12.5% font.png
magick font.png -filter Jinc ( +clone -negate -morphology Distance Euclidean -level 50%,-50% ) -morphology Distance Euclidean -compose Plus -composite -level 42%,58% font.png
But if you’ll try to convert TGA that way, the result will be an empty file. The thing is that filter must be applied to each channel seprately. I haven’t understood how to apply filter to channel in ImageMagick yet, but before it’s done it’s easier to save channels manually and process them, and then glue them back together.
That was the result:
Just what I needed. Now I need to convert to TEX, but how?
As I wrote eariler, TEX is a DDS with its own header. So I just need to convert TGA to DDS and add necessary bytes.
font0.tex
and putting in right folder is enough.All done, now you can include the font in mod and test it in-game. But there was a surprise waiting for me.
Most of the text became totally unreadable. But some letters are shown correctly. What’s wrong?
As it turned out, only green channel was shown correctly. After swapping red and blue channels and re-packing everything started to work as expected.
Few closing words
It’s kinda hard to change the font in Griftlands currently. Maybe there will be people that will write specialized programs for that. I’m planning to write a proper guide with better commands and easier generation options.
Regarding Russian translation, I’ve planned to fix its mistakes because they weren’t fixed after Griftlands left the early access. But nobody knows when that happen. Even me. But I hope it will.
By the way, you can use the font in-game through this mod:
Note that to get it to work, you need the Font Switcher: