Page 1 of 1
Constructing localized strings in game
Posted: Wed Sep 18, 2019 6:45 am
by Pi-C
I've another localization problem.
Suppose you have these strings defined:
Code: Select all
[strings]
list=You get __1__ as result.
AND=and
That's easy to use if you only want to show one value:
Code: Select all
local a = "an iron gear"
game.print({"", "strings.list", a})
But how about a list composed of variables that may or may not be set?
Code: Select all
local a = entity.get_driver()
if a then a = a. player end
local b = entity.get_passenger()
if b then b = b.player end
local output = ""
if a then output = a end
if a and b then output = output .. ' ' .. {"strings.AND"} .. ' ' end
if b then output = output .. b
game.print({"", "strings.list", output})
I can't get this to work! The best I could achieve was getting wrong output (output would contain literal "strings.AND" instead of localized "and") without crashing the game, the worst was a crash due to trying to concatenate a table when a string was expected. Where is my mistake?
Re: Constructing localized strings in game
Posted: Wed Sep 18, 2019 7:33 am
by DaveMcW
Code: Select all
[strings]
list=You get __1__ as result.
AND=__1__ and __2__
Code: Select all
game.print({"strings.list", {"strings.AND", {"item-name.copper-plate"}, {"item-name.iron-plate"}}})
Re: Constructing localized strings in game
Posted: Wed Sep 18, 2019 8:38 am
by Pi-C
DaveMcW wrote: Wed Sep 18, 2019 7:33 am
Code: Select all
[strings]
list=You get __1__ as result.
AND=__1__ and __2__
Code: Select all
game.print({"strings.list", {"strings.AND", {"item-name.copper-plate"}, {"item-name.iron-plate"}}})
That's so easy again … So, I don't have to add the individual pieces to compose one string, but define three different strings (one for "only a", one for "only b", one for "a and b" -- I can't use variables that have no value).
Guess it was getting too late last night, and switching between different Factorio instances (with occasional restarts of both because otherwise the mods' checksums would cause desync) so many times took its toll. Thank you for your help!

Re: Constructing localized strings in game
Posted: Wed Sep 18, 2019 10:15 am
by eradicator
Pi-C wrote: Wed Sep 18, 2019 6:45 am
Code: Select all
game.print({"", "strings.list", output})
Only the first string in each localised string (==table) is a template, so this would literally print "strings.list".
But so many possibilities to get to your result:
Dynamic composition:
Code: Select all
[strings]
youhave=You have __1__.
and=and
if driver and passenger then
game.print{"strings.youhave",{"",driver,{"strings.and"},passenger}}
else
game.print{"strings.youhave",driver or passenger}
end
By-case templates:
Code: Select all
[strings]
twothing=You have __1__ and __2__
onething=You have __1__
if driver and passenger then
game.print{"strings.twothing",driver,passenger}
else
game.print{"strings.onething",driver or passenger}
end
Pi-C wrote: Wed Sep 18, 2019 8:38 am
I can"t use variables that have no value).
A localized string is a table, so you can abuse the fact that in lua every undefined element is nil, so adding nil to the end of a table does nothing:
Code: Select all
local lstring = {"","hi "}
local last_name = "foo"
local first_name = nil
table.insert(lstring,"my name is ")
table.insert(lstring,first_name)
table.insert(lstring,last_name)
Re: Constructing localized strings in game
Posted: Wed Sep 18, 2019 11:08 am
by Pi-C
eradicator wrote: Wed Sep 18, 2019 10:15 am
But so many possibilities to get to your result:
Dynamic composition:
Code: Select all
if driver and passenger then
game.print{"strings.youhave",{"",driver,{"strings.and"},passenger}}
else
game.print{"strings.youhave",driver or passenger}
end
I like this one! The "or" saves one ifelse-block, that's more elegant than my current solution.
By-case templates:
Code: Select all
[strings]
twothing=You have __1__ and __2__
onething=You have __1__
Will definitely work, but means more strings to translate.
Pi-C wrote: Wed Sep 18, 2019 8:38 am
I can"t use variables that have no value).
A localized string is a table, so you can abuse the fact that in lua every undefined element is nil, so adding nil to the end of a table does nothing:
Code: Select all
local lstring = {"","hi "}
local last_name = "foo"
local first_name = nil
table.insert(lstring,"my name is ")
table.insert(lstring,first_name)
table.insert(lstring,last_name)
That's a neat trick! Basically, it's the same thing I tried to achieve (build the message from individual blocks if these blocks exist), but without any checks required, so it looks much cleaner. Thanks for showing!