STAR TREK 2d20
  1. #1

    Can someone explain "super" and how it works in FGU?

    I can never seem to be able to tell when I can just override one function in a .lua file or use the super reference or not.

    I would dearly love to understand how to override only the parts I want to override which I can do sometimes and not others.

    For example, I can override a <script file... statement in an .xml with no problems at all. I don't need to copy any other part of the xml into my version...

    <root>
    <windowclass name="TheName" merge="join">>
    <script file="somedir/scripts/TheName.lua" />
    </windowclass>
    </root>

    But when I start replacing things in that file (not clone it as that is always a nightmare of risks) I end up with really bizarre things happening.

    A clone of the file will always work.

    An onInit using super calls and my own code - will work "most times but not all"...

    function onInit()
    if super and super.onInit then
    super.onInit();
    end
    -- My stuff
    end

    Even if the onInit works and all previous functions in the original .lua file are left off - they all still work. Sometimes - depends on .lua I'm overriding.

    And even when they still work - they won't let me override the individual functions as it seems somehow when I come into this thing triggered externally (via the engine usually - some event or whatever) I can't just replace the function call I'm interested in changing - I have to replace the entire set of functions from the first on* to some unknown level. Not all the way down - and super does work - but its a mystery what I can and can't directly override. For example...

    function onSomeButtonPressed()
    -- have to clone code - which I don't need as I'm not changing anything but onInit - which works - this button does not
    end

    function onOtherButtonPressed()
    -- have to clone code - which I don't need as I'm not changing anything but onInit - which works - this button does not
    end

    function onDoingStuff()
    -- have to clone code - which I don't need as I'm not changing anything but onInit - now if I've done all this the button works - not I don't need anything in this logic - it just will not work without providing this small subset of the original lua
    end

    It's even wilder for template script files and how layered down they are.

    What I would like is for someone to explain to me the rules for when I can replace functions that I want (and not the whole thing). Because right now it seems random to me on when I can do this (and not clone a function - which I try never to do).

    Overriding declared functions (declared with a name for the lua file in extensions.xml) seems to always have super working with no problems - but of course not many things I need are like this - most are unnamed .lua references buried in templates or .xml files.

    I'd like to understand how it all works so I don't waste so much trial and error on how to override something with super calls.
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

  2. #2
    Think of scripts as individual layers that layer over the top of each other. "self" will get the topmost layer; and "super" will get the layer underneath (if any). All scoping is unique to each layer; but will fall through to lower layers if not defined in the current layer.

    Scoping does not go "up"; only "down". This means that you can not overwrite functions in lower layers if they are called in lower layers (because the function reference is local to that scope.)

    Regards,
    JPG

  3. #3
    Quote Originally Posted by Moon Wizard View Post
    Think of scripts as individual layers that layer over the top of each other. "self" will get the topmost layer; and "super" will get the layer underneath (if any). All scoping is unique to each layer; but will fall through to lower layers if not defined in the current layer.

    Scoping does not go "up"; only "down". This means that you can not overwrite functions in lower layers if they are called in lower layers (because the function reference is local to that scope.)

    Regards,
    JPG
    As in my example above, how do I "tell" if I'm overriding what appears to be a top level (.lua script file) that my extension is overriding? I always thought that would allow super calls because mine is overlaying that layer (it's underneath) - yet it never does. Right now I'm overriding CW to make it more as I need it and I keep having to pull in more and more of the charwizard.lua functions - even though I can call super ones within them. It's like if I don't have a certain entry point I can't override the things it calls by themselves - I have to override everything that calls it leading up to it. That is my confusion - how do I tell the layered order looking at the .xml(s) and their scripts (directly defined or in .lua file)? Trying to grok the rules so I know when something won't work except by trial and error (which always has me missing something and I have to drag in more).
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

  4. #4
    You can't override a lower layer function without replacing all functions that call that function as well. If a call in a lower layer calls a function internally, it will call that scoped version of the function every time.

    Remember, each script has it's own scope, and each function is defined within that scope by Lua on load. In reality, even when you layer on top, the lower layer still has the same function defined in it's environment table, and that will be called by any local calls within it's own scope.

    { Scope A (Base) defines function x and function y (which calls function x) }
    { Scope B (Layered) defines function y (replacement) (which calls function x) }
    { Scope C (Layered) attempts to define function x (failed replacement) }

    If Scope A version of function y is called, it will use the function x in Scope A.
    If Scope B version of function y is called, it will see that no function x is defined in Scope B, and fall through to a lower level to call function x in Scope A.
    If Scope C version of function y is called, it falls through to function y in Scope B (which as noted above, calls function x in Scope A)

    The function references for Lua environments are set at the time the scripts are loaded, and each file is loaded separately with it's own environment. The Lua indexes fall through to lower levels due to the way that Lua works via the meta indexes on the objects (but it can only go one way due to the way Lua works).

    Regards,
    JPG

  5. #5
    Quote Originally Posted by Moon Wizard View Post
    You can't override a lower layer function without replacing all functions that call that function as well. If a call in a lower layer calls a function internally, it will call that scoped version of the function every time.

    Remember, each script has it's own scope, and each function is defined within that scope by Lua on load. In reality, even when you layer on top, the lower layer still has the same function defined in it's environment table, and that will be called by any local calls within it's own scope.

    { Scope A (Base) defines function x and function y (which calls function x) }
    { Scope B (Layered) defines function y (replacement) (which calls function x) }
    { Scope C (Layered) attempts to define function x (failed replacement) }

    If Scope A version of function y is called, it will use the function x in Scope A.
    If Scope B version of function y is called, it will see that no function x is defined in Scope B, and fall through to a lower level to call function x in Scope A.
    If Scope C version of function y is called, it falls through to function y in Scope B (which as noted above, calls function x in Scope A)

    The function references for Lua environments are set at the time the scripts are loaded, and each file is loaded separately with it's own environment. The Lua indexes fall through to lower levels due to the way that Lua works via the meta indexes on the objects (but it can only go one way due to the way Lua works).

    Regards,
    JPG
    This actually makes sense and helps a lot in my understanding.

    So I assume the reason I'm having to "define" things I never call or never use its because some global variable definition is being used from some other scope? I ask because I had to replace functions that had nothing to do with my changes, but somehow when it came in through a different mechanism (LVL UP from charsheet logic for charwizard) it would not work without replacing things that accessed an export variable. That is the kind of weirdness that causes trial and error to figure this stuff out.

    So can you verify that a local variable declaration at top of lua file, or inside the .xml it belongs too, is also treated as some sort of function call in terms of scope? I admit this is more confusing to me as the charwizard.lua is defined in one .xml yet when another .xml triggers its owner .xml logic (LVL UP) it somehow requires an entire new branch of the functional code to be dragged in. That is the part confusing me.
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

  6. #6
    Any scripts that are meant to be modified at that level have to be designed to be modified.

    In particular, the Character Wizard scripts are not meant to be enhanced and modified; because they are constantly under flux, as we've been migrating developers on this particular project. I highly recommend not modifying the character wizard in any way; as it receives almost weekly updates and any overrides you write will not get those updates.

    Regards,
    JPG

  7. #7
    Quote Originally Posted by Moon Wizard View Post
    Any scripts that are meant to be modified at that level have to be designed to be modified.

    In particular, the Character Wizard scripts are not meant to be enhanced and modified; because they are constantly under flux, as we've been migrating developers on this particular project. I highly recommend not modifying the character wizard in any way; as it receives almost weekly updates and any overrides you write will not get those updates.

    Regards,
    JPG
    LOL - and don't I know its under flux! Unfortunately I play games and have players and I need it to do what it used to do in order for them to use CW or the LVL UP option which triggers CW - which is handle stuff FGU does not handle well or really even have a concept for handling - i.e. Supplemental modules. For sure I can still just drop the class over the charsheet class - but I like the way CW is starting to work. And yes I tell people who want to take Advantages its RISKY RISKY and why.

    Even now I find myself adding a priority to modules load page so that I can check it in code that needs to pick one thing for my users so they don't get confused on which version we are playing with.

    I have a detailed explanation here as I've had to explain the "why" things don't work for supplemental module user in CW and why I did this update (which I do not want to do believe me) for as I've said in a discord post...

    And its not a limit of CW - its a limit as I say in how there is no way to say "I want this one when there is more than one choice" in all of FGU - not just CW. They attempt to get around it in CW by hardcoding some things of theirs - which in the wider world does not solve supplemental data.
    Or just show a list with everything and say "you choose" neither of which helps something where
    THERE CAN BE ONLY ONE (insert highlander picture here)
    If you want a workaround - copy everything you want to use in your local DB and remove the modules. Presto - guaranteed work as you wish it.
    A detailed explanation so I don't have to repeat it as I'm asked so much is here...
    https://www.fantasygrounds.com/forum...l=1#post634543
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

  8. #8
    This seemed some a good explanation to reference in here regarding super and self... https://www.fantasygrounds.com/forum...l=1#post634898
    Free(Forums/Forge) Extension(FGU 5E):
    Paid (Forge) Extension(FGU 5E):

  9. #9
    This thread was enlightening for me too.
    Daniel Salles de Araújo (@dsaraujo)
    Developer of PFRPG2 GM Enhancements - Improve your Pathfinder 2E game!
    Check out the Pathfinder Deck of Endless NPCs!

  10. #10
    EDIT: ignore me; I've given up this tract and trying a different method of getting what I'm looking for. There are some subtleties I'm just not getting (probably in the drag calls)

    I think this might be a thread that might help me; I'm not really sure what it is that is causing my problem, but I'll try to sum up.

    GURPS has a file <script name="ActionMelee" file="scripts/manager_action_melee.lua" /> in it's /root of the base.xml.

    I'm trying to use this file as a base but I have to expand on one of the three functions within (onInit, and modRoll I don't use, just onMelee).

    In my xml do I need to (and is TheName the same as TheName.lua, or would it be ActionMelee and manager_action_melee.lua for me?). I don't quite get how to override a gamesystem lua.
    <root>
    <windowclass name="TheName" merge="join">>
    <script file="somedir/scripts/TheName.lua" />
    </windowclass>
    </root>

    Currently my version is in <root>... <base>....<script name="ActionMelee" file="scripts/manager_action_melee.lua" /> ... etc; it works, but it messes up some other functions (namely ones on the character sheet where you roll.)
    Last edited by Fezzik Buttercup; March 31st, 2022 at 21:54.
    Anybody want a peanut!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
DICE PACKS BUNDLE

Log in

Log in