Tkh's Translation Helper program (downloadable)

Latest update [2018-06-14]
v.0.7.2 is using a new library (Newtonsoft for reading and saving json files. It’s a quite big update from 0.6 and solves many old problems and workarounds! Only limited tested at release but it seems to work.

Direct download: (256.1 KB)

TranslateHelper_a061 removed for now, send a PM if you need it for some reason.

Hi guys, as you know I have been working on a little piece of software that could aid the translation work. Feel free to download and try, when you find bugs, post here or send a PM.

I know the game is not finished, and things could change which makes this program obsolete. If the format isn’t changed too much, it shouldn’t be that hard to update my program. I’m also aware of my limitations, I am not actually a programmer, so anyone with experience and skill should be able to do a better job - that’s also ok :blush:

User Guide:

  1. Open original file (to translate from)
  2. Start to translate directly, or open your previouslys translated file
  3. Save to a new file (you can only “Save As”, this is on purpose)

It can also be used to compare two different versions of the same language file thanks to the color coding.

Color explanations:

  • White = Value is not the same, you have probably translated this row already
  • Yellow = Value is the same. Is that really ok? It could be.
  • Orange = A translated value is missing, most probably not ok!

Planned features and such:

  • Another (optional) input file for the previous original file (same “version” as the previous translation file) to mark differences/changes in the input file.
  • Give tips!

Issue List:

  • Seems to be a problem with “full width symbols”… Don’t use them please.
  • With the 0.7.0 version some characters are saved as escaped.

Here is an updated guide of how to use the program and implement the translation mod:

If you’re interested in the code (to copy it or to review/help/improve), you can find it here:


well, my hat’s off to you sir… very well done, and again, this should be immensely helpful to other budding translators in the community… thanks! :+1:

edit: thanks for referencing it in the translation thread too… :wink:

1 Like

Hey people, just wanted to put out a new version of this tool, feels quite stable, but have done only limited testing due to limited time… :wink:

Patch notes to this new version, I called it “alpha 0.2” just to keep track of it (the log window will have version info from now on):

Feature changes:
-Tag names can now be edited ( and added), switch on/off by a checkbox. Will not affect original files!
-Add row gives a choice: at selected position or at bottom.
-Improved behavior when changing number of rows and resaving to the same file, I think… Changed the mechanics of this so at least a previous strange behavior/bug is gone now.

-Fixed “several empty rows at top”, all are deleted now.
-Fixed a bug when re-opening translation file to a shorter version.
-Fixed some bugs and unclear messages in log window.

Updated download link is in the first post.
edit: Removed the download link to avoid confusion later on.


Important news for those who uses this program! Well, I guess it’s only me, but let this be a dev blog in that case :blush:

I have found a critical error (the first so far!) when reading a file. Due to a stupid mistake from me when I divide the rows in input file on the colon… any row containing a colon in the text will not be shown!

For example:

"hotkey" : "hot key: ",

Will not be listed at all…

This is how it looks in the program and in Notepad:

I will have to rewrite this part of the software for this to be fixed. Perhaps I divide on " instead, hopefully no values or tags will contain additional "…

It might be done today, or in a month.

1 Like

Post edited, see further down for info. Problem described should be fixed already.

Ok, the critical bug was easy to fix by dividing on " instead of : and ".

This will of course only work as long as there are no " inside of the value part, like this:

"soldier_conversation_1" : "Oh, that's a nice "hat", haha",

As long as there are no such things, this will be the solution. Perhaps Team Radiant can use an apostrophe with a special sign… In that case, this will break again. (edit: It won’t break after even later update.) For example:

"soldier_conversation_1" : "Oh, that's a nice \"hat\", haha",

Until further notice, this is how it works, and I will continue to think about this… If you have a suggestion on how to split strings in a good way, feel free to post it.

So alpha 0.3 will be released soon when I have tested it a little more. Features already in:
-Critical bug for text with colons is fixed
-Save warning when exiting
-Automatic search for duplicated tags, error in log and pop-up notification
-Changed log messages to be slightly more logical.
-New (and improved) name :wink:

I tried to re-write the line reading-splitting-stuff, and I think I got it working. So the latest dev build supports both colon and aposthropes inside the data field. Just want to verify it by a little more testing before releasing anything. But everything on the issue list is fixed!

1 Like

Ok, I have tested it a little and here is the alpha 0.3 release! :smiley: Download link is updated in the first post as well.
-link removed due to later release-

The zip file contains the program, the English r118 file as well as a semi-translated Swedish file. This is a quite big update, so I expect there to be bugs… both new and old.

Patch notes:
-All (I hope) characters are now allowed in the text field, including colon and apostrophes.
-If you have done work but not saved, you will get a warning when exiting.
-When opening original file, a search for duplicates will be performed. Notification in pop-up and more details in log. For future versions, this will probably be the way to present errors.
-More useful information in log window, but still more than will be there later
-Fixed a bug where the last row also printed out the comma sign
-Minor change, no rows after last tag will be printed (as empty rows)
-Upgraded the name of the program :blush:

If you feel like doing some bug testing, feel free to! Just tell me if you have any issues, from downloading and running file to finding crazy bugs due to impossible task combinations.

Hello again, for the latest (r127) update I decided to make a video of the translation process using this program. See video below (I’ll put it in the top post as well) for a detailed walkthrough of the following steps:

  1. Extracting a new original file to work from.
  2. Comparing old and new original files (English in this case).
  3. Continue on an old translation to…
  4. …prepare a new (translated) file.
  5. Import into the game and use the new one (Swedish in this case). This is not how it will work later on, but it kind of works for now.

In the video I am using the 0.3 relese, and it actually works just fine it seems :blush:

Good things came out of it. For example, I noticed a tag text change for “town_happiness_tab”: happiness was now called journal. It is always hard to know if things are supposed to be like that, but I hope that @sdee and the guys know what they’re doing :wink:

Oh, btw, there are no tag duplicates in r127, but as said before, the program would tell me if that was the case. So that’s good!

Also in the video: I imported the file into stonehearth.smod to get my translations ingame as well. We still have that problem with special symbols (in the Swedish alphabet: å ä ö). They get some strange formatting, but the team already knows about this from before, I guess that’s low priority. However, it is only the “main font”, in the settings menu there are special symbols that shows just fine.

Anyway, here’s the video, enjoy! :smile:

@SteveAdamo or @Geoffers747, why can’t I edit the first post to put the video up there…? :frowning: I had no problems with those things before, I could update that post after the 0.3 release… but not now…


i’m not entirely sure, to be honest… in the meantime, i’ve edited the OP, and dropped the new video at the bottom… hope this is OK…

That’s ok for now, thanks man :thumbsup:

However, it will be annoying for you to be my secretary and update the post after every future update, so if we can find the cause of this problem it would be good for us all :wink:

( Not that I don’t believe in you as a secretary… but… you know… )

1 Like

hello your tools is very goog.

some suggestion for the large number of Json file to translate

  1. Can you add on the left side, list all the files (json) in the master stoneheard folder.

1.1) when you click on the file it automatically loads the two files en and other from the two folders

1.2) should also provide some hide files so that it does not appear, because there is nothing in it to translate

there would be a big win for the translation!

  1. a quick indicator would also be a big More

identical file
x changes
missing file

  1. a check box at the top of the interface
    hide identical lines
    hide empty lines
    next button, Next line not identical

Feedback is nice, first time I get input to the program since its release more than one year ago :smile:

I don’t know how to handle the compressed files to be honest. And I don’t know if it would be the proper way of doing it once the game is truly ready to be translated. I agree, it would be a good way of doing it since it would help us to keep track of all files we should translate. For now, I’ll keep it manual, but I will absolutely think about it for future versions.

There are some info being put into the log when reading, saving and changing. But perhaps could expand that part. I got an idea or two that I will start look into :blush:

Good suggestion! At the moment I don’t know how to hide empty lines, but do we want to? I find them a good indicator for different groups, plus, I use them when saving the file :wink: However, “jump to next” is a great suggestion, of course I’ll have to do that!

The program has some limitations. Today, it can only handle json files with the depth of 1. And most of the things are manually done - no json library or something like that. This means I have no functions to handle more depth, and the program has issues with multiple tags with same name because of my simple search function when building the dataset. These two limitations makes this kind of structure not usable as of today (it wouldn’t look like this, but you get the idea):

{ "salesman_items" : {
    "item_name" : "buildingblocks_claybrick", {
      "display_name" : "Clay Brick",
      "description" : "Almost like stone, but it's not",
      "value" : "5"
    "item_name" : "buildingblocks_stonebrick", {
      "display_name" : "Stone Brick",
      "description" : "Harder than Clay Bricks, but heavier to carry",
      "value" : "10"

In the example above, the “display_name” and “description” should be translated. And what I mean is that there might be useful to have tag names used over and over, but the program can’t handle it today - and can’t export to that format either. It would probably take me a lot of time to fix that, and without a clear indication of that it is how things will be structured… I probably won’t do it. I’ll have to look into the other json files and then ask the team how they plan to use the format later on.

Just wanted to say that the next/prev buttons are added now. Didn’t take long at all, and they are working as one could expect. Need some layout improvements (just squeezed them to fit in the little empty area I had left). Don’t know if I’ll release it as an 0.3.1 update or if I’ll save it for 0.4 where more functionality is added. I’ll think about it!

Gotta love version handling! :wink:

Another update, was able to find a little time to add a function so that a number is given and constantly updated when working with a file. Basically it is “number of orange lines left to handle”. So when the english file is loaded it will automatically say the number of tags (should be the same as in the log, but they are counted in different ways) in the file. But after loading the translation file that number will be the remaining of orange lines.

I’m not counting the amount of yellow (same) texts, because they are not critical and might be correct in being the same. But the function from last post (Next/Prev item) will step through both yellow and orange so they are easy to find anyway.

To make this work I had to totally re-write the color matching code. And even though I think it’s correct as it is I don’t want to release this yet. So you’ll have to wait for alpha 0.4 to try it out. I mean, it seems unprofessional to release something with bugs :wink: :wink:

But seriously, it was good anyway, because I wasn’t proud of that color matching code… it was inefficient and would have given any coder nightmares due to the nested if-statements…

When I noticed that all “citizen(s)” were exchanged to “Hearthling(s)” I felt I needed a search function to easily find things. And now there is one :blush: Not fully tested, but it is possible to search for tags, in original text or in translation text. Manual switch between them. As of now, you either search up or down from current location. Only did it on my lunch break so this might be changed.

Latest screenshot below, testing search function (not case sensitive). You can also see “jump to next/prev item” to the right and number of remaining “orange” items to take care of.

1 Like

So I found a bug, not critical, but I think I fixed in an ugly way… Or was it a feature that shouldn’t be touched?

Steps to reproduce (that means, don’t work like this :wink:):

  • Open original file (perhaps 100 lines)
  • Open translation file (perhaps 100 lines)
  • Open older translation file (perhaps 80 lines)

In v0.3, the 20 extra translations will still be listed. Bug or feature?

I think the 20 translations should be cleared. Because I want the view to represent what is in the file, and those 20 was not in that file.

So in v0.4 (already implemented in dev build), I will make sure that the content in translation is null (or “” ?) before writing the value from the file. This will guarantee that what you see is what the file contains.

A little more testing to do, but soon I will release 0.4. I know you’re screaming for it! :stuck_out_tongue:

Just wanted to say that your program is helping me out greatly with translating. Just from curiosity what did you code this in,

1 Like

Glad to hear that! :blush: Remember to report bugs or give suggestions to improvements, it’s easy to go blind when doing something yourself.

The entire thing is coded in C# as a Form (using Visual Studio Express). As said in the first post, I’m not a programmer, so I guess most people with a little coding education (from school) could do this :wink:

Testing v0.4 now and have no plans for more features for this release, will release it any day!

So here’s the release of my alpha 0.4, download link updated in the first post! It has both English and Swedish file as example for alpha 8 0.1.0 r201 or something like that :wink:


  • Added feature to show how many orange (critical) lines are left
  • Added feature to step next/prev item to check (yellow + orange)
  • Added feature to search for text. Might be improved later.
  • Fixed a behavior when opening a “lesser” translation file after a bigger one, now it will clear translation column first.

Feel free to use or try it out and give feedback of bugs and things that are missing! :blush:

New, small release (0.4.1). Download link updated in first post. As usual, with example files for eng-swe for the latest release to date.


  • Bugfix: The last minute fixed “behavior” in previous release introduced a bug when stepping prev/next items (explanation below)
  • Modified the search function to continue from top or botton once reached (question)

Thinking of doing the same “continue from top/bottom”-feature for next/prev item stepping as well. Could come in a small 0.4.2 release.

The bug with the stepping thing. If opening a lesser file after a bigger one, the program didn’t clear out tags that should be empty. So I did a “set all translations to null” before filling with translation data. But that broke the step-next function, because it was only looking for “” (and not null). Seems like an empty cell contains “” by default, but I don’t know for sure.