Page 2 of 3

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Sun Sep 18, 2016 8:17 am
by Rseding91
Zeblote wrote:Anyways, this topic was about accessing the localized text in mods.

Where exactly is the problem with determinism, assuming we have the following:

- player variable that has the locale he is using
- method to get localized text given a specific string and locale
- event that runs when a player changes locale
Locale doesn't have to be identical on all peers.

You can make a mod that changes/adds locale and use it in MP without any other peers having to have that mod.

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Sun Sep 18, 2016 8:35 am
by aubergine18
Sync .cfg files amongst peers?

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Tue Sep 27, 2016 11:55 pm
by aubergine18
Another example of a mod stymied by not being able to get actual translations for text - the search feature in "What does it do?" mod can only search on locale keys, not the translated names of items etc. viewtopic.php?p=210544#p210544

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Sat May 20, 2017 10:23 am
by Coppermine
aubergine18 wrote:Another example of a mod stymied by not being able to get actual translations for text - the search feature in "What does it do?" mod can only search on locale keys, not the translated names of items etc. viewtopic.php?p=210544#p210544
I've been working on some improvements to What Is It Used For and hit both the problems listed in this thread. I wanted to be able to sort by localised name and filter by localised name, and both are impossible.

So I just wanted to add my voice to this request.

If we can't request a particular string in a particular locale because not all players need to have the same locales installed then perhaps we can have a function to get the English localised name? That would still be better than what we have now. There are quite a lot of items where the internal name is quite different from the English localised name (e.g. mods often add prefixes for namespacing, which ruins sort order).

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Sat May 20, 2017 10:09 pm
by mickael9
Coppermine wrote:If we can't request a particular string in a particular locale because not all players need to have the same locales installed then perhaps we can have a function to get the English localised name? That would still be better than what we have now. There are quite a lot of items where the internal name is quite different from the English localised name (e.g. mods often add prefixes for namespacing, which ruins sort order).
English locale is like any other: it can be modified by the client and be different than the server's version which would cause desyncs.

Here is my proposal for a sortable & filterable table which would solve the problem: viewtopic.php?f=28&t=48164

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Tue Apr 03, 2018 4:47 am
by sparr
Proposed solution over in viewtopic.php?f=28&t=59296

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Sat Apr 28, 2018 12:58 pm
by Coppermine
Just to keep track of all the threads in one place, here's another: viewtopic.php?f=28&t=57945

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Mon Jan 27, 2020 10:25 am
by Coppermine
In case anyone missed it, this is now possible (and has been for a while now) thanks to this addition to the API.

I just finished implementing localized string filtering for What is it Really Used For?, and it seems to work great. Thanks, devs!

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Mon Jan 27, 2020 10:55 am
by eradicator
Coppermine wrote: Mon Jan 27, 2020 10:25 am In case anyone missed it, this is now possible (and has been for a while now) thanks to this addition to the API.

I just finished implementing localized string filtering for What is it Really Used For?, and it seems to work great. Thanks, devs!
Care to share a few details about the implementation? In particular how many requests do you dispatch at once? Or how long does it take to finish translation of a heavily modded game on a not-so-great connection etc?

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Mon Jan 27, 2020 11:36 am
by Coppermine
eradicator wrote: Mon Jan 27, 2020 10:55 am Care to share a few details about the implementation? In particular how many requests do you dispatch at once? Or how long does it take to finish translation of a heavily modded game on a not-so-great connection etc?
You can of course look at the code. I just set up a memoised function that requests a translation if it's not already locally cached. It requests all the translations the first time you try to filter the list, so I suspect there might be a noticeable hiccup the first time each player uses the filter, but hopefully it should be fast after that.

I haven't tested on a multiplayer game.

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Mon Jan 27, 2020 12:43 pm
by eradicator
Coppermine wrote: Mon Jan 27, 2020 11:36 am
eradicator wrote: Mon Jan 27, 2020 10:55 am Care to share a few details about the implementation? In particular how many requests do you dispatch at once? Or how long does it take to finish translation of a heavily modded game on a not-so-great connection etc?
You can of course look at the code. I just set up a memoised function that requests a translation if it's not already locally cached. It requests all the translations the first time you try to filter the list, so I suspect there might be a noticeable hiccup the first time each player uses the filter, but hopefully it should be fast after that.

I haven't tested on a multiplayer game.
In that case i can tell you that it won't work in multiplayer. I tested the "request everything at once" approach myself before and it basically becomes impossible for anyone to join multiplayer servers even though it works fine in singleplayer.

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Mon Jan 27, 2020 11:37 pm
by Coppermine
eradicator wrote: Mon Jan 27, 2020 12:43 pm In that case i can tell you that it won't work in multiplayer. I tested the "request everything at once" approach myself before and it basically becomes impossible for anyone to join multiplayer servers even though it works fine in singleplayer.
Thanks for the warning. Can you point me to any established best practices that have been found effective?

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Tue Jan 28, 2020 12:03 pm
by eradicator
Coppermine wrote: Mon Jan 27, 2020 11:37 pm
eradicator wrote: Mon Jan 27, 2020 12:43 pm In that case i can tell you that it won't work in multiplayer. I tested the "request everything at once" approach myself before and it basically becomes impossible for anyone to join multiplayer servers even though it works fine in singleplayer.
Thanks for the warning. Can you point me to any established best practices that have been found effective?
If i knew those i wouldn't have asked you how your implementation works ;). My guess is that nobody has done enough testing yet.

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Wed Jan 29, 2020 1:22 pm
by Helfima
my mod has been using the function for several months and no one reported a problem on this feature

for each player
1) I build a set of all localised string
2) I request translate for all localised string in a loop (https://github.com/Helfima/helmod/blob/ ... r.lua#L422)
3) I listen the event on_string_translated (https://github.com/Helfima/helmod/blob/ ... r.lua#L292 , https://github.com/Helfima/helmod/blob/ ... r.lua#L642)

https://mods.factorio.com/mods/Helfima/helmod

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Mon Mar 09, 2020 12:11 pm
by Coppermine
I did indeed have some reports of multiplayer issues with requesting all the translations at once. So in WIIRUF version 1.5.6 I throttled the requests to 100 at a time (that is, 100 per keypress in the search box) and that seems to have resolved the issue. It does mean that the very first time any player searches they may not get all the results they expect, but it was a reasonable quick fix.

It would probably be better to do the rate-limiting based on time rather than keypresses, but this was much simpler. Ideally someone should probably roll all this into some standard library code (if they haven't already).

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Mon Mar 16, 2020 1:52 am
by Helfima
Me i push all values by step of 100 on few tick before display the result

https://github.com/Helfima/helmod/blob/ ... r.lua#L399

if you see the next function you can see the waiting

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Sat Apr 11, 2020 6:18 am
by raiguard
Coppermine wrote: Mon Mar 09, 2020 12:11 pm Ideally someone should probably roll all this into some standard library code (if they haven't already).
I spent a lot of time writing and rewriting a translation module that I use in my mods. It rate-limits to 50 translations per tick, and that's total - if two players are doing translations at once, it'll do 25 per player. It also supports multiple dictionaries being translated simultaneously, and even creates and manages a /retranslate-all-dictionaries command that will cause any mods using it to retranslate their dictionaries (assuming they're set up to do so).

It does depend on my lualib's event module, but could fairly easily be made to work standalone.

Usage is very simple:

Code: Select all

local function do_translations(player)
  local translation_data = {
    {internal="iron-ore", localised={"item-name.iron-ore"}},
    {internal="copper-ore", localised={"item-name.copper-ore"}},
    -- etc...
  }

  translation.start(player, 'ores', translation_data)
end

-- later on, somewhere
script.on_event(translation.finish_event, function(e)
  global.players[e.player_index].dictionary = {
    lookup = e.lookup,
    sorted_translations = e.sorted_translations,
    translations = e.translations
  }
end
EXAMPLE OUTPUT:

Code: Select all

lookup = {
  ["Iron ore"] = {"iron-ore"},
  ["Copper ore"] = {"copper-ore"}
}
sorted_translations = {
  "Copper ore",
  "Iron ore",
}
translations = {
  ["iron-ore"] = "Iron ore",
  ["copper-ore"] = "Copper ore"
}
(lookup values are arrays in the case that multiple different internal names have the same translation)

The way that this module is meant to be used is to run when a player first joins a game. You prevent usage of your GUI until the translations are finished, store the translations in global, then enable use of your GUI. In your search loop, you can simply use the data stored in global.

Right now it's designed to retranslate whenever a player re-joins a game. However, I'm considering changing this behavior since most people probably don't change languages all that often. In the case that they do, they can retranslate all dictionaries using the /retranslate-all-dictionaries command.

TL;DR: I made a library to do this, you can use it if you like.

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Sun Apr 12, 2020 1:20 am
by eradicator
After just looking at your examples... can your library handle these cases?

a) *different* translations for {'item-name.copper-ore'} and {'entity-name.copper-ore'} (recipe-name, etcpp).

b) Compound localised strings like {'__1__ blabla', {'item-name.copper-ore'}} (i.e. fluid barrels)

Also would you mind sharing how did you arrived at the solution of limiting per tick instead of per batch? (i.e. independant of network latency)

(Also thanks for sharing really! 50~100 batch size is at least a good starting point.)

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Sun Apr 12, 2020 3:55 am
by raiguard
eradicator wrote: Sun Apr 12, 2020 1:20 am After just looking at your examples... can your library handle these cases?

a) *different* translations for {'item-name.copper-ore'} and {'entity-name.copper-ore'} (recipe-name, etcpp).

b) Compound localised strings like {'__1__ blabla', {'item-name.copper-ore'}} (i.e. fluid barrels)

Also would you mind sharing how did you arrived at the solution of limiting per tick instead of per batch? (i.e. independant of network latency)

(Also thanks for sharing really! 50~100 batch size is at least a good starting point.)
a) Yes. When you're giving it stuff to translate, the "internal" name can be whatever you want. So you can differentiate between recipes and items easily. You could also put them into entirely separate dictionaries if you want (that's what I do).

b) Also yes. It supports any localised strings you throw at it.

c) I'm not sure what you mean? The library has an array of localised strings that it needs to translate for every player. On every tick, it runs through the next n amount of translations, then saves the position where it ended. Then on the next tick it picks back up and does the next batch. Network latency has never been an issue, it just works.

I made a script to test it with while I was developing it, you can view it here to see how I used it.

Re: LuaPlayer.translate( LocalisedString ), LuaPlayer.locale

Posted: Sun Apr 12, 2020 10:36 pm
by eradicator
Raiguard wrote: Sun Apr 12, 2020 3:55 am c) I'm not sure what you mean? The library has an array of localised strings that it needs to translate for every player. On every tick, it runs through the next n amount of translations, then saves the position where it ended. Then on the next tick it picks back up and does the next batch. Network latency has never been an issue, it just works.
That's just "theorycrafting" on my part. There's two possible implementation: a) the one you use that sends stuff in fixed intervals and b) one that waits until the result of the previous request arrives before sending off the next one. Not having done any extensive testing i was merely curious if you had evidence that makes one of them universally better than the other. On further thought a continous data stream (a) is probably better even if latency is high.