Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Lua Deep Table Introspection and Call Path Analyzer ..

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials -> LUA Tutorials
View previous topic :: View next topic  
Author Message
AylinCE
Grandmaster Cheater Supreme
Reputation: 37

Joined: 16 Feb 2017
Posts: 1532

PostPosted: Thu Nov 13, 2025 11:26 am    Post subject: Lua Deep Table Introspection and Call Path Analyzer .. Reply with quote

A nested table analysis and call path analysis code for testing table dumps and call paths of long, nested tables in Lua or in an application.

This is a helpful function for those who create very long tables, allowing them to check where they left off and how to call them.

I won't go into much detail.

You will understand what it does with a dump analysis code, a sample table and output.

Dump, analysis:

Code:
--[[
  Function: deepDumpWithPath
  Description: Recursively prints the contents of a Lua table, including nested subtables,
               without depth restrictions. It also displays the full **call path** (syntax) for accessing each element. Safely handles circular references.
  Parameters:
    tbl: (table) - The main table to inspect.
    indent: (number) [Optional] - The current indentation level (defaults to 0).
    currentPath: (string) [Optional] - The accumulated call path string
                 (e.g., "myTable[1].settings"). Defaults to "table".
    seen: (table) [Optional] - Internal table to track circular references.
--]]
function deepDumpWithPath(tbl, indent, currentPath, seen)
    indent = indent or 0
    seen = seen or {}
    currentPath = currentPath or "table" -- Default starting path
    local currentIndent = string.rep("  ", indent)

    -- 1. Table Check and Circular Reference Check
    if type(tbl) ~= "table" then
        print(currentIndent .. "[ERROR: Expected table, received: " .. type(tbl) .. "]")
        return
    end

    if seen[tbl] then
        print(currentIndent .. "{" .. currentPath .. " = ... CIRCULAR REFERENCE DETECTED ...}")
        return
    end
    -- Mark the current table as seen
    seen[tbl] = true

    print(currentIndent .. "{ > " .. currentPath .. " < .. (TABLE  START)") -- Print the table path at the opening brace

    -- 2. Traverse Elements
    for k, v in pairs(tbl) do
        local keyString
        local nextPath
        local nextIndent = string.rep(" -", indent + 1)

        -- Format the key and build the next call path
        if type(k) == "string" then
            -- String keys: Use brackets for consistency, but build path for dot notation if possible
            if string.match(k, "^[a-zA-Z_][a-zA-Z0-9_]*$") then
                keyString = string.format('["%s"]', k)
                nextPath = currentPath .. "." .. k -- Suitable for object access (e.g., CE objects)
            else
                keyString = string.format('["%s"]', k)
                nextPath = currentPath .. string.format('["%s"]', k)
            end
        else
            -- Numeric keys: object[index]
            keyString = string.format("[%s]", tostring(k))
            nextPath = currentPath .. string.format("[%s]", tostring(k))
        end

        -- Process based on Value Type
        if type(v) == "table" then
            print(nextIndent .. keyString .. " = [table]")
            -- Recursive call: Pass the new path and increased indentation
            deepDumpWithPath(v, indent + 2, nextPath, seen)

        elseif type(v) == "function" then
            -- Special output for functions
            print(nextIndent .. keyString .. " = [Function] -- CALL: " .. nextPath .. "()")

        elseif type(v) == "userdata" then
            -- Special output for UserData/CE Objects
            print(nextIndent .. keyString .. " = [UserData] -- PATH: " .. nextPath)

        else
            -- Simple types (string, number, boolean, etc.)
            print(nextIndent .. keyString .. " = " .. tostring(v) .. " -- PATH: " .. nextPath)
        end
    end

    -- 3. Close Table
    print(currentIndent .. "} > " .. currentPath .. " < .. (TABLE  END)")
end


-- ************************ E X A M P L E T A B L E ************************--

Code:
-- Global assumption for CE's AddressList object for demonstration purposes
--local AddressList = AddressList -- Use the actual CE object in CE environment

local GameConfig_V3 = {
    -- 1. Main Configuration Structure
    ["GeneralSettings"] = {
        Resolution = "1920x1080",
        FPS_Cap = 144,
        ["DebugMode_Enabled"] = true,
        -- Array with numerical indices (Error Codes)
        ErrorCodes = {401, 404, 500, [4] = 503}
    },

    -- 2. Resources and Functions
    Resources = {
        -- Function: Simulates a method to format player names
        formatName = function(name) return string.upper(name) end,

        -- UserData Simulation (as seen in CE)
        CurrentAddressList = AddressList, -- References a CE UserData object

        -- Mixed Table (String and Numerical keys)
        Materials = {
            Wood = 500,
            Stone = 250,
            ["Special Dust"] = 10,
            [99] = "Unused slot"
        }
    },

    -- 3. Deeply Nested Player Data
    PlayerData = {
        ["Player_1"] = {
            -- Nested Array of Tables
            Inventory = {
                {id = 101, name = "Health Potion", count = 3},
                {id = 205, name = "Magic Scroll", count = 1}
            },
            Position = {x = 12.5, y = 45.1, z = 0.0},
            ["isOnline"] = true,

            -- String-keyed sub-table
            Stats = {
                HP = 100,
                MP = 50,
                Attack = 15
            }
        },
        ["Player_2"] = {
            Inventory = {}, -- Empty table array
            Position = {x = 88.0, y = 12.0}
        }
    },

    -- 4. Circular Reference (for safety testing)
    Reference = nil
}

-- Create the circular reference (Table references itself!)
GameConfig_V3.Reference = GameConfig_V3


-- ********************************* U S E ***********************************--

Code:
deepDumpWithPath(GameConfig_V3, 0, "GameConfig_V3")


-- ****************************** R E S U L T ********************************--

Code:
{ > GameConfig_V3 < .. (TABLE  START)
 -["PlayerData"] = [table]
    { > GameConfig_V3.PlayerData < .. (TABLE  START)
 - - -["Player_2"] = [table]
        { > GameConfig_V3.PlayerData.Player_2 < .. (TABLE  START)
 - - - - -["Position"] = [table]
            { > GameConfig_V3.PlayerData.Player_2.Position < .. (TABLE  START)
 - - - - - - -["y"] = 12.0 -- PATH: GameConfig_V3.PlayerData.Player_2.Position.y
 - - - - - - -["x"] = 88.0 -- PATH: GameConfig_V3.PlayerData.Player_2.Position.x
            } > GameConfig_V3.PlayerData.Player_2.Position < .. (TABLE  END)
 - - - - -["Inventory"] = [table]
            { > GameConfig_V3.PlayerData.Player_2.Inventory < .. (TABLE  START)
            } > GameConfig_V3.PlayerData.Player_2.Inventory < .. (TABLE  END)
        } > GameConfig_V3.PlayerData.Player_2 < .. (TABLE  END)
 - - -["Player_1"] = [table]
        { > GameConfig_V3.PlayerData.Player_1 < .. (TABLE  START)
 - - - - -["Stats"] = [table]
            { > GameConfig_V3.PlayerData.Player_1.Stats < .. (TABLE  START)
 - - - - - - -["HP"] = 100 -- PATH: GameConfig_V3.PlayerData.Player_1.Stats.HP
 - - - - - - -["MP"] = 50 -- PATH: GameConfig_V3.PlayerData.Player_1.Stats.MP
 - - - - - - -["Attack"] = 15 -- PATH: GameConfig_V3.PlayerData.Player_1.Stats.Attack
            } > GameConfig_V3.PlayerData.Player_1.Stats < .. (TABLE  END)
 - - - - -["isOnline"] = true -- PATH: GameConfig_V3.PlayerData.Player_1.isOnline
 - - - - -["Position"] = [table]
            { > GameConfig_V3.PlayerData.Player_1.Position < .. (TABLE  START)
 - - - - - - -["y"] = 45.1 -- PATH: GameConfig_V3.PlayerData.Player_1.Position.y
 - - - - - - -["x"] = 12.5 -- PATH: GameConfig_V3.PlayerData.Player_1.Position.x
 - - - - - - -["z"] = 0.0 -- PATH: GameConfig_V3.PlayerData.Player_1.Position.z
            } > GameConfig_V3.PlayerData.Player_1.Position < .. (TABLE  END)
 - - - - -["Inventory"] = [table]
            { > GameConfig_V3.PlayerData.Player_1.Inventory < .. (TABLE  START)
 - - - - - - -[1] = [table]
                { > GameConfig_V3.PlayerData.Player_1.Inventory[1] < .. (TABLE  START)
 - - - - - - - - -["name"] = Health Potion -- PATH: GameConfig_V3.PlayerData.Player_1.Inventory[1].name
 - - - - - - - - -["id"] = 101 -- PATH: GameConfig_V3.PlayerData.Player_1.Inventory[1].id
 - - - - - - - - -["count"] = 3 -- PATH: GameConfig_V3.PlayerData.Player_1.Inventory[1].count
                } > GameConfig_V3.PlayerData.Player_1.Inventory[1] < .. (TABLE  END)
 - - - - - - -[2] = [table]
                { > GameConfig_V3.PlayerData.Player_1.Inventory[2] < .. (TABLE  START)
 - - - - - - - - -["name"] = Magic Scroll -- PATH: GameConfig_V3.PlayerData.Player_1.Inventory[2].name
 - - - - - - - - -["id"] = 205 -- PATH: GameConfig_V3.PlayerData.Player_1.Inventory[2].id
 - - - - - - - - -["count"] = 1 -- PATH: GameConfig_V3.PlayerData.Player_1.Inventory[2].count
                } > GameConfig_V3.PlayerData.Player_1.Inventory[2] < .. (TABLE  END)
            } > GameConfig_V3.PlayerData.Player_1.Inventory < .. (TABLE  END)
        } > GameConfig_V3.PlayerData.Player_1 < .. (TABLE  END)
    } > GameConfig_V3.PlayerData < .. (TABLE  END)
 -["GeneralSettings"] = [table]
    { > GameConfig_V3.GeneralSettings < .. (TABLE  START)
 - - -["DebugMode_Enabled"] = true -- PATH: GameConfig_V3.GeneralSettings.DebugMode_Enabled
 - - -["ErrorCodes"] = [table]
        { > GameConfig_V3.GeneralSettings.ErrorCodes < .. (TABLE  START)
 - - - - -[1] = 401 -- PATH: GameConfig_V3.GeneralSettings.ErrorCodes[1]
 - - - - -[2] = 404 -- PATH: GameConfig_V3.GeneralSettings.ErrorCodes[2]
 - - - - -[3] = 500 -- PATH: GameConfig_V3.GeneralSettings.ErrorCodes[3]
 - - - - -[4] = 503 -- PATH: GameConfig_V3.GeneralSettings.ErrorCodes[4]
        } > GameConfig_V3.GeneralSettings.ErrorCodes < .. (TABLE  END)
 - - -["FPS_Cap"] = 144 -- PATH: GameConfig_V3.GeneralSettings.FPS_Cap
 - - -["Resolution"] = 1920x1080 -- PATH: GameConfig_V3.GeneralSettings.Resolution
    } > GameConfig_V3.GeneralSettings < .. (TABLE  END)
 -["Resources"] = [table]
    { > GameConfig_V3.Resources < .. (TABLE  START)
 - - -["formatName"] = [Function] -- CALL: GameConfig_V3.Resources.formatName()
 - - -["Materials"] = [table]
        { > GameConfig_V3.Resources.Materials < .. (TABLE  START)
 - - - - -["Wood"] = 500 -- PATH: GameConfig_V3.Resources.Materials.Wood
 - - - - -["Special Dust"] = 10 -- PATH: GameConfig_V3.Resources.Materials["Special Dust"]
 - - - - -[99] = Unused slot -- PATH: GameConfig_V3.Resources.Materials[99]
 - - - - -["Stone"] = 250 -- PATH: GameConfig_V3.Resources.Materials.Stone
        } > GameConfig_V3.Resources.Materials < .. (TABLE  END)
 - - -["CurrentAddressList"] = [UserData] -- PATH: GameConfig_V3.Resources.CurrentAddressList
    } > GameConfig_V3.Resources < .. (TABLE  END)
 -["Reference"] = [table]
    {GameConfig_V3.Reference = ... CIRCULAR REFERENCE DETECTED ...}
} > GameConfig_V3 < .. (TABLE  END)



Of course, kudos to all the coders who create tables of this size.

Until we meet again with another crazy topic or solution, enjoy!

_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials -> LUA Tutorials All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites