Need some help with a script

This is the place to request new mods or give ideas about what could be done.
LoneWolf_LWP
Inserter
Inserter
Posts: 39
Joined: Thu Jan 07, 2021 11:20 pm
Contact:

Need some help with a script

Post by LoneWolf_LWP »

Could someone help me with a script?

I want to dump this information from my active mods recipes to a file but all examples i find give me a different type of string.
I believe these are called the localised names but i find no examples on them how to find them using a script.

I'm new to scripting for factorio, I try to learn from small examples.
Thank you,

Image
https://imgur.com/a/pS4eg9X
Pi-C
Smart Inserter
Smart Inserter
Posts: 1742
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Need some help with a script

Post by Pi-C »

LoneWolf_LWP wrote: Sat Jan 22, 2022 12:46 am Could someone help me with a script?

I want to dump this information from my active mods recipes to a file but all examples i find give me a different type of string.
I believe these are called the localised names but i find no examples on them how to find them using a script.
If you want to do this in the data stage:

Code: Select all

for r, recipe in pairs(data.raw.recipes) do 
  log("Name: "..r.."\tlocalised_name: "..serpent.line(recipe.localised_name))
end
In the control stage:

Code: Select all

for r, recipe in pairs(game.recipe_prototypes) do
  log({"", "Name: "..r, "\tlocalised_name: "..serpent.line(recipe.localised_name), "\tLocalised name: ", recipe.localised_name})
end
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
LoneWolf_LWP
Inserter
Inserter
Posts: 39
Joined: Thu Jan 07, 2021 11:20 pm
Contact:

Re: Need some help with a script

Post by LoneWolf_LWP »

First of all thank you for your time,

Code: Select all

for r, recipe in pairs(game.recipe_prototypes) do
  log({"", "Name: "..r, "\tlocalised_name: "..serpent.line(recipe.localised_name), "\tLocalised name: ", recipe.localised_name})
end
This indeed works like I would like it to work but it's throwing it in the log file and i'm trying to get it in script-output to get a clean version

it kinda defaulted back to what i have and am struggling with.

this works and shows me what I want
(I removed all working code to isolate this problem)

Code: Select all

for recipeName, recipeData in pairs(game.recipe_prototypes) do
  game.print(recipeData.localised_name)
end
game.print("Done.")
this does not because at first it looked like it gave me a string but now its complaining its a table
I tried tostring(recipeData.localised_name) but that resulted in "table" as a return

Code: Select all

myDB = ""

for recipeName, recipeData in pairs(game.recipe_prototypes) do
  myDB = myDB .. "Name : " .. recipeData.name .. "\n" .. "Localised Name : " .. recipeData.localised_name .. "\n\n"
end

game.write_file("DB_Recipes", myDB)
game.print("Done.")
User avatar
Silari
Filter Inserter
Filter Inserter
Posts: 539
Joined: Sat Jan 27, 2018 10:04 pm
Contact:

Re: Need some help with a script

Post by Silari »

https://lua-api.factorio.com/latest/Lua ... write_file lets you write data out to a file in script-output, log always goes to the log file.

The proper way to make a string representation of a table is using serpent.block(<table>). See https://lua-api.factorio.com/latest/Lib ... ml#serpent
LoneWolf_LWP
Inserter
Inserter
Posts: 39
Joined: Thu Jan 07, 2021 11:20 pm
Contact:

Re: Need some help with a script

Post by LoneWolf_LWP »

Silari wrote: Sat Jan 22, 2022 3:24 pm https://lua-api.factorio.com/latest/Lua ... write_file lets you write data out to a file in script-output, log always goes to the log file.

The proper way to make a string representation of a table is using serpent.block(<table>). See https://lua-api.factorio.com/latest/Lib ... ml#serpent
Thank you i will take a closer look at this.

Right now i found this what i think has the key to the problem

"request_translation (localised_string)" https://lua-api.factorio.com/latest/Lua ... ranslation
"on_string_translated" https://lua-api.factorio.com/latest/eve ... translated
(just trying to find an example on how to use this correctly, i'm still new to this scripting thing)

I can tear this entire recipe up and use it the way i want, but why they don't let us easely take that localised_name as a string baffels me.
Pi-C
Smart Inserter
Smart Inserter
Posts: 1742
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Need some help with a script

Post by Pi-C »

LoneWolf_LWP wrote: Sat Jan 22, 2022 3:46 pm I can tear this entire recipe up and use it the way i want, but why they don't let us easely take that localised_name as a string baffels me.
Because you can't know what will actually be printed when you reference recipe.localised_name in your script. Remember, this is just a placeholder that will be replaced with the string that's appropriate for the user sitting at the keyboard. You could have multiplayer games with people speaking plain English, German, Chinese, or whatever other language the game is localized for. In each instance of the game, the locale files corresponding to the player's language setting will be chosen. You could then consider recipe.localised_name as the key part in a table, and its translation in the locale file as its value. This is great, because as a modder you don't have do to things like

Code: Select all

if player.language == "german" then name = " Mein Rezept" 
elseif player.language == "english" then name = "My recipe"
elseif player.language == "spanish" then name = "Mi receta" 
…
end
But you've got a price to pay for this convenience: You won't know how a string will be translated in every language.

Well. I guess my explanation may be simplified a bit too much. For a better understanding of how localized strings work, you'd better read the Localisation tutorial.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Pi-C
Smart Inserter
Smart Inserter
Posts: 1742
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Need some help with a script

Post by Pi-C »

LoneWolf_LWP wrote: Sat Jan 22, 2022 1:24 pm this works and shows me what I want
(I removed all working code to isolate this problem)

Code: Select all

for recipeName, recipeData in pairs(game.recipe_prototypes) do
  game.print(recipeData.localised_name)
end
game.print("Done.")
This works because recipeData.localised_name is a localised_string, which follows a certain format: If you look at the raw code of recipeData.localised_name (check out CTRL+SHIFT+E in the game to explore a recipe prototype!), it's a table containing a template for the output. Usually, this template will default to just a key name, but there may be parameters as well.
this does not because at first it looked like it gave me a string but now its complaining its a table
I tried tostring(recipeData.localised_name) but that resulted in "table" as a return

Code: Select all

myDB = ""

for recipeName, recipeData in pairs(game.recipe_prototypes) do
  myDB = myDB .. "Name : " .. recipeData.name .. "\n" .. "Localised Name : " .. recipeData.localised_name .. "\n\n"
end

game.write_file("DB_Recipes", myDB)
game.print("Done.")
This won't work because myDB is not a table, but a string that you try to combine with a table. This would work:

Code: Select all

local myDB, append
local cnt = 0
for recipeName, recipeData in pairs(game.recipe_prototypes) do
  myDB = {
   "", 	-- Name of the template. As this is empty, the other table entries will be printed in the order in which they appear
    "Name : " .. recipeData.name .. "\n" .. "Localised Name : ",
     recipeData.localised_name,
      "\n\n"
  }
  append = cnt > 0	-- Create/overwrite the file for the first recipe, or append to file for all other recipes
game.write_file("DB_Recipes", myDB, append)
cnt = cnt + 1  
end

game.print("Done.")
By the way, you also could use another notation to define myDB:

Code: Select all

  myDB = {
   "", 	-- Name of the template is empty
    "Name : ",
     recipeData.name,
      "\n", 
      "Localised Name : ",
     recipeData.localised_name,
      "\n\n"
  }
This way, there's just a sequence of 5 strings and 1 table (recipeData.localised_name) instead of one long concatenated string, one table, and a plain string for the final line breaks. It wouldn't even matter if there was "nil" (or a variable resolving to nil) somewhere -- this would just be ignored in the second notation.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
LoneWolf_LWP
Inserter
Inserter
Posts: 39
Joined: Thu Jan 07, 2021 11:20 pm
Contact:

Re: Need some help with a script

Post by LoneWolf_LWP »

Pi-C wrote: Sat Jan 22, 2022 8:08 pm
LoneWolf_LWP wrote: Sat Jan 22, 2022 3:46 pm I can tear this entire recipe up and use it the way i want, but why they don't let us easely take that localised_name as a string baffels me.
Because you can't know what will actually be printed when you reference recipe.localised_name in your script. Remember, this is just a placeholder that will be replaced with the string that's appropriate for the user sitting at the keyboard. You could have multiplayer games with people speaking plain English, German, Chinese, or whatever other language the game is localized for. In each instance of the game, the locale files corresponding to the player's language setting will be chosen. You could then consider recipe.localised_name as the key part in a table, and its translation in the locale file as its value. This is great, because as a modder you don't have do to things like

Code: Select all

if player.language == "german" then name = " Mein Rezept" 
elseif player.language == "english" then name = "My recipe"
elseif player.language == "spanish" then name = "Mi receta" 
…
end
But you've got a price to pay for this convenience: You won't know how a string will be translated in every language.

Well. I guess my explanation may be simplified a bit too much. For a better understanding of how localized strings work, you'd better read the Localisation tutorial.
I understand what you say.

and no excuse, but this is a peronal script, not a mod. intended to be used only by me, not multiplayer.

but still.
Its hard to accept (even though you are probably 100% right) when seeing it been printed when using the console that it's not available to me as a string variant. i mean, at that moment its producing the string, right?
So i kinda already stepped away after to much lost time, on something so trivial.

I'm now busy writing a program to post process the log file (that magicly "can do it", but is full of other junk that i need to filter out)
So i can better spend the time doing that then finding this solution that apperantly is impossible?
I have searched all day and everywhere its a dead end for those who looked for the same solution or people claiming its possible but not providing a working example even once.

Thanks to everybody that contributed in trying to find a solution.
LoneWolf_LWP
Inserter
Inserter
Posts: 39
Joined: Thu Jan 07, 2021 11:20 pm
Contact:

Re: Need some help with a script

Post by LoneWolf_LWP »

Pi-C wrote: Sat Jan 22, 2022 8:34 pm
LoneWolf_LWP wrote: Sat Jan 22, 2022 1:24 pm this works and shows me what I want
(I removed all working code to isolate this problem)

Code: Select all

for recipeName, recipeData in pairs(game.recipe_prototypes) do
  game.print(recipeData.localised_name)
end
game.print("Done.")
This works because recipeData.localised_name is a localised_string, which follows a certain format: If you look at the raw code of recipeData.localised_name (check out CTRL+SHIFT+E in the game to explore a recipe prototype!), it's a table containing a template for the output. Usually, this template will default to just a key name, but there may be parameters as well.
this does not because at first it looked like it gave me a string but now its complaining its a table
I tried tostring(recipeData.localised_name) but that resulted in "table" as a return

Code: Select all

myDB = ""

for recipeName, recipeData in pairs(game.recipe_prototypes) do
  myDB = myDB .. "Name : " .. recipeData.name .. "\n" .. "Localised Name : " .. recipeData.localised_name .. "\n\n"
end

game.write_file("DB_Recipes", myDB)
game.print("Done.")
This won't work because myDB is not a table, but a string that you try to combine with a table. This would work:

Code: Select all

local myDB, append
local cnt = 0
for recipeName, recipeData in pairs(game.recipe_prototypes) do
  myDB = {
   "", 	-- Name of the template. As this is empty, the other table entries will be printed in the order in which they appear
    "Name : " .. recipeData.name .. "\n" .. "Localised Name : ",
     recipeData.localised_name,
      "\n\n"
  }
  append = cnt > 0	-- Create/overwrite the file for the first recipe, or append to file for all other recipes
game.write_file("DB_Recipes", myDB, append)
cnt = cnt + 1  
end

game.print("Done.")
By the way, you also could use another notation to define myDB:

Code: Select all

  myDB = {
   "", 	-- Name of the template is empty
    "Name : ",
     recipeData.name,
      "\n", 
      "Localised Name : ",
     recipeData.localised_name,
      "\n\n"
  }
This way, there's just a sequence of 5 strings and 1 table (recipeData.localised_name) instead of one long concatenated string, one table, and a plain string for the final line breaks. It wouldn't even matter if there was "nil" (or a variable resolving to nil) somewhere -- this would just be ignored in the second notation.
Ok we both replied at the same time. i'll take a look at this and see if i could make this work and understand for the entire thing.

Thank you
LoneWolf_LWP
Inserter
Inserter
Posts: 39
Joined: Thu Jan 07, 2021 11:20 pm
Contact:

Re: Need some help with a script

Post by LoneWolf_LWP »

Pi-C wrote: Sat Jan 22, 2022 8:34 pm This won't work because myDB is not a table, but a string that you try to combine with a table. This would work:

Code: Select all

local myDB, append
local cnt = 0
for recipeName, recipeData in pairs(game.recipe_prototypes) do
  myDB = {
   "", 	-- Name of the template. As this is empty, the other table entries will be printed in the order in which they appear
    "Name : " .. recipeData.name .. "\n" .. "Localised Name : ",
     recipeData.localised_name,
      "\n\n"
  }
  append = cnt > 0	-- Create/overwrite the file for the first recipe, or append to file for all other recipes
game.write_file("DB_Recipes", myDB, append)
cnt = cnt + 1  
end

game.print("Done.")
OMG, yes this is it, thank you so much, I will inspect this until i understand how this excalty works. And start reforming the parts i have to work with this way then.
Thank you so much.
Post Reply

Return to “Ideas and Requests For Mods”