## How to Translate a Game 3/3: Gamemaker Studio 2 Example

This is part 3 of my article series about translating video games. Part 1 gave you a high level overview of the process, and things to consider when translating a game. Part 2 talked about splitting up the content and handing it back and forth, plus tools for getting it done.

In this final act I talk implementing it all, using a Gamemaker Studio 2 project as an example (download link below). Note however, that using this approach can be done with any engine. With a few changes, you could adapt a similar solution using XML-files with C#, instead of ini-files and GML.

Open the example project to get a better idea of how all the elements fit together. Note that the free version of Gamemaker Studio 2 does not support included files. For the record, yours truly has no official affiliation with YoYo Games or Gamemaker. I use Gamemaker in this article, because that is the engine I used for Torgar’s Quest. As a final disclaimer, while these scripts are all fairly simple, I do not explain any basic concepts like if/else-statements.

DOWNLOAD EXAMPLE PROJECT FILE: LocTut.zip – You will need to unzip it, before you can open it in Gamemaker Studio.

### Setting Up Project and Assets

Your text assets should be correctly formatted files, added and organized by language for easy navigation. A main folder with a subfolder for each language is a good starting point, giving you a path like: text_assets/en/strings.ini

If you want to generate a set of ini-files that go with the example project, you can use the spreadsheet provided in part 2. It already contains the needed data and a macro that spits out an ini-file for both languages in that project.

When abbreviating a language for reference, use its actual ISO code. That way everyone knows what you mean, or can at least google it. Find a list of codes here: https://en.wikipedia.org/wiki/ISO_639-1

Next, make sure you have imported all relevant special characters for each language. From umlauts to caron characters, fonts are not always imported with these by default, or may not even include them at all. The reasoning is that fonts take up memory, so any unneeded character that is excluded equals memory saved and performance gained. This especially true with alphabets containing many characters, such as Chinese.

Identify exactly which special characters are needed for your translations, and add them to the game. For Torgar’s Quest, I asked each translator to provide a list of special characters (since they know their language better than me), and trusted that they did not miss one. And when it happened anyway, it was still caught in QA and fixed in a couple of minutes.

If a font used in the project does not include the characters you need, you may have to use a different font altogether. At that point you will have to decide whether to change that font game-wide or just for this one language. Game-wide changes can affect the overall look and feel of the game, and language specific changes can result in a mess of exceptions, as different languages have their own issues. This is a common example of a translation related problem that appears late in the development or QA phase of a project, and may require last minute design compromises.

### Implementation in Gamemaker Studio

Match the folder structure in your project with the one on your drive to avoid unnecessary confusion. Little consistencies like that make a big difference in keeping things organized as your project scales.

When the game launches, it loads the default settings. In our example, the default is English. Next, the strings are loaded into a ds_map called global.text (if you are unfamiliar with GML, a ds_map is the equivalent of a Dictionary/Hashmap in other languages). Since I only have a small amount of data, I just add it directly. If you don’t have a ton of text, this is fine. If you have a lot of data, you may want to make a loop of some kind instead.

This script is only executed on launch.

GML Script:
// default language global.language = "en";

 // Initial setup of map to hold the strings global.text = ds_map_create(); // Open the ini-file matching the language ini_open(working_directory+"\\text_assets\\"+global.language+"\\strings.ini"); // Copy data from the ini to the map. ds_map_add(global.text,"MENU_BUTTON_SAVE",ini_read_string("menu","MENU_BUTTON_SAVE","MENU_BUTTON_SAVE")); 

ini_close();

Normally, I would put this code in a persistent controller object, but for the sake of simplicity, in the example project the button itself runs the code to set things up as well as switching the language, which comes next.

The current language reference code is stored in a simple, global string. To change the language, we call a script called s_setLoc() and provide the language code, we want to switch to, as an argument.

Any time you want to change the language, run this script with the target language as the parameter, for example to change the language to Danish, type:
s_setLoc(“da”);

GML Script for s_setLoc:
/// Sets the active language. global.language = argument[0];

 // Opens the ini file matching the language. ini_open(working_directory+"\\text_assets\\"+global.language+"\\strings.ini"); // Replace the current string with the same one from the new language ds_map_replace(global.text,"MENU_BUTTON_SAVE",ini_read_string("menu","MENU_BUTTON_SAVE","MENU_BUTTON_SAVE")); 

ini_close();

As you can see, changing the language is very similar to the initial setup.

The strings are loaded into memory to avoid opening the ini-file every time a string is displayed. Continual loading of a file would slow down your game’s performance on lower end systems, and it’s just not a good approach. Loading from memory is faster and more efficient. If you have tons of text, you may have to expand on this to support several sources instead of just one ini-file per language, and then only load what is needed for the section of the game that is running.

Once the language is set and the assets are loaded, you call another script to show the specific string. That script takes the string ID as its parameter, then matches the ID with the keys of the string map in memory, and spits out the matching value.

This script doesn’t care what your language setting is, it strictly matches an ID with whatever is in that slot in the map. If there is no translation for a string at all, or the ID was mistyped, the ID itself will be displayed in-game. This helps with debugging, making it very easy to see, what still needs to be translated.

Call this script from anywhere in your code to fetch a string. Following the example project, to display the button text, the script is called like this:
s_print("MENU_BUTTON_SAVE")

GML Script for s_print:
/// Fetches string based on language setting and resource ID myString = argument[0]; // Resource ID requested

 

// If the string does not exist, return the ID as a string. // Otherwise return the string value matching the ID. if (global.text[? myString] == undefined) { return myString; } else { return global.text[? myString]; }

### Troubleshooting

If you are seeing unexpected results, check that…

• You are using the most current assets.
• Are you using the right version of Gamemaker Studio?
• Your ini-files are utf-8 formatted, which is what Gamemaker expects. You can check this (and convert if necessary) from most text editors.
• You have included all necessary special characters in your font set.

### Final Words

Translation is so much more than switching one language out with another, both in terms of content considerations and technical challenges. I hope these three articles have helped shed some light on what is actually involved, what most of the dangers are, and how some of them can be averted. I don’t claim to have all the answers, in part because I believe every project is unique and will come with its own set of challenges.

I guess you can boil it down to this: successful translation of a video game is the sum of good source material, careful scope consideration and properly equipped translators, held together by a streamlined workflow. It may be rare to see those factors all come together perfectly, but aiming for the best is always a good starting point.

If I missed anything, please do share it, drop a comment or reach out to me on twitter (@theprint).

## Procrastinating a Milestone

Do you ever put off finishing something, because finishing means that it’s over? That’s kind of where I am right now. It is an exciting place to be, because it feels like I am accomplishing something.

It is also frustrating as hell.

In this case, the project is my game Torgar’s Quest. I’ve been working on it for several months, slowly developing and implementing all the features I thought it should have. Even many that I didn’t think I could figure out how to code or design, because it was new and scary.

Now, it’s nearly all there, maybe not fully polished or balanced – but at least it’s in there – yet I find myself procrastinating the last few details as if to prolong the process in some act of self sabotage. I have seen this symptom before, and it can be a killer if you let it take root. Like the writer I know, who has several unfinished novels on his hard drive, or the musician I know, who has hundreds of unfinished songs stored away.

There is still a LOT of work to do, don’t get me wrong. Making a video game is a lot like writing a book. You start with an idea and turn it into a rough outline (alpha), which then forms the basis for your first draft (beta). That’s me, now, with Torgar. What follows next is editing and making it nice, before I can finally unleash it on the world in its full, pixelicious glory.

Still to do: more balancing and testing and tweaking and, did I mention balancing? Polishing an endless list of detail, localization and somehow finding time to also promote the game.

So I have to kick myself into gear and add those last few features on my list, so I can start testing and balancing for real. Even if part of me is enjoying that feeling of almost being done with the first draft.

First up, no more writing blog posts about procrastination, as an act of procrastination! Instead, I should start getting ready for beta testing. If you want to be part of the beta testing, let me know.

## Story in Game Design (2/2)

This is part 2. Part 1 is about story in video games in general. I have split this post in two, but could have just as easily filled the pages of a book. Incidentally, there are already many excellent books about storytelling out there. Part 2 focuses on the story in Torgar’s Quest.

## Story in Torgar’s Quest

Basically, Torgar’s Quest is about a dwarf running through a dungeon, killing and destroying things along the way, while looking for treasure. That is where I started, and while the game mechanics were fun, the game needed story to better tie the elements together.

Some background and motivation for the game’s main character seemed like a good place to start. In this case, a reason for Torgar Splitbeard to be in the dungeon, and a goal the player can help him achieve.

Early on, I had decided that to win the game, you would need to find and collect 7 crystals. It was an easy jump from there, to say that these were actually shards that together form a powerful artifact – The Mastery Crystal, which Torgar of course is seeking to find. Brainstorming is your friend when developing story, and much of what came next was a product of exploring this initial idea.

Seeking to boost Torgar’s motivation, I decided that he was the underdog of his clan, a younger prince with no hope of inheriting power, and everyone in his family saw him as weak, and incapable of achieving greatness. Here I had my first glimpse of Torgar’s personality: clearly upset, with a strong need to prove himself to his clan, and more so, to become powerful in his own right.

Whenever I am stuck in developing a story, I start asking questions. Why is this character interested in X? How did Y learn about Z? What if something unexpected happened? By asking questions, I soon had a tie-in between the crystal artifact and Torgar’s own story.

Why was the artifact split into shards? What if the Mastery Crystal was too powerful, and hunting for it could corrupt Torgar’s very soul? I liked that, so in the game, the longer you take to find the seven shards, the more twisted Torgar becomes.

I also started wondering about the dungeon itself, and decided it had once been the home of Torgar’s clan, but that the dwarves had been driven out during an invasion of monsters many years ago. This adds to Torgar’s resolve: he is not only seeking a magical crystal, he is also taking back his clan’s old home. Tying story strings together is never a bad thing.

I included bits of lore to spice up the Deepgold Mines, which can be found in hidden tomes around the dungeon. These books of lore serve no other purpose than to add flavor, a dash of humor and to make the game more fun. But if you’re the kind of person who tends to skip the flavor text, you can simply ignore it and play the game with no penalty – an important detail, because I definitely did not want to force players to stop and read, if all they want is to bash monsters (Diablo handles this by using a voice over that plays in the background, but that was a little out of my budget).