How do you create a common gui if possible ?

Place to get help with not working mods / modding interface.
Post Reply
Masamune00
Inserter
Inserter
Posts: 27
Joined: Sat Nov 26, 2016 11:48 am
Contact:

How do you create a common gui if possible ?

Post by Masamune00 »

Hello everyone,

I'm developing on a mod and I've an issue in my scenario, sometimes in the server I get like 40 players that are playing, the issue is that the GUI is updated frequently which generates a lot of calls because you need to the update of gui to same value 40 times (bad for perf late game with all that is happening around it too).

My idea to avoid that issue was to create a common gui, but I can't figure out how to make one, and if it's ever possible... Any idea? I just want to initialize in the end a variable as a luagui so other players gui points to it.

I've tried things like that :

Code: Select all

/c global.common_gui= {}
/c global.common_gui.add  {name="test",type = "label", caption = "Threat: "}
It didn't work obviously (error cant add to nil)

I've also tried things like that :

Code: Select all

/c global.common_gui = LuaGui 
But it doesnt' work too.

And my idea was then once I've this common gui variable, I could just do something along this line for the elements that are frequently updated :

Code: Select all

for player in players
  player.gui = global.common_gui
end
The goal is in the end is to improve performance even more, gui being one of the top issues.

Thanks in advance,
Masamune

robot256
Filter Inserter
Filter Inserter
Posts: 596
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Re: How do you create a common gui if possible ?

Post by robot256 »

When you update all 40 guis, are you recreating all of them from scratch? Or can you just change the text in a preexisting element, for example? You can do this if you store a handle to a particular LuaGuiElement object within each player's gui.

The other way to reduce lag is to not update every player on every tick, and spread them out over multiple ticks if there are many players.

Pi-C
Smart Inserter
Smart Inserter
Posts: 1654
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: How do you create a common gui if possible ?

Post by Pi-C »

Masamune00 wrote:
Sun Aug 28, 2022 12:03 pm
Hello everyone,

I'm developing on a mod and I've an issue in my scenario, sometimes in the server I get like 40 players that are playing, the issue is that the GUI is updated frequently which generates a lot of calls because you need to the update of gui to same value 40 times (bad for perf late game with all that is happening around it too).

My idea to avoid that issue was to create a common gui, but I can't figure out how to make one, and if it's ever possible... Any idea? I just want to initialize in the end a variable as a luagui so other players gui points to it.
I believe that you can't have a common GUI shared between multiple players, for quite obvious reasons: If everybody used the same GUI, individual players couldn't close it or move it around on the screen -- if one player closed the GUI, it would be closed for all players. So I'm afraid you're stuck with having to update 40 different GUIs.

However, you can optimize how the GUIs are updated. When I first dappled with GUIs, my way of updating them was to destroy and rebuild everything. That was foolproof because I could be sure that I wouldn't miss to update an element that depended on the state of another GUI element -- but it certainly wasn't efficient.

Now, for one of my mods I've made a GUI where information on vehicles is presented in a table, with each vehicle occupying a line with several elements. The names for the elements (i.e. the table colums) are defined in another table:

Code: Select all

select_area.table_columns = {
  -- Vehicle list
  icon                                  = select_area_prefix.."vehicle_list_icon_",
  proto_name                            = select_area_prefix.."vehicle_list_prototype_name_",
  id                                    = select_area_prefix.."vehicle_list_id_",
  owner                                 = select_area_prefix.."vehicle_list_owner_",
  locker                                = select_area_prefix.."vehicle_list_locker_",
  toggle_lock                           = select_area_prefix.."vehicle_list_toggle_lock_",
  toggle_owned                          = select_area_prefix.."vehicle_list_toggle_owned_",
}
When I add a vehicle, I create the new GUI elements by using the predefined column names and appending the vehicle's unit_number. In other words, I've got predictable name patterns and unique names. Now it may happen that another mod swaps out vehicles: destroying the old entity and creating a new one. Naturally, the new entity will have a new unit_number, so I must update my GUIs. So what's a good way to do that?

Obviously, rebuilding a list of 20 vehicles just because one vehicle has been changed doesn't cut it. But with the GUI elements having predictable + unique names, I'm in a position where I can comfortably select all elements that belong to a specific vehicle. So, I could do something like this:

Code: Select all

    for c, column in pairs(column_names) do
      if gui_table[column..old_id] and gui_table[column..old_id].valid then
        gui_table[column..old_id].destroy()
	gui_table[column..new_id] = gui_table.add{ … }
      end
    end
That's definitely more efficient than rebuilding everything, but it has a major flaw: The new elements will be created at the end of the table, so whenever a vehicle is swapped, it will change its position in the table -- something which wouldn't have happened when I rebuilt the GUI from scratch. So, anything we could do about it?

There is, and it is possible because LuaGuiElement.name is NOT the actual identifier of an element! According to the APi description, LuaGuiElement.index is "the index of this GUI element (unique amongst the GUI elements of a LuaPlayer)". What this really means is, you can change LuaGuiElement.name just like LuaGuiElement.enabled, LuaGuiElement.state, LuaGuiElement.visible, etc. This also means that if you change just the name, you won't have to worry about updating the other properties -- they will stay as they are! So, I swap vehicles on my GUI like this:

Code: Select all

    for c, column in pairs(column_names) do
      old_name = column..old_id
      new_name = column..new_id

      if gui_table[old_name] and gui_table[old_name].valid then
        gui_table[old_name].name = new_name

      end
    end
Quite neat, isn't it? Of course, I don't know if that would be possible with your GUI as well, but perhaps you may get some ideas from it. :-)
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!

Masamune00
Inserter
Inserter
Posts: 27
Joined: Sat Nov 26, 2016 11:48 am
Contact:

Re: How do you create a common gui if possible ?

Post by Masamune00 »

Thanks a lot for your input ! I will try what you said.

Yes we had destroy at the beginning, but now that we removed it, it's much better.

Post Reply

Return to “Modding help”