Usage of mod-gui

Place to get help with not working mods / modding interface.
Post Reply
JasonMiles
Burner Inserter
Burner Inserter
Posts: 15
Joined: Thu Sep 21, 2017 9:28 am
Contact:

Usage of mod-gui

Post by JasonMiles »

Hi,

I'm currently working on a library/framework to make automated testing for Factorio mods possible and easy (inspired by the stdlib project). You can find the first version here: https://github.com/JonasJurczok/faketorio

The question I have is:
Is anyone using mod-gui for the UI in their mods? I could not find anything about it in the forums and nothing on the internet except the blogpost where it was announced.

If I'm the only user of this thing I'll just drop support for it and not go through the (legal) hassle of providing a copy of it with faketorio.

Thanks for your responses :D

Bilka
Factorio Staff
Factorio Staff
Posts: 3128
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Usage of mod-gui

Post by Bilka »

viewtopic.php?f=25&t=53020
Bilka wrote:Here is something that I explained Blank a few weeks ago, and he said that it helped, so here you go:
There is also the mod gui, which adds a flow in the gui.left space for buttons and gui. I'd suggest you to use that. For that you access the button flow using: mod_gui.get_button_flow(player). (You need to do require("mod-gui") at the top of the file). You can access the normal flow, where you will place your gui window using: mod_gui.get_frame_flow(player). To add a gui element, you simply add it to the parent gui, so in your case, the frame flow.
That was mostly what I explained. For more info, definitely have a look at the api doc (LuaGui,LuaGuiElement, LuaStyle). I personally learned gui mostly by looking at this mod and I used Klonan's upgrade planner to learn how to use the mod gui. The mod-gui file in core/lualib also has some documentation to it though. You can see the fruits of my work in the New game+ mod, most of the code is at least somewhat commented, so it should be understandable.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

JasonMiles
Burner Inserter
Burner Inserter
Posts: 15
Joined: Thu Sep 21, 2017 9:28 am
Contact:

Re: Usage of mod-gui

Post by JasonMiles »

Hey,

thanks for the explanation. I know how mod-gui works and I'm actively using it.
The question is: Is anyone else using it?

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Usage of mod-gui

Post by eradicator »

JasonMiles wrote: The question is: Is anyone else using it?
Can't answer for everybody else ofc but personally i'm not using it. Mostly because never seen any screenshots of it (let alone a comparison with/without) thus i don't even know what it looks like or how it works with custom logic. And second mostly because based on the descriptions in FFFs i suspect that - my usual gui endavors not being a simple button or two in a corner - it wouldn't have any benefits for me.

You say you're using it, got any pictures/links?

Also being a stranger to automatic testing :oops: i'd probably need a pretty detailed manual to get it working.../cough.
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.

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Usage of mod-gui

Post by bobingabout »

I don't even know what mod-gui is, I just used game knowledge to write my own GUI for my inserters mod.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

JasonMiles
Burner Inserter
Burner Inserter
Posts: 15
Joined: Thu Sep 21, 2017 9:28 am
Contact:

Re: Usage of mod-gui

Post by JasonMiles »

I somehow missed the notification for posts in this thread -.-

I completely rewrote faketorio by now. It is now running inside of Factorio and thus you can do whatever you want/could do anyway.

Automated testing basically removes the long and error prone phase of testing everything in your mod after you changed something.
If your mod is a little more complex it is very likely that you forget an edge case and the ONE TIME you don't test that the small change that could not possibly break anything breaks exactly this.

Automated testing allows you to test every single feature every single time simply because the test run is extremely fast.

We are currently using it for Todo-List. It really helps because instead of needing to remember every small detail we added over time I can run the tests and in under 1 second I have an answer if I broke anything else.
You can find examples for tests here (in the *_feature files).

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Usage of mod-gui

Post by eradicator »

Hi there! It's me, the noob coder :). From a quick look at the explanation page i have a few thought that are hopefully useful insigts into how other people code. If not feel free to ignore ^^.

@click
faketorio.click(name)

To interact with your mod you need to be able to click on things ;) This is what the click function is for. The name parameter is the name of your gui element.

Faketorio will search through the four guis (left, top, center, goal) of the first player in the players list. If an element with the provided name is found it will raise an event for this element.

Currently only left mouse button clicks without modifiers (shift, alt, control) are supported.
Is that up to date? Because i'm afraid that's far too limited to be of any use for my guis. Click-testing is certainly the most interesting aspect. But, even ignoring the major restriction of only being able to test straight left-clicks: Gui elements do not have unique names, another mod might even be using the same name for something (like an "ok" button being named "ok") without me knowing it. If they have names at all (might just be numeric), and i might not even know the name even if it has a name because it's automatically generated. Tl;dr: How about "click any child of this" or "click any child and then any child of that (etc)". And probably the ability to supply a LuaGuiElement directly.

@mocks:
Trying to understand how that is supposed to work, staring at the example for far too long....

Code: Select all

function myMod.is_setting_enabled(player)
    return settings.get_player_settings(player)["my-mod-setting"].value
end
Think, think, think...so...it only works if i have a singular function for every mod setting? Because i don't. They're buried into other functions, if they're "static" values they might be in some sort of messable-with cache structure, but mostly they will be used directly.

Here's an example from one of my mods:

Code: Select all

local function set_render_mode(p,mode)
  --*snip*
  local s = settings.get_player_settings(p)
  s = {
    --read only options
    bars       = s['number-of-bars'     ] .value, --int
    slots      = s['slots-per-bar'      ] .value, --int
    bshift     = s['bottom-shift'       ] .value, --int
    rshift     = s['right-shift'        ] .value, --int
    sgroupsize = s['slot-group-size'    ] .value, --int
    bgroupsize = s['bar-group-size'     ] .value, --int
    horizontal = s['bar-horizontal-mode'] .value, --bool
    }
  --*snip
  end*
I guess i could outsource and parametrize the whole thing into function set_render_mode(p,mode,make_settings(p)), would that work then? It'd still be changing code just to make it testable (hm..and make_settings would still need to be exposed to the global scope so you can overwrite it, which is not something i'm willing to do). Ideally there would be some randomization on the values required too. So it sounds easier to change the actual mod-settings.dat and restart the game each time, that way you can test startup settings too.
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.

JasonMiles
Burner Inserter
Burner Inserter
Posts: 15
Joined: Thu Sep 21, 2017 9:28 am
Contact:

Re: Usage of mod-gui

Post by JasonMiles »

Hey :)
Thanks for the input. Somehow I still don't get full notifications for everything here in the forum :/
eradicator wrote:
Wed Oct 31, 2018 10:14 am
Hi there! It's me, the noob coder :). From a quick look at the explanation page i have a few thought that are hopefully useful insigts into how other people code. If not feel free to ignore ^^.

@click
faketorio.click(name)

To interact with your mod you need to be able to click on things ;) This is what the click function is for. The name parameter is the name of your gui element.

Faketorio will search through the four guis (left, top, center, goal) of the first player in the players list. If an element with the provided name is found it will raise an event for this element.

Currently only left mouse button clicks without modifiers (shift, alt, control) are supported.
Is that up to date? Because i'm afraid that's far too limited to be of any use for my guis. Click-testing is certainly the most interesting aspect. But, even ignoring the major restriction of only being able to test straight left-clicks: Gui elements do not have unique names, another mod might even be using the same name for something (like an "ok" button being named "ok") without me knowing it. If they have names at all (might just be numeric), and i might not even know the name even if it has a name because it's automatically generated. Tl;dr: How about "click any child of this" or "click any child and then any child of that (etc)". And probably the ability to supply a LuaGuiElement directly.
Yes this is up to date and yes this is the very first version :) So far the only stakeholder has been me and the Todo List is quite simple in itself.
I created this ticket for the issue.

AFAIK ui elements have to be unique, at least in the context of your mod. As the faketorio tests run inside of your mod they share the same context.
And it is generally recommended to prefix your names with the mod name (at least according to "the internet") to limit conflicts. I somehow assumed that global uniqueness is actually enforced as the names are used for identification of elements.
Please correct me if I'm wrong here. I read about this a long time ago and assumed it never changed (cannot find the original source at the moment).
eradicator wrote:
Wed Oct 31, 2018 10:14 am
@mocks:
Trying to understand how that is supposed to work, staring at the example for far too long....

Code: Select all

function myMod.is_setting_enabled(player)
    return settings.get_player_settings(player)["my-mod-setting"].value
end
Think, think, think...so...it only works if i have a singular function for every mod setting? Because i don't. They're buried into other functions, if they're "static" values they might be in some sort of messable-with cache structure, but mostly they will be used directly.

Here's an example from one of my mods:

Code: Select all

local function set_render_mode(p,mode)
  --*snip*
  local s = settings.get_player_settings(p)
  s = {
    --read only options
    bars       = s['number-of-bars'     ] .value, --int
    slots      = s['slots-per-bar'      ] .value, --int
    bshift     = s['bottom-shift'       ] .value, --int
    rshift     = s['right-shift'        ] .value, --int
    sgroupsize = s['slot-group-size'    ] .value, --int
    bgroupsize = s['bar-group-size'     ] .value, --int
    horizontal = s['bar-horizontal-mode'] .value, --bool
    }
  --*snip
  end*
I guess i could outsource and parametrize the whole thing into function set_render_mode(p,mode,make_settings(p)), would that work then? It'd still be changing code just to make it testable (hm..and make_settings would still need to be exposed to the global scope so you can overwrite it, which is not something i'm willing to do). Ideally there would be some randomization on the values required too. So it sounds easier to change the actual mod-settings.dat and restart the game each time, that way you can test startup settings too.
hmm.. I try to follow the single responsibility principle and I think it improves readability if you have single functions for everything.

To answer your question: It works for every function that you wrote yourself. So in your case you could create a function that does nothing except returning

Code: Select all

local function get_settings(player)
  return settings.get_player_settings(player)  
end
Then you could mock out that function and inject the settings you want (:then_return returns whatever you put in there). I never tried overwriting global functions, though. But it should work similarly.

Randomization of values is a really hard problem since you can literally use it for everything :) In the long run we could come up with generators for certain values but.. yeah.. most probably this is not worth the effort as the usage is just way to broad.

If you want to take a look how I use this stuff: Todo list mod

Thanks again for the input. Feel free to post again if it didn't work. I'm happy to help out :)

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Usage of mod-gui

Post by eradicator »

JasonMiles wrote:
Mon Nov 19, 2018 1:22 pm
AFAIK ui elements have to be unique, at least in the context of your mod. As the faketorio tests run inside of your mod they share the same context.
And it is generally recommended to prefix your names with the mod name (at least according to "the internet") to limit conflicts. I somehow assumed that global uniqueness is actually enforced as the names are used for identification of elements.
Please correct me if I'm wrong here. I read about this a long time ago and assumed it never changed (cannot find the original source at the moment).
Basically all you assumed there is..eer..how to say it nicely..."wrong". *cough*
Gui Elements names behave the same as table keys, except that it's an error to try to assign a new element to an existing key. That means a) gui element names can be either string or integer. And b) names only have to be unique within the same "table". So a gui element player.gui.center.one.one.one.one is perfectly valid. As is player.gui.center[1][1][1][1]. Additionally all mods share the same gui space. So it's also valid to have two gui elements player.gui.center.my_gui.ok_button and player.gui.center.other_gui.ok_button. This shared space is the reason that "the internet" recommends prefixing, because if you rely on name checks without prefixing, your events will trigger on the wrong element and break. You can compare elements for identity though, which i do exlusively because element identity is unique (same as table identity), and as identity checks do not rely on element names most of my gui elements do not have a string name, only the automatically assigned integer name.
Though i guess it could be argued that with this approach i'm simply too far away from the "common modders" coding style and thus my usecase is irrelevant. (When i learned gui modding i did the usual "everything has a string name" approach too because i didn't even know that names are optional.)

JasonMiles wrote:
Mon Nov 19, 2018 1:22 pm
hmm.. I try to follow the single responsibility principle and I think it improves readability if you have single functions for everything.
I feel the other way around. I write code so that i can easily see at a glance what it does without having to scroll through 5 files, looking at 10 different functions to know what a bit of code does. So replacing one line with a 3 line function is - to me - the very opposite of readability. Also function calls are not free, and with one-line functions like that i'd quickly accumulate 10 times the function-call-overhead that i have now.
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.

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Usage of mod-gui

Post by bobingabout »

JasonMiles wrote:
Mon Nov 19, 2018 1:22 pm
Thanks for the input. Somehow I still don't get full notifications for everything here in the forum :/
I only get alerts when someone does a full reply to my post.
the quote opener has to include the extra information, EG, in this case it says: quote=JasonMiles post_id=387168 time=1542633749 user_id=48117
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Usage of mod-gui

Post by eradicator »

bobingabout wrote:
Tue Nov 20, 2018 8:56 am
JasonMiles wrote:
Mon Nov 19, 2018 1:22 pm
Thanks for the input. Somehow I still don't get full notifications for everything here in the forum :/
I only get alerts when someone does a full reply to my post.
the quote opener has to include the extra information, EG, in this case it says: quote=JasonMiles post_id=387168 time=1542633749 user_id=48117
I always take extra care to use proper quotes instead of orphaned/unnamed ones because i find it really annoying when people quote me without my name. But in that post i was quoting a website he wrote, so there's no proper forum-source to use. Personally i only use the "your posts" feature so no clue how notifications work. Also i hate full-quotes (generally speaking: they waste attention/screenspace and i consider it bad manner to not cut out the bits one is actually answering to), so sometimes i might not put a quote at all.
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.

User avatar
bobingabout
Smart Inserter
Smart Inserter
Posts: 7352
Joined: Fri May 09, 2014 1:01 pm
Contact:

Re: Usage of mod-gui

Post by bobingabout »

eradicator wrote:
Tue Nov 20, 2018 1:15 pm
Also i hate full-quotes (generally speaking: they waste attention/screenspace and i consider it bad manner to not cut out the bits one is actually answering to), so sometimes i might not put a quote at all.
Yeah, I often cut them down too. Just like I did here.
Creator of Bob's mods. Expanding your gameplay since version 0.9.8.
I also have a Patreon.

markonis
Manual Inserter
Manual Inserter
Posts: 1
Joined: Mon Jul 04, 2016 5:14 pm
Contact:

Re: Usage of mod-gui

Post by markonis »

Is faketorio still functional? I was able to get through Rocks installation and importing faketorio. After few days of fixing small errors that I was getting I managed to make faketorio create new map and load it ( using CMD command faketorio "run" ).
But when I'm trying to use faketorio in game after I type /faketorio in console I'm getting a message ' Uknown command "faketorio" '.
Seems like the command is not registered properly and is not recognized by factorio.
I saw in other mod that console command was added via remote library function ( remote.add_interface ).
But in your case faketorio is not a mod.

Also, when starting the factorio the game is waiting on Steam's confirmation. I didn't find any info how to suppress it.
Any ideas?

Post Reply

Return to “Modding help”