anonymousException / renpy-translator

A translator for renpy based on google | youdao | deepl | open-ai | offline-ai tranlation supports extract untranslated words and translate
MIT License
101 stars 12 forks source link
ai-translator deepl openapi renpy renpy-game renpy-language renpy-visual-novels translation youdao-fanyi-api

Renpy Translator

A free and open-source translator for ren'py


Another Docs

Offline AI Version

If you want to use offline ai translation, you can refer to :

https://github.com/anonymousException/renpy-translator/blob/feature/ai-translate/README.md

Chinese

中文版 README 在 这里

Supported Translation Services

Translator Supported Language number Charge Service Country Reference
Google 108 Free | Token Required Google America pygtrans
Youdao 11 | 114 Free | Token Required Netease China
Deepl 29 Token Required Deepl Germany
OpenAI 108 Token Required OpenAI America openai-python
Alibaba 214 Free damo China translators
ModernMt 200 Free Modernmt / Translated Italy translators
Bing 133 Free Modernmt / Translated Italy translators
CloudTranslation 8 Free Xiamen University / CloudTranslation China translators
Caiyun 3 Token Required ColorfulClouds China

Usage

One Key Translate

Support one key translate , just select the target language and the font file and the game will be translated automatically

It's equal to the following complete tutorial

https://github.com/anonymousException/renpy-translator/assets/157234942/1230607c-7313-4ba3-bf3e-ace19efa3c32

Complete Tutorial

https://github.com/anonymousException/renpy-translator/assets/157234942/6b71c914-8f64-45c4-a1f8-809299b3c8e6

The video shows in order :

  1. show the original game
  2. unpack game package
  3. runtime extraction (extract dialogues only)
  4. official extraction (equals to the extract function in official renpy-sdk)
  5. extraction
  6. replace font
  7. add an entrance to change langauge in preference
  8. translate
  9. show the translated game

Pack Game(Generate Translation Mod)

Support pack game package based on rpatool , you can make a translation mod now

https://github.com/anonymousException/renpy-translator/assets/157234942/4816245b-3690-47ba-9501-4b50cf03eedb

Translate with brower

https://github.com/user-attachments/assets/3023cb0a-138e-4951-935c-d9f58d1027d7

https://github.com/anonymousException/renpy-translator/assets/157234942/e0e56ee3-4064-4655-8046-f49309fdfaad

https://github.com/anonymousException/renpy-translator/assets/157234942/06008b44-8e46-4df9-8aa9-c978733dbd7d

https://github.com/anonymousException/renpy-translator/assets/157234942/a26f7186-fcc2-461e-9ae4-416d7b8ae293

https://github.com/anonymousException/renpy-translator/assets/157234942/676bea79-3083-469b-805a-520f44907bbd

https://github.com/anonymousException/renpy-translator/assets/157234942/dd579d7d-6f76-423f-8d64-2da002e37d34

Convert To Html

https://github.com/anonymousException/renpy-translator/assets/157234942/30d5bedb-60c2-4369-aea4-de5bc18b0549

Format Rpy Files

Support format rpy files which do not cotain the original contents

You can translate the contents after format

https://github.com/user-attachments/assets/00ebd44a-6623-4d65-8562-6e8ec90cca3d

Add Entrance

https://github.com/anonymousException/renpy-translator/assets/157234942/67a04032-c8d7-46bf-bfa1-bd9307764d08

Runtime Extract

https://github.com/anonymousException/renpy-translator/assets/157234942/64e82f3f-7d85-4e33-8226-a06a7ba60270

Official Extract

https://github.com/anonymousException/renpy-translator/assets/157234942/bdc122d8-4334-461f-8ce0-70206a5b7a8b

Unpack Game

https://github.com/anonymousException/renpy-translator/assets/157234942/a3fac173-8555-42de-ae36-e375684728b0

Editor Mode

https://github.com/anonymousException/renpy-translator/assets/157234942/eb140430-2b58-4a46-b913-b2df07d1bb6d

Local Glossary

For advanced edit , it is recommended to use professional software such as EXCEL

This tool only supports loading and simple modifications

https://github.com/anonymousException/renpy-translator/assets/157234942/c9b8bc7d-a5e0-4df6-a4d6-6005644daa74

Imported Glossary format

You should offer 2 columns :

Original : the words before replaced

Current(Replaced) : the words replaced

The first row should be the header (just for show you can rename them)

img

Translate Files

https://github.com/anonymousException/renpy-translator/assets/157234942/495be06c-9751-4966-b22c-84602fb3dc0a

Translate Directory

https://github.com/anonymousException/renpy-translator/assets/157234942/0034bbaa-d1fc-4981-b228-9bde62423367

Replace fonts

https://github.com/anonymousException/renpy-translator/assets/157234942/46e524d7-14ef-472e-8426-ac47d923bef0

Extract File(s)

https://github.com/anonymousException/renpy-translator/assets/157234942/7d1efbfd-7152-407f-9896-c63a98538f02

Extract Directory(s)

https://github.com/anonymousException/renpy-translator/assets/157234942/518e34a9-12f6-4e69-9ac4-80a6b181081c

Extract all extractable contents to tl directory and rename(if tl name is empty will just extracted to the tl directory):

https://github.com/anonymousException/renpy-translator/assets/157234942/09edf9fa-0f5c-410a-acd9-6fd219b55893

Target

As you see the above translated contents. The original contents will be remained after translation.

If the contents are short of the original contents(behind the "#" as comment) , translation will not take effect on them

The reason why I made this tool is not to replace the real translator's work , but to help.

The translated contents will be not accurate enough due to auto google | youdao | deepl translation.

So the original contents will do the effect. You can re-translate the translated contents according to the original contents. And what you modified will not be replaced during next translation.

This tool also take care of the special symbols like "{}" "[]" and "<>" in untranslated contents , for detail you can see it on the Features point 2

Download

You can download the latest version through https://github.com/anonymousException/renpy-translator/releases/latest

Features


Tutorial

https://github.com/anonymousException/renpy-translator/assets/157234942/381ad014-442f-458d-a304-4547a4d6a38a

Prerequisite

A good network environment , if not you may not able to translate words through the translation engine

If you can not access the translate engine, you can try use vpn tool like v2ray and set local-proxy

before:

proxy_fail

usage:

proxy_setting


An unpacked ren‘py game (for what you can find .rpa files under the game directory) like this:

img

You can try to translate the tutorial game following the tutorial

if not you can try to unpack it

I usually use UnRen-ultrahack.bat from https://f95zone.to/ to unpack the game

https://github.com/anonymousException/renpy-translator/assets/157234942/718b2b71-ca98-4dfd-999b-ffdc9c112102

It's strongly not recommended for translators to make translation through unpack and then deliver a translated version without the original author's permission. Please respect the original author

Download the [UnRen-ultrahack.bat]() and copy it to the game directory (where game.exe locates)

Now unpack function is supported : Support unpack game through runtime hook which can bypass most encryption

The dumped file format is rpyc , so will auto call UnRen-forall(v9.4) to tranform into rpy

https://github.com/anonymousException/renpy-translator/assets/157234942/a3fac173-8555-42de-ae36-e375684728b0


FirstTranslation

If the game is completely blend-new for you to translate , you can continue to the following contents

If the game has already been translated , you want to update the translation (translate the contents still not been translated) , you can jump to the next caption : UpdateTranslation

the first thing for the First-Translation is to extract the untranslated words from game

there are two methods to do that:

It's recommended to use Offical Extract first and then translate the game. If you found that there still remains plenty of words not been translated after translation (Sometimes ren'py engine's official extract may miss many words). You can use the tool extract function and retranslate the game.

Official Extract(Recommend)

Offcial Extract is supported in this tool now

https://github.com/anonymousException/renpy-translator/assets/157234942/bdc122d8-4334-461f-8ce0-70206a5b7a8b

https://github.com/anonymousException/renpy-translator/assets/157234942/b032480f-fc2f-4438-9730-611b3e219556

you can forward to https://www.renpy.org/ and then download the latest version

Unzip the ren'py engine you download

img

Click "preferences" in the lower right corner

img

Reset the "Projects Directory" to the parent directory of the game you want to translate

img

Return back to the last interface and Click "Generate Translations"

img

Fill the "Language" , this is just a tag (It's related to the "tl name" label in this tool) used for the translation that you can name whatever you want. But it's recommended to name the target language you want to translate. Such as "japanese" or "chinese" etc.

It would be alright to keep other options default ,Especially for "Generate Translations" option , do not tick the "Generate empty strings for translations"

img

After all options have been set . Click the "Generate Translations" and wait to complete

img

And then you can close the software , the official extract is done

You can see the generated folder , remember the path

img

The folder path in this tutorial is :

F:\Games\RenPy\DemoGame\game\tl\japanese

Runtime Extract(Recommend)

https://github.com/anonymousException/renpy-translator/assets/157234942/64e82f3f-7d85-4e33-8226-a06a7ba60270

Runtime Extract can extract only dialogues without unpacking the game and the format is block like official

Tool Extract(Optional)

Fill (input,drag or brower) the directory that generated by Official Extract before and just tap the extract buttion , and then extraction will be done

img

Quite easy, right ? That's why I made this tool.

Add Entrance

https://github.com/anonymousException/renpy-translator/assets/157234942/67a04032-c8d7-46bf-bfa1-bd9307764d08

It's supportable to add entrance through this tool automatically

https://github.com/anonymousException/renpy-translator/assets/157234942/a0316ab5-f912-4e25-8423-19b82b7fbfbe

You need to add an entrance to change the language in game

Open the game directory and then enter subfolder "game", open the "screens.rpy" file (you can use notepad to open it)

img

Search the key words:"gamemenu(("Preferences")" (usually the words do effect if not you may need to explore what the game use to replace "Preferences")

Normally you will found many "vbox:" like this:

img

Try to find a vbox that contains "Language" or some other words can replace "Language"

If not found , add the following code to the file(the location next to the vbox contains "skip"):

vbox:
    style_prefix "radio"
    label _("Language")
    textbutton "English" action Language(None) 
    textbutton "LanguageName" action Language("The Tag you fill in official Extract") 
    #such as textbutton "turn to Japanese" action Language("japanese")

Pay attention to the indentation to keep it aligned. After edit it should be like this

img


If found , just add a new line to the vbox:

textbutton "LanguageName" action Language("The Tag you fill in official Extract") 
#such as textbutton "turn to Japanese" action Language("japanese")

After the file saved,open the game and make sure the preference show the content you just edit

img


Replace font

https://github.com/anonymousException/renpy-translator/assets/157234942/46e524d7-14ef-472e-8426-ac47d923bef0

Before translation you need to get the font file (.ttf or .otf) you want to translate

The default font path is filled with your default system font which is compatible with the language you used now

For example , if you are a japanese user and your system font is japanese , the default font file can support japanese , you need not to download a japanese font from the internet to solve the garbled code problem

https://github.com/anonymousException/renpy-translator/assets/157234942/2d1a841a-723e-4408-a4c3-e30ea114e764

For japanese, I usually use the hanazomefont

For chinese, I usally use the SourceHanSansCN

For other language , you can find relative font files using search engine easily

Translation

Open the ren'py translator and fill the following blanks

directory : the path generated during Official Extract before

font: the font file you downloaded

target : the target language you want to translate (input the letter in front of the target language to search is supportable , need not to scroll to search)

source: default Auto Detect is OK

img

Wait until the translation done:

img

So far , the translation is done , you can open game and check it :

img

 UpdateTranslation

Update-Translation is quite easy, directly use the Official Extract (optional) and Tool Extarct

After extraction , just input the directory generated during Official Extract and choose the target

As for font , if the updated game appended new special style with different font settings , you can use replace font function without font path to cover the appended special styles (font has been replaced before)

img

Development

If you are willing to develop based on this project. You will need to have a python3 environment.

And install the following packages :requirements.txt

FAQ

All the translation skip

skip

Make sure when you in Official Extract step , for "Generate Translations" option , do not tick the "Generate empty strings for translations"

The translation will only do effect when the format like this:

# game/script.rpy:553
translate schinese naming_0f7b6e71:
    # r "Do name yourself like that and I'll break your face..."
    r "Do name yourself like that and I'll break your face..."

or

    # game/script.rpy:30886
    old "Win or Lose?"
    new "Win or Lose?"

Notice that the original text (behind # or old) should be the same with untranslated text (behind no # or new)


Some errors made it impossible to translate certain lines

you may meet errors like this:

2024-01-30 14:55:19 D:\Download\Nova-Pasta\SunshineLoveCH2-1.01-pc\game\tl\Portugues/10_week10_00.rpy Error in line:1320
It’s [s_name]. And [y_name].
It’s [0] . And [1] .
É [0] . E 1] .
Error

It's depend on the translation result. In order to skip translate special symbols like '[]' '{}' '<>' , this tool will replace the contents in special symbols in order nums.

For example :

"It’s [s_name]. And [y_name]."

will be replaced to

"It’s [0] . And [1] ."

Normally, this format will not be translated and will remain '[0]' and '[1]' , and the tool will restore the orginal contents with the ordered nums.

However , sometimes this format may be destroyed after translation. As mentioned : "É [0] . E 1] ."

You can found that one '[' is missing , so this tool can't restore the original contents. And will not translate this line.

You may need to modify these certain lines manually.

Fortunately this situation occurs rarely , you need not to spend too much time to modify these certain lines.

Currently Google is the best choice to translate the contents which contain special symbols , you can re-translate these contents with Google

Anti-virus software report viruses

This program is packed by pyinstaller and with file operation (open read write) , so may cause false detection

If you are worried about this , you can download the source code and run the program yourself

Pyinstaller Build Version is easy to be detected as virus , it's false positive

If you are still worried about this , you can try the Nuitka verison (Nuitka.Build or RenpyTranslatorInstaller)

Release Package Explanation Advantage Disadvantage
RenpyTranslator-Win.Pyinstaller.Build.zip build by Pyinstaller the executable file is single and light may cause false positive as virus
RenpyTranslator-Win.Nuitka.Build.zip build by Nuitka will not cause a false positive for most antiviruses the executable file contain many extra support libraries
RenpyTranslatorInstaller.exe installer for Nuitka version make things easier need to install

Some errors occur after running the translated game

you may meet errors after running the translated game like this :

error_after_translation

error_after_translation_source

You can found that after translation "[[XXXX]" was translated into "[ [XXXX]" , an extra space was added (you may meet other error format but the important point is that after translation the structure of the special symbols destroyed)

The result is translated by translate engine , sometimes translation engine is not friendly to special symbols like '[]' '<>' ... especially when the special symbols used repeatedly

But there still remains good news , normally the case will not happen frequently , you only need to modify the error sentences manually (For the case mentioned above , just remove the extra space)

Some sentences seem not to be translated after translation

tooltip

For special text in tooltip is actually translated but seems not work

the original code looks like this :

tooltip "this is a tooltip"

Following the tutorial from https://f95zone.to/threads/translation-of-text-in-screen.90781/

Just open the rpy file (any one under tl folder else if you can create a new one) and add the following code :

# if you choose to create a new one,you need to add the next line remove header # and relace tl_name with the directory name under tl folder like japanese
#translate tl_name strings:
    old "[tooltip]"
    new "[tooltip!t]"

notify

For special text in notify is actually translated but seems not work

You need to locate the sentence on the orginal code (not the translation tl folder)

You will found the original code looks like this :

show screen notify(_("Find old Man Gibson"), None)

replace it with

show screen notify(__("Find old Man Gibson"), None)

the operation is just to add '_' after notify(

quite easy right? And then the translation will do the effect

other

It probably remains other case that some sentences seem not to be translated after translation

It depends on the original code , extraction may not completely covered if the original code is not quite translation-friendly

To avoid extra useless extraction , the extraction function in this tool will not extract sentences match the following style :

the length of sentences (space and special synbol will be counted as zero length) lower than 8

for example :

"I know [special symbol]"

the actual effect content is

Iknow

the length is only 5 , so it will not be extracted by the extraction from the tool


Besides the contents in ConditionSwitch() will also not be translated due to switch code may contained in it

0 KB file is generated after extraction

It's normal because the target file has nothing to extract

Do not delete the 0 kb file , it is used to occupy position

Errors may occur if the file does not exist

Weird content generated after extraction

you can view content like this after extraction

old "old:1709016761.706834_0.8853030081254853"
new "new:1709016761.706834_0.8853030081254853"

it's an unique timestamp to mark the time you extract , the format is timestamp_random (random value is to make sure the generated content is unique otherwise will cause error)

you can convert the part before '_' (in this example is 1709016761.706834) to readable time through https://www.epochconverter.com/ or other timestamp convert website

OpenAI

You can view your rate-limits on : rate-limits and set a reasonable limit

There are great restrictions for a new user of openai , can only post max 3 requests in per minute. almost unusable to translate

The default setting is for this situation , If you don't pay much attention to the time cost , you can try it with the default config

For higher-level user , it's recommended to turn up the setting. A suggested config is :

parameter recommend
RPM(requests per minute) 250
RPS(requests per second) 10
TPM(requests token limits) rate-limits
model gpt-3.5-turbo | gpt-4 (smarter but slower and more expensive)

Some errors made it impossible to translate certain lines

OpenAI seems not to be friendly to special symbols like '{}' '[]' , you may meet errors mentioned before : Some errors made it impossible to translate certain lines

You can re-translate the error lines with google engine (translated lines will be auto skipped , just re-translate the full directory or file(s) translated before)

(Google translation is more friendly to the special symbols but may still remain few errors)

At last you need to modify the remained few error lines manually

JSONDecodeError

Besides if you meet traceback errors in openai , try to disable the option Multi-Translate and re-translate (it's more stable but slower).

And you may meet errors like this:

2024-02-22 11:18:28 Traceback (most recent call last):
  File "openai_translate.py", line 180, in translate_limit
  File "json\__init__.py", line 346, in loads
  File "json\decoder.py", line 337, in decode
  File "json\decoder.py", line 353, in raw_decode
json.decoder.JSONDecodeError: Unterminated string starting at: line 1 column 1613 (char 1612)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "openai_translate.py", line 187, in translate_limit
Exception: Unterminated string starting at: line 1 column 1613 (char 1612)

It's due to the error format data returned by openai , fortunately this will not happened frequently and will only cause partially untranslated in one file. You can re-translate the untranslated lines with other translation engine such as google translation

Unmatch translated result

You may meet errors like this:

2024-02-23 10:19:34 translated result can not match the untranslated contents

The reason is that openai may merge multi-translation result occasionally , such as:

#untranslated
["Hello","Good"]
#translated
["こんにちは,良い"]

This can lead to mismatching of translations , so the partial translation will not do effect , you may need to translate the untranslated lines with other translation engine

ConnectError

You may meet errors like this:

2024-02-23 10:19:34 Another non-200-range status code was received:400 <Response [400 Bad Request]>
2024-02-23 10:19:34 Error code: 400 - {'error': {'message': 'Connection error (request id: 20240223101928248984704uoEfBgvh)', 'type': '', 'param': '', 'code': 'connection_error'}}
2024-02-23 10:19:34 ['untranslated1','untranslated2','....']

It's depend on your network environment , re-translate may do effect

Custom Engine

You can write a python script which supports translation api , and import it to this tool

you should write like _caiyun.py and _baidu.py (the api name must be tranlate_single or tranlate_queue)

besides you should offer two language files for source and target like caiyun.source.rst and caiyun.target.rst

A good example setting looks like this:

custom_engine