Questions on GUI creation from a fresh modder

Place to get help with not working mods / modding interface.
Post Reply
eduran
Filter Inserter
Filter Inserter
Posts: 344
Joined: Fri May 09, 2014 2:52 pm
Contact:

Questions on GUI creation from a fresh modder

Post by eduran »

A few days ago, I started working on a mod. It's my first contact with Factorio modding and LUA. The purpose is to create a GUI displaying some information I would like to be able to see at a glance.
Data collection and a bare-bones version of the GUI work already. Before continuing, I would like to ask a few questions, mostly about best-practice when it comes to GUIs in Factorio.

1. I want to be able to toggle the UI on and off. Most mods I looked at seem to implement that by calling destroy() on their UI's top-most element and rebuild it when needed. My intuitive approach would have been to build it just once on init and use the style.visible property to show and hide. Which approach is better and why? Are invisible GUI elements properly persisted through save/load? Do invisible GUI elements impact performance?

2. What is the best way to reference and modify existing UI elements? Should I store a reference to that element in global (potentially for every player, if multiplayer were to ever become an issue)? Or a "path", i.e. a chain of parent elements? What is the most efficient way to update ~20 different label captions, spread over several UI elements?

3. Is there a way to reorder cells in a table after creation? I would like to delete or replace rows. So far, the best way seems to be to clear the entire table and populate it from scratch.

4. Is the built-in tabbed pane (used to display production statistics) available to modders? style.lua has an entry for a tabbed_pane_style, but the documentation for LuaGuiElement does not list anything like it.

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5150
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: Questions on GUI creation from a fresh modder

Post by Klonan »

1. I want to be able to toggle the UI on and off. Most mods I looked at seem to implement that by calling destroy() on their UI's top-most element and rebuild it when needed. My intuitive approach would have been to build it just once on init and use the style.visible property to show and hide. Which approach is better and why? Are invisible GUI elements properly persisted through save/load? Do invisible GUI elements impact performance?
I prefer implementing a GUI with 3 functions, a create, update, and a destroy.
Create will check if it exists, if it doesn't it creates the GUI, if it already exsits, its fine. Then it calls the update function.
The update, will check if the GUI exists, if it does, update it, if not, do nothing.
Destroy will, check is it exists and if so, destroy it.
Some times, I use a toggle instead of create and destroy, which works best for the GUI buttons people can click, the toggle just checks, if it exists, destroy it, otherwise, create it.

The reason for this, is that its much easier to recreate the GUI will all updated values, than to try to hold a reference or navigate to those specific labels and widgets and change their values.
Also if you change you GUI, all you will need to do is call refresh and the layout will be with the new code.
2. What is the best way to reference and modify existing UI elements? Should I store a reference to that element in global (potentially for every player, if multiplayer were to ever become an issue)? Or a "path", i.e. a chain of parent elements? What is the most efficient way to update ~20 different label captions, spread over several UI elements?
Recently I have started using a new system of registering GUI actions, when I add them to a global table with an associated function and values.
I call register GUI action after creating the element,
And unregister when I go to delete it.
Then on the GUI event, I check if there is a GUI with that player and GUI index in the global.gui_actions table, and if so, run the associated event with the stored global data.

To update 20 different labels, it is easy to specifically put them in a list when they are created, and then loop through and update them all at once, instead of trying to navigate through each player and the parent GUI's.
3. Is there a way to reorder cells in a table after creation? I would like to delete or replace rows. So far, the best way seems to be to clear the entire table and populate it from scratch.
No, destroying and recreating is the only way so far.
4. Is the built-in tabbed pane (used to display production statistics) available to modders? style.lua has an entry for a tabbed_pane_style, but the documentation for LuaGuiElement does not list anything like it.
It is not, the internals in the core engine were too irregular to be easily added to the mod gui. This might change in the future, and if so, it will be lsited in the docs and changelog.

eduran
Filter Inserter
Filter Inserter
Posts: 344
Joined: Fri May 09, 2014 2:52 pm
Contact:

Re: Questions on GUI creation from a fresh modder

Post by eduran »

Thank you, that is very helpful.
Klonan wrote:
Wed Jan 23, 2019 1:16 pm
Recently I have started using a new system of registering GUI actions, when I add them to a global table with an associated function and values.
I call register GUI action after creating the element,
And unregister when I go to delete it.
Then on the GUI event, I check if there is a GUI with that player and GUI index in the global.gui_actions table, and if so, run the associated event with the stored global data.
With that approach, do you need to worry about the number of gui elements registered? Imagine a table listing all train stations with name and some other information. When a station name is clicked, the stations GUI should open. In a large factory that would lead to registering a large number of labels.
Alternatively, I could give them a fixed, indexed name like <my_mod_button_NNN> and do a string match in the event handler.

Is any of those methods faster? Does a large global table cause problems (and if so, what counts as large)? Should I just think about what's easier to code and maintain and ignore performance?

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5150
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: Questions on GUI creation from a fresh modder

Post by Klonan »

eduran wrote:
Wed Jan 23, 2019 4:45 pm
With that approach, do you need to worry about the number of gui elements registered? Imagine a table listing all train stations with name and some other information. When a station name is clicked, the stations GUI should open. In a large factory that would lead to registering a large number of labels.
Alternatively, I could give them a fixed, indexed name like <my_mod_button_NNN> and do a string match in the event handler.

Is any of those methods faster? Does a large global table cause problems (and if so, what counts as large)? Should I just think about what's easier to code and maintain and ignore performance?
You're not reallly going to notice a difference,
Do whatever makes it most readable, maintanable and workable for you

eduran
Filter Inserter
Filter Inserter
Posts: 344
Joined: Fri May 09, 2014 2:52 pm
Contact:

Re: Questions on GUI creation from a fresh modder

Post by eduran »

A few more:

1. Is it possible to make an entire row in a table clickable? Ideally, the row should be highlighted on mouseover. There is a table_with_selection style, but it doesn't actually allow any kind of selection.
2. Alternatively, is it possible to register clicks / mouseover through GuiElements, triggering the one in the back? The minimap buttons in the train menu for example light up even if the mouse is over the minimap part covering the button.
3. Would running a headless server and joining it as the sole player allow me to test for multiplayer desyncs?
4. Are names for LuaGuiElements shared between mods? Will my lua instance register clicks on UI elements created by other mods?

User avatar
Therenas
Factorio Staff
Factorio Staff
Posts: 232
Joined: Tue Dec 11, 2018 2:10 pm
Contact:

Re: Questions on GUI creation from a fresh modder

Post by Therenas »

eduran wrote:
Sun Jan 27, 2019 6:49 pm
A few more:

1. Is it possible to make an entire row in a table clickable? Ideally, the row should be highlighted on mouseover. There is a table_with_selection style, but it doesn't actually allow any kind of selection.
2. Alternatively, is it possible to register clicks / mouseover through GuiElements, triggering the one in the back? The minimap buttons in the train menu for example light up even if the mouse is over the minimap part covering the button.
3. Would running a headless server and joining it as the sole player allow me to test for multiplayer desyncs?
4. Are names for LuaGuiElements shared between mods? Will my lua instance register clicks on UI elements created by other mods?
I can answer some of those:
1. It's not really possible with stock UI elements, you would need to really hack around it to get some semblance of what you want.
2. Yes, take a look at LuaGuiElement.ignored_by_interaction. If you set that to true on any element, the click goes 'through' it as if it wasn't there.
3. Would like to know that too.
4. Yes, they are. You can't for example add a new element to gui.center if there already is one with that name, even from another mod. So prefixes are encouraged. For listeners, it is the same way. All button-clicks (for example) go out to the appropriate listener of every mod. So if two mods listen for the same button-name, for example, they will both react.

eduran
Filter Inserter
Filter Inserter
Posts: 344
Joined: Fri May 09, 2014 2:52 pm
Contact:

Re: Questions on GUI creation from a fresh modder

Post by eduran »

Thanks, especially for your answer to my second question. I overlooked that property.

User avatar
Therenas
Factorio Staff
Factorio Staff
Posts: 232
Joined: Tue Dec 11, 2018 2:10 pm
Contact:

Re: Questions on GUI creation from a fresh modder

Post by Therenas »

eduran wrote:
Sun Feb 03, 2019 7:17 pm
Thanks, especially for your answer to my second question. I overlooked that property.
No problem! I have given your first question some thought, and I might need something like that soon in a project I'm working on, so if I come up with anything, I will let you know.

Post Reply

Return to “Modding help”