5E Character Create Playlist
Page 1 of 7 123 ... Last
  1. #1

    node.getChild(string) vs DB.getChild(node, string)

    I have recently heard in Discord that there are changes coming around this (if I understand correctly).

    In case it helps anyone, here are some regex replace strings I wrote up.

    I used this to change node.getChild() to DB.getChild(node)
    Code:
    ([\( ])([0-9A-Za-z]+[\(\)]*)(?<!DB)\.getChild\((.+)\)
    Code:
    $1DB.getChild($2, $3)
    I didn't see any false positives in my code, but I would recommend only using regex replace on your code if you're using version control to vet all its changes.

    I used this to change node.getChildren() to DB.getChildren(node)
    Code:
    ([\( ])([0-9A-Za-z]+[\(\)]*)(?<!DB)\.getChildren\(\)
    Code:
    $1DB.getChildren($2)
    Unfortunately, I haven't found a really good method of doing this for getValue, setValue, getType, and other functions that also exist for interface objects. These all result in many false positives (although it's still a time saver compared to changing everything by hand).
    Last edited by bmos; January 5th, 2023 at 14:47.

  2. #2
    Also, does anyone have performance data around the two approaches?
    Is DB.getChild faster or something?

  3. #3
    I wasn't quite ready to move this change/concept forward yet, though it was pointed out to me that it was leaked on Discord that this is something we're working on in the background.

    Currently, there is no expected positive or negative performance change between the two different approaches, because in order to keep everything working, both implementations have to be supported at this time.

    The gist of the change is that the original FG developers (before my time) chose to make databasenode objects (as well as a few others) into full-fledged scriptable objects with embedded APIs, even though those objects can not be assigned a script tag/file. This creates a lot of overhead in every object, since the entire global namespace and APIs need to be built for every object. So, when you have an object that is as prolific as databasenode (i.e. every possible node in the database), my theory is that this creates a massive amount of overhead for database operations which is completely unnecessary. Also, with the continued growth of the FG catalog, the size of the databases used by DLC and in campaigns continues to grow with every year.

    My working project is to migrate databasenode objects to simple Lua userdata objects without any additional script spaces, global namespaces or APIs to make them as streamlined as possible. However, since it is unknown how much of a performance savings this will gain, I had to build up the replacement APIs (which are useful anyway) and now I'm adjusting the CoreRPG and other included rulesets to only use the replacement APIs. This will allow me to make an internal build with the simplified databasenode data objects and actually run performance tests to see whether my theory is valid.

    This is something I've been thinking about for many years, but the sheer volume of heavy lifting and disruption always pushed it to backburner. In reality, the coming changes are just one more step in the process that allows me to test the theory. It's not a high-priority project, so it gets done in small chunks. Once I have real testing numbers later this year, we will need to make a decision whether the performance gain justifies the short/medium term chaos of breaking DLC, or coming up with some migration methods.

    Regards,
    JPG

  4. #4
    Will there be an easy explanation for Hobby, non commercial Coders like me to migrate the database node calls to DB. Value calls? F. E. I built an extension for Char sheet, npc sheet with automatization rolls etc and use database node calls for getchild, getparent get or Set value etc All over. Otherwise i hope for next Video from damned, who elevated my Project with this up to this point.

  5. #5
    damned's Avatar
    Join Date
    Mar 2011
    Location
    Australia
    Posts
    26,649
    Blog Entries
    1
    Quote Originally Posted by Elawyn View Post
    Will there be an easy explanation for Hobby, non commercial Coders like me to migrate the database node calls to DB. Value calls? F. E. I built an extension for Char sheet, npc sheet with automatization rolls etc and use database node calls for getchild, getparent get or Set value etc All over. Otherwise i hope for next Video from damned, who elevated my Project with this up to this point.
    Hi Elawyn

    If/when Moon Wizard implements this we will first see DEPRECATION warnings in the console which will tell us what line the code is executing from. Then errors later on. Ultimately I think there will be a lot of Find in Files for "node" and then rewriting all the older method (which I use a lot )
    The required change is not difficult - it might be time consuming though!

  6. #6
    Thx damned for Quick Response. I Was a little concerned so, i am looking forward to an explanation Video from you or a workaround contributed by moon wizard himself. Cheers!

  7. #7
    damned's Avatar
    Join Date
    Mar 2011
    Location
    Australia
    Posts
    26,649
    Blog Entries
    1
    here are a couple of examples:

    existing code:
    Code:
    local nodeWin = window.getDatabaseNode();
    local sCommand = nodeWin.getChild("clichatcommand").getValue();
    local sRollstype = nodeWin.getChild("rollstype").getValue();
    
    local nStart,nEnd,sCommand,sParams = string.find(sCommand, '^/([^%s]+)%s*(.*)');
    if sCommand == "rollon" then
    	nodeWin.getChild("rollstype").setValue("table");
    this would need to be rewritten:
    Code:
    local nodeWin = window.getDatabaseNode();
    local sCommand = DB.getChild(nodeWin, "clichatcommand").getValue();
    local sRollstype = DB.getValue(nodeWin, "rollstype");
    
    local nStart,nEnd,sCommand,sParams = string.find(sCommand, '^/([^%s]+)%s*(.*)');
    if sCommand == "rollon" then
    	DB.getChild(nodeWin, "rollstype").setValue("table");
    lines 2,3 and 7 have been changed.

    where I have used getChild in conjunction with getValue I could have just used getValue but the examples should be valid (I hope).

    EDIT in case people read this far and no further. Moon Wizard has said that those getChild getValues should also be rewritten at the same time:

    Better Code
    Code:
    local nodeWin = window.getDatabaseNode();
    local sCommand = DB.getValue(nodeWin, "clichatcommand");
    local sRollstype = DB.getValue(nodeWin, "rollstype");
    
    local nStart,nEnd,sCommand,sParams = string.find(sCommand, '^/([^%s]+)%s*(.*)');
    if sCommand == "rollon" then
    	DB.setValue(nodeWin, "rollstype", "string", "table");
    and then Trenloe adds that getParent() should also be replaced like this:

    Code:
    nodeWin.GetParent().GetParent().GetChild("string") .getValue("number")
    4 API calls

    Code:
    DB.getValue(nodeWin, "...string.number", "")
    is only 1 API call.

  8. #8
    Quote Originally Posted by damned View Post
    here are a couple of examples:

    existing code:
    Code:
    local nodeWin = window.getDatabaseNode();
    local sCommand = nodeWin.getChild("clichatcommand").getValue();
    local sRollstype = nodeWin.getChild("rollstype").getValue();
    
    local nStart,nEnd,sCommand,sParams = string.find(sCommand, '^/([^%s]+)%s*(.*)');
    if sCommand == "rollon" then
    	nodeWin.getChild("rollstype").setValue("table");
    this would need to be rewritten:
    Code:
    local nodeWin = window.getDatabaseNode();
    local sCommand = DB.getChild(nodeWin, "clichatcommand").getValue();
    local sRollstype = DB.getValue(nodeWin, "rollstype");
    
    local nStart,nEnd,sCommand,sParams = string.find(sCommand, '^/([^%s]+)%s*(.*)');
    if sCommand == "rollon" then
    	DB.getChild(nodeWin, "rollstype").setValue("table");
    lines 2,3 and 7 have been changed.

    where I have used getChild in conjunction with getValue I could have just used getValue but the examples should be valid (I hope).
    Thank you. I know the db. Call til now only from the ctnode calls. But if thats the recommended change, i am looking forward to Do so. Thanks a lot!

  9. #9
    To go one step further with @damned's example code:

    Old Code
    Code:
    local nodeWin = window.getDatabaseNode();
    local sCommand = nodeWin.getChild("clichatcommand").getValue();
    local sRollstype = nodeWin.getChild("rollstype").getValue();
    
    local nStart,nEnd,sCommand,sParams = string.find(sCommand, '^/([^%s]+)%s*(.*)');
    if sCommand == "rollon" then
    	nodeWin.getChild("rollstype").setValue("table");
    New Code
    Code:
    local nodeWin = window.getDatabaseNode();
    local sCommand = DB.getValue(nodeWin, "clichatcommand");
    local sRollstype = DB.getValue(nodeWin, "rollstype");
    
    local nStart,nEnd,sCommand,sParams = string.find(sCommand, '^/([^%s]+)%s*(.*)');
    if sCommand == "rollon" then
    	DB.setValue(nodeWin, "rollstype", "string", "table");
    Lines 2 and 7 actually need to be even more streamlined.

    Regards,
    JPG

  10. #10
    Even more, thank you too, mood wizard! If i understand it the right way, if i can get the value directly from db without specifing the child first, but taking the string in brackets (node, "string", "number" ). If starting a call from f. E. a list today i use nodeWin.GetParent().GetParent().GetChild("string") .getValue("number"). Is this still neccassary/possible with the db. Call for the value? Ok. Sorry for explicit questions to you All. I will See and try, when the changes come in Action. But this is so far good to hear and Not so overwhelming like i was concerned about in first place.

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