Forum rules - please read before posting.

An additional performance option related to menu/GUI overhead?

edited May 2017 in Engine development
I was glad to see @ChrisIceBox implementing my earlier performance requests. I have a similar request for a feature that probably very few people would ever use, except those that want to avoid any unnecessary overhead (and who are ahum.. are using their beloved adventure engine for any game genre).

So, after the earlier GC improvements, the AC menu system still eats about 25-30% of the frame generation time in my FPS intensive game, and this happens even when the menus are not updated in any way. I'm using AC+UGUI only.

To test if I can avoid that, I implemented a hack with a few lines of code in PlayerMenus.UpdateAllMenus() -method, which looks somewhat like this:

// Skip adding further menu overhead, if we choose to optimize current frame.
if (MyLevelManager.Inst.HackyHackOptimizeFrame()){

// Non-hack code continues here
if (Time.time > 0f)
int languageNumber = Options.GetLanguage ();

A proper way to would probably not be "MyLevelManager.Inst.HackyHackOptimizeFrame()", but using a delegate method, I think? The purpose is that can we can return with TRUE or FALSE, allowing us to decide during each frame in our custom code if PlayerMenus.UpdateAllMenus() should allow to run till the end. 

With this simplistic hack I saved those 20-30% of total overhead most frames. In my case the hack is active most of the time during normal gameplay, but not when the game is paused etc.

So, would @ChrisIceBox ;consider adding non-hacky (delegate?) way to do this :)?


  • Well, it would be cool if they updated only when there was an actual change in the data, and maybe only update the affected menu. But I better not assume since I haven't really gone through the source code and am not sure what's actually happening under the covers. But, yeah, these kind of optimizations would really help taking AC to other genres (I'm also only working on Hybrid adventure games too, so framerate is important).
  • Thanks for the comment @Alverik

    To be honest I think that AC probably wouldnt be able to 100% accurately and efficiently check if any data in the menus have changed or not. Especially if the user has AC-linked but UGUI-based menus with their own additional scripts. So I assume that checking in AC if anything has changed would probably be too complex and maybe slower than running the normal menu update routine.
    I may be wrong, @ChrisIceBox probably could stop climate change and end the Trump precidency with an AC plugin ;)

    This is why I would leave the actual logic (of when to skip the slow part of menu uploading) to (advanced) end-users via this delegate method. They would need to know enough about their game menus and custom scripts to know when to skip the update.
  • edited May 2017
    Would if I could, @ilmari ;)

    Indeed, updating the Menus each frame is certainly a large process - not least because of their co-dependance.  Hovering over an Inventory item needs to update the text within a Hotpspot label, for example.

    There is, however, already a means to prevent the UpdateAllMenus () function:

    AC.KickStarter.playerMenus.SetMenuSystem (false);

    That will disable the Menu system completely - if you're using AC's drawing system.  If UGUI, it'll pretty much just prevent UpdateAllMenus from being run.  Similar functions exist for the various input, movement, interaction etc systems.

    While this is designed to be set at discrete moments (for example, at the beginning of a puzzle with a separate UI asset), rather than every frame, I suspect it could be placed in an Update() function to serve your purpose.  It may not be as "neat" as a delegate, but introducing that while an alternative exists seems feature-creep to me - though I'll listen if it's not suitable after all.
  • edited May 2017
    Thanks @CrisIceBox

    I knew about SetMenuSystem (false), but didn't use it before for a few reasons:

     1. It seemed a bit scary, since I was unsure about the effects, and didn't want to disable / hide menus that are currently displayed - just wanted avoid running unnecessary heavyish updates on AC. 

     2. I also thought that this system call would be potentially heavy, and not something I could do several times per second, thinking it could trigger a big overhead. Since I've chosen to updates menus most of the time only max 5 times a second, I thought that disabling / enabling a core system would likely lead to worse performance now or in the future.

    3. My hack in UpdateAllMenus() did not disable the method fully, it always ran at least the first 20 lines which would react to resolution changes etc, but which had virtually no noticiable overhead.

    4. I've avoided using Update() like the plague in my custom code. I probably need to add a common Update()-function somewhere for custom code, like AC does.

    ... But, I made these assumptions without looking SetMenuSystem (false)-method, which just changes a boolean on/off. At least currently the frequent on/off changes seems to not trigger actual overhead, which is great. And probably changes my view on points 1-3. 

    I'm still not unsure if it creates additional unwanted side effects, like delay in touch input handling / stutter, etc, but I'm now using the SetMenuSystem() -method. So far it seems I can continue using it :)

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.