We hacked together a small tool to extract translation files for Ren’Py games.

Ren’Py is built to support translations natively, and it comes with a handy-dandy button to easily extract translation files.

The files come out looking something like:

Note the unique strings underlined in the image. Those are identifiers that allow Ren’Py to easily substitute translations into the correct place. So usually, generating these translation files is a breeze, and the localization process, at least on the textual end, is not too bad.

However, recently, that handy-dandy “Extract Translations” button has been broken for us. We have been unable to use it to generate the files, with Ren’Py complaining with every attempt. Luckily, the “Extract Dialogue” button still works, and it contains the unique identifiers for each string. The format is simply incorrect though.

Extract Dialogue gives us a tab-delimited file.

The same file has been loaded into a table for easy viewing.

We need to convert that file into something that looked like the translation files. The code snippet below is pretty messy and hard-coded, but it works, at least. We’ll upload a cleaner/better version to a public Git repo with all the random snippets that we create. Hopefully it will save others some hair-pulling.

import pandas as pd
import math

# load the dialogue file into a pandas table
# we're working with Chess of Blades here

# define the translation folder language we want
lang = "simplified_chinese"

# iterate through each row in the table
for _, row in cob_df.iterrows():
filename = row['Filename'].split('/')[-1]
with open('chess_of_blades/game/tl/'+lang+'/'+filename, 'a', encoding='utf-8') as f:
# this try clause is for any translation text that doesn't have a character speaking
# such as a choice menu
try:
if math.isnan(row['Character']):
old_char = 'old'
new_char = 'new'
f.write('''
# {}:{}
translate {} strings:

old "{}"
new ""

'''.format(row['Filename'], row['Line Number'], lang, row['Dialogue']))
except TypeError:
old_char = row['Character']
new_char = old_char

f.write('''
# {}:{}
translate {} {}:

# {} "{}"
{} ""

'''.format(row['Filename'], row['Line Number'], lang, row['Identifier'],
old_char, row['Dialogue'], new_char))