Page 1 of 2

A solution to searching prototypes in natural language

Posted: Thu Sep 12, 2019 4:39 pm
by Therenas
There are many situations where you want to find items/recipes/etc. by their localised name, ie. the user entering the name of an item (in their own natural language and locale). As a mod, you can't currently search localised strings because of determinism. This can't be circumvented without a lot of effort, so it hasn't been done yet, for good reason. There are many threads in this subforum documenting these proposals and rejections.

Now I think there might be a way to add a way to make your items/recipes/etc searchable in a better way. The idea is to add an additional field to the prototypes, named search_strings or something, that contains the words the developer wants to let people find their item as. So, for an item with the name 'gear', and the localised name 'Iron gear', you could have search_strings like 'Iron', 'Gear', 'Eisen', 'Zahnrad' (German translation of those). So even if the internal name is different from the localised one, users would still find it if they search for 'Iron'.

Whether this is a csv or a lua table doesn't really matter. This list would need names in many different languages potentially, same as the locale does. But the mod author could just add them in English, and translation/locale mods could just append their language version of those strings to the prototype attribute, which would make it searchable in that language too.

Now how this is implemented exactly, and for which prototypes and such I don't know, but items/recipes/technologies seem like the prime contenders, maybe entities too.

Re: A solution to searching prototypes in natural language

Posted: Thu Sep 12, 2019 5:09 pm
by eradicator
I'm all in for a translate() function, but i want a proper solution, and i want it to work for all locale strings. And as far as the old thread goes, this requires making locales deterministic in one way or the other. I.e. by synchronizing locales between players or by making locales part of the mod checksum in the first place.

What you propose has several issues:
  1. You essentially introduce a second locale file that can be asynchronus with the actual locale file. Meaning double work for translators/modderes.
  2. The serach keywords are an incomplete representation of the locale and as such won't do what the user expects them to do 90% of the time.
  3. You're blindly mixing languages. For all i know "Iron" could be the Estonian word for "Bomb". Leading to completely wrong results for every user.
  4. You can already implmenet this on your own via remote.call() so it doesn't improve the situation at all.

Re: A solution to searching prototypes in natural language

Posted: Thu Sep 12, 2019 5:48 pm
by Bilka
eradicator wrote: Thu Sep 12, 2019 5:09 pm I'm all in for a translate() function, but i want a proper solution, and i want it to work for all locale strings. And as far as the old thread goes, this requires making locales deterministic in one way or the other. I.e. by synchronizing locales between players or by making locales part of the mod checksum in the first place.
Something changed since that thread - all mods are now part of "game changing mods", so all players will have the same mods active and the right locale file on their system. My first reaction to that was: "great, locale is deterministic now". Except it's not: 1. Player locale is not game state - easily solvable, that's not a lot of data to send around. 2. You only ever load your own locale. Using a different one for Lua means also loading that. Now, loading like 30 different locales? That sounds insane. I still hope for translate(), but I want to explain why it's not a thing yet.

Re: A solution to searching prototypes in natural language

Posted: Thu Sep 12, 2019 7:49 pm
by eradicator
Bilka wrote: Thu Sep 12, 2019 5:48 pm Something changed since that thread - all mods are now part of "game changing mods", so all players will have the same mods active and the right locale file on their system.
As i suspected. So locale is also part of the mod checksum now?
Bilka wrote: Thu Sep 12, 2019 5:48 pm Using a different one for Lua means also loading that. Now, loading like 30 different locales? That sounds insane.
That's the same reasoning as in the old thread. Let me try to hold something against it (again?) for arguments sake:
  1. Is 30 locales really that big? A search over my factorio folder says there are 947 ".cfg" files with a total of 9MB. With RAM in the gigabytes this should be negligible.
  2. If it's still too much anyway (table overhead or whatever) then why not load them dynamically? To keep the game deterministic it would be sufficient if only locales were loaded that *someone* is actually using. The players see only their own locale. And i suspect that multiplayer servers with players from more than 10 different countries are extremely rare, and most of the time it's less than 5.
  3. There are benefits besides modding to this. It'd be possible to e.g. have a button that toggles between the players two/three favourite locales, making communication much easier when playing with friends in a different locale. (Ok, would probably require too much engine rewrite to actually happen...)
Bilka wrote: Thu Sep 12, 2019 5:48 pm I still hope for translate(), but I want to explain why it's not a thing yet.
So do i. Just look at how often many of the posts in that other thread are mine. I also have a horrible voodoo hack on paper that could probably do this right now. But maybe a horrible hack is what this thing needs to "get rolling", after all they keep saying "stuff that mods demonstrate are more likely to be implemented" :twisted:.

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 2:56 am
by Rseding91
I could implement a

Code: Select all

player.translate(localised-string)
but it's not going to be instant and would only work when the player is connected to the game.

How it would work is:
  • API call is made requesting that a translation for 'localised-string' by 'player' is done
  • If the player is online the game sends an InputAction with the localised-string and translated result + a bool if it failed to translate
  • Whenever the action gets to the game and is run it fires a "on_string_translated" event which contains the player it was translated by, the original localised string, and the result translation + if it failed to translate
In single player it would be instant or 1 tick later that results come back. In multiplayer it's N ticks later or never if the player disconnects before finishing the request. It's not perfect but I think for most cases it would work.

Is this something that would handle peoples needs?

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 5:46 am
by Optera
Rseding91 wrote: Fri Sep 13, 2019 2:56 am I could implement a

Code: Select all

player.translate(localised-string)
but it's not going to be instant and would only work when the player is connected to the game.

How it would work is:
  • API call is made requesting that a translation for 'localised-string' by 'player' is done
  • If the player is online the game sends an InputAction with the localised-string and translated result + a bool if it failed to translate
  • Whenever the action gets to the game and is run it fires a "on_string_translated" event which contains the player it was translated by, the original localised string, and the result translation + if it failed to translate
In single player it would be instant or 1 tick later that results come back. In multiplayer it's N ticks later or never if the player disconnects before finishing the request. It's not perfect but I think for most cases it would work.

Is this something that would handle peoples needs?
Just to be sure I understand this proposal.

Code: Select all

player.translate("Eisenplatte")
would raise

Code: Select all

on_string_translated(player, "iron-plate")
That would be a step towards searching by localized names. However that still requires players to search for exact matching strings.
Every other search in game supports fuzzy search. A search function should be able to return all item names where the localized string contains a certain string.
Searching for "Eisen" should return an array containing iron-ore, iron-plate, iron-chest, ...

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 5:57 am
by posila
No, I think it's the other way around

Code: Select all

player.translate({ "iron-plate" })
would raise

Code: Select all

on_string_translated(player, "Eisenplatte")

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 6:34 am
by Rseding91
posila wrote: Fri Sep 13, 2019 5:57 am No, I think it's the other way around

Code: Select all

player.translate({ "iron-plate" })
would raise

Code: Select all

on_string_translated(player, "Eisenplatte")
Correct.

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 7:28 am
by Optera
That seems only useful to check if a certain translation exists.

Just going by the thread name the goal is to search for a prototype by translated name. Any mod trying to do a translated name> prototype name search would need to call this function for every prototype and player to build a translation dictionary.
Ideally that would then be used to create one function library shared between all mods wanting to use this feature, as if that would ever happen. We all know every larger mod created makes his own library because none of us trust the other to keep a library working with all mods depending on it.

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 8:06 am
by Rseding91
Optera wrote: Fri Sep 13, 2019 7:28 am That seems only useful to check if a certain translation exists.

Just going by the thread name the goal is to search for a prototype by translated name. Any mod trying to do a translated name> prototype name search would need to call this function for every prototype and player to build a translation dictionary.
Ideally that would then be used to create one function library shared between all mods wanting to use this feature, as if that would ever happen. We all know every larger mod created makes his own library because none of us trust the other to keep a library working with all mods depending on it.
Yes, that's what mods would have to do. Doing reverse translation lookups isn't something even the base game can do. Any time anything does searching/filtering it's "get all of the translations for every prototype i'm filtering and then match what the player typed against them".

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 10:10 am
by eradicator
posila wrote: Fri Sep 13, 2019 5:57 am No, I think it's the other way around

Code: Select all

player.translate({ "iron-plate" })
would raise

Code: Select all

on_string_translated(player, "Eisenplatte")
I would very much prefer if it raised

Code: Select all

on_string_translated(player,{["iron-plate"]="Eisenplatte"})
I.e. if it a) allows multiple requests at once and b) is trivial to know what was translated (named key, or same numeric key as in request). Because if i have to build a dictionary one string at a time with a 1+ tick delay each it'd be really really slow.
Rseding91 wrote: Fri Sep 13, 2019 8:06 am Any time anything does searching/filtering it's "get all of the translations for every prototype i'm filtering and then match what the player typed against them".
And that is obviously what a mod would need to do to. For *every prototype*, all at once, preferably in on_player_joined_game. Or if that's too much traffic cut it down into a few packages.

As a slight addition it would be nice to have LuaPlayer.locale = 'string', i.e. "de" or "en", so i can skip the building of the dictionary if it already exists for the newly joined players language.

Apart from that it sounds good:)

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 10:24 am
by eradicator
On second thought, is that really more efficient than just

Code: Select all

player.request_locale()
or even

Code: Select all

player.request_locale_filtered({types={'item-name','recipe-name','entity-name'})
that raises an event that contains the complete locale? Mods will have to build dictionaries anyway, so translating only a single keyword will be a rare edge case.

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 3:45 pm
by Optera
eradicator wrote: Fri Sep 13, 2019 10:24 am On second thought, is that really more efficient than just

Code: Select all

player.request_locale()
or even

Code: Select all

player.request_locale_filtered({types={'item-name','recipe-name','entity-name'})
that raises an event that contains the complete locale? Mods will have to build dictionaries anyway, so translating only a single keyword will be a rare edge case.
Good idea.
Call that function once in on_player_joined_game and receive a full dictionary like

Code: Select all

{["en"] = {["iron-plate] = "Iron plate", ...}
Delaying by 1 or more ticks would produce a window where not all players have a translation available which could cause desyncs.

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 4:32 pm
by Pi-C
Therenas wrote: Thu Sep 12, 2019 4:39 pm The idea is to add an additional field to the prototypes, named search_strings or something, that contains the words the developer wants to let people find their item as. So, for an item with the name 'gear', and the localised name 'Iron gear', you could have search_strings like 'Iron', 'Gear', 'Eisen', 'Zahnrad' (German translation of those).
Bad example! What does "iron" mean, exactly? In English, the word "iron" can be used as noun (German: "Eisen") and as adjective (German: "eisern", or -- in the right context -- "ehern"). Would you expect people to search only for nouns? Would you include every alternative translation imaginable in the dictionary? Seems like opening a whole box of new problems to me. :-)

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 7:00 pm
by Rseding91
A function which gives the full set of translations wouldn't be useful because translations aren't a 1-1 mapping of key<>value. They have substitutions/replacements and can even include each other.

The way I imagined it would work is you ask through a given player for some localised string to be translated.

Then later the event is fired and contains the player_index, localised_string, string, and boolean saying if it translated it or not. If you wanted multiple just call the event multiple times in what ever tick you want.

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 7:23 pm
by eradicator
Rseding91 wrote: Fri Sep 13, 2019 7:00 pm A function which gives the full set of translations wouldn't be useful because translations aren't a 1-1 mapping of key<>value. They have substitutions/replacements and can even include each other.
I was just trying to be clear that for my and probably 90% of other mods the main usecase will be the creation of a dictionary of *all* item/tech/recipe/etc-names when the player joins. Then store the dictionary in global for later use. So a one-by-one interface might produce more overhead than needed.

But... if you want to go the extra steps and give us a full translation function that can translate any abitrary (concatenation of) localised strings i will be totally happy with that. :)

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 8:03 pm
by Rseding91
One at a time vs multiple at once won't have any significant difference in performance but it will make the backing logic easier if it's one at a time.

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 8:50 pm
by eradicator
Rseding91 wrote: Fri Sep 13, 2019 8:03 pm One at a time vs multiple at once won't have any significant difference in performance but it will make the backing logic easier if it's one at a time.
Well then. Very much looking forward to this unexpected present. I'm guessing it'll happen after 0.17 stable?

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 10:27 pm
by pleegwat
Problems like this make me think of a different potential solution: Having a distinct UI stage which can read from and send commands to the control stage. Those commands would need to be synchronized across all players, but the UI itself could remain local to each player. Probably isn't feasible in this stage of factorio development though, and would break mods bigtime. Or not possible at all because I'm not seeing the entire picture.

Re: A solution to searching prototypes in natural language

Posted: Fri Sep 13, 2019 11:13 pm
by Rseding91
Capture.PNG
Capture.PNG (14.36 KiB) Viewed 5411 times
Capture.PNG
Capture.PNG (7.87 KiB) Viewed 5411 times