Fantasy Grounds Fridays Pre
View RSS Feed


A Neophyte Tackles the FG Extension - Dumping DB's Field Names (1 of 2)

Rate this Entry
This session I will implement some Lua script to dump database field names to the console.

Two housekeeping items:
(1) This blog is very long. I was required to divide it into two parts. This is part 1 of 2.
(2) You should consider making your browser full-screen so that the code displays correctly.

I shall try to describe my tactics in solving a problem but not each and every step of their implementation. In a previous post I looked at the <inventorylist> in the db.xml file. A couple of tags higher up in the hierarchy is <charsheet>. It’s reasonable to assume this is character sheet data, and due to the XML’s hierarchy it contains an inventory list.

Previously, I used “Find in Files” in Notepad++ to get a list of files containing specified text. This time, I’ll search for charsheet, but I’ll narrow the search parameters. I’ll only search in Lua files by placing *.lua in the “Filters:” field and I’ll only search in the rulesets\CoreRPG subfolder of the FG data directory. My search results in 21 files to look through. Aarrgh!

While looking at the details in each of these files, I need to find a Lua function that is triggered by an action in the GUI and that has some sort of reference to charsheet. Luck is with me, I think I have found it in the fifth file, named “charselect_host_entry.lua“, in a function called “openCharacter( )”. To verify that this is the code I am looking for I’ll add a “Debug.console( )” function call and save the file.

function openCharacter()

    Debug.console("ZYX:charselect_host_entry.lua:openCharacter():status", "ARRIVED!");

    Interface.openWindow("charsheet", getDatabaseNode().getNodeName());
Detour: Debug.console(…) is a function call. The stuff between the parentheses are called parameters. When there is more than one parameter they are separated by commas. So in my function call to the console above, there are two parameters.
My first parameter is a combination of four items separated by colons. They are:
(1) a unique three character string, oftentimes my initials, this time I use ZYX
(2) the name of the file I am putting the call in
(3) the name of function I am adding the call to
(4) the name of the data I am printing out (e.g. a variable name)
My second parameter is the data I am interested in, in this case “program execution made it to here!”
Consistently using this format helps me know that it is my code that wrote to the console and where I put that function call. As I add console calls to existing code, knowing where the information is coming from is just as important as the information itself.

Since FG is not running, I start it up and load my “Tom‘s Holdings” campaign. I then go to “Characters” and click my “Jimmy the Greek” character. The following immediately appears in the console window:
Runtime Notice: s'ZYX:charselect_host_entry.lua:openCharacter():st atus' | s'ARRIVED!'
Success! I found a place in existing code that easily triggers my console call. It will be the right place, IF there is some link to the data I want. Note in the section of code listed above, in the line that begins with “Interface”, there is a function call “getDatabaseNode( )”. It seems reasonable to me that that function might provide the answer to “IF“. So I add another console call in the line just after my first call and save the file.

Debug.console("ZYX:charselect_host_entry.lua:openCharacter():dbnode", getDatabaseNode());
Since FG is running I need to reload my edited ruleset. I type /reload ruleset in the chat window and press Enter. Then bring up the character “Jimmy the Greek” again.

Runtime Notice: Reloading ruleset
Runtime Notice: s'ZYX:charselect_host_entry.lua:openCharacter():st atus' | s'ARRIVED!'
Runtime Notice: s'ZYX:charselect_host_entry.lua:openCharacter():db node' | databasenode = { }
Fantastic, “charsheet” and “id-00001” same as in the db.xml file!

Detour: When objects contain objects contain objects, one can visualize this hierarchical relationship as a tree. Starting at a root, and working up through branches and sub branches out to the leaves, the actual data items. In computer programming a collection of data is often called a database. When the database has a hierarchical structure, it is commonly thought of and referred to as a tree. Where different parts intersect one another, two or more branches come together, a branch terminates in a leaf, these intersections are referred to as nodes.

Detour: Recursion is a common programming methodology for navigating a data tree. Recursion is typically just a function that calls itself. The programmer begins execution of the recursive function at a node, the function does whatever data handling is necessary then calls itself for each of the branches on the node. Recursively doing this until every sub branch from the original node has been processed.
IMPORTANT! One might immediately wonder, how does it know when to stop? That is the crux of recursion. Should the software developer fail to ensure the function has adequate terminating functionality, the recursive routine will enter an infinite loop. The computer will appear to hang. It is likely the program and possibly the operating system will crash.

Now on to the coding of my recursive function. I have heavily commented the code so that I don’t have to document what’s going on here in the narration. Note that there is no recursion yet. (When you are playing with “Doom!“ and you have the BFG, it’s one step at a time.)

function openCharacter()
  -- these aren't needed any more, move the output of the node info to the recursive
  -- Debug.console("ZYX:charselect_host_entry.lua:openCharacter():status", "ARRIVED!");
  -- Debug.console("ZYX:charselect_host_entry.lua:openCharacter():dbnode", getDatabaseNode());
  -- fire up the recursive function, provide the starting node as a parameter

	Interface.openWindow("charsheet", getDatabaseNode().getNodeName());

function dumpNodeNames(oCurr)
  -- recursive function!, it will call itself, always providing the next node 
  -- get the path of the parameter, a node, and send it to the console,
  -- the path is just a string listing all nodes leading to this node
  local sPath = DB.getPath(oCurr);
  Debug.console("ZYX:charselect_host_entry.lua:dumpNodeNames():path", sPath);


Submit "A Neophyte Tackles the FG Extension - Dumping DB's Field Names (1 of 2)" to Digg Submit "A Neophyte Tackles the FG Extension - Dumping DB's Field Names (1 of 2)" to Submit "A Neophyte Tackles the FG Extension - Dumping DB's Field Names (1 of 2)" to StumbleUpon Submit "A Neophyte Tackles the FG Extension - Dumping DB's Field Names (1 of 2)" to Google Submit "A Neophyte Tackles the FG Extension - Dumping DB's Field Names (1 of 2)" to Facebook Submit "A Neophyte Tackles the FG Extension - Dumping DB's Field Names (1 of 2)" to Twitter

Updated May 18th, 2016 at 02:13 by Minty23185Fresh



Joshua Stream Pre

Log in

Log in