Quantcast Some LUA questions - ESOUI
Thread Tools Display Modes
03/18/19, 05:45 AM   #1
Supportic
Join Date: Mar 2019
Posts: 24
Question Some LUA questions

Hey, I recently started messing around with Addons in ESO. I've built my first basic addon and there are still some questions left about structering code and XML fragments.

1. There are several ways to call functions

local example = function(x, y, z)
local example = Addon.function(x, y, z)
local example = Addon:function(x, y, z)

When do I use which call? Has it something to do if the call is in a external file?

2. When exactly do I need to tell the Event_Manager to shut down the listener and will it be harmful for the latency or FPS if I keep the listener alive for the whole time?

I know everytime when I do not need the listener anymore I can turn it off but is it necessary in terms of performance?

3. When is it usefull to make new sub folders with external .lua files except for languages and libs?

I can imagine that it's usefull for e.g. constants which you use through the whole addon but makes it sense to make a, lets say, combat sub folder with a combat.lua and a synergy.lua file in it which deal with all the combat stuff?

I've built a settings menu with a combat tracker ON/OFF option. When the tracker is ON, the [setFunc] should turn on the EM:RegisterForEvent - EVENT_PLAYER_COMBAT_STATE with a OnPlayerCombatState callback function which lays in a combat/combat.lua file. For some reason it cannot find the OnPlayerCombatState function. (Yes, I've put the files in the Addon.txt) On the other hand when I scamble everything into one file, everything works as intented.

4. Are there any tutorials regarding building a UI?

I just want to start with a simple resizable rectangle background with a close button on the top right hand side and some information in it like labels or controls (lists, dropdown boxes).
As far as I know you can build the UI without touching a XML file but it also works the other way around. What is the better option?

Thanks for the help in advance. Cheers

Last edited by Supportic : 03/18/19 at 05:56 AM.
  Reply With Quote
03/18/19, 05:58 AM   #2
Baertram
 
Baertram's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 2,499
Hey, I recently started messing around with Addons in ESO. I've built my first basic addon and there are still some questions left about structering code and XML fragments.

1. There are several ways to call functions

local example = function(x, y, z)
local example = Addon.function(x, y, z)
local example = Addon:function(x, y, z)

When do I use which call? Has it something to do if the call is in a external file?
Your choice
function is just a function.

Addon is a table (https://wiki.esoui.com/LUA_Tables) and you add a function to it via Addon.function. So you are able to access Addon within your code if it's defined local, or without local it will be globally accessible from your AND other addons. So be sure to define a unique name like MyAddonsName = {} instead of Addon = {} (which other addons might use as well).
You use a table like Addon = Addon or {} at the start of several lua files of your project if you want to pass variables etc. to different lua files of your project. This way you can make the files "communicate" with each other (and other addons use your functions as well, e.g. build an API, or at least check if your global table exists and know your addon is active this way).

Addon: says you are using kind of Object oriented programming. lua does not really support it, but uses metatables (search for it please) to define objects and re-use predefined functions and attributes from parent objects.
Addon:callFunction(parameter1) is the same like Addon.callFunction(objectName, parameter1).


2. When exactly do I need to tell the Event_Manager to shut down the listener and will it be harmful for the latency or FPS if I keep the listener alive for the whole time?

I know everytime when I do not need the listener anymore I can turn it off but is it necessary in terms of performance?
Yes it is. Depends on WHAT you check and how often the events trigger. e.g. combat events should ALWAYS use an event filter as well:
https://wiki.esoui.com/AddFilterForEvent

And some other events need a check that it won't be called if you are not in a dungeon or the circumstances you like your addon to work in. If users deactivate a setting (libAddonMenu-2.0) in your addon it often makes sense to add the parameter "requiresReload = true" to this LAM setting. And at your event registering functions (e.g. in event_add_on_loaded or event_player_Activated) check if this setting is enabled or disabled+ only register the event callback funcs if it is enabled.


3. When is it usefull to make new sub folders with external .lua files except for languages and libs?

I can imagine that it's usefull for e.g. constants which you use through the whole addon but makes it sense to make a, lets say, combat sub folder with a combat.lua and a synergy.lua file in it which deal with all the combat stuff?

I've built a settings menu with a combat tracker ON/OFF option. When the tracker is ON, the [setFunc] should turn on the EM:RegisterForEvent - EVENT_PLAYER_COMBAT_STATE with a OnPlayerCombatState callback function which lays in a combat/combat.lua file. For some reason it cannot find the OnPlayerCombatState function. (Yes, I've put the files in the Addon.txt) On the other hand when I scamble everything into one file, everything works as intented.
This again depends on how you like it. Structure it the way you like to.
For your combat example see my answer to 2. about the lam settings requiresReload + event_player_Activated to register the event properly then. Otherwise it might be too late (depening on the event you are using) or not working properly anymore.
And for combat please ALWAYS use the event filters or this might be a real FPS or performance issue as they trigger for EACH user in your group e.g. + other addons use it a lot too.

BUT PLEASE do NOT include libraries anymore in the addons subfolders!
Let the user install them as standalone libraries (like addons, via Minion e.g.) and just put in your txt file the tag ##DependsOn: Library1 Library2
This will assure you are not shipping embedded libraries with old versions which might be a problem after updates again! And this assures the idea of libraries is fullfilled.

lua is reading your code from top to the bottom of a file.
If you define the func OnPlayerCombatState in the same file where you register the event and want to acccess the func OnPlayerCombatState you need to assure that the func OnPlayerCombatState is defined MORE TO THE TOP of the file than the event registering.
If you define the func in anothe file you need to be sure to put it into your addon table like
in file /src/combat.lua
function myAddonName.OnPlayerCombatState(...)
end
in file myAddonName.lua
event_manager:registerforevent(myAddonNme.name, EVENT_..., myAddonName.OnPlayerCombatState)

See my answer to your question 1 for that as well.

4. Are there any tutorials regarding building a UI?

I just want to start with a simple resizable rectangle background with a close button on the top right hand side and some information in it like labels or controls (lists, dropdown boxes).
As far as I know you can build the UI without touching a XML file but it also works the other way around. What is the better option?
https://wiki.esoui.com/SimpleNotebookTutorial/
You need to advance in the parts of this tutorial but it should help you.
Again this depends on your ideas and likes.
I'd go with XML as a base and use lua functions to update some stuff dynamically like re-anchoring the controls etc. if needed.

You can also build it totally within lua source code and just define the controls in there without XML.
XML got some nice stuff like using "templates" for e.g. a backdrop (black rectangle background in eso) or an input text field etc.
Maybe spy on other addons how they do it

Last edited by Baertram : 03/18/19 at 06:11 AM.
  Reply With Quote
03/18/19, 06:18 AM   #3
Baertram
 
Baertram's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 2,499
oh btw some links in general. We really should put this into the FAQ at a point "How to learn addon development"

ESOUI wiki with api and other info, tutorials etc.
ESOUI source code, locally for you
ESOUI source code at github (search etc.)
Existing ESO language constants (can be used via function GetString(SI_...) in yoiur addons so you do not need to reinvent the wheel)
https://github.com/esoui/esoui/blob/...tedstrings.lua
https://github.com/esoui/esoui/blob/...tedstrings.lua
Get in touch with other eso devs (chat)
  Reply With Quote
03/18/19, 06:46 AM   #4
Supportic
Join Date: Mar 2019
Posts: 24
Thank you so much for the quick and detailed response, you're a hero!
I just skipped quick through it and will take some notes when I'm home.

I can already tell that I forgot that the function with the . operator sticks to the Addon namespace which can be passed to other files. I think it also makes sense to check if Addon ~= nil at the start before I define it.

The event filter thing was a new thing to me and I will take care of it asap to improve the performance.

BUT PLEASE do NOT include libraries anymore in the addons subfolders!
Let the user install them as standalone libraries (like addons, via Minion e.g.) and just put in your txt file the tag ##DependsOn: Library1 Library2
This will assure you are not shipping embedded libraries with old versions which might be a problem after updates again! And this assures the idea of libraries is fullfilled.
Regarding the libs. I have a lib folder with LibAddonMenu-2.0 and LibStub in it because I saw it in tutorials and other addons. In addition I added the dependsOn tag in my .txt file for the LibAddonMenu-2.0 lib. If i understood it correctly I should delete the lib folder and install the libs as "addon" in my Addon directory so that I can benefit from lib updates? What if the lib is going to change functionallities and my addon will brake because of it. Isn't it also good to have a older version as backup?

Thanks for the UI links and tips, I will take a look into it. Also the "SI_..." is something which really confuses me because of the huge amount of constants.

New question: Is there a site except http://esoitem.uesp.net/viewlog.php where I can track boss mechanics or assign the skills to the bosses or do I have to track them via console outputs and combat stats?
  Reply With Quote
03/18/19, 07:01 AM   #5
sirinsidiator
 
sirinsidiator's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 1,289
Keeping an older version of the lib inside your addon will only work if no other addons or versions of the lib are loaded. Libraries in ESO are a shared global resource and it will always try to load the newest version in any case.

I can't speak for other library authors, but I am very careful to not break the api defined in a version of a library ever since I did just that a long time ago and someone complained about it quite angrily.
If I have to make breaking changes, I either add a new function in a minor version or do a major update which will provide a separate instance of the library object in order to not break addons that use the old version.
__________________
Like what I do? Support me on Patreon!
>siri.exe MyAddon
Does your addon work? [y/n] n
There is a typo in there.
  Reply With Quote
03/18/19, 07:30 AM   #6
Wheels
AddOn Author - Click to view addons
Join Date: Feb 2017
Posts: 41
Originally Posted by Supportic View Post
New question: Is there a site except http://esoitem.uesp.net/viewlog.php where I can track boss mechanics or assign the skills to the bosses or do I have to track them via console outputs and combat stats?
While sites like that can give you some information regarding skills and such, if you want detailed information about what casts which skill and the details about it then you have to get that information from ingame. RaidNotifier has a built-in logger, and you could make your own if you need some other details.
  Reply With Quote
03/18/19, 08:01 AM   #7
Baertram
 
Baertram's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 2,499
You do not need a "if Addon ~= nil" check as this is already handled via
Addon = Addon or {}

It basically does the nil check and it it is nil it will create a new table via {}.
You can use this for each table variable, or even other variables to do a nil check.
e.g.
local var1 = var2 or var3

You can even use some short forms like this
local booleanVar1 =(addon ~= nil and addon.booleanVar1) or false
  Reply With Quote
03/18/19, 08:43 AM   #8
Supportic
Join Date: Mar 2019
Posts: 24
So be sure to define a unique name like MyAddonsName = {} instead of Addon = {} (which other addons might use as well).
You use a table like Addon = Addon or {} at the start of several lua files of your project if you want to pass variables etc. to different lua files of your project. This way you can make the files "communicate" with each other.
Just to clarify, am I allowed to do this:

Addon = {
name = "uniqueName"
}

basically the same as:

Addon.name = "uniqueName"

OR

Do you mean the table Addon should not exist because everyone could use the same name and I should choose something like:

uniqueTable = {
addonName = "uniqueName"
}
  Reply With Quote
03/18/19, 08:50 AM   #9
Wheels
AddOn Author - Click to view addons
Join Date: Feb 2017
Posts: 41
Originally Posted by Supportic View Post
Just to clarify, am I allowed to do this:

Addon = {
name = "uniqueName"
}

basically the same as:

Addon.name = "uniqueName"

OR

Do you mean the table Addon should not exist because everyone could use the same name and I should choose something like:

uniqueTable = {
addonName = "uniqueName"
}
The second one, your addon's namespace will be global, and you don't want to run the risk of having your table be the same name as another, as data will start being overwritten.
  Reply With Quote
03/18/19, 11:50 AM   #10
Supportic
Join Date: Mar 2019
Posts: 24
Ok so I:
  • deleted the local libs and downloaded the global libs
  • renamed the global namspace to a more unique one
  • reordered the loading order in my .txt file so that it's now possible to load code from external files

TODO
  • take a closer look into Event Filters
  • mess around with UI stuff
  • try out RaidNotifier's combat forensic tools

Thanks again to everyone.
  Reply With Quote
03/20/19, 03:27 PM   #11
Supportic
Join Date: Mar 2019
Posts: 24
Okay, the next question appeared

First of all I understand now that those two function calls:

Code:
uniqueAddonName.function1(param1, param2)
uniqueAddonName:function2(param1, param2)
Just differs from each other how you want to access the global namespace inside the function.

Code:
uniqueAddonName.function1(param1, param2)
  uniqueAddonName.variable1 = param1
  uniqueAddonName.variable2 = param2
end

uniqueAddonName:function2(param1, param2)
  self.variable1 = param1
  self.variable2 = param2
end
So the next thing was to understand the concept of global and local function calls.
I thought if you use a function like this:

Code:
function(param1, param2)
it can only be used in this file. And when I bind that function to a global namespace it can be used globally.

Code:
uniqueAddonName.function(param1, param2)
But either way both functions are used across files. Is there a concept of local and global functions at all?

Cheers

Last edited by Supportic : 03/20/19 at 03:29 PM.
  Reply With Quote
03/20/19, 03:34 PM   #12
Baertram
 
Baertram's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 2,499
Sure:

Everything defined local can only be used within the area you deifned it
e.g.

Lua Code:
  1. if ... then
  2. local var ...
  3. end

var is only known inside the if!

Same for
Lua Code:
  1. for ... do
  2. local var
  3. end
loops.

Same for functions

Lua Code:
  1. function thisIsAGlobalFuncKnwonInEveryOtherAddonAndAllYourFiles(param1)
  2. end
  3.  
  4. local function thisIsALocallFuncKnwonOnlyIntheAreaWhereItIsDefined(param1)
  5. --e.g. inside a file or even inside an if .. then end, or for .. do end
  6. end

https://www.lua.org/pil/4.2.html
  Reply With Quote
03/20/19, 03:47 PM   #13
Supportic
Join Date: Mar 2019
Posts: 24
Okay, that's understandable. So what's the point to bind functions to a namespace like:

Lua Code:
  1. function uniqueAddonName.myFunction(param1, param2)
  2.     doSomething()
  3. end

then? Instead you can just make it for everything accessable like:

Lua Code:
  1. function myFunction(param1, param2)
  2.     doSomething()
  3. end
  Reply With Quote
03/20/19, 03:54 PM   #14
Rhyono
AddOn Author - Click to view addons
Join Date: Sep 2016
Posts: 555
Let's say I decided to make a function called start(). What are the odds that in the other thousand addons, that no one else has ever done that?

Now, how many people do you think have made a function called MyEntirelyUniqueAddonName.start()?
  Reply With Quote
03/20/19, 04:00 PM   #15
Supportic
Join Date: Mar 2019
Posts: 24
Ahhhhhh!

That's why I need a namspace for EventListeners as well because almost every addon is calling certain events.

Thanks
  Reply With Quote
03/20/19, 04:05 PM   #16
Rhyono
AddOn Author - Click to view addons
Join Date: Sep 2016
Posts: 555
Correct and to be more specific on event listeners: they aren't unique to the addon, but to the first parameter in the register. So if your addon is called "Something" and you make the listener "Banana": it'll still work. Furthermore, you can make multiple listeners for the same event in the same addon by naming them different things. In general, it's preferred if you only make one listener and that function would branch off into more functions with the data as necessary, but the concept is there.
  Reply With Quote
03/20/19, 04:26 PM   #17
Supportic
Join Date: Mar 2019
Posts: 24
So you can do something like:

Lua Code:
  1. EM:RegisterForEvent(<your_addon_name> .. "Synergy", <event_to_register_to>, <function_to_run>)

to use the same event for a different function.
  Reply With Quote
03/20/19, 04:31 PM   #18
Baertram
 
Baertram's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 2,499
Correct.
If you only need it once you can simply use <your_addon_name> as name.
But if you want to use it for different purposes add a connecting character (like - or _ ) and something unique at the end like the purpose you want to use it for (like within your example "Synergy").

The connecting character is only needed if you want to dynamically access the events again and don't know the exact names. So you can be sure to use <your_addon_name> as starter and split the string at - or _ afterwards to get the last part e.g.
  Reply With Quote
03/21/19, 07:56 AM   #19
Supportic
Join Date: Mar 2019
Posts: 24
Hi again,

why do SavedVariables generate the same output when I modify my code, delete my SavedVariables file and reload UI. I have to restart my game everytime in order to see the new changes AND I have to reload UI to be able to see the new generated SavedVariables file.
  Reply With Quote
03/21/19, 08:14 AM   #20
Baertram
 
Baertram's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 2,499
SV are ONLY updated on the hardrive/SSD as you do a reloadui or zone change or logout. This is normal and intended.

SVs are not updated on your hdd/sdd as you change them. The data will be changed in your variables of your addon. And just kept there until a reloaduiw rites them.

If you change something in the SV data of your addon and do no reloadui or logout or zone change (e.g. client crashes) the data will not be written to your hdd/sdd.

There is a security SV setting though for this to save small amounts of IMPORTANT data. Currently I cannot find the info but wil llink it here as I did again.

You cannot access files within ESO. Only using the SVs is possible. So if you want to transfer data on the fly there is no choice to do this so far, only with a reloadui.

You internal SV table will be kept in memory as well. So if you change the file manually via text editor the next reloadui wil loverwrite the file on the hdd/sdd again from the memory ingame!

If you want to reset the savedvariables you need to set them nil ingame and do a reloadui.
OR you can use the SavedVariables version parameter in ZO_SavedVars:... functions! Increasing/changing the version will reset the savedvariables! SO never use the save version number for your addon + the savedvariables or they will reset EACH time you change the addon version.

There also exists a library to help with the SavedVariables in your addons:
https://www.esoui.com/downloads/info...SavedVars.html

Edit:
SV information: https://www.esoui.com/forums/showthr...=savedvariable
SV tutorial: https://wiki.esoui.com/Circonians_Sa...ables_Tutorial
Clean SV data: https://www.esoui.com/forums/showthr...=savedvariable
Using character bound and account bound SVs at the same time in your addon (e.g. general account wide settings + character settings for each toon): https://www.esoui.com/forums/showthread.php?t=7953
Info about libSavedVars and some other SV related stuff: https://www.esoui.com/forums/showthr...savedvariables


SV saving of small IMPORTANT data without reloadui (do not abuse it or it might break other addons REALLY IMPORTANT save of small data!): No link, just some information about functions:
• RequestAddOnSavedVariablesPrioritySave(addonName)
This function prioritizes the add on to be saved before non-prioritized add ons. After a save it will no longer be marked as a priority.
You may also disable auto saving for your add on by putting the following line at the top of your addon manifest file:
• ## DisableSavedVariablesAutoSaving 1
Hint from ZOs: I think that if you call the priority function (RequestAddOnSavedVariablesPrioritySave) it will do one save even if it is disabled in the manifest (## DisableSavedVariablesAutoSaving 1)

Linked it to the Wiki's SV tutorial now:
https://wiki.esoui.com/Circonians_Sa...oadui.2Flogout

Additional forum thread with insights:
https://www.esoui.com/forums/showthread.php?t=8407

Last edited by Baertram : 03/21/19 at 09:55 AM.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » Some LUA questions

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off