API to extract localised strings for prototypes
API to extract localised strings for prototypes
There are complex rules used by the C++ to determine the correct localised string for a given blueprint.
An entity's name in the world is entity_prototype.localised_name, or if that doesn't exist, then it is {"entity-name.<entity_prototype.name>"}.
If an item has a place result, its localised_name is the localised_name of the placed entity, as determined from the entity prototype using the method above. If it doesn't have a place_result, the localised_name is {"item-name.<item_prototype.name>"}.
If a recipe has a main_product, or it has single result, its localised_name is the localised_name of the result item, as determined using the method above. If the recipe has multiple products defined and no main_product, the localised_name is {"recipe-name".<recipe_prototype.name>}.
The rules are unambiguous but tedious to implement, and it would be nice to have a Lua API somewhere that does the recursive resolution, and returns a LocalizedString suitable for display (i.e. by interpolation in another Localized String).
An entity's name in the world is entity_prototype.localised_name, or if that doesn't exist, then it is {"entity-name.<entity_prototype.name>"}.
If an item has a place result, its localised_name is the localised_name of the placed entity, as determined from the entity prototype using the method above. If it doesn't have a place_result, the localised_name is {"item-name.<item_prototype.name>"}.
If a recipe has a main_product, or it has single result, its localised_name is the localised_name of the result item, as determined using the method above. If the recipe has multiple products defined and no main_product, the localised_name is {"recipe-name".<recipe_prototype.name>}.
The rules are unambiguous but tedious to implement, and it would be nice to have a Lua API somewhere that does the recursive resolution, and returns a LocalizedString suitable for display (i.e. by interpolation in another Localized String).
Miniloader — UPS-friendly 1x1 loaders
Bulk Rail Loaders — Rapid train loading and unloading
Beltlayer & Pipelayer — Route items and fluids freely underground
Bulk Rail Loaders — Rapid train loading and unloading
Beltlayer & Pipelayer — Route items and fluids freely underground
Re: API to extract localised strings for prototypes
I'm not sure what specifically you're asking for. The game uses a specific localized name for a specific prototype. If you want a recipe name you call recipe.localized_name.
Unless you mean something else?
Unless you mean something else?
If you want to get ahold of me I'm almost always on Discord.
Re: API to extract localised strings for prototypes
Sorry, this request was particularly badly written. Yes, at control phase prototype.localised_name works great. The original use case was for something that could be used during data phase to generate localised strings based on recipe names.
For example, in base/data-updates.lua, we find this line:
for automatically generating barrel filling recipes.
This works for fluids because the LocalisedString for fluids is predictable and simple to derive. If a mod wants to create recipes derived from other recipes, such as a "recycling" mod that generates inverse recipes, determining the proper localised_name during the data phase is tricky, and each mod ends up re-implementing the same logic, often incorrectly.
The request is for a Lua function accessible during data phase and maintained by Wube, say in core/lualib or similar, that mirrors the C++ behavior that generates the localised_name for a prototype during prototype compilation which is then available as prototype.localised_name during control phase. This wouldn't be perfect since another mod could modify data between the time this function was called to compute a LocalisedString and the actual compilation of prototypes.
An alternative would be a way to add a form of LocalisedString that would be evaluated by the C++ during prototype compilation. For example, the above might be expressed as:
During prototype compilation, this would be replaced by the value of "game.fluid_prototypes[fluid.name].localised_name". In other words, a LocalisedString that could reference a prototype, instead of only being able to directly reference the localization tables. This could break due to circular references which would have to be detected during prototype compilation, however, so I understand if that's not something you're willing to implement.
For example, in base/data-updates.lua, we find this line:
Code: Select all
localised_name = {"recipe-name.fill-barrel", {"fluid-name." .. fluid.name}},
This works for fluids because the LocalisedString for fluids is predictable and simple to derive. If a mod wants to create recipes derived from other recipes, such as a "recycling" mod that generates inverse recipes, determining the proper localised_name during the data phase is tricky, and each mod ends up re-implementing the same logic, often incorrectly.
The request is for a Lua function accessible during data phase and maintained by Wube, say in core/lualib or similar, that mirrors the C++ behavior that generates the localised_name for a prototype during prototype compilation which is then available as prototype.localised_name during control phase. This wouldn't be perfect since another mod could modify data between the time this function was called to compute a LocalisedString and the actual compilation of prototypes.
An alternative would be a way to add a form of LocalisedString that would be evaluated by the C++ during prototype compilation. For example, the above might be expressed as:
Code: Select all
localised_name = {"recipe-name.fill-barrel", {type="fluid", name=fluid.name}}
Miniloader — UPS-friendly 1x1 loaders
Bulk Rail Loaders — Rapid train loading and unloading
Beltlayer & Pipelayer — Route items and fluids freely underground
Bulk Rail Loaders — Rapid train loading and unloading
Beltlayer & Pipelayer — Route items and fluids freely underground
- eradicator
- Smart Inserter
- Posts: 5207
- Joined: Tue Jul 12, 2016 9:03 am
- Contact:
Re: API to extract localised strings for prototypes
I once wrote a function to extract the current localized name of an item in data stage. (original post):
So i can wholeheartedly agree that it would be awesome to not have to guess this myself. (i.e. an official utility function get_localized_name(prototype) -> LocalisedString). Also looking at this and at the fluid-barrel naming function i'd suspect that the fluid barrel recipe doesn't get a correct name if a fluid happens to have a localized_name instead of using fluid-name.fluid-name. I.e. because the fluid itself is procedurally derived from another prototype.eradicator wrote: Here's the hopefully 100% correct version:Code: Select all
local derived --courtesy of eradicator if item.localised_name then derived = item.localised_name elseif item.place_result then derived = 'entity-name.'..item.place_result elseif item.placed_as_equipment_result then derived = 'equipment-name.'..item.placed_as_equipment_result else derived = 'item-name.'..item.name end
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
Re: API to extract localised strings for prototypes
And even this is incorrect if the entity or equipment declares its own localised_name. This stuff is tricky.eradicator wrote: Here's the hopefully 100% correct version:Code: Select all
local derived --courtesy of eradicator if item.localised_name then derived = item.localised_name elseif item.place_result then derived = 'entity-name.'..item.place_result elseif item.placed_as_equipment_result then derived = 'equipment-name.'..item.placed_as_equipment_result else derived = 'item-name.'..item.name end
Miniloader — UPS-friendly 1x1 loaders
Bulk Rail Loaders — Rapid train loading and unloading
Beltlayer & Pipelayer — Route items and fluids freely underground
Bulk Rail Loaders — Rapid train loading and unloading
Beltlayer & Pipelayer — Route items and fluids freely underground
Re: API to extract localised strings for prototypes
Ideally we shouldn't need to do any lookup at all. Instead it should be sufficient to go:
and have the runtime lookup what recipe's localised name happens to be, regardless of if the translation for recipe-name.that-item is defined, or if it is in fact a explicit localised_string defined on the entity that's placed by the item that recipe creates.
Code: Select all
new_recipe.localised_name = { "", { "description.My prefix" }, { "recipe-name." .. recipe.name } }
-
- Inserter
- Posts: 35
- Joined: Fri Aug 24, 2018 7:42 pm
- Contact:
Re: API to extract localised strings for prototypes
fully agree with this request, it is a major headache to get this correct. An API/Approach in the data stage would be appreciated.
It gets even worse when reusing an entities description: the base game displays nothing if no description is present. yet if you use it in a localized_description (use case is an entity description: "__1__ (Quality level: __2__)", where 1 is supposed to be the entities actual description and 2 is a string from my mod), we get the missing locale error string unless a description exists. only 20% (42 out of 209 in "en") of entities have a description, so the only 100% correct way for me is to hard-code the list of entities for which the base game defines a description(wrongly relying only on the "en" locale file) and only use it when inside this list.
It gets even worse when reusing an entities description: the base game displays nothing if no description is present. yet if you use it in a localized_description (use case is an entity description: "__1__ (Quality level: __2__)", where 1 is supposed to be the entities actual description and 2 is a string from my mod), we get the missing locale error string unless a description exists. only 20% (42 out of 209 in "en") of entities have a description, so the only 100% correct way for me is to hard-code the list of entities for which the base game defines a description(wrongly relying only on the "en" locale file) and only use it when inside this list.
Re: API to extract localised strings for prototypes
Hey, this is starting to narrow down to something that could be considered a bug! The game treats a missing description entry as blank, but the locale parser treats it as an error. If the parser treated missing entries as blank too, it still wouldn't be perfect (your example would end up with a leading space) but it would be much better.the base game displays nothing if no description is present. yet if you use it in a localized_description ..., we get the missing locale error string unless a description exists
My mods: Multiple Unit Train Control, Smart Artillery Wagons
Maintainer of Vehicle Wagon 2, Cargo Ships, Honk
Maintainer of Vehicle Wagon 2, Cargo Ships, Honk
Re: API to extract localised strings for prototypes
Worse; for many entity types, a blank description results in an auto-generated description, and there's no way I know of to add to it, you can only replace it.
Edit: fix tyop
Edit: fix tyop
-
- Fast Inserter
- Posts: 194
- Joined: Sat Apr 23, 2016 7:11 am
- Contact:
Re: API to extract localised strings for prototypes
https://gist.github.com/theRustyKnife/4 ... e61affe5ab (WIP) recipe ( + a few others ) -> localised_name
Tested with GDIW + Bobs
Tested with GDIW + Bobs