Содержание

Русский шрифт Griftlands

Замечание
На момент написания статьи русский перевод в Griftlands ещё не был доделан. Но шрифт, как я и предполагал, не исправлен, поэтому статья в любом случае актуальна.

Несмотря на то, что в русской локализации подобрали похожий шрифт, он всё равно заметно расходится с оригиналом.

/posts/griftlands-ru-font/default-font.png
Оригинальный шрифт Griftlands: Titillium.

В оригинале используется шрифт Titillium . Несмотря на то, что я не особо фанат подобных шрифтов, он вполне хорошо вписывается в игру.

/posts/griftlands-ru-font/ru-font.png
Шрифт из русского перевода Griftlands: Exo 2. Не обращайте внимания на “1 игра активно”, это я тестировал возможности перевода.

В русском переводе используется Exo 2 , так как у оригинального Titillium нет поддержки кириллицы. Благо, есть русифицированная версия от некого Daymarius. Её, собственно, я и собирался портировать.

Но не всё так просто. Несмотря на то, что в Griftlands есть система модов, где текстуры подгружаются в формате PNG, шрифты всё ещё имеют формат TEX, и из TGA или PNG их подгрузить не получится. Но даже при таком раскладе заменить шрифт у меня всё же получилось.

Извлечение оригинального шрифта

Для того, чтобы понять, как заменять шрифт, для начала нужно разобраться, в каком формате оригинальный шрифт.

Сами шрифты можно найти в папка с Griftlands/data.zip/fonts. Благо, .zip там простой и его можно открыть любым архиватором.

/posts/griftlands-ru-font/game-archive-fonts.png
Папки со шрифтами в игровом архиве.

В оригинале используется последний, Titillium. Собственно, его и будем извлекать.

/posts/griftlands-ru-font/game-archive-titillium.png
Для каждого шрифта нужно два файла: font.fnt и font0.tex.

Скрин немного спойлерит, что этот файл открывается через Sublime Text. Как можно по этому догадаться, это текстовый файл, а точнее, XML.

/posts/griftlands-ru-font/fnt-file-sublime.png
Файл font.fnt.

Но что делать с файлом .tex? Недолго думая, я отправился в Google на поиски.

Вначале я нашёл утилиту для работы с файлами .tex из Don’t Starve . Но к сожалению, при открытии мне просто показало пустой экран.

/posts/griftlands-ru-font/textool-attempt.png
Открытая текстура шрифта в TEXTool. Ошибки не выдало, но и текстуру не показало.

Далее я нашёл возможность экспорта текстур в PNG. В ответе на форуме был указан код функции для этого , но как именно его вызывать, я нашёл позже . Если вкратце:

  1. Включить debug-режим. Для этого в свойствах игры в параметрах запуска нужно прописать --debug.
  2. Открыть консоль в игре. Это делается сочетанием клавиш Ctrl+~ (тильда, на том же месте, что и русская Ё).
  3. Вызвать оттуда функцию. Я делал копипастом из текстового редактора, потому что так быстрее и удобнее.

После этого текстура сохранится в папку Griftlands в папка пользователя/Appdata/Roaming/Klei/Griftlands/steam-***.

Для извлечения шрифта код выглядел следующим образом:

UIHelpers.SaveTextureAsPNG(
	engine.asset.Texture("fonts/titillium_sdf.zip/font0.tex"),
	"titillium")
Однострочная версия

Форматирование я добавил для читаемости, но скорее всего, консоль это не примет, поэтому если хотите протестировать в игре, то лучше использовать эту однострочную версию:

UIHelpers.SaveTextureAsPNG(engine.asset.Texture("fonts/titillium_sdf.zip/font0.tex"), "titillium")

Результат вышел… странным.

/posts/griftlands-ru-font/export-result.png
Извлечённая версия текстуры шрифта Titillum в PNG.

Сразу хочется задать несколько вопросов:

  • Почему здесь не все символы?
  • Почему шрифт размытый?
  • Почему он радужный?

После этого я попробовал извлечь русскоязычный шрифт. Там-то уж явно должно быть больше символов. Код для извлечения не поменялся, только пара аргументов:

UIHelpers.SaveTextureAsPNG(
	engine.asset.Texture("fonts/exo_ru_sdf.zip/font0.tex"),
	"exo")
Однострочная версия

Форматирование я добавил для читаемости, но скорее всего, консоль это не примет, поэтому если хотите протестировать в игре, то лучше использовать эту однострочную версию:

UIHelpers.SaveTextureAsPNG(engine.asset.Texture("fonts/exo_ru_sdf.zip/font0.tex"), "exo")

Вот только результат вообще выдал пустую картинку:

/posts/griftlands-ru-font/export-result-exo.png
Извлечённая версия текстуры шрифта Exo 2 в PNG.

Сразу понятно, что при экспорте в PNG что-то теряется, а значит, нужно раскапывать сам формат. Поэтому я его открыл в hex-редакторе и нашёл интересную вещь.

/posts/griftlands-ru-font/ktex-hex.png
Открытый файл font0.tex в hex-редакторе.

Первым делом сразу видно DDS. Неужели действительно DirectDraw Surface? Что же, есть простой способ проверить: удалить все байты до него.

/posts/griftlands-ru-font/ktex-hex-clean.png
Очищенный файл от первых байт файл font0.tex.

А вот теперь закономерный вопрос: а через что его открывать? Для начала я попробовал Paint.net:

/posts/griftlands-ru-font/dds-paint-net.png
Открытый в Paint.net пропатченный файл font0.tex.

Догадка подтвердилась: это действительно DirectDraw Surface. Но вопросы всё ещё остались: если это оригинальный DDS, то как он работает?

Я решил поискать, чем ещё можно открыть этот файл, и нашёл очень неожиданный вариант: Visual Studio.

/posts/griftlands-ru-font/dds-visual-studio.png

Всё то же самое, разве что зелёный фон вместо шашек. Но именно тут я и выяснил, в чём тут дело.

Когда-то, когда я копался в текстурах на движке Source через VTFEdit, в них был по умолчанию включён альфа-канал. И нередко было, что часть текстуры скрывалась этим самым альфа-каналом. Поэтому я решил глянуть: быть может, и тут так же? И отключил альфа-канал.

/posts/griftlands-ru-font/dds-visual-studio-no-alpha.png

Джекпот.

Теперь всё стало понятно: наборы букв запакованы в разные каналы.

/posts/griftlands-ru-font/dds-visual-studio-r.png
/posts/griftlands-ru-font/dds-visual-studio-g.png

/posts/griftlands-ru-font/dds-visual-studio-b.png
/posts/griftlands-ru-font/dds-visual-studio-a.png

Теперь понятно, почему там не все символы, и почему они были радужными.

После этого мне не составило труда сконвертировать это в TGA: это можно сделать всё в той же Visual Studio. Почему TGA? Потому что так было указано в файле .fnt.

Кстати, как оказалось, Paint.net тоже умеет конвертировать DDS в TGA. Так что это как возможная альтернатива, если не хочется ставить Visual Studio. Но наверняка есть и другие способы.

/posts/griftlands-ru-font/tga-photoshop.png

Сконвертированный TGA отлично работает в Adobe Photoshop.

Тут мне стало интересно, а как выглядит внутриигровой Exo 2?

/posts/griftlands-ru-font/exo-tga-photoshop.png

В целом, так же, но тут используется текстура большего разрешения, и занимает это в сложности примерно 1.3 канала. Но в целом всё выглядит так же.

Что же, способ извлечь найден, теперь нужно найти способ создать свой и запаковать.

Но один вопрос всё ещё так и остался нерешённым.

Замена извлечённого шрифта

Как можно заметить, на текстурах шрифт… немного размытый. Непонятно, что за подсвечивающий контур вокруг него.

/posts/griftlands-ru-font/font-channel.png

Но благо, тут есть подсказка, и она прямо в названии шрифтов.

/posts/griftlands-ru-font/archive-folders.png

Да, вы правильно поняли, речь об SDF.

Недолго думая, я полез искать хоть какую-то информацию по этой теме. И наткнулся на эту статью: Рендеринг UTF-8 текста с помощью SDF шрифта

Я не буду рассказывать тут, что такое SDF, потому что это уже там расписано. Но что мне действительно пригодилось оттуда:

  1. Программа BMFont . Это программа для генерации bitmap-шрифта. Инструкция была не под неё, поэтому настройки пришлось подбирать вручную. Возможно, через UBFG было бы сделать легче, но я не стал возиться со сборкой.
  2. Команда для ImageMagick. Для того, чтобы получить то, что мне надо, я немного поигрался с параметрами.

Для начала я установил шрифт (так как из файла он не загрузился) и открыл его в BMFont. Также я сразу выбрал все группы символов, которые там были.

/posts/griftlands-ru-font/bmfont-titillium-rus.png

С настройками шрифта оказалось всё просто: поменял только шрифт и размер. Правда, размер шрифта я подбирал под примерный размер текстуры.

/posts/griftlands-ru-font/bmfont-font-settings.png

А вот с настройками экспорта пришлось помучаться, но я подобрал что-то вроде этого:

/posts/griftlands-ru-font/bmfont-export-options.png

Из важного:

  • Padding задаёт отступ от символа. Он должен быть достаточным, так как шрифт генерируется без учёта SDF-контура.
  • Texture width и texture height. Я старался подобрать размер, который не будет сильно большим, но сможет вместить в себя все символы. Более того, я старался на всякий случай не трогать альфа-канал.
  • Pack chars into multiple channels. Это позволяет генерировать такие же текстуры шрифтов, которые есть в самой игре: запакованные по разным каналам.
  • Chnl и Value. Вот здесь я решил подобрать такие же значения, как в оригинале: encoded glyph & outline – это 2 (выставлено для альфа-канала в оригинальном шрифте), а glyph – это 0 (выставлено для остальных каналов).

Но тут есть проблема. Дело в том, что если стоит галочка Pack into multiple channels, то можно выбрать или пресет, или альфа-канал. В таком случае можно сделать следующее:

  1. Выбрать в Presets “White text on black (no alpha)”.
  2. Для альфа-канала выставить encoded glyph & outline вместо one.

Ну и само собой, я выставил тип Targa без RLE-сжатия и XML в Font Descriptor.

Замечание
Настройки можно подобрать и другие, и, может, даже лучше, чем те, что уже есть. Например, когда я проходил по второму разу, я заметил, что там есть экспорт в DDS напрямую. Однако после экспорта появилась ещё одна проблема, поэтому это ещё нуждается в проверке.

Предварительно шрифт можно просмотреть в Options > Visualize, но так как цвет слишком резкий (он ярко-красный!), я лучше покажу результат экспорта:

/posts/griftlands-ru-font/bmfont-export-result.png

Осталось сделать его в SDF. Для этого я использовал следующую команду из статьи:

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

Я использовал более новую версию ImageMagick, а также немного подстроил значения, поэтому вышло так:

magick font.png ^
	-filter Jinc ^
	( +clone -negate -morphology Distance Euclidean -level 50%,-50% ) ^
	-morphology Distance Euclidean ^
	-compose Plus ^
	-composite ^
	-level 42%,58% ^
	font.png
Немного о форматировании

В целях читаемости я разбил на несколько строк, и так как в статье всё проделывалось на Windows, разбивка здесь используется именно для её командной строки. Тем не менее, здесь нет ничего специфичного для командной строки Windows, поэтому это вполне легко адаптируется для Bash простой заменой ^ на \:

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

Или даже написано в одну строку, что должно работать и там, и там:

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

Но если попробовать так сконвертировать TGA, то вы получите пустой файл. Дело в том, что фильтр нужно применять к каждому каналу по отдельности. Я ещё не разобрался с тем, как это сделать через ImageMagick, но пока это будет сделано, проще вручную посохранять каналы раздельно и прогнать их, после чего слепить в один.

Результат вышел следующим:

/posts/griftlands-ru-font/exported-sdf.png

То, что надо. Теперь нужно конвертнуть в TEX, но как?

Как я уже писал выше, TEX – это DDS со своей шапкой. Поэтому нужно просто конвертировать TGA в DDS и добавить нужные байты.

/posts/griftlands-ru-font/dds-ktex-bytes.png
Дополнение
Позже я выяснил, что ни добавление первых байт, ни конвертирование в DDS не нужны. Достаточно файл TGA переименовать в font0.tex и положить в нужную папку.

Всё готово, можно подключать шрифт в мод и проверять его в игре. Но тут меня ждал сюрприз.

/posts/griftlands-ru-font/griftlands-garbled-font.jpg
Небольшая пометка: это скрин из старой версии, когда я экспериментировал с размером текстур, поэтому она запакована была иначе. Оно может отображаться по-другому с текущими настройками, но суть остаётся та же.

Большая часть текста стала совершенно нечитаема. Но некоторые буквы отображаются нормально. В чём же дело?

Как оказалось, нормально отображался только зелёный канал. Когда я поменял местами красный и синий, повторив процедуру перепаковки, всё заработало как надо.

/posts/griftlands-ru-font/griftlands-fixed-font.jpg

Несколько слов в заключение

На данный момент поменять шрифт в Griftlands довольно сложно. Возможно, вскоре появятся люди, которые напишут для этого специальные программы. Я же планирую написать полноценный гайд, подобрав команды получше и способ генерации полегче.

Что касается русского перевода, то я планировал исправить его косяки, потому что, как выяснилось при выходе из раннего доступа, они исправлены не были. Но когда это будет, никто не знает. Даже я сам. Но надеюсь, что будет.

К слову, готовый шрифт можно поставить через этот мод:

Имейте в виду, что для его работы нужен мод Font Switcher: