Thread Tools Display Modes
08/14/15, 09:30 AM   #1
haggen
 
haggen's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2015
Posts: 137
Arrow What is a Scene, the SceneManager and other concepts

I've been fooling around here fore about 2 weeks now. I even published my very first - and beta - add-on.

I've spent some dozens hours now reading the game UI code base.

Still, I don't grasp most of the concepts here, for instance, what is a Scene ?

And I come from a web development background, so I'm not a layman at all.

I don't mean to sound ungrateful, I know and value all the effort and time put into the wiki, but I think it lacks broader introductions to how things work, and the concepts involved.

Things like:

1. Event and initialization order, for instance, does the GUI is ready when the load event is triggered ?
2. The most prominent ZO_* objects, what they're for and how can you benefit from them
2. Callbacks; I know what they're but what are some actual use cases, besides events I haven't see any asynchrony
3. Other stuff that once you discovered allowed you to write add-ons more efficiently and add more features

I'm willing to expand the wiki once I understand more of all this!

Thanks for everything so far and for everything to come!
  Reply With Quote
08/14/15, 10:07 AM   #2
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 578
About scenes is alot to say:
  1. All UI (especially in-build) are scenes.
  2. Scenes are groups of FRAGMENTs and FRAGMENTs wrapping Top-Level-Controls.
    One fragment can be part of several scenes.
    e.g. if a fragment is a child of HUD_SCENE and HUD_UI_SCENE (with mouse pointer) it will be visible in both modes.
    If a fragment is child of LOOT_SCENE it is visible while looting, and so on.
    The visibility is automatically handle from build-in (native?) code. So you don't need to.
  3. There are build-in "classes" for fragments, which already handle nice fade-in/fade-outs.
  4. There are fragments automatically handling to enable some backgrounds, showing mouse, turn your avatar (which in opposite can be disabled just by removing the fragment)

Ayantir and Garkin (two of our Grandmasters) already wrote examples and libs:
http://www.esoui.com/downloads/info989-LibMainMenu.html
http://www.esoui.com/portal.php?&id=27&pageid=12

If you use ZO_FadeSceneFragment, always specify a fade-out duration less than 200ms:
Lua Code:
  1. local fragment = ZO_FadeSceneFragment:New(yourTopLevelWindow, true, 150)
See, why:
Secure Render Mode Bug

You can take a look to Rare Fish Tracker for fadings > 200ms.
  Reply With Quote
08/14/15, 10:12 AM   #3
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by haggen View Post
Still, I don't grasp most of the concepts here, for instance, what is a Scene ?
A Scene is like a mode of the UI. When you login, you see the "hud" scene. When you open inventory, the SceneManager makes a transition to the "inventory" scene, and when you close inventory, back to "hud".

Every Scene contains Fragments. A Fragment may be visual -- displaying a TopLevelControl, e.g. the inventory window with buttons and a list of items -- or behavioral -- switching keybinding sets for example. When a Scene is shown, its fragments are shown/activated, and all other fragments are hidden/deactivated. A fragment may be contained in multiple scenes at once, in which case transitions between those scenes keep the fragment shown ("mailInbox" and "mailSend" are two scenes with common interface, and you can't even notice they're different scenes when switching the tab).

Originally Posted by haggen View Post
1. Event and initialization order, for instance, does the GUI is ready when the load event is triggered ?
The order in which you list files in addon manifest.txt matters. The files are interpreted in that order (both Lua and XML). So if your XML defines a (non-virtual) control with an <OnInitialized> handler, the control is created right after the XML has been parsed, and if the handler calls one of your global functions, the Lua file defining that function must precede the XML in the manifest. ZOS Lua and XML sources are run before any add-ons, so most of their controls already exist by the time add-ons load. Not all of them, though, for example Character sheet contents is not created until its Scene is shown for the first time.

After all add-ons have been compiled and executed, EVENT_ADD_ON_LOADED events are generated.

Originally Posted by haggen View Post
2. Callbacks; I know what they're but what are some actual use cases, besides events I haven't see any asynchrony
They're useful for implementing publisher-subscriber pattern. For example SHARED_INVENTORY holds a cache of inventory slot data, and defines callbacks anyone interested in inventory contents updates can subscribe to.
  Reply With Quote
08/14/15, 10:41 AM   #4
haggen
 
haggen's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2015
Posts: 137
@merlight and @votan thank you so much, you already have given me enough to chew on for days!

One question though; when developing an add-on with a form-like GUI, should I use an existing scene or scene fragment or should it reside in its own ? And why ?
  Reply With Quote
08/14/15, 11:08 AM   #5
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by haggen View Post
@merlight and @votan thank you so much, you already have given me enough to chew on for days!

One question though; when developing an add-on with a form-like GUI, should I use an existing scene or scene fragment or should it reside in its own ? And why ?
1 Fragment <-> 1 TopLevelControl, so your own fragment. As for scene, that depends on when/where you want to show the fragment.

A) If you wanted to add another tab to the guild interface (the four existing tabs switch scenes), you'd probably create a new scene, add some of the common fragments in there (e.g. the background and the guild selection dropdown), and add your own fragment to that.

B) If you wanted to show your form next to the character sheet, you'd add your fragment to the existing "stats" scene.
  Reply With Quote
08/14/15, 11:19 AM   #6
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 578
Originally Posted by haggen View Post
@merlight and @votan thank you so much, you already have given me enough to chew on for days!

One question though; when developing an add-on with a form-like GUI, should I use an existing scene or scene fragment or should it reside in its own ? And why ?
For example: In Potion Maker you have a new scene to fade/hide all other elements (if outside crafting station) I reuse the right background fragment, which is the same as at the crafting station or inventory.
It may also helps you to keep a look'n'feel.

And why? Because all controls are created forever and use memory forever. If you can re-use, why not.
Another nice topic: control-pools.
  Reply With Quote
08/14/15, 01:12 PM   #7
Lodur
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 108
I just want to add another topic which I have been wondering about.

- GUI size units and scaling.


What are the units on when you do something like in XML:
Code:
<Dimensions x="750" y="52" />
Is it screen resolution? What is the aspect ratio of the screen. What happens when someone plays in a different screen resolution / aspect ratio?

What are the best practices for building a GUI that scales correctly?
  Reply With Quote
08/14/15, 01:29 PM   #8
Wandamey
Guest
Posts: n/a
Originally Posted by Lodur View Post
What are the best practices for building a GUI that scales correctly?
from what i have experienced, i'd say the less you bother, the better it will look.
Just do thing so they look well proportionned on your screen, it should render the same for everybody.

try to change your UI scale in the UI settings of ESO to see that everything is handled without you having to touch anything.

you can lock/unlock the scaling of controls in special situations (text Inside a preformatted tooltip, etc...) but messing with the maths behind the scale is just asking for problems.

now i'm a bit limited to test things on many resolutions. But from the screenshot/videos i've seen, i'm confident the game looks the same whatever the screen size.

and the units, you answered yourself, they seem to be GUI size units

edit : scale is inherited from parents to children, so that's the only thing you have to care for : placing elements one according to the other (with raw dimensions), then scale the top one if needed.
If you need to do something that looks proportional to the window/screen you can use as raw dimensions something alongside of : width, height = yourproportion * GuiRoot:GetDimensions() -- didn't check the syntax, but you'll get the idea-- knowing that the result will be scalable again with SetScale()
But that may force you to use % for all children dimensions depending on what you're doing
Better start with fixed dimensions (choose it with the default scale UI setting) then later on you'll always be able to add an option to rescale if needed.

rereredit, idk if we can use something similar to $lang to conditionally set dimension of a "sub"ui according to some Guiroot sizes ranges (like bootstrap could do for example) but i don't see why not if you have some very specific needs to do something like that.

Last edited by Wandamey : 08/14/15 at 04:10 PM.
  Reply With Quote
08/14/15, 03:47 PM   #9
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Some great technical answers have already been given, so I tried to list a few more basic answers.

Originally Posted by haggen View Post
Still, I don't grasp most of the concepts here, for instance, what is a Scene ?
A scene is a group of fragments (windows) that are shown/hidden all at once when the scene is shown/hidden. So basically it just shows/hides a group of objects so you don't have to show/hide each individual object.

Originally Posted by haggen View Post
2. The most prominent ZO_* objects, what they're for and how can you benefit from them
Heres a thread where it was discussed: zo_objects

Originally Posted by haggen View Post
2. Callbacks; I know what they're but what are some actual use cases, besides events I haven't see any asynchrony
They are used when you need to run code after something happens, typically used when there is not a pre-defined event for something. Merlights example of using callbacks with the inventory is a great example. Some others might be if you need to run some code when the fence "Sell" panel or the fence "Luander" panel opens. There is an event for when the fence window opens or closes, but not for the invididual "sell" & "launder" panels. You could register a callback
Lua Code:
  1. FENCE_MANAGER:RegisterCallback("FenceEnterSell", OnFenceEnterSell)
  2. FENCE_MANAGER:RegisterCallback("FenceEnterLaunder", OnFenceEnterLaunder)
And then whenever that window/panel is shown it will run your function. Other useful ones might be when the map changes, or when a scenes state changes (when it is shown/hidden).
Lua Code:
  1. WORLD_MAP_SCENE:RegisterCallback("StateChange", OnMapStateChange)
  2. CALLBACK_MANAGER:RegisterCallback("OnWorldMapChanged", OnWorldMapChanged)

Originally Posted by haggen View Post
One question though; when developing an add-on with a form-like GUI, should I use an existing scene or scene fragment or should it reside in its own ? And why ?
It depends on when you want it shown. If you want your GUI to show "with" the other fragments in a scene, then you would put it into that scene. For example if you created something that was related to the world map, you may only want it to show when the world map is shown, so put it in that scene. If your GUI is unrelated to, or not strictly tied to, the fragments in any given scene then you probably want to create your own scene for it.


Originally Posted by haggen View Post
3. Other stuff that once you discovered allowed you to write add-ons more efficiently and add more features
  1. Using the free program "Total Commander" that allows you to search multiple files at once to search the eso lua code for functions/constants to allow me to see an example of how it is used. I'm sure there are other programs that do this, but this is one Garkin told me about & I would not have been able to do a fraction of what I have done without it.
  2. Knowing how to look up functions, constants, & their values in game. You can look them up on the wiki, but this has saved me a lot of time. There are at least 2 addons that I know of that do the work for you Click4Info and Mer Torchbug
  3. Learning how to use zgoo or merlights new Mer Torchbug
  4. Using some type of ingame notepad that allows you to write & run code from within the game so you don't have to alt+tab out, write some code, go back to the game, & reload the ui to test something. Addons that do that: Click4Info and ZAM Notebook
  Reply With Quote
08/15/15, 04:28 PM   #10
haggen
 
haggen's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2015
Posts: 137
This is real gold, thank you so much guys!

My schedule's kinda tight but I'll definitely take some time to organize the content and write it down.
  Reply With Quote
08/15/15, 04:37 PM   #11
haggen
 
haggen's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2015
Posts: 137
Look at this http://esodata.uesp.net/100011/data/...ForUpdate.html

You'll see a bunch of cases where the game code calls RegisterForUpdate function on a control. I'm only 90% sure of what it does, do you guys know ?

What I got from it is that it registers a callback for when a given UI is updated (more like a tick, and many times per second actually, maybe the same as frames per second) but I'm not sure about the second argument, which looks like a delay. Maybe it's something like, "on update call this, but only once every X milliseconds" ?

Last edited by haggen : 08/15/15 at 04:50 PM.
  Reply With Quote
08/15/15, 05:01 PM   #12
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
Originally Posted by haggen View Post
Look at this http://esodata.uesp.net/100011/data/...ForUpdate.html

You'll see a bunch of cases where the game code calls RegisterForUpdate function on a control. I'm only 90% sure of what it does, do you guys know ?

What I got from it is that it registers a callback for when a given UI is updated (more like a tick, and many times per second actually, maybe the same as frames per second) but I'm not sure about the second argument, which looks like a delay. Maybe it's something like, "on update call this, but only once every X seconds" ?
RegisterForUpdate is one of EVENT_MANAGER's methods which calls function in specified intervals.
Lua Code:
  1. EVENT_MANAGER:RegisterForUpdate(identifier, interval, function)

identifier (string) - unique identifier, you can use for example name of your addon or some kind of description. If you register the same identifier again, it will overwrite previous function call.
interval (integer) - interval in milliseconds between function calls
function (function) - function which will be called


Example - function OnUpdate is called every 5 seconds (5000ms):
Lua Code:
  1. EVENT_MANAGER:RegisterForUpdate("DurabilityWarner", 5000, OnUpdate)

If you want to unregister this function call, use:
Lua Code:
  1. EVENT_MANAGER:UnregisterForUpdate(identifier)

Last edited by Garkin : 08/15/15 at 05:05 PM.
  Reply With Quote
08/15/15, 06:56 PM   #13
haggen
 
haggen's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2015
Posts: 137
Originally Posted by Garkin View Post
RegisterForUpdate is one of EVENT_MANAGER's ...
Thanks a lot! That was exactly what I thought
  Reply With Quote
08/15/15, 07:02 PM   #14
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Unless I misunderstand what you meant:
Originally Posted by Garkin View Post
identifier (string) - unique identifier, you can use for example name of your addon or some kind of description. If you register the same identifier again, it will overwrite previous function call.
It does not overwrite the previously registered update.

If you try to register it twice (without unregistering):
Lua Code:
  1. EVENT_MANAGER:RegisterForUpdate("DurabilityWarner", 5000, OnUpdate)
  2. EVENT_MANAGER:RegisterForUpdate("DurabilityWarner", 1000, SomeOtherUpdate)
It will still call OnUpdate, every 5000 ms. The second register does nothing.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » What is a Scene, the SceneManager and other concepts


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