Text, text, text! There’s so much text in Daggerfall – from “Rat just died” all the way up to multi-page books. Before it’s possible to tackle many gameplay elements, something must be done about all this text. All the better if the text engine provides localization features at the same time.
Rather than start from scratch, I have integrated the excellent free Unity asset Smart Localization into Daggerfall Tools for Unity. On this solid foundation, I’m building import tools to convert Daggerfall’s various text sources into a format that can be easily localized and consumed at runtime.
Let’s take a look at the basic workflow. Everything starts with creating a “Localization Workspace” in your project Assets. By the way, it’s possible to work on translations without Unity installed, more on this towards the end.
What you see above is the Smart Localization workspace. I have already created 3 languages for English – en, French – fr, and German – de. There is also a Root Language File, which needs a bit more explanation.
The Root Language is a database of native key/object pairs that can be morphed into other supported languages. In addition to strings, the Root Language also supports images, sounds, and other game objects.
I am writing one-click importers that transfer text data out of Daggerfall’s various files (even the .exe) into their own text namespace. See below for an example after importing the contents of TEXT.RSC.
There’s a fair bit going on here, so I’ll break down all the parts.
Type is the type of asset being worked with. These are all STRING for now, but GAME_OBJECT, AUDIO, and TEXTURE are also supported.
Key is the unique key for this resource. As we’re importing from Daggerfall, the tool maintains each unique key in its own namespace. RSC means that TEXT.RSC was the source and the following digits are the unique ID for that text record. Each distinct resource will have its own three-letter namespace (BOK, IMG, SND, etc.) and unique ID.
Comment is the actual value, or contents, of that record. Anyone that has worked with Daggerfall’s text data will be familiar with the % codes. What’s a little different are how the control bytes are parsed into text format, for example [0xFD] for end of line. This is done because the control bytes are not valid characters for XML (which is how everything is saved to disk) and they are not generally human readable. The [0x00] format makes it very clear where control bytes are used and simple for a human to edit. It’s also trivial to parse these back into byte format.
A little more on those control bytes for anyone unfamiliar with them. They are basically for TTY-styled formatting. They control things like text position, justification, and font, and are very specific to the native Daggerfall GUI at 320×200 resolution. It’s very likely that future developers will prefer not to use the control bytes for their modern scalable UI. However, I pass through the control bytes exactly as-is and its up to the end developer how they wish to use them. If you would like read more about Daggerfall’s text then this article would be of use.
Once the Root Lanuage is ready, it’s time to create our translations. As the text is already in English – en it’s just a simple matter of opening that language and copying all values from Root.
Now the great thing about Smart Localization is that it supports CSV import/export. This means you can export out your language data to CSV file to edit in Excel or similar tool.
Because everything is uniquely keyed, translation teams can build “master” CSV files that implementors can use to quickly add/update languages in their projects. For example, below is the CSV for German – de from their TEXT.RSC file.
And then imported into Unity ready to use in a game project.
One issue with existing translations is that localization teams have needed to squeeze more complicated character sets down into Daggerfall’s 8-bit format. The good news is this is no longer necessary – you are no longer limited by Daggerfall’s engine. The bad news is that a lot of text will probably need to be rewritten for true character set translations for modern platforms. I will work with international Daggerfall fans to ensure they can use native character sets in the translation tool chain.
So we can create a giant resource database and spin-off various translations. How does this get used in a game project?
Accessing localized resources is very easy. For example, to retrieve a localized text string above, you would use the following code. Other resources are just as easy.
string textValue = LanguageManager.Instance.GetTextValue("RSC.1004");
As the native IDs are preserved, it will be easy for upstream developers to call for the correct translations as linked from quests and elsewhere. You can also add custom values for your own project, just need to give them a unique key.
Fell free to hit me up in the comments or via email if you have any question.