CREATE YOUR AI CUM SLUT ON CANDY.AI TRY FOR FREE
x

Tool RPGM SLR Translator - Offline JP to EN Translation for RPG Maker VX, VX Ace, MV, and MZ

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
I've released v1.116.
Improvements to automatic word wrapping.
Over 15000 new characters of code and you probably will not notice any difference. :HideThePain:
 
  • Sad
Reactions: 92cbf4dd

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
I've released v1.117.
Behold! I present to you, the dumbest solution to a problem nobody even reported, yet!
JavaScript:
                //Check if not wrapped stuff has less lines than the original cells and try to fix it
                if (row[3] == undefined || row[3] == "" || row[3] == null) {
                    let row0noemptylines = trans.project.files[file].data[k][0].replaceAll(/[\n][\n]+/gmi, "");
                    row0noemptylines = row0noemptylines.replaceAll(/[\n]$/gmi, "");
                    let row0count = row0noemptylines.split(/\r\n|\r|\n/).length;
                    let row0lines = row0noemptylines.split(/\r\n|\r|\n/);
                    //For stuff in row 2 if there is stuff in row 2
                    if (row[2] != undefined && row[2] != "" && row[2] != null) {
                        let row2count = trans.project.files[file].data[k][2].split(/\r\n|\r|\n/).length;
                        if (row0count > row2count) {
                            let wrapattempt = trans.project.files[file].data[k][2];
                            //command stuff at the start of lines
                            if (row0noemptylines.match(/^[  ]*\\/gmi) != null && row0noemptylines.match(/^[  ]*\\.*[一-龠ぁ-ゔァ-ヴー々〆〤ヶレディファイッ]+.*\\/gmi) == null && row0noemptylines.match(/^[  ]*[^  \\]/gmi) == null) {
                                wrapattempt = wrapattempt.replaceAll(/[\r\n]+/gm, " ");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/g, "");
                                if (trans.project.files[file].data[k][0].match(/^[  ]*\\[\w_]\[[\w_]+\]/gmi) != null) {
                                    let wraplinecounter = 0;
                                    let wraplinecounter2 = 0;
                                    let thingcounter = 1;
                                    let wrapprogress = "";
                                    let regexvar = '^()(.*?)\\\\';
                                    while (wraplinecounter2 < row0count) {
                                        wraplinecounter2 = wraplinecounter2 + 1;
                                        let row0thingcount = row0lines[wraplinecounter].split(/\\[\w_]\[[\w_]+\]/).length;
                                        wraplinecounter = wraplinecounter + 1;
                                        while (thingcounter < row0thingcount) {
                                            thingcounter = thingcounter + 1;
                                            regexvar = regexvar.replaceAll(/(\)\(\.\*\?\))\\\\/gi, "[  ]*\\\\+[\\w_]+\\[[\\w_]+\\][^\\w\\n\\r]*$1\\\\");
                                        }
                                        thingcounter = 1;
                                        wrapattempt = wrapattempt.replaceAll(new RegExp(regexvar, "gi"), "$1$2\n\\");
                                        regexvar = '^()(.*?)\\\\';
                                        let wrapattemptsplit = wrapattempt.split(/\r\n|\r|\n/);
                                        if (wrapattempt.match(/\n/gim) != null) {
                                            wrapprogress = wrapprogress + "\n" + wrapattemptsplit[0];
                                            wrapattempt = wrapattemptsplit[1];
                                        }
                                        else {
                                            wrapprogress = wrapprogress + "\n" + wrapattempt;
                                        }
                                        }
                                    wrapprogress = wrapprogress.replaceAll(/^\s+/g, "");
                                    wrapattempt = wrapprogress;
                                }
                                else if (trans.project.files[file].data[k][0].match(/^[  ]*\\[a-z]+[  ]*[一-龠ぁ-ゔァ-ヴー々〆〤ヶレディファイッ]/gmi) != null) {
                                    wrapattempt = wrapattempt.replaceAll(/(\\[a-z])/gi, "\n$1");
                                }
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/gm, "");
                                wrapattempt = wrapattempt.replaceAll(/^\n/g, "");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/gm, "");
                            }
                            //Single variables at the end of lines
                            else if (row0noemptylines.match(/\\v\[\d+\][  回mlkgkgGGml$%$%#€]*$/gmi) != null && row0noemptylines.match(/\\v\[\d+\].*\\v\[\d+\]/gmi) == null && row0noemptylines.match(/[^v\\\[\]  回mlkgkgGGml$%$%#€]+$/gmi) == null) {
                                wrapattempt = wrapattempt.replaceAll(/[\r\n]+/gm, " ");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/g, "");
                                wrapattempt = wrapattempt.replaceAll(/((?:\\v\[\d+\][  ]*ct)|(?:\\v\[\d+\][  ]*ml)|(?:\\v\[\d+\][  ]*$)|(?:\\v\[\d+\][  ]*kg)|(?:\\v\[\d+\][  ]*g)|(?:\\v\[\d+\][  ]*G)|(?:\\v\[\d+\][  ]*$)|(?:\\v\[\d+\][  ]*€)|(?:\\v\[\d+\][  ]*%)|(?:\\v\[\d+\][  ]*回)|(?:\\v\[\d+\][  ]*%)|(?:\\v\[\d+\][  ]*G)|(?:\\v\[\d+\][  ]*ml)|(?:\\v\[\d+\][  ]*g)|(?:\\v\[\d+\][  ]*kg)|(?:\\v\[\d+\][  ]*(?=[^  回mlkgkgGGml$%$%#€])))/gm, "\n$1");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/gm, "");
                                wrapattempt = wrapattempt.replaceAll(/^\n/g, "");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/gm, "");
                            }
                            if (row0count == wrapattempt.split(/\r\n|\r|\n/).length) {
                                trans.project.files[file].data[k][3] = wrapattempt;
                            }
                        }
                    }
                    //For stuff in row 1 if there is stuff in row 1 and nothing in row 2
                    else if (row[1] != undefined && row[1] != "" && row[1] != null) {
                        let row1count = trans.project.files[file].data[k][1].split(/\r\n|\r|\n/).length;
                        if (row0count > row1count) {
                            let wrapattempt = trans.project.files[file].data[k][1];
                            //command stuff at the start of lines
                            if (row0noemptylines.match(/^[  ]*\\/gmi) != null && row0noemptylines.match(/^[  ]*\\.*[一-龠ぁ-ゔァ-ヴー々〆〤ヶレディファイッ]+.*\\/gmi) == null && row0noemptylines.match(/^[  ]*[^  \\]/gmi) == null) {
                                wrapattempt = wrapattempt.replaceAll(/[\r\n]+/gm, " ");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/g, "");
                                if (trans.project.files[file].data[k][0].match(/^[  ]*\\[\w_]\[[\w_]+\]/gmi) != null) {
                                    let wraplinecounter = 0;
                                    let wraplinecounter2 = 0;
                                    let thingcounter = 1;
                                    let wrapprogress = "";
                                    let regexvar = '^()(.*?)\\\\';
                                    while (wraplinecounter2 < row0count) {
                                        wraplinecounter2 = wraplinecounter2 + 1;
                                        let row0thingcount = row0lines[wraplinecounter].split(/\\[\w_]\[[\w_]+\]/).length;
                                        wraplinecounter = wraplinecounter + 1;
                                        while (thingcounter < row0thingcount) {
                                            thingcounter = thingcounter + 1;
                                            regexvar = regexvar.replaceAll(/(\)\(\.\*\?\))\\\\/gi, "[  ]*\\\\+[\\w_]+\\[[\\w_]+\\][^\\w\\n\\r]*$1\\\\");
                                        }
                                        thingcounter = 1;
                                        wrapattempt = wrapattempt.replaceAll(new RegExp(regexvar, "gi"), "$1$2\n\\");
                                        regexvar = '^()(.*?)\\\\';
                                        let wrapattemptsplit = wrapattempt.split(/\r\n|\r|\n/);
                                        if (wrapattempt.match(/\n/gim) != null) {
                                            wrapprogress = wrapprogress + "\n" + wrapattemptsplit[0];
                                            wrapattempt = wrapattemptsplit[1];
                                        }
                                        else {
                                            wrapprogress = wrapprogress + "\n" + wrapattempt;
                                        }
                                        }
                                    wrapprogress = wrapprogress.replaceAll(/^\s+/g, "");
                                    wrapattempt = wrapprogress;
                                }
                                else if (trans.project.files[file].data[k][0].match(/^[  ]*\\[a-z]+[  ]*[一-龠ぁ-ゔァ-ヴー々〆〤ヶレディファイッ]/gmi) != null) {
                                    wrapattempt = wrapattempt.replaceAll(/(\\[a-z])/gi, "\n$1");
                                }
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/gm, "");
                                wrapattempt = wrapattempt.replaceAll(/^\n/g, "");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/gm, "");
                            }
                            //Single variables at the end of lines
                            else if (row0noemptylines.match(/\\v\[\d+\][  回mlkgkgGGml$%$%#€]*$/gmi) != null && row0noemptylines.match(/\\v\[\d+\].*\\v\[\d+\]/gmi) == null && row0noemptylines.match(/[^v\\\[\]  回mlkgkgGGml$%$%#€]+$/gmi) == null) {
                                wrapattempt = wrapattempt.replaceAll(/[\r\n]+/gm, " ");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/g, "");
                                wrapattempt = wrapattempt.replaceAll(/((?:\\v\[\d+\][  ]*ct)|(?:\\v\[\d+\][  ]*ml)|(?:\\v\[\d+\][  ]*$)|(?:\\v\[\d+\][  ]*kg)|(?:\\v\[\d+\][  ]*g)|(?:\\v\[\d+\][  ]*G)|(?:\\v\[\d+\][  ]*$)|(?:\\v\[\d+\][  ]*€)|(?:\\v\[\d+\][  ]*%)|(?:\\v\[\d+\][  ]*回)|(?:\\v\[\d+\][  ]*%)|(?:\\v\[\d+\][  ]*G)|(?:\\v\[\d+\][  ]*ml)|(?:\\v\[\d+\][  ]*g)|(?:\\v\[\d+\][  ]*kg)|(?:\\v\[\d+\][  ]*(?=[^  回mlkgkgGGml$%$%#€])))/gm, "\n$1");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/gm, "");
                                wrapattempt = wrapattempt.replaceAll(/^\n/g, "");
                                wrapattempt = wrapattempt.replaceAll(/^[  ]+/gm, "");
                            }
                            if (row0count == wrapattempt.split(/\r\n|\r|\n/).length) {
                                trans.project.files[file].data[k][3] = wrapattempt;
                            }
                        }
                    }
                }
 

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
I've released v1.118.
Since I've started to make new automatic word wrapping stuff for non dialogue, mostly to support some niche MZ plugins that allow linebreaks, there's obviously going to be cells that look like they need changes, but do not have automation, yet.
But since that is something the average MTLer does not care about I didn't want to make an error code insert for it so instead I added yet another color tag.
Whenever it now does not wrap a cell, but notices that the original Japanese cell has more lines, it will tag that cell indigo and a popup will tell you about it, unless the cell already has a purple tag.
"Indigo" is basically just dark purple, since this is pretty similar to the purple tagging, but you can search and process them independent from one another.
If you use the Prepare for batch translation or the fix cells and check for errors button all indigo tags will be removed at the start of the process to not interfere with it.
 
Last edited:

iYuma

Member
Nov 17, 2017
353
826
Damn appreciate the effort man! I still use your tool whenever a niche JP game gets released.
 

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
I've released v1.119.
This one will feel like a massive downgrade on some games, but it's "working as intended".
Basically it will spam lost placeholder errors, but that doesn't actually mean those cells looked any better beforehand, it just actually tries, and reports failure...

The big issue is and always was custom colors.
When Japanese text suddenly has a word in a different color.
In the actual text box that looks like this:
Code:
TEXTTEXT\C[12]COLOREDTEXT\C[0]TEXTTEXT
And the big issue is, how the fuck do you feed that to Sugoi?
If you just feed TEXTTEXT, COLOREDTEXT, TEXTTEXT separately while escaping the color commands, the result is horrible because they need the context of one another to make sense.

If you feed it TEXTTEXTCOLOREDTEXTTEXTTEXT, the resulting translation will be decent, but different length and you have no way of knowing which word or words are actually supposed to be in the color box.
Because Japanese is almost always shorter than English, it will almost always be wrong.

So unless you just remove all colors from all text, your only option is to isolate the color block, translate it on its own, and then feed Sugoi TEXTTEXTPLACEHOLDERTEXTTEXT.
But the only way for that to give the desired result is if Sugoi on one hand leaves enough of the placeholder intact so the color block can be inserted back in, but on the other hand doesn't ignore its existence and actually treats it as a "thing" to integrate in its output.
And that's super inconsistent, hence all those previously hidden bad translations.
 
Last edited:

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
If someone has an idea I'd be happy to hear it.
My current placeholders are @@1@, @@2@, @@3@ etc., because in all tests I've run so far they've had the highest success rate with SugoiV4.
 

derakino999

Well-Known Member
Sep 30, 2017
1,255
657
I trust your idea, but if that thing doesn't work out in the end, in my opinion i wouldn't mind getting rid of the color altogether as in make the whole sentence default color, no custom colored words, as in fuck it
A small price to pay for a better translation, but that's just the opinion of one man
"Indigo" is basically just dark purple, since this is pretty similar to the purple tagging, but you can search and process them independent from one another.
also about these indigo cells that you say we can process them independently, in what way do we process them? i don't understand
like process them how or what do we do
 

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
I trust your idea, but if that thing doesn't work out in the end, in my opinion i wouldn't mind getting rid of the color altogether as in make the whole sentence default color, no custom colored words, as in fuck it
A small price to pay for a better translation, but that's just the opinion of one man
SLR Translator isn't just meant as a MTool replacement, but allow the creation of higher quality edited MTLs.
While the cells in which the placeholders get lost have a bad translations, it still preserves all parts of it and so someone manually editing can fix them without knowing any Japanese.
However if I get rid of all colors then someone who cannot manually translate themselves would have to use an external translator to find out which word is supposed to be in color and the whole process would be really annoying.
also about these indigo cells that you say we can process them independently, in what way do we process them? i don't understand
like process them how or what do we do
That is just meant for someone who wants to manually review them as to whether or not they need fixing. For a quick MTL you can completely ignore that they exist. They are much less likely to be relevant than the purple ones.
 

fantasmic

Member
Modder
Nov 3, 2021
398
968
Let's say a sentence is supposed to be [You should head north through the forest to find the witch's hut].
As a player, I prefer [You should head north through the forest to find the witch's hut.] since that let's me know that something in that sentence was important (probably north, forest, witch's hut, or some combination of them) and the dev cares enough about the player experience to try to help us not spend an hour wandering aimlessly since we didn't pay attention to npcs.
As a translator, I prefer [You should head north through the forest to find the witch's hut.LOSTCOLORCODEerror.], since I certainly don't mind running a search to find all the affected cells and manually editing them. Then again, if the search returns 1013 affected cells, I also don't mind using a find-and-replace of [LOSTCOLORCODEerror.] for []. The first method is probably the best all-around since I know I'm a poor metric for what the average user wants to do. In any case, I consider both of those options (a half-colored sentence, or giving the translator the option to simply delete all color codes) preferable to something like [Let's go. North. The witch's hut is in the forest.].
 

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
Let's say a sentence is supposed to be [You should head north through the forest to find the witch's hut].
As a player, I prefer [You should head north through the forest to find the witch's hut.] since that let's me know that something in that sentence was important (probably north, forest, witch's hut, or some combination of them) and the dev cares enough about the player experience to try to help us not spend an hour wandering aimlessly since we didn't pay attention to npcs.
As a translator, I prefer [You should head north through the forest to find the witch's hut.LOSTCOLORCODEerror.], since I certainly don't mind running a search to find all the affected cells and manually editing them. Then again, if the search returns 1013 affected cells, I also don't mind using a find-and-replace of [LOSTCOLORCODEerror.] for []. The first method is probably the best all-around since I know I'm a poor metric for what the average user wants to do. In any case, I consider both of those options (a half-colored sentence, or giving the translator the option to simply delete all color codes) preferable to something like [Let's go. North. The witch's hut is in the forest.].
Since it's happening during the translation it neither gets an error code nor a special color atm, I do not have tagging/inserting functionality implemented during the translation phase at the moment. (That would actually be harder to do than it sounds.)

Instead it gives you a log message during the translation that says something along the lines of:

Could not recover placeholder position. 'placeholder' Placed it at position X because that is closest to the original position.
'Original text'
'Current Translation'

Or when it "could" have fucked it up:

Recovered placeholder by using these partial remains. 'used remains' 'placeholder'
'Original text'
'Current Translation'

I tend to just copy the entire log to a txt file and search for the original text to find the cells I want to edit. Not exactly convenient I know...

But when I say a lot of lost placeholders I actually mean like 10 in a medium sized translation. (Not counting identical cells.)

Edit: Inserting an error code along with whatever the placeholder replaced would be easy enough, but I don't think the average person would want that. I mean there's a purple tag now because people were annoyed by the sugoi error codes.
 
Last edited:

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
Hello
Can you try to add Baidu Web addon to SLR ?
It works really well in translating game to my native language
View attachment 4298130
The issue is that the dictionary system and the post fixes of SLR are English or designed for English, so while you could technically add any Translator++ addon to SLR Translator, it would have to use Dreamsavior's batch translator and Escaper, meaning there would not be script protection or error detection. You would likely just end up with a broken mess.

I would have to make a completely new engine wrapper and post process specifically for the new target language or there wouldn't be much difference to just using Translator++ instead, but that would take a long time and for that to actually have a decent result I would need to be fluent in that language.

I'm sorry, but I do not think that fits the current scope and (not existent) funding of the SLR project.
 

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
I've released v1.121.
It will now insert the error code LOSTPLACEHOLDERMIDDLE into cells during batch translation, that have had a seriously lost placeholder.
Seriously lost in the sense that there is very little chance that the translation actually turned out okay because it was supposed to be in the middle of the text.
Those codes will be removed if you press the "Fix cells and check for errors" button and instead the cells will be tagged purple.
(That was a lot easier to implement than tagging them purple from the start)
Also added progress bars to all the buttons now and fixed loading related bugs.
 

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
I've released v1.122.
More complicated word wrapping stuff nobody besides me cares about. :PogChamp:
Also you can now clear wrapped translations by typing in "clear", and all translations in general by typing in "nuke". (Not sure why you would ever want to nuke your project, but it seemed like a good idea at the time. :WeSmart:)
 
Oct 21, 2022
50
5
The issue is that the dictionary system and the post fixes of SLR are English or designed for English, so while you could technically add any Translator++ addon to SLR Translator, it would have to use Dreamsavior's batch translator and Escaper, meaning there would not be script protection or error detection. You would likely just end up with a broken mess.

I would have to make a completely new engine wrapper and post process specifically for the new target language or there wouldn't be much difference to just using Translator++ instead, but that would take a long time and for that to actually have a decent result I would need to be fluent in that language.

I'm sorry, but I do not think that fits the current scope and (not existent) funding of the SLR project.
Do you know how to auto delete translation data in the red/blue tag rows ?
Some games have many red tag row(almost hundreds of row) after translated so if I delete manually it will take so much time
 

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
Do you know how to auto delete translation data in the red/blue tag rows ?
Some games have many red tag row(almost hundreds of row) after translated so if I delete manually it will take so much time
I'm not sure what you are talking about. :confused:
If you follow the standard procedure red and blue cells will never be translated in the first place.
Using standard settings the batch translator does not translate cells tagged red, blue, dark red, cyan, yellow, gold, or gray.
Just make sure you did not remove them from the Blacklist.
 
Oct 21, 2022
50
5
I'm not sure what you are talking about. :confused:
If you follow the standard procedure red and blue cells will never be translated in the first place.
Using standard settings the batch translator does not translate cells tagged red, blue, dark red, cyan, yellow, gold, or gray.
Just make sure you did not remove them from the Blacklist.
Um well
I run batch translate Sword Art Online: The Trap of Breath Concealed Magic by google
The game ran well
But after plenty of playing time,i got this error
1733931266873.png
I think somewhere in translated data conflict with the raw one
Do you know how to search for the destination of the error ?
 

Shisaye

Engaged Member
Modder
Dec 29, 2017
3,209
5,573
Um well
I run batch translate Sword Art Online: The Trap of Breath Concealed Magic by google
The game ran well
But after plenty of playing time,i got this error
View attachment 4322255
I think somewhere in translated data conflict with the raw one
Do you know how to search for the destination of the error ?
I'm sorry, but like I said before, SLR Translator is not meant for translations to languages other than English, and I currently have no plans to change that. The SLR project neither has any funding, nor can I speak any other languages worth adding.
 
Oct 21, 2022
50
5
I'm sorry, but like I said before, SLR Translator is not meant for translations to languages other than English, and I currently have no plans to change that. The SLR project neither has any funding, nor can I speak any other languages worth adding.
Oh i fixed it
Now the only problem is too long message that go out of the dialog text box
Do you know how to edit max character per line or default word wrapping ?