Lua:Class:Addresslist
AddressList class: (Inheritance: Panel->WinControl->Control->Component->Object)
The AddressList class represents Cheat Engine's address list (also known as the cheat table), which is the primary container for managing MemoryRecord entries. This class provides methods to create, retrieve, and manipulate memory records, as well as trigger UI updates for description, address, type, and value changes.
The AddressList is accessible through the getAddressList function, which returns the main address list instance from Cheat Engine's main form.
Contents
- 1 Properties
- 2 Methods
- 3 Usage Examples
- 3.1 Basic Address List Access
- 3.2 Creating Memory Records
- 3.3 Finding Records by Description
- 3.4 Finding Records by ID
- 3.5 Working with Selected Records
- 3.6 Triggering UI Dialogs
- 3.7 Managing Auto Assembler Scripts
- 3.8 Iterating Through All Records
- 3.9 Batch Operations
- 3.10 Rebuilding Description Cache
- 3.11 Working with Hierarchical Records
- 3.12 Advanced: Monitoring Changes
- 4 Important Notes
- 5 See also
Properties
| Property | Type | Access | Description |
|---|---|---|---|
| Count | Integer | Read-only | The total number of MemoryRecord entries in the address list (all levels, including children). |
| SelectedRecord | MemoryRecord | Read/Write | Gets or sets the currently selected memory record. Returns nil if no record is selected. Setting this property deselects all other records and selects the specified one. |
| MemoryRecord[index] | MemoryRecord | Read-only | Array accessor to retrieve memory records by index (0-based). Can also be accessed using function call syntax: AddressList[index]. Same as getMemoryRecord(index). Alternatively, can be accessed with a string to search by description. |
| [index] | MemoryRecord | Read-only | Default array accessor. Equivalent to MemoryRecord[index]. |
Properties Not Exposed to Lua
The following properties are available in the Pascal TAddressList class but are not exposed to Lua scripts:
- LoadedTableVersion
- SelCount
- CheckboxActiveSelectedColor, CheckboxActiveColor, CheckboxSelectedColor, CheckboxColor
- SelectedBackgroundColor, SelectedSecondaryBackgroundColor
- ExpandSignColor, IncreaseArrowColor, DecreaseArrowColor
- MouseHighlightedRecord
- OnDescriptionChange, OnAddressChange, OnTypeChange, OnValueChange, OnAutoAssemblerEdit (event callbacks)
These properties are used internally by Cheat Engine's UI but cannot be accessed or modified from Lua scripts.
Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
| getCount | None | Integer | Returns the total number of memory records in the address list. |
| getMemoryRecord | Integer (index) OR String (description) | MemoryRecord | Returns the memory record at the specified index (0-based). Also accepts a string description to search by description. Returns nil if index is out of bounds or description not found. |
| getMemoryRecordByDescription | String (description) | MemoryRecord | Returns the first memory record with the specified description. Returns nil if not found. Uses an internal hash table for fast lookups. |
| getMemoryRecordByID | Integer (id) | MemoryRecord | Returns the memory record with the specified unique ID. Returns nil if not found. |
| createMemoryRecord | None | MemoryRecord | Creates a new memory record and adds it to the address list. The record is initialized with default values (description: "Plugin Address", address: "0", type: vtDword). Returns the newly created MemoryRecord object. |
| getSelectedRecords | None | Table | Returns a table (1-indexed) containing all currently selected MemoryRecord objects. Returns nil if no records are selected. |
| getSelectedRecord | None | MemoryRecord | Returns the currently selected memory record. Same as accessing the SelectedRecord property. Returns nil if no record is selected. |
| setSelectedRecord | MemoryRecord (memrec) | None | Sets the currently selected memory record, deselecting all others. Same as setting the SelectedRecord property. |
| doDescriptionChange | None | None | Shows the GUI window to change the description of the selected entry. Opens a dialog allowing the user to modify the description. Equivalent to double-clicking the description column. |
| doAddressChange | None | None | Shows the GUI window to change the address of the selected entry. Opens a dialog allowing the user to modify the address and pointer settings. Equivalent to double-clicking the address column. |
| doTypeChange | None | None | Shows the GUI window to change the type of the selected entries. Opens a dialog allowing the user to change the variable type. Equivalent to double-clicking the type column. |
| doValueChange | None | None | Shows the GUI window to change the value of the selected entries. Opens a dialog allowing the user to modify the value. Equivalent to double-clicking the value column. |
| disableAllWithoutExecute | None | None | Disables all active auto assembler script entries without executing their [DISABLE] sections. Useful for quickly disabling all scripts when detaching from a process or when scripts have failed. |
| rebuildDescriptionCache | None | None | Rebuilds the internal hash table used for fast description-based lookups. Call this after making many changes to descriptions if you need to ensure getMemoryRecordByDescription reflects the latest state. |
Inherited Properties and Methods
As AddressList inherits from Panel, it also has access to all Panel, WinControl, Control, Component, and Object properties and methods. However, most inherited UI properties are not typically used in scripting contexts since the AddressList is part of the main Cheat Engine form.
Useful inherited properties include:
- Visible (boolean) - Show/hide the address list panel
- Enabled (boolean) - Enable/disable user interaction
- PopupMenu (PopupMenu) - Custom context menu for the address list
Usage Examples
Basic Address List Access
-- Get the main address list
local addressList = getAddressList()
-- Get the count of all records
print("Total records: " .. addressList.Count)
-- Get selected records to find selection count
local selected = addressList.getSelectedRecords()
if selected then
print("Selected records: " .. #selected)
else
print("Selected records: 0")
end
-- Access records by index (0-based)
if addressList.Count > 0 then
local firstRecord = addressList[0]
print("First record: " .. firstRecord.Description)
-- Alternative syntax
local secondRecord = addressList.getMemoryRecord(1)
if secondRecord then
print("Second record: " .. secondRecord.Description)
end
end
-- Access by description (alternative to index)
local healthRec = addressList["Player Health"]
if healthRec then
print("Found by description: " .. healthRec.Description)
end
-- Get/set selected record
local selected = addressList.SelectedRecord
if selected then
print("Currently selected: " .. selected.Description)
print("Value: " .. selected.Value)
end
Creating Memory Records
local addressList = getAddressList()
-- Create a basic memory record
local mr = addressList.createMemoryRecord()
mr.Description = "Player Health"
mr.Address = "game.exe+1234"
mr.Type = vtDword
-- Create multiple records
local stats = {"Health", "Mana", "Stamina"}
local offsets = {0x10, 0x14, 0x18}
for i = 1, #stats do
local record = addressList.createMemoryRecord()
record.Description = "Player " .. stats[i]
record.Address = string.format("player_base+%X", offsets[i])
record.Type = vtFloat
record.ShowAsHex = false
end
print("Created " .. #stats .. " new records")
print("Total records now: " .. addressList.Count)
Finding Records by Description
local addressList = getAddressList()
-- Find by exact description
local healthRecord = addressList.getMemoryRecordByDescription("Player Health")
if healthRecord then
print("Health value: " .. healthRecord.Value)
healthRecord.Active = true
else
print("Player Health not found")
end
-- Alternative: Search by index with description
local record = addressList.getMemoryRecord("Player Mana")
if record then
print("Mana address: " .. record.Address)
end
-- Note: Description lookup is case-sensitive
local notFound = addressList.getMemoryRecordByDescription("player health") -- Won't find "Player Health"
Finding Records by ID
local addressList = getAddressList()
-- Get a record's ID and store it
local healthRecord = addressList.getMemoryRecordByDescription("Player Health")
if healthRecord then
local storedID = healthRecord.ID
print("Stored ID: " .. storedID)
-- Later, retrieve by ID (even if description changed)
local retrievedRecord = addressList.getMemoryRecordByID(storedID)
if retrievedRecord then
print("Retrieved: " .. retrievedRecord.Description)
print("Same record: " .. tostring(healthRecord == retrievedRecord))
end
end
-- IDs are unique and persistent within a session
-- Useful for tracking records across description changes
Working with Selected Records
local addressList = getAddressList()
-- Get all selected records
local selected = addressList.getSelectedRecords()
if selected then
print("Processing " .. #selected .. " selected records")
for i = 1, #selected do
local record = selected[i]
print(i .. ": " .. record.Description)
-- Modify all selected records
record.Active = true
record.Color = 0x0000FF -- Red (BGR format)
end
else
print("No records selected")
end
-- Select a specific record programmatically
local targetRecord = addressList.getMemoryRecordByDescription("God Mode")
if targetRecord then
addressList.SelectedRecord = targetRecord
print("Selected: " .. targetRecord.Description)
end
-- Check current selection
local currentSelection = addressList.getSelectedRecord()
if currentSelection then
print("Current selection: " .. currentSelection.Description)
end
Triggering UI Dialogs
local addressList = getAddressList()
-- Select a record first
local record = addressList.getMemoryRecordByDescription("Player Health")
if record then
addressList.SelectedRecord = record
-- Open description editor dialog
-- addressList.doDescriptionChange()
-- Open address editor dialog
-- addressList.doAddressChange()
-- Open type selector dialog
-- addressList.doTypeChange()
-- Open value editor dialog
-- addressList.doValueChange()
-- Note: These dialogs are modal and will pause script execution
-- Uncomment the lines above to test interactively
end
Managing Auto Assembler Scripts
local addressList = getAddressList() -- Create an auto assembler script local script = addressList.createMemoryRecord() script.Description = "Infinite Health" script.Type = vtAutoAssembler script.Script = [[ [ENABLE] aobscan(health_code,89 0D * * * * 8B 45 08) alloc(newmem,32) label(code) label(return) newmem: code: mov [health_address],#1000 // Set to 1000 mov [edx],ecx jmp return health_code: jmp newmem nop return: registersymbol(health_code) [DISABLE] health_code: db 89 0D * * * * 8B 45 08 unregistersymbol(health_code) dealloc(newmem) ]] -- Activate the script script.Active = true -- Later, disable all scripts without executing [DISABLE] sections -- Useful when the process is about to close or has crashed addressList.disableAllWithoutExecute()
Iterating Through All Records
local addressList = getAddressList()
-- Iterate through all records (including children)
print("=== All Records ===")
for i = 0, addressList.Count - 1 do
local record = addressList[i]
local indent = string.rep(" ", record.Parent and 1 or 0)
print(string.format("%s[%d] %s = %s (%s)",
indent, i, record.Description, record.Value,
record.Active and "Active" or "Inactive"))
end
-- Find all active records
print("\n=== Active Records ===")
local activeCount = 0
for i = 0, addressList.Count - 1 do
local record = addressList[i]
if record.Active then
print(record.Description)
activeCount = activeCount + 1
end
end
print("Total active: " .. activeCount)
-- Find all records of a specific type
print("\n=== Float Records ===")
for i = 0, addressList.Count - 1 do
local record = addressList[i]
if record.Type == vtFloat or record.Type == vtDouble then
print(record.Description .. " @ " .. record.Address)
end
end
Batch Operations
local addressList = getAddressList()
-- Deactivate all records
print("Deactivating all records...")
for i = 0, addressList.Count - 1 do
addressList[i].Active = false
end
-- Activate records matching a pattern
print("Activating player-related records...")
local activatedCount = 0
for i = 0, addressList.Count - 1 do
local record = addressList[i]
if record.Description:lower():find("player") then
record.Active = true
activatedCount = activatedCount + 1
end
end
print("Activated " .. activatedCount .. " records")
-- Change all values matching a condition
for i = 0, addressList.Count - 1 do
local record = addressList[i]
local numValue = tonumber(record.Value)
if numValue and numValue < 100 then
record.Value = "999"
print("Changed " .. record.Description .. " to 999")
end
end
Rebuilding Description Cache
local addressList = getAddressList()
-- Make many description changes
for i = 0, addressList.Count - 1 do
local record = addressList[i]
record.Description = "Modified_" .. record.Description
end
-- Rebuild the description cache for fast lookups
addressList.rebuildDescriptionCache()
-- Now lookups will work correctly
local modifiedRecord = addressList.getMemoryRecordByDescription("Modified_Player Health")
if modifiedRecord then
print("Found: " .. modifiedRecord.Description)
end
-- Note: The cache is automatically updated for individual changes,
-- but rebuilding is useful after bulk modifications or when debugging
Working with Hierarchical Records
local addressList = getAddressList()
-- Create a parent group
local group = addressList.createMemoryRecord()
group.Description = "Player Stats"
group.IsGroupHeader = true
group.Options = "[moActivateChildrenAsWell,moDeactivateChildrenAsWell]"
-- Create children and attach to group
local childDescriptions = {"Health", "Mana", "Stamina"}
for i, desc in ipairs(childDescriptions) do
local child = addressList.createMemoryRecord()
child.Description = desc
child.Type = vtDword
child.Address = string.format("player_base+%X", (i-1) * 4)
child.appendToEntry(group)
end
-- Activate the group (children will activate too)
group.Active = true
-- Note: All records are still in the flat addressList.Count
-- Parent-child relationships are maintained separately
print("Total records: " .. addressList.Count)
print("Group children: " .. group.Count)
Advanced: Monitoring Changes
local addressList = getAddressList()
-- Store initial state
local recordStates = {}
for i = 0, addressList.Count - 1 do
local record = addressList[i]
recordStates[record.ID] = {
description = record.Description,
value = record.Value,
active = record.Active
}
end
-- Later, check for changes
print("=== Changes Detected ===")
for i = 0, addressList.Count - 1 do
local record = addressList[i]
local oldState = recordStates[record.ID]
if oldState then
if oldState.value ~= record.Value then
print(record.Description .. " value changed: " ..
oldState.value .. " -> " .. record.Value)
end
if oldState.active ~= record.Active then
print(record.Description .. " activation changed: " ..
tostring(oldState.active) .. " -> " .. tostring(record.Active))
end
end
end
Important Notes
Record Indexing
- The MemoryRecord[index] property uses 0-based indexing
- The getSelectedRecords() method returns a 1-indexed table (Lua convention)
- Child indices within parent records use 0-based indexing
- You can use AddressList[index] as a shorthand for AddressList.MemoryRecord[index]
- You can also use AddressList["description"] to search by description
Description Lookup Performance
- getMemoryRecordByDescription uses an internal hash table for O(1) lookups
- The cache is automatically maintained for most operations
- Some reserved descriptions (e.g., "BYTE", "WORD", "DWORD", "QWORD", "INT", "FLOAT", "DOUBLE") cannot be found by description as they're in the forbidden list
- If lookups fail after many changes, call rebuildDescriptionCache()
- Description lookups are case-sensitive
Selection Behavior
- Setting SelectedRecord deselects all other records
- Multiple selection is typically done through the UI (Ctrl+Click, Shift+Click)
- getSelectedRecords() includes records at all hierarchy levels if selected
- Selected records remain selected until explicitly changed
- Use getSelectedRecord() or SelectedRecord property to get the main selected record
Memory Record Lifecycle
- Creating records with createMemoryRecord() adds them to the address list
- Records are removed from the count when deleted via memoryrecord.delete()
- The Count property reflects all records at all hierarchy levels (including children)
- Deleting a parent record automatically deletes all its children
Thread Safety
- Address list operations should be performed on the main thread
- Use synchronize if accessing from background threads
- UI dialog methods (do*Change) must be called from the main thread and will block script execution
See also
Related Functions
- getAddressList - Get the main AddressList object
- getMainForm - Get the main Cheat Engine form
Related Classes
- MemoryRecord - Individual address list entries
- MemoryRecordHotkey - Hotkeys attached to memory records
- Panel - Parent class
- WinControl - Grandparent class
- Control - Base control class
- Component - Base component class