Page 1 of 1

Updated documentation of the MOD Factorio Library

Posted: Mon Jan 16, 2023 4:48 am
by yaim904
Hello, I hope everyone is well.
I need your help to understand how to use the MOD Factorio Library.
I want to use the directory, the translation and the GUI, maybe something else; but I can't find an updated manual on how to use it.

I have reviewed various mods that use them, hoping to learn from them, but they are too complex, I require something simpler. This is an example of what I expect to find and this is the manual I tried.

I have to clarify that with the translation I also expect to see the translated text indicator in the corner of the screen.

I appreciate any help you can give me.

Re: Updated documentation of the MOD Factorio Library

Posted: Mon Jan 16, 2023 11:55 am
by Stringweasel
Best is usually to show what you have tried, otherwise it's hard to know how to help.

Re: Updated documentation of the MOD Factorio Library

Posted: Mon Jan 16, 2023 1:28 pm
by yaim904
I literally have zero knowledge of how to use the Factorio Library.

Take the simplest example and let's explain.

For example:
When I try to use the directory example shown in the documentation, I get an error.
Captura de pantalla (10).png
Captura de pantalla (10).png (1.01 MiB) Viewed 2627 times

Re: Updated documentation of the MOD Factorio Library

Posted: Mon Jan 16, 2023 2:32 pm
by Stringweasel
Best would be to show your code as well, otherwise we still can't see what you're doing.
yaim904 wrote: Mon Jan 16, 2023 1:28 pm I literally have zero knowledge of how to use the Factorio Library.
That's usually the case when you start learning a new skill :)

It's likely that dictionary.init() is never called, because flib looking for a variable that doesn't exist in the global table, and it should be initialized here. Are you creating a new save? Or added it to an existing one? As in the example you need to add dictionary.init() to event.on_init and event.on_configuration_changed.

Re: Updated documentation of the MOD Factorio Library

Posted: Tue Jan 17, 2023 12:16 pm
by sfyb
I had a similar problem like you.
While the example at https://factoriolib.github.io/flib/exam ... y.lua.html worked in single player it caused an instant de-sync in multi-player.

I managed to adapt the demo code so it works and does not de-sync.
The only changes I had to make were:
  • Change the dictionary to use local storage ("dictionary.set_use_local_storage(true)")
  • Save the protoypes I want to translate and iterate over those (you dont have access to game protoypes in the "on_load" event but you need to know what you want to translate in this event)
Here is the changed demo code.
I hope this helped you!

Code: Select all

local dictionary = require("__flib__.dictionary")
dictionary.set_use_local_storage(true)

local event = require("__flib__.event")
local migration = require("__flib__.migration")
local table = require("__flib__.table")

-- this is used in on_string_translated to store the translated dictionaries
global.player_dictionaries = {}

local types_to_translate = {"entity", "fluid", "item", "recipe", "technology", "tile"}

local function create_demo_dicts()
    for _, type in pairs(types_to_translate) do
        -- If the object's name doesn't have a translation, use its internal name as the translation
        local Names = dictionary.new(type.."_names", true)
        -- If a description doesn't exist, it won't exist in the resulting dictionary either
        local Descriptions = dictionary.new(type.."_descriptions")
        
        
        for name, prototype in pairs(global.prototypes[type]) do
            if prototype.valid then
                Names:add(name, prototype.localised_name)
                Descriptions:add(name, prototype.localised_description)
            end
        end
    end
end

local function init()
    -- Initialize the module
    dictionary.init()

    
    -- copy the prototypes we want to translate so we have access to them in the "on_load" event
    -- it is also possible to just save the localised_name and localised_description instead of the prototype
    -- Note: I am not exactly sure how factorio handles prototypes. 
    -- It might be possible they are just mapped back to the factorio prototype instead of completly copied when copied,
    -- in which case this is the better option (because we only save refernces,
    -- which are quite small compared to multiple strings)
    -- But again: I am not sure
    global.prototypes = {}
    
    for _, type in pairs(types_to_translate) do
        global.prototypes[type] = table.shallow_copy(game[type .. "_prototypes"])
    end
    
    create_demo_dicts()
end

event.on_init(init)

event.on_load(function ()
    dictionary.load()
    
    create_demo_dicts()
end)

event.on_configuration_changed(function(e)
  if migration.on_config_changed(e, {}) then
    -- Reset the module to effectively cancel all ongoing translations and wipe all dictionaries

    -- also I am lazy
    init()

    -- Request translations for all connected players
    for _, player in pairs(game.players) do
        if player.connected then
            dictionary.translate(player)
        end
    end
  end
end)

event.on_player_created(function(e)
    local player = game.get_player(e.player_index)
    -- Only translate if they're connected - if they're not, then it will not work!
    if player.connected then
        dictionary.translate(player)
    end
end)

event.on_player_joined_game(function(e)
    -- This serves two purposes: To translate the player's initial dictionaries, and to update the language if they player
    -- switched locales.
    dictionary.translate(game.get_player(e.player_index))
end)

event.on_player_left_game(function(e)
    -- If the player was actively translating, cancel it and hand it off to another player (if any).
    dictionary.cancel_translation(e.player_index)
end)

event.on_tick(dictionary.check_skipped)

event.on_string_translated(function(e)
    local language_data = dictionary.process_translation(e)
    if language_data then
        for _, player_index in pairs(language_data.players) do
            -- the dictionaries are stored in global.player_dictionaries and accessed by player player index
            -- this can be changed to fit your needs
            global.player_dictionaries[player_index] = language_data.dictionaries
            game.print("Player "..player_index.." now has dictionaries for their language!")
        end
    end
end)

Re: Updated documentation of the MOD Factorio Library

Posted: Tue Jan 17, 2023 12:50 pm
by Xorimuth
sfyb wrote: Tue Jan 17, 2023 12:16 pm I had a similar problem like you.
While the example at https://factoriolib.github.io/flib/exam ... y.lua.html worked in single player it caused an instant de-sync in multi-player.

I managed to adapt the demo code so it works and does not de-sync.
The only changes I had to make were:
  • Change the dictionary to use local storage ("dictionary.set_use_local_storage(true)")
  • Save the protoypes I want to translate and iterate over those (you dont have access to game protoypes in the "on_load" event but you need to know what you want to translate in this event)
Here is the changed demo code.
I hope this helped you!

Code: Select all

local dictionary = require("__flib__.dictionary")
dictionary.set_use_local_storage(true)

local event = require("__flib__.event")
local migration = require("__flib__.migration")
local table = require("__flib__.table")

-- this is used in on_string_translated to store the translated dictionaries
global.player_dictionaries = {}

local types_to_translate = {"entity", "fluid", "item", "recipe", "technology", "tile"}

local function create_demo_dicts()
    for _, type in pairs(types_to_translate) do
        -- If the object's name doesn't have a translation, use its internal name as the translation
        local Names = dictionary.new(type.."_names", true)
        -- If a description doesn't exist, it won't exist in the resulting dictionary either
        local Descriptions = dictionary.new(type.."_descriptions")
        
        
        for name, prototype in pairs(global.prototypes[type]) do
            if prototype.valid then
                Names:add(name, prototype.localised_name)
                Descriptions:add(name, prototype.localised_description)
            end
        end
    end
end

local function init()
    -- Initialize the module
    dictionary.init()

    
    -- copy the prototypes we want to translate so we have access to them in the "on_load" event
    -- it is also possible to just save the localised_name and localised_description instead of the prototype
    -- Note: I am not exactly sure how factorio handles prototypes. 
    -- It might be possible they are just mapped back to the factorio prototype instead of completly copied when copied,
    -- in which case this is the better option (because we only save refernces,
    -- which are quite small compared to multiple strings)
    -- But again: I am not sure
    global.prototypes = {}
    
    for _, type in pairs(types_to_translate) do
        global.prototypes[type] = table.shallow_copy(game[type .. "_prototypes"])
    end
    
    create_demo_dicts()
end

event.on_init(init)

event.on_load(function ()
    dictionary.load()
    
    create_demo_dicts()
end)

event.on_configuration_changed(function(e)
  if migration.on_config_changed(e, {}) then
    -- Reset the module to effectively cancel all ongoing translations and wipe all dictionaries

    -- also I am lazy
    init()

    -- Request translations for all connected players
    for _, player in pairs(game.players) do
        if player.connected then
            dictionary.translate(player)
        end
    end
  end
end)

event.on_player_created(function(e)
    local player = game.get_player(e.player_index)
    -- Only translate if they're connected - if they're not, then it will not work!
    if player.connected then
        dictionary.translate(player)
    end
end)

event.on_player_joined_game(function(e)
    -- This serves two purposes: To translate the player's initial dictionaries, and to update the language if they player
    -- switched locales.
    dictionary.translate(game.get_player(e.player_index))
end)

event.on_player_left_game(function(e)
    -- If the player was actively translating, cancel it and hand it off to another player (if any).
    dictionary.cancel_translation(e.player_index)
end)

event.on_tick(dictionary.check_skipped)

event.on_string_translated(function(e)
    local language_data = dictionary.process_translation(e)
    if language_data then
        for _, player_index in pairs(language_data.players) do
            -- the dictionaries are stored in global.player_dictionaries and accessed by player player index
            -- this can be changed to fit your needs
            global.player_dictionaries[player_index] = language_data.dictionaries
            game.print("Player "..player_index.." now has dictionaries for their language!")
        end
    end
end)
You should really be using dictionary-lite as the dictionary module is deprecated :)

Re: Updated documentation of the MOD Factorio Library

Posted: Tue Jan 17, 2023 1:25 pm
by sfyb
I appreciate the advice. But for one this isn't about me and they specifically requested help with the "dictionary" module not "dictionary-lite"
yaim904 wrote: Mon Jan 16, 2023 1:28 pm For example:
When I try to use the directory example shown in the documentation, I get an error.
Also "dictionary-lite" is not available in all of the versions of flib I want to support.
I think this is enough of a sidetrack for this post.

Re: Updated documentation of the MOD Factorio Library

Posted: Sun Jan 22, 2023 3:35 pm
by yaim904
I already found how to use the dictionary
I'm not very clear how it works, but for now it works.
I don't know how it would work in multiplayer.
Just embed the sample code.

Now what I don't know how to do is take the name of the MOD in the "window" that is displayed.
(294).png
(294).png (7.54 KiB) Viewed 2432 times

Re: Updated documentation of the MOD Factorio Library

Posted: Sun Jan 22, 2023 3:48 pm
by Stringweasel
yaim904 wrote: Sun Jan 22, 2023 3:35 pm
I already found how to use the dictionary
I'm not very clear how it works, but for now it works.
I don't know how it would work in multiplayer.
Just embed the sample code.

Now what I don't know how to do is take the name of the MOD in the "window" that is displayed.
(294).png
Pretty sure you define that in the locale files like this:
https://github.com/ClaudeMetz/FactoryPl ... .cfg#L1-L2

Re: Updated documentation of the MOD Factorio Library

Posted: Sun Jan 22, 2023 4:49 pm
by yaim904
Stringweasel wrote: Sun Jan 22, 2023 3:48 pm Pretty sure you define that in the locale files like this:
https://github.com/ClaudeMetz/FactoryPl ... .cfg#L1-L2
I tried that and it didn't work.
(295).png
(295).png (3.89 KiB) Viewed 2417 times
What am I doing wrong??

Re: Updated documentation of the MOD Factorio Library

Posted: Sun Jan 22, 2023 5:15 pm
by Stringweasel
yaim904 wrote: Sun Jan 22, 2023 4:49 pm
Stringweasel wrote: Sun Jan 22, 2023 3:48 pm Pretty sure you define that in the locale files like this:
https://github.com/ClaudeMetz/FactoryPl ... .cfg#L1-L2
I tried that and it didn't work.
(295).png
What am I doing wrong??

Did you add it to the locale file of the language you have selected? But if it's not that then I don't know :)

Re: Updated documentation of the MOD Factorio Library

Posted: Mon Jan 23, 2023 2:08 am
by yaim904
Stringweasel wrote: Sun Jan 22, 2023 5:15 pm Did you add it to the locale file of the language you have selected? But if it's not that then I don't know :)
I added it where are all the translations I have

Code: Select all

zzYAIM_0.0.2\locale\en\base.cfg
zzYAIM_0.0.2\locale\es-ES\base.cfg
(295).png
(295).png (84.22 KiB) Viewed 2383 times
It didn't work

Re: Updated documentation of the MOD Factorio Library

Posted: Wed Feb 01, 2023 11:02 pm
by yaim904
HELP!!