Skip to content

Database & Persistence Hooks

This page documents the hooks for database operations, data persistence, and entity management in the Lilia framework.


Overview

The database and persistence system forms the foundation of Lilia's data management architecture, providing comprehensive hooks for managing data storage, entity persistence, character management, and inventory operations. These hooks enable developers to customize every aspect of data handling, from basic save/load operations to complex entity state management and character lifecycle events.

The database and persistence system in Lilia is built around a sophisticated architecture that supports multiple database backends, automatic data serialization, and extensive customization capabilities. The system handles everything from simple key-value storage to complex relational data structures, ensuring that all game state is properly maintained across server restarts and player sessions.

Core Data Management Hooks provide the fundamental building blocks for data persistence, including entity state tracking, data validation, and automatic serialization. These hooks allow developers to define custom data structures, implement data migration strategies, and ensure data integrity across all operations.

Character Lifecycle Management hooks handle the complete character experience from creation to deletion, including character data persistence, inventory management, and state restoration. These hooks enable complex character systems with custom attributes, persistent inventories, and sophisticated character progression mechanics.

Entity Persistence System hooks manage the persistence of game entities, allowing developers to save and restore entity states, positions, and custom properties. This system supports both automatic persistence for important entities and manual control for specific use cases.

Inventory and Item Management hooks provide comprehensive control over item storage, transfer, and persistence. These hooks enable complex inventory systems with custom item properties, transfer restrictions, and automatic data synchronization.

Database Schema Management hooks allow developers to customize database initialization, table creation, and data migration processes. These hooks ensure that custom data structures are properly integrated into the framework's database system.

Data Validation and Security hooks provide mechanisms for data validation, sanitization, and security checks. These hooks help prevent data corruption, ensure data integrity, and implement custom security measures for sensitive data.

Performance and Optimization hooks enable developers to optimize database operations, implement caching strategies, and manage data cleanup processes. These hooks help maintain optimal performance even with large amounts of persistent data.

Cross-System Integration hooks facilitate integration between the persistence system and other framework components, ensuring that data changes are properly propagated throughout the system and that all components remain synchronized.

Error Handling and Recovery hooks provide robust error handling for database operations, including automatic retry mechanisms, data recovery procedures, and comprehensive logging for debugging and monitoring.

Custom Data Types hooks allow developers to define custom data types and serialization methods, enabling the persistence of complex data structures that go beyond basic Lua types.


OnEntityPersistUpdated

Purpose

Notifies that a persistent entity's stored data has been updated and saved.

When Called

This hook is triggered when: - A persistent entity's data has been modified and saved to disk - The entity persistence system has completed updating stored data - After entity data changes are committed to the database - During the entity persistence update process

Parameters

  • ent (Entity): The persistent entity.
  • data (table): The saved persistence payload for this entity.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- This example demonstrates how to respond when persistent entity data is updated and saved.
-- Persistent entities maintain their state across server restarts.
-- This hook is useful for logging persistence updates and debugging entity state changes.

-- Log when vendor entities are saved to persistence
hook.Add("OnEntityPersistUpdated", "LogVendorSave", function(ent, data)
    -- Check if the entity is valid and is a vendor
    if IsValid(ent) and ent:GetClass() == "lia_vendor" then
        -- Print the vendor's name to server console
        print("Vendor persistence updated:", data.name or "Unknown")
    end
end)

-- Track all entity persistence updates for debugging
hook.Add("OnEntityPersistUpdated", "DebugPersistence", function(ent, data)
    if IsValid(ent) then
        print("Entity", ent:GetClass(), "persistence data updated")
        -- Log specific data fields if they exist
        if data.position then
            print("  Position:", data.position)
        end
        if data.angles then
            print("  Angles:", data.angles)
        end
    end
end)

UpdateEntityPersistence

Purpose

Request that the gamemode re-save a persistent entity's data to disk.

When Called

This hook is triggered when: - A request is made to update persistent entity data - Entity data needs to be re-saved to disk - Manual persistence updates are requested - The system needs to force-save entity state

Parameters

  • ent (Entity): The persistent entity to update.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- This example demonstrates how to request that persistent entity data be re-saved to disk.
-- This hook is useful for forcing immediate persistence updates after entity modifications.
-- It can be used to ensure data is saved when entities are modified programmatically.

-- After editing a vendor entity, persist changes immediately
local vendor = ents.FindByClass("lia_vendor")[1]
if IsValid(vendor) then
    -- Force the entity to save its current state
    hook.Run("UpdateEntityPersistence", vendor)
    print("Vendor persistence updated")
end

-- Update persistence after modifying entity properties
hook.Add("PlayerSay", "UpdateEntityOnCommand", function(ply, text)
    if text == "!saveentities" then
        -- Find all persistent entities and update them
        for _, ent in ents.iterator do
            if ent:GetPersistent() then
                hook.Run("UpdateEntityPersistence", ent)
            end
        end
        ply:ChatPrint("All persistent entities updated")
    end
end)

SaveData

Purpose

Called when the server saves data to disk. Allows adding custom data to the save payload.

When Called

This hook is triggered when: - The server initiates a data save operation - Server data is being prepared for disk storage - Before the save payload is written to disk - During the server save process

Parameters

  • data (table): Save data table to populate.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- This example demonstrates how to add custom data to the server save payload.
-- The save system persists server state across restarts.
-- This hook allows you to include custom data that should be preserved.

-- Add custom data to the save payload
hook.Add("SaveData", "SaveCustomData", function(data)
    -- Add server-specific data that should persist
    data.serverName = GetHostName()
    data.saveTime = os.time()
    data.customValue = "example"

    -- Add player count at time of save
    data.playerCount = #player.GetAll()

    print("Custom data added to save payload")
end)

-- Save module-specific data
hook.Add("SaveData", "SaveModuleData", function(data)
    -- Ensure data table exists
    if not data.modules then
        data.modules = {}
    end

    -- Save custom module state
    data.modules.customModule = {
        enabled = true,
        version = "1.0.0",
        settings = {
            debug = false,
            maxItems = 100
        }
    }
end)

OnDataSet

Purpose

Fires when a key-value pair is stored in the server's data system.

When Called

This hook is triggered when: - A data key-value pair is set in the server data system - Server data is modified or updated - New data entries are created in the data system - Existing data values are changed

Parameters

  • key (string): Data key that was set.
  • value (any): Value that was stored.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Log all data changes for debugging
hook.Add("OnDataSet", "LogDataChanges", function(key, value)
    -- Convert value to string for logging
    local valueStr = tostring(value)
    if istable(value) then
        valueStr = util.TableToJSON(value)
    end

    print("Data set:", key, "=", valueStr)
end)

-- Track specific data keys
hook.Add("OnDataSet", "TrackImportantData", function(key, value)
    -- Monitor important configuration changes
    if string.find(key, "config_") then
        print("Configuration updated:", key, "to", tostring(value))

        -- Notify administrators of config changes
        for _, ply in player.Iterator() do
            if ply:IsAdmin() then
                ply:ChatPrint("Config changed: " .. key)
            end
        end
    end
end)

PersistenceSave

Purpose

Called before an entity's persistence data is saved to disk.

When Called

This hook is triggered when: - An entity is about to have its persistence data saved - Before entity data is written to disk - During the entity save preparation process - Prior to persistence data serialization

Parameters

  • ent (Entity): Entity being saved.
  • data (table): Persistence data being saved.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Add timestamp to all saved entities
hook.Add("PersistenceSave", "AddTimestamp", function(ent, data)
    -- Add save timestamp for tracking
    data.lastSaved = os.time()
    data.saveDate = os.date("%Y-%m-%d %H:%M:%S")

    -- Add entity-specific metadata
    data.entityClass = ent:GetClass()
    data.mapName = game.GetMap()
end)

-- Add custom data for specific entity types
hook.Add("PersistenceSave", "AddCustomData", function(ent, data)
    -- Add custom data for vendor entities
    if ent:GetClass() == "lia_vendor" then
        data.vendorData = {
            lastRestocked = ent.lastRestocked or 0,
            totalSales = ent.totalSales or 0,
            isActive = ent:GetActive()
        }
    end

    -- Add health data for NPCs
    if ent:IsNPC() then
        data.health = ent:Health()
        data.maxHealth = ent:GetMaxHealth()
    end
end)

CanPersistEntity

Purpose

Determines if an entity should be saved for persistence.

When Called

This hook is triggered when: - The system evaluates whether an entity should be persisted - Before an entity is added to the persistence system - During entity persistence eligibility checks - When determining which entities to save

Parameters

  • ent (Entity): Entity to check.

Returns

  • boolean (boolean): False to prevent persistence.

Realm

Server

Example Usage

-- Prevent temporary entities from being saved
hook.Add("CanPersistEntity", "NoTempEntities", function(ent)
    -- Don't save temporary entities
    if ent:IsTemporary() then
        return false
    end

    -- Don't save entities that are being removed
    if ent:IsMarkedForDeletion() then
        return false
    end
end)

-- Only save specific entity types
hook.Add("CanPersistEntity", "OnlySpecificTypes", function(ent)
    local allowedTypes = {
        "lia_vendor",
        "lia_item",
        "lia_money",
        "prop_physics"
    }

    -- Check if entity class is in allowed list
    for _, class in pairs(allowedTypes) do
        if ent:GetClass() == class then
            return true
        end
    end

    -- Deny persistence for other entity types
    return false
end)

GetEntitySaveData

Purpose

Allows modification of the data saved for an entity's persistence.

When Called

This hook is triggered when: - An entity's save data is being prepared for persistence - Before entity data is serialized and stored - During the entity data preparation process - When entity persistence data can be modified

Parameters

  • ent (Entity): Entity being saved.
  • data (table): Current save data.

Returns

  • modifiedData (table): Modified save data.

Realm

Server

Example Usage

-- Add metadata to all saved entities
hook.Add("GetEntitySaveData", "AddMetadata", function(ent, data)
    -- Add system metadata
    data.metadata = {
        savedBy = "system",
        saveVersion = "1.0",
        timestamp = os.time()
    }

    -- Add entity-specific data
    if ent:GetClass() == "lia_vendor" then
        data.vendorInfo = {
            owner = ent:GetOwner() and ent:GetOwner():Nick() or "Unknown",
            lastInteraction = ent.lastInteraction or 0
        }
    end

    return data
end)

-- Clean up sensitive data before saving
hook.Add("GetEntitySaveData", "CleanSensitiveData", function(ent, data)
    -- Remove sensitive information
    if data.password then
        data.password = nil
    end

    -- Sanitize player names
    if data.ownerName then
        data.ownerName = string.gsub(data.ownerName, "[^%w%s]", "")
    end

    return data
end)

OnEntityPersisted

Purpose

Fires when an entity has been successfully saved to persistence.

When Called

This hook is triggered when: - An entity has been successfully persisted to disk - After entity persistence data is written and confirmed - Following successful entity save operations - When entity persistence is completed

Parameters

  • ent (Entity): Entity that was saved.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Log successful entity persistence
hook.Add("OnEntityPersisted", "LogPersistence", function(ent)
    -- Log the entity class and position
    local pos = ent:GetPos()
    print("Entity persisted:", ent:GetClass(), "at", pos)

    -- Track persistence statistics
    if not _G.persistenceStats then
        _G.persistenceStats = {}
    end

    local class = ent:GetClass()
    _G.persistenceStats[class] = (_G.persistenceStats[class] or 0) + 1
end)

-- Notify administrators of important entity saves
hook.Add("OnEntityPersisted", "NotifyAdmins", function(ent)
    -- Notify for vendor saves
    if ent:GetClass() == "lia_vendor" then
        for _, ply in player.Iterator() do
            if ply:IsAdmin() then
                ply:ChatPrint("Vendor entity saved: " .. (ent:GetName() or "Unnamed"))
            end
        end
    end
end)

OnEntityLoaded

Purpose

Called when a persistent entity is loaded from disk.

When Called

This hook is triggered when: - A persistent entity is restored from saved data - During server startup when loading persisted entities - When entity data is read from disk and applied - After entity persistence data is loaded

Parameters

  • ent (Entity): Entity that was loaded.
  • data (table): Loaded persistence data.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Restore entity state from saved data
hook.Add("OnEntityLoaded", "RestoreState", function(ent, data)
    -- Restore health if it was saved
    if data.health then
        ent:SetHealth(data.health)
    end

    -- Restore position and angles
    if data.position then
        ent:SetPos(data.position)
    end
    if data.angles then
        ent:SetAngles(data.angles)
    end

    -- Restore custom properties
    if data.customProps then
        for key, value in pairs(data.customProps) do
            ent:SetKeyValue(key, tostring(value))
        end
    end
end)

-- Initialize vendor-specific data
hook.Add("OnEntityLoaded", "InitializeVendor", function(ent, data)
    if ent:GetClass() == "lia_vendor" then
        -- Restore vendor inventory
        if data.vendorInventory then
            ent:SetInventory(data.vendorInventory)
        end

        -- Restore vendor settings
        if data.vendorSettings then
            ent:SetVendorSettings(data.vendorSettings)
        end

        print("Vendor loaded:", data.name or "Unnamed")
    end
end)

LoadData

Purpose

Called when the server loads saved data from disk.

When Called

This hook is triggered when: - The server loads its saved data from disk - During server startup when restoring saved state - When server data is read from storage - After data files are loaded into memory

Parameters

  • data (table): Loaded data table.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Load custom data from save file
hook.Add("LoadData", "LoadCustomData", function(data)
    -- Load custom values
    if data.customValue then
        print("Loaded custom value:", data.customValue)
        _G.customValue = data.customValue
    end

    -- Load server settings
    if data.serverSettings then
        for key, value in pairs(data.serverSettings) do
            _G.serverSettings = _G.serverSettings or {}
            _G.serverSettings[key] = value
        end
        print("Server settings loaded")
    end

    -- Load module data
    if data.modules then
        for moduleName, moduleData in pairs(data.modules) do
            print("Loading module data for:", moduleName)
            -- Process module-specific data
            if moduleName == "customModule" then
                _G.customModuleData = moduleData
            end
        end
    end
end)

-- Validate loaded data integrity
hook.Add("LoadData", "ValidateData", function(data)
    -- Check for required data
    if not data.version then
        print("Warning: No version data found in save file")
    end

    -- Validate data structure
    if data.characters and type(data.characters) ~= "table" then
        print("Error: Invalid characters data structure")
        data.characters = {}
    end

    print("Data validation completed")
end)

PostLoadData

Purpose

Runs after all saved data has been loaded and processed.

When Called

This hook is triggered when: - All server data has been loaded from disk - After the complete data loading process is finished - When all saved data has been restored and processed - Following successful data initialization

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Initialize systems after all data is loaded
hook.Add("PostLoadData", "InitializeAfterLoad", function()
    print("All data loaded successfully")

    -- Initialize custom systems
    if _G.customModuleData then
        -- Set up custom module with loaded data
        CustomModule:Initialize(_G.customModuleData)
    end

    -- Start background processes
    timer.Create("DataCleanup", 300, 0, function()
        -- Clean up old data every 5 minutes
        print("Performing data cleanup...")
    end)

    -- Notify all players that data is ready
    for _, ply in player.Iterator() do
        ply:ChatPrint("Server data loaded and ready!")
    end
end)

-- Perform post-load validation
hook.Add("PostLoadData", "PostLoadValidation", function()
    -- Validate that all critical systems are working
    local success = true

    -- Check database connection
    if not lia.db then
        print("Error: Database not connected after load")
        success = false
    end

    -- Check essential modules
    if not lia.module then
        print("Error: Module system not initialized")
        success = false
    end

    if success then
        print("Post-load validation passed")
    else
        print("Post-load validation failed - some systems may not work properly")
    end
end)

ShouldDataBeSaved

Purpose

Determines if a specific data key should be saved to disk.

When Called

This hook is triggered when: - The system evaluates whether a data key should be persisted - Before data is written to the save file - During the data filtering process - When determining which data to include in saves

Parameters

  • key (string): Data key to check.

Returns

  • boolean (boolean): False to skip saving this key.

Realm

Server

Example Usage

-- Skip temporary data from being saved
hook.Add("ShouldDataBeSaved", "SkipTempData", function(key)
    -- Don't save temporary data
    if string.find(key, "temp_") then
        return false
    end

    -- Don't save debug data
    if string.find(key, "debug_") then
        return false
    end

    -- Don't save session-specific data
    if string.find(key, "session_") then
        return false
    end
end)

-- Filter sensitive data
hook.Add("ShouldDataBeSaved", "FilterSensitiveData", function(key)
    -- List of sensitive keys that should not be saved
    local sensitiveKeys = {
        "password",
        "token",
        "secret",
        "private_key"
    }

    -- Check if key contains sensitive information
    for _, sensitive in pairs(sensitiveKeys) do
        if string.find(string.lower(key), sensitive) then
            print("Blocked saving sensitive data:", key)
            return false
        end
    end

    return true
end)

DatabaseConnected

Purpose

Fires when the database connection is established.

When Called

This hook is triggered when: - The database connection is successfully established - After database initialization is completed - When the database becomes available for queries - Following successful database connection setup

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Initialize systems when database connects
hook.Add("DatabaseConnected", "InitDatabase", function()
    print("Database connection established")

    -- Set up database tables
    lia.db.query([[
        CREATE TABLE IF NOT EXISTS custom_data (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            key TEXT UNIQUE,
            value TEXT,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        )
    ]])

    -- Load initial data
    lia.db.query("SELECT * FROM custom_data", function(data)
        if data then
            print("Loaded", #data, "custom data entries")
        end
    end)

    -- Start database maintenance timer
    timer.Create("DatabaseMaintenance", 3600, 0, function()
        -- Run database maintenance every hour
        lia.db.query("VACUUM")
        print("Database maintenance completed")
    end)
end)

-- Notify administrators of database status
hook.Add("DatabaseConnected", "NotifyAdmins", function()
    for _, ply in player.Iterator() do
        if ply:IsAdmin() then
            ply:ChatPrint("Database connection established successfully")
        end
    end
end)

CanSaveData

Purpose

Checks if data can be saved at this time.

When Called

This hook is triggered when: - The system checks if data saving is currently allowed - Before initiating a data save operation - When validating save conditions - During save permission evaluation

Parameters

  • nil (nil): This function does not return a value.

Returns

  • boolean (boolean): False to prevent saving.

Realm

Server

Example Usage

-- Prevent saving during special events
hook.Add("CanSaveData", "PreventSaveDuringEvent", function()
    -- Don't save during active events
    if game.GetGlobalState("event_active") then
        print("Saving blocked: Event in progress")
        return false
    end

    -- Don't save during map changes
    if game.GetGlobalState("map_changing") then
        print("Saving blocked: Map changing")
        return false
    end

    return true
end)

-- Check database availability before saving
hook.Add("CanSaveData", "CheckDatabaseStatus", function()
    -- Ensure database is connected
    if not lia.db or not lia.db.isConnected() then
        print("Saving blocked: Database not connected")
        return false
    end

    -- Check if database is busy
    if lia.db.isBusy() then
        print("Saving blocked: Database busy")
        return false
    end

    return true
end)

SetupDatabase

Purpose

Called during database initialization to set up tables and schema.

When Called

This hook is triggered when: - The database is being initialized - During database schema setup - When database tables need to be created - Before the database is ready for use

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("SetupDatabase", "CreateCustomTables", function()
    -- Custom table creation logic
end)

OnDatabaseLoaded

Purpose

Fires after the database schema and initial data have been loaded.

When Called

This hook is triggered when: - The database schema has been fully loaded - After initial database data is populated - When the database is ready for normal operations - Following complete database initialization

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnDatabaseLoaded", "PostDatabaseInit", function()
    print("Database fully loaded")
end)

OnWipeTables

Purpose

Called when database tables are being wiped/reset.

When Called

This hook is triggered when: - Database tables are about to be wiped or reset - Before database cleanup operations - When performing database maintenance - During database table reset procedures

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnWipeTables", "BackupBeforeWipe", function()
    -- Backup logic before wipe
end)

LiliaTablesLoaded

Purpose

Fires when all Lilia database tables have been loaded and are ready.

When Called

This hook is triggered when: - All Lilia database tables have been loaded - After database table initialization is complete - When the database system is fully ready - Following successful table loading

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("LiliaTablesLoaded", "InitializeModules", function()
    -- Initialize modules that depend on database tables
end)

OnLoadTables

Purpose

Called during the table loading process.

When Called

This hook is triggered when: - A database table is being loaded - During the table initialization process - For each table as it's being set up - While database tables are being prepared

Parameters

  • tableName (string): Name of the table being loaded.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnLoadTables", "LogTableLoading", function(tableName)
    print("Loading table:", tableName)
end)

OnItemRegistered

Purpose

Fires when an item is registered in the system.

When Called

This hook is triggered when: - A new item is registered in the item system - During item initialization and setup - When items are loaded and processed - After item data is validated and stored

Parameters

  • item (table): Item data that was registered.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("OnItemRegistered", "LogItemRegistration", function(item)
    print("Item registered:", item.name)
end)

OnCharVarChanged

Purpose

Called when a character variable changes.

When Called

This hook is triggered when: - A character's variable is modified - When character data is updated - After character variable values change - During character data synchronization

Parameters

  • character (Character): Character whose variable changed.
  • key (string): Variable key that changed.
  • oldValue (any): Previous value.
  • newValue (any): New value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("OnCharVarChanged", "LogCharChanges", function(character, key, old, new)
    print("Character var changed:", key, "from", old, "to", new)
end)

OnCharLocalVarChanged

Purpose

Fires when a character's local variable changes.

When Called

This hook is triggered when: - A character's local variable is modified on the client - When client-side character data changes - After local character variable updates - During client-side character data synchronization

Parameters

  • character (Character): Character whose variable changed.
  • key (string): Variable key that changed.
  • oldValue (any): Previous value.
  • newValue (any): New value.

Returns

  • nil (nil): This function does not return a value.

Realm

Client

Example Usage

hook.Add("OnCharLocalVarChanged", "UpdateUI", function(character, key, old, new)
    -- Update UI elements based on local var changes
end)

LocalVarChanged

Purpose

Called when any local variable changes.

When Called

This hook is triggered when: - Any local variable is modified on the client - When client-side data changes - After local variable updates - During client-side data synchronization

Parameters

  • key (string): Variable key that changed.
  • oldValue (any): Previous value.
  • newValue (any): New value.

Returns

  • nil (nil): This function does not return a value.

Realm

Client

Example Usage

hook.Add("LocalVarChanged", "TrackChanges", function(key, old, new)
    print("Local var changed:", key)
end)

NetVarChanged

Purpose

Fires when a network variable changes.

When Called

This hook is triggered when: - A network variable (netvar) is modified - When networked data changes between client and server - After netvar synchronization - During network variable updates

Parameters

  • entity (Entity): Entity whose netvar changed.
  • key (string): Variable key that changed.
  • oldValue (any): Previous value.
  • newValue (any): New value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("NetVarChanged", "MonitorNetVars", function(ent, key, old, new)
    print("NetVar changed on", ent, ":", key)
end)

ItemDataChanged

Purpose

Called when an item's data changes.

When Called

This hook is triggered when: - An item's data properties are modified - When item attributes or values change - After item data updates - During item data synchronization

Parameters

  • item (Item): Item whose data changed.
  • key (string): Data key that changed.
  • oldValue (any): Previous value.
  • newValue (any): New value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("ItemDataChanged", "LogItemData", function(item, key, old, new)
    print("Item data changed:", item:getName(), key)
end)

ItemQuantityChanged

Purpose

Fires when an item's quantity changes.

When Called

This hook is triggered when: - An item's quantity is modified - When items are added or removed from stacks - After quantity adjustments - During item stack changes

Parameters

  • item (Item): Item whose quantity changed.
  • oldQuantity (number): Previous quantity.
  • newQuantity (number): New quantity.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

-- Track quantity changes for items
hook.Add("ItemQuantityChanged", "TrackQuantity", function(item, old, new)
    local itemName = item:getName()
    print("Quantity changed for", itemName, "from", old, "to", new)

    -- Log significant quantity changes
    local change = new - old
    if math.abs(change) > 10 then
        print("Large quantity change detected:", itemName, "by", change)
    end
end)

-- Update item statistics
hook.Add("ItemQuantityChanged", "UpdateItemStats", function(item, old, new)
    -- Track total quantity changes
    local totalChanges = item:getData("quantityChanges", 0)
    item:setData("quantityChanges", totalChanges + 1)

    -- Track net quantity change
    local netChange = item:getData("netQuantityChange", 0)
    item:setData("netQuantityChange", netChange + (new - old))

    -- Update last modified timestamp
    item:setData("lastModified", os.time())
end)

InventoryDataChanged

Purpose

Called when inventory data changes.

When Called

This hook is triggered when: - Inventory data properties are modified - When inventory attributes or settings change - After inventory data updates - During inventory data synchronization

Parameters

  • inventory (Inventory): Inventory whose data changed.
  • key (string): Data key that changed.
  • oldValue (any): Previous value.
  • newValue (any): New value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("InventoryDataChanged", "LogInventoryData", function(inv, key, old, new)
    print("Inventory data changed:", key)
end)

InventoryInitialized

Purpose

Fires when an inventory is initialized.

When Called

This hook is triggered when: - A new inventory is created and initialized - During inventory setup and configuration - When inventory data is first loaded - After inventory creation is completed

Parameters

  • inventory (Inventory): Inventory that was initialized.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("InventoryInitialized", "SetupInventory", function(inv)
    print("Inventory initialized with ID:", inv:getID())
end)

InventoryItemAdded

Purpose

Called when an item is added to an inventory.

When Called

This hook is triggered when: - An item is successfully added to an inventory - After item placement in inventory slots - When inventory contents are updated with new items - Following successful item addition operations

Parameters

  • inventory (Inventory): Inventory that received the item.
  • item (Item): Item that was added.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

-- Log item additions to inventory
hook.Add("InventoryItemAdded", "LogItemAddition", function(inv, item)
    local itemName = item:getName()
    local invID = inv:getID()

    print("Item added to inventory:", itemName, "inventory ID:", invID)

    -- Log to file for tracking
    file.Append("logs/inventory_changes.txt", 
        os.date("%Y-%m-%d %H:%M:%S") .. " - Added " .. itemName .. " to inventory " .. invID .. "\n"
    )
end)

-- Update inventory statistics
hook.Add("InventoryItemAdded", "UpdateStats", function(inv, item)
    -- Update item count
    local currentCount = inv:getData("itemCount", 0)
    inv:setData("itemCount", currentCount + 1)

    -- Update total value
    local itemValue = item:getData("value", 0)
    local totalValue = inv:getData("totalValue", 0)
    inv:setData("totalValue", totalValue + itemValue)

    -- Check if inventory is full
    local maxItems = inv:getData("maxItems", 100)
    if currentCount + 1 >= maxItems then
        print("Inventory is full:", inv:getID())
    end
end)

InventoryItemRemoved

Purpose

Fires when an item is removed from an inventory.

When Called

This hook is triggered when: - An item is successfully removed from an inventory - After item extraction from inventory slots - When inventory contents are updated after removal - Following successful item removal operations

Parameters

  • inventory (Inventory): Inventory that lost the item.
  • item (Item): Item that was removed.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

-- Log item removals from inventory
hook.Add("InventoryItemRemoved", "LogItemRemoval", function(inv, item)
    local itemName = item:getName()
    local invID = inv:getID()

    print("Item removed from inventory:", itemName, "inventory ID:", invID)

    -- Log to file for tracking
    file.Append("logs/inventory_changes.txt", 
        os.date("%Y-%m-%d %H:%M:%S") .. " - Removed " .. itemName .. " from inventory " .. invID .. "\n"
    )
end)

-- Update inventory statistics after removal
hook.Add("InventoryItemRemoved", "UpdateStats", function(inv, item)
    -- Update item count
    local currentCount = inv:getData("itemCount", 0)
    inv:setData("itemCount", math.max(0, currentCount - 1))

    -- Update total value
    local itemValue = item:getData("value", 0)
    local totalValue = inv:getData("totalValue", 0)
    inv:setData("totalValue", math.max(0, totalValue - itemValue))

    -- Check if inventory is now empty
    local newCount = inv:getData("itemCount", 0)
    if newCount == 0 then
        print("Inventory is now empty:", inv:getID())
    end
end)

InventoryDeleted

Purpose

Called when an inventory is deleted.

When Called

This hook is triggered when: - An inventory is being deleted or destroyed - Before inventory cleanup operations - When inventory data is being removed - During inventory deletion procedures

Parameters

  • inventory (Inventory): Inventory that was deleted.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("InventoryDeleted", "CleanupInventory", function(inv)
    print("Inventory deleted:", inv:getID())
end)

ItemDeleted

Purpose

Fires when an item is deleted.

When Called

This hook is triggered when: - An item is being deleted or destroyed - Before item cleanup operations - When item data is being removed - During item deletion procedures

Parameters

  • item (Item): Item that was deleted.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("ItemDeleted", "LogItemDeletion", function(item)
    print("Item deleted:", item:getName())
end)

ItemInitialized

Purpose

Called when an item is initialized.

When Called

This hook is triggered when: - A new item is created and initialized - During item setup and configuration - When item data is first loaded - After item creation is completed

Parameters

  • item (Item): Item that was initialized.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("ItemInitialized", "SetupItem", function(item)
    print("Item initialized:", item:getName())
end)

OnCharDisconnect

Purpose

Fires when a character disconnects.

When Called

This hook is triggered when: - A character is disconnecting from the server - Before character cleanup operations - When a player leaves the server - During character disconnection procedures

Parameters

  • character (Character): Character that disconnected.
  • client (Player): Player who owned the character.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Log character disconnections
hook.Add("OnCharDisconnect", "LogDisconnect", function(character, client)
    local charName = character:getName()
    local playerName = client:Nick()

    print("Character disconnected:", charName, "owned by", playerName)

    -- Log to file for admin review
    file.Append("logs/character_disconnects.txt", 
        os.date("%Y-%m-%d %H:%M:%S") .. " - " .. charName .. " (" .. playerName .. ")\n"
    )
end)

-- Save character data before disconnect
hook.Add("OnCharDisconnect", "SaveBeforeDisconnect", function(character, client)
    -- Save character's current state
    character:save()

    -- Save inventory data
    if character:getInv() then
        character:getInv():save()
    end

    -- Save any custom data
    if character.customData then
        lia.db.update("characters", {
            custom_data = util.TableToJSON(character.customData)
        }, "id = " .. character:getID())
    end

    print("Character data saved before disconnect")
end)

CharPreSave

Purpose

Called before a character is saved.

When Called

This hook is triggered when: - A character is about to be saved to the database - Before character data is written to storage - During character save preparation - Prior to character data serialization

Parameters

  • character (Character): Character being saved.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Prepare character data before saving
hook.Add("CharPreSave", "PrepareSave", function(character)
    -- Update last seen timestamp
    character:setData("lastSeen", os.time())

    -- Save current position
    local pos = character:getPos()
    if pos then
        character:setData("lastPosition", pos)
    end

    -- Save current health
    character:setData("lastHealth", character:getHealth())

    -- Clean up temporary data
    character:setData("tempData", nil)

    print("Character prepared for save:", character:getName())
end)

-- Validate character data before saving
hook.Add("CharPreSave", "ValidateData", function(character)
    -- Ensure character has required data
    if not character:getName() or character:getName() == "" then
        print("Warning: Character has no name, using fallback")
        character:setName("Unknown_" .. character:getID())
    end

    -- Validate character level
    local level = character:getData("level", 1)
    if level < 1 then
        character:setData("level", 1)
    end

    -- Ensure character has valid faction
    if not character:getFaction() then
        character:setFaction("citizen")
    end
end)

CharPostSave

Purpose

Fires after a character is saved.

When Called

This hook is triggered when: - A character has been successfully saved to the database - After character data is written to storage - Following successful character save operations - When character persistence is completed

Parameters

  • character (Character): Character that was saved.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Perform actions after character save
hook.Add("CharPostSave", "PostSaveActions", function(character)
    local charName = character:getName()
    print("Character saved:", charName)

    -- Log save event
    file.Append("logs/character_saves.txt", 
        os.date("%Y-%m-%d %H:%M:%S") .. " - " .. charName .. "\n"
    )

    -- Update save statistics
    if not _G.saveStats then
        _G.saveStats = {}
    end
    _G.saveStats.totalSaves = (_G.saveStats.totalSaves or 0) + 1
    _G.saveStats.lastSave = os.time()
end)

-- Clean up after save
hook.Add("CharPostSave", "CleanupAfterSave", function(character)
    -- Clear any temporary data
    character:setData("saveInProgress", nil)

    -- Update character cache
    if character.cache then
        character.cache.lastSave = os.time()
    end

    -- Notify character owner if online
    local client = character:getPlayer()
    if IsValid(client) then
        client:ChatPrint("Character data saved successfully")
    end
end)

CharLoaded

Purpose

Called when a character is loaded.

When Called

This hook is triggered when: - A character is loaded from the database - During character initialization from saved data - When a player selects and loads their character - After character data is restored from storage

Parameters

  • character (Character): Character that was loaded.
  • client (Player): Player who loaded the character.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Welcome message when character loads
hook.Add("CharLoaded", "WelcomeMessage", function(character, client)
    local charName = character:getName()
    client:ChatPrint("Welcome back, " .. charName)

    -- Show last login time
    local lastSeen = character:getData("lastSeen", 0)
    if lastSeen > 0 then
        local timeAgo = os.time() - lastSeen
        local hours = math.floor(timeAgo / 3600)
        client:ChatPrint("Last seen " .. hours .. " hours ago")
    end
end)

-- Initialize character after loading
hook.Add("CharLoaded", "InitializeCharacter", function(character, client)
    -- Set up character-specific data
    if not character:getData("level") then
        character:setData("level", 1)
    end

    -- Restore health if it was saved
    local savedHealth = character:getData("lastHealth")
    if savedHealth then
        character:setHealth(savedHealth)
    end

    -- Restore position if it was saved
    local savedPos = character:getData("lastPosition")
    if savedPos then
        character:setPos(savedPos)
    end

    -- Update last seen timestamp
    character:setData("lastSeen", os.time())

    print("Character initialized:", character:getName())
end)

PreCharDelete

Purpose

Fires before a character is deleted.

When Called

This hook is triggered when: - A character is about to be deleted - Before character data is removed from the database - During character deletion preparation - Prior to character cleanup operations

Parameters

  • character (Character): Character being deleted.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Create backup before character deletion
hook.Add("PreCharDelete", "BackupCharacter", function(character)
    local charName = character:getName()
    local charID = character:getID()

    -- Create backup data
    local backupData = {
        name = charName,
        id = charID,
        faction = character:getFaction(),
        level = character:getData("level", 1),
        health = character:getHealth(),
        position = character:getPos(),
        deletedAt = os.time(),
        deletedBy = "system"
    }

    -- Save backup to file
    local backupFile = "backups/characters/" .. charID .. "_" .. os.time() .. ".json"
    file.Write(backupFile, util.TableToJSON(backupData, true))

    print("Character backup created:", charName, "->", backupFile)
end)

-- Log character deletion
hook.Add("PreCharDelete", "LogDeletion", function(character)
    local charName = character:getName()
    local charID = character:getID()

    -- Log to admin file
    file.Append("logs/character_deletions.txt", 
        os.date("%Y-%m-%d %H:%M:%S") .. " - " .. charName .. " (ID: " .. charID .. ")\n"
    )

    -- Notify administrators
    for _, ply in player.Iterator() do
        if ply:IsAdmin() then
            ply:ChatPrint("Character being deleted: " .. charName)
        end
    end
end)

OnCharDelete

Purpose

Called when a character is deleted.

When Called

This hook is triggered when: - A character has been successfully deleted - After character data is removed from the database - Following character deletion operations - When character cleanup is completed

Parameters

  • character (Character): Character that was deleted.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Log character deletion completion
hook.Add("OnCharDelete", "LogDeletion", function(character)
    local charName = character:getName()
    print("Character deleted:", charName)

    -- Update deletion statistics
    if not _G.deletionStats then
        _G.deletionStats = {}
    end
    _G.deletionStats.totalDeletions = (_G.deletionStats.totalDeletions or 0) + 1
    _G.deletionStats.lastDeletion = os.time()

    -- Clean up related data
    local charID = character:getID()
    if charID then
        -- Remove from any caches
        if _G.characterCache then
            _G.characterCache[charID] = nil
        end

        -- Clean up inventory data
        lia.db.query("DELETE FROM lia_inventories WHERE character_id = " .. charID)

        -- Clean up item data
        lia.db.query("DELETE FROM lia_items WHERE character_id = " .. charID)
    end
end)

-- Notify administrators of deletion
hook.Add("OnCharDelete", "NotifyAdmins", function(character)
    local charName = character:getName()

    -- Notify all administrators
    for _, ply in player.Iterator() do
        if ply:IsAdmin() then
            ply:ChatPrint("Character deletion completed: " .. charName)
        end
    end

    -- Send to admin chat if available
    if lia.chat then
        lia.chat.send(nil, "admin", "Character deleted: " .. charName)
    end
end)

OnCharCreated

Purpose

Fires when a character is created.

When Called

This hook is triggered when: - A new character is created and added to the database - After character creation is completed - When a player successfully creates a new character - Following character initialization and setup

Parameters

  • character (Character): Character that was created.
  • client (Player): Player who created the character.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnCharCreated", "WelcomeNew", function(character, client)
    client:ChatPrint("Welcome to the server, " .. character:getName())
end)

OnTransferred

Purpose

Called when something is transferred.

When Called

This hook is triggered when: - Data or objects are transferred between systems - During transfer operations - When items or data change ownership or location - After successful transfer operations

Parameters

  • old (any): Previous state/location.
  • new (any): New state/location.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("OnTransferred", "LogTransfer", function(old, new)
    print("Transfer occurred from", old, "to", new)
end)

CharListLoaded

Purpose

Fires when the character list is loaded.

When Called

This hook is triggered when: - The character selection list is loaded from the database - During character list initialization - When a player's characters are retrieved for selection - After character list data is loaded

Parameters

  • characters (table): List of characters.

Returns

  • nil (nil): This function does not return a value.

Realm

Client

Example Usage

hook.Add("CharListLoaded", "ProcessCharacters", function(characters)
    print("Character list loaded with", #characters, "characters")
end)

CharListUpdated

Purpose

Called when the character list is updated.

When Called

This hook is triggered when: - The character selection list is refreshed or updated - When character list data changes - After character creation, deletion, or modification - During character list synchronization

Parameters

  • characters (table): Updated character list.

Returns

  • nil (nil): This function does not return a value.

Realm

Client

Example Usage

hook.Add("CharListUpdated", "RefreshUI", function(characters)
    -- Refresh character selection UI
end)

CharListExtraDetails

Purpose

Allows adding extra details to character list entries.

When Called

This hook is triggered when: - Character list entries are being prepared for display - During character list rendering - When additional character information is needed - Before character list is shown to the player

Parameters

  • character (Character): Character to add details for.

Returns

  • details (table): Extra details to display.

Realm

Client

Example Usage

hook.Add("CharListExtraDetails", "AddLevel", function(character)
    return {level = character:getData("level", 1)}
end)

KickedFromChar

Purpose

Fires when a player is kicked from a character.

When Called

This hook is triggered when: - A player is forcibly disconnected from their character - During administrative character kick operations - When a player is removed from their character session - After character kick procedures are initiated

Parameters

  • character (Character): Character the player was kicked from.
  • reason (string): Reason for the kick.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("KickedFromChar", "LogKick", function(character, reason)
    print("Player kicked from character:", reason)
end)

CharRestored

Purpose

Fires when a character is restored.

When Called

This hook is triggered when: - A character is restored from backup or previous state - During character recovery operations - When character data is reverted or restored - After character restoration procedures

Parameters

  • character (Character): Character that was restored.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("CharRestored", "LogRestore", function(character)
    print("Character restored:", character:getName())
end)

CreateDefaultInventory

Purpose

Called to create a default inventory.

When Called

This hook is triggered when: - A default inventory needs to be created for a player - During character initialization - When setting up initial inventory for new characters - Before inventory system is ready for use

Parameters

  • client (Player): Player to create inventory for.

Returns

  • inventory (Inventory): Created inventory.

Realm

Server

Example Usage

hook.Add("CreateDefaultInventory", "SetupDefaultInv", function(client)
    -- Create and return default inventory
end)

CreateInventoryPanel

Purpose

Fires when an inventory panel is created.

When Called

This hook is triggered when: - An inventory UI panel is being created - During inventory interface initialization - When inventory GUI needs to be displayed - Before inventory panel is shown to the player

Parameters

  • inventory (Inventory): Inventory the panel is for.

Returns

  • panel (Panel): Created inventory panel.

Realm

Client

Example Usage

hook.Add("CreateInventoryPanel", "CustomPanel", function(inventory)
    -- Create and return custom inventory panel
end)

DoModuleIncludes

Purpose

Called during module inclusion process.

When Called

This hook is triggered when: - Modules are being included and loaded - During module initialization process - When module files are being processed - Before modules become available for use

Parameters

  • moduleName (string): Name of the module being included.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("DoModuleIncludes", "LogIncludes", function(moduleName)
    print("Including module:", moduleName)
end)

InitializedConfig

Purpose

Fires when configuration is initialized.

When Called

This hook is triggered when: - System configuration is initialized - After configuration files are loaded - When configuration system is ready - Following configuration setup completion

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("InitializedConfig", "PostConfigInit", function()
    print("Configuration initialized")
end)

InitializedItems

Purpose

Called when items are initialized.

When Called

This hook is triggered when: - Item system initialization is completed - After all items are loaded and registered - When item definitions are processed - Following item system setup

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("InitializedItems", "PostItemInit", function()
    print("Items initialized")
end)

InitializedModules

Purpose

Fires when modules are initialized.

When Called

This hook is triggered when: - Module system initialization is completed - After all modules are loaded and activated - When module dependencies are resolved - Following module system setup

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("InitializedModules", "PostModuleInit", function()
    print("Modules initialized")
end)

InitializedOptions

Purpose

Called when options are initialized.

When Called

This hook is triggered when: - Options system initialization is completed - After option definitions are loaded - When option system is ready for use - Following options setup completion

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("InitializedOptions", "PostOptionInit", function()
    print("Options initialized")
end)

InitializedSchema

Purpose

Fires when schema is initialized.

When Called

This hook is triggered when: - Schema system initialization is completed - After schema definitions are loaded - When schema is ready for use - Following schema setup completion

Parameters

  • nil (nil): This function does not return a value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("InitializedSchema", "PostSchemaInit", function()
    print("Schema initialized")
end)

OnPlayerPurchaseDoor

Purpose

Called when a player purchases a door.

When Called

This hook is triggered when: - A player successfully purchases a door - After door ownership is transferred - When door purchase transaction is completed - Following successful door acquisition

Parameters

  • client (Player): Player who purchased the door.
  • door (Entity): Door that was purchased.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnPlayerPurchaseDoor", "LogPurchase", function(client, door)
    print(client:Nick(), "purchased door")
end)

OnServerLog

Purpose

Fires when a server log entry is created.

When Called

This hook is triggered when: - A log entry is being created - During logging operations - When events are being recorded - Before log data is written to storage

Parameters

  • message (string): Log message.
  • category (string): Log category.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnServerLog", "CustomLogging", function(message, category)
    -- Custom log processing
end)

PlayerMessageSend

Purpose

Called when a player sends a message.

When Called

This hook is triggered when: - A player sends a chat message - During message processing - After message validation - Before message is distributed to recipients

Parameters

  • client (Player): Player who sent the message.
  • chatType (string): Type of chat message.
  • message (string): Message content.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("PlayerMessageSend", "LogMessages", function(client, chatType, message)
    print(client:Nick(), "sent", chatType, ":", message)
end)

ChatParsed

Purpose

Fires when a chat message is parsed.

When Called

This hook is triggered when: - A chat message is being parsed and processed - During message analysis and formatting - After message content is evaluated - Before message handling is completed

Parameters

  • speaker (Player): Player who sent the message.
  • text (string): Original message text.
  • chatType (string): Type of chat.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("ChatParsed", "ProcessChat", function(speaker, text, chatType)
    -- Process parsed chat message
end)

OnConfigUpdated

Purpose

Called when configuration is updated.

When Called

This hook is triggered when: - Configuration values are modified - During configuration changes - After configuration updates are applied - When configuration synchronization occurs

Parameters

  • key (string): Configuration key that was updated.
  • oldValue (any): Previous value.
  • newValue (any): New value.

Returns

  • nil (nil): This function does not return a value.

Realm

Shared

Example Usage

hook.Add("OnConfigUpdated", "LogConfigChange", function(key, old, new)
    print("Config updated:", key, "from", old, "to", new)
end)

OnOOCMessageSent

Purpose

Fires when an out-of-character message is sent.

When Called

This hook is triggered when: - A player sends an OOC (out-of-character) message - During OOC message processing - After OOC message validation - Before OOC message is distributed

Parameters

  • client (Player): Player who sent the message.
  • text (string): Message content.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnOOCMessageSent", "ProcessOOC", function(client, text)
    -- Process OOC message
end)

OnSalaryGive

Purpose

Called when salary is given to a player.

When Called

This hook is triggered when: - A player receives their salary payment - During salary distribution events - After salary calculations are completed - When periodic salary payments are made

Parameters

  • client (Player): Player receiving salary.
  • amount (number): Salary amount.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnSalaryGive", "LogSalary", function(client, amount)
    print(client:Nick(), "received salary:", amount)
end)

OnTicketClaimed

Purpose

Fires when a ticket is claimed.

When Called

This hook is triggered when: - A support ticket is claimed by an administrator - During ticket assignment operations - After ticket ownership is transferred - When ticket status changes to claimed

Parameters

  • ticket (table): Ticket that was claimed.
  • claimer (Player): Player who claimed the ticket.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnTicketClaimed", "ProcessClaim", function(ticket, claimer)
    -- Process ticket claim
end)

OnTicketClosed

Purpose

Called when a ticket is closed.

When Called

This hook is triggered when: - A support ticket is closed or resolved - During ticket completion operations - After ticket resolution is confirmed - When ticket status changes to closed

Parameters

  • ticket (table): Ticket that was closed.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnTicketClosed", "ProcessClosure", function(ticket)
    -- Process ticket closure
end)

OnTicketCreated

Purpose

Fires when a ticket is created.

When Called

This hook is triggered when: - A new support ticket is created - During ticket submission process - After ticket validation is completed - When ticket is added to the system

Parameters

  • ticket (table): Ticket that was created.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnTicketCreated", "ProcessCreation", function(ticket)
    -- Process ticket creation
end)

OnVendorEdited

Purpose

Called when a vendor is edited.

When Called

This hook is triggered when: - A vendor's properties or inventory are modified - During vendor configuration changes - After vendor updates are applied - When vendor data is synchronized

Parameters

  • vendor (Entity): Vendor that was edited.
  • client (Player): Player who edited the vendor.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

hook.Add("OnVendorEdited", "LogEdit", function(vendor, client)
    print("Vendor edited by", client:Nick())
end)

CanPlayerEquipItem

Purpose

Queries if a player can equip an item. Returning false stops the equip action.

When Called

This hook is triggered when: - A player attempts to equip an item - Before item equipping is processed - During equipment validation checks - When item equip permissions are evaluated

Parameters

  • client (Player): Player equipping.
  • item (table): Item to equip.

Returns

  • boolean (boolean): False to block equipping.

Realm

Server

Example Usage

-- Check level requirement for equipping items
hook.Add("CanPlayerEquipItem", "CheckLevel", function(ply, item)
    local character = ply:getChar()
    if not character then return false end

    -- Check if item has level requirement
    if item.minLevel then
        local playerLevel = character:getAttrib("level", 0)
        if playerLevel < item.minLevel then
            ply:ChatPrint("You need level " .. item.minLevel .. " to equip this item!")
            return false
        end
    end

    -- Check faction requirement
    if item.requiredFaction then
        local playerFaction = character:getFaction()
        if playerFaction ~= item.requiredFaction then
            ply:ChatPrint("Your faction cannot equip this item!")
            return false
        end
    end

    return true
end)

-- Check if player has required attributes
hook.Add("CanPlayerEquipItem", "CheckAttributes", function(ply, item)
    local character = ply:getChar()
    if not character then return false end

    -- Check strength requirement
    if item.requiredStrength then
        local strength = character:getAttrib("str", 0)
        if strength < item.requiredStrength then
            ply:ChatPrint("You need " .. item.requiredStrength .. " strength to equip this item!")
            return false
        end
    end

    -- Check if item is cursed
    if item.cursed then
        ply:ChatPrint("This item is cursed and cannot be equipped!")
        return false
    end

    return true
end)

CanPlayerUnequipItem

Purpose

Called before an item is unequipped. Return false to keep the item equipped.

When Called

This hook is triggered when: - A player attempts to unequip an item - Before item unequipping is processed - During unequip validation checks - When item removal permissions are evaluated

Parameters

  • client (Player): Player unequipping.
  • item (table): Item being unequipped.

Returns

  • boolean (boolean): False to prevent unequipping.

Realm

Server

Example Usage

-- Prevent unequipping cursed gear
hook.Add("CanPlayerUnequipItem", "Cursed", function(ply, item)
    -- Check if item is cursed
    if item.cursed then
        ply:ChatPrint("This item is cursed and cannot be unequipped!")
        return false
    end

    -- Check if item is bound to player
    if item.boundToPlayer and item.boundToPlayer ~= ply:SteamID() then
        ply:ChatPrint("This item is bound to another player!")
        return false
    end

    return true
end)

-- Check if player is in combat
hook.Add("CanPlayerUnequipItem", "CombatCheck", function(ply, item)
    -- Prevent unequipping during combat
    if ply:getChar() and ply:getChar():getData("inCombat", false) then
        ply:ChatPrint("You cannot unequip items while in combat!")
        return false
    end

    -- Check if item is essential
    if item.essential then
        ply:ChatPrint("This item is essential and cannot be unequipped!")
        return false
    end

    return true
end)

CanPlayerRotateItem

Purpose

Called when a player attempts to rotate an inventory item. Return false to block rotating.

When Called

This hook is triggered when: - A player attempts to rotate an item in their inventory - Before item rotation is processed - During rotation validation checks - When item rotation permissions are evaluated

Parameters

  • client (Player): Player rotating.
  • item (table): Item being rotated.

Returns

  • boolean (boolean): False to block rotating.

Realm

Server

Example Usage

-- Prevent rotating certain special items
hook.Add("CanPlayerRotateItem", "NoRotatingArtifacts", function(ply, item)
    -- Prevent rotating artifacts
    if item.isArtifact then
        ply:ChatPrint("Artifacts cannot be rotated!")
        return false
    end

    -- Prevent rotating fragile items
    if item.fragile then
        ply:ChatPrint("This item is too fragile to rotate!")
        return false
    end

    return true
end)

-- Check if player has permission to rotate
hook.Add("CanPlayerRotateItem", "CheckPermission", function(ply, item)
    -- Check if player is admin or has special permission
    if not ply:IsAdmin() and not ply:getChar():getData("canRotateItems", false) then
        ply:ChatPrint("You don't have permission to rotate items!")
        return false
    end

    -- Check if item is locked
    if item.locked then
        ply:ChatPrint("This item is locked and cannot be rotated!")
        return false
    end

    return true
end)

PostPlayerSay

Purpose

Runs after chat messages are processed. Allows reacting to player chat.

When Called

This hook is triggered when: - A chat message has been fully processed - After message validation and distribution - When chat processing is completed - Following successful message handling

Parameters

  • client (Player): Speaking player.
  • message (string): Chat text.
  • chatType (string): Chat channel.
  • anonymous (boolean): Whether the message was anonymous.

Returns

  • nil (nil): This function does not return a value.

Realm

Server

Example Usage

-- Log all OOC chat
hook.Add("PostPlayerSay", "LogOOC", function(ply, msg, chatType)
    -- Log OOC messages to file
    if chatType == "ooc" then
        print("[OOC]", ply:Nick(), msg)

        -- Log to file for admin review
        file.Append("logs/ooc_chat.txt", 
            os.date("%Y-%m-%d %H:%M:%S") .. " [OOC] " .. ply:Nick() .. ": " .. msg .. "\n"
        )
    end

    -- Log admin chat
    if chatType == "admin" then
        print("[ADMIN]", ply:Nick(), msg)

        -- Log to admin file
        file.Append("logs/admin_chat.txt", 
            os.date("%Y-%m-%d %H:%M:%S") .. " [ADMIN] " .. ply:Nick() .. ": " .. msg .. "\n"
        )
    end
end)

-- Track chat statistics
hook.Add("PostPlayerSay", "TrackChatStats", function(ply, msg, chatType)
    -- Initialize stats if not exists
    if not _G.chatStats then
        _G.chatStats = {}
    end

    -- Track message count by type
    _G.chatStats[chatType] = (_G.chatStats[chatType] or 0) + 1

    -- Track player message count
    local steamID = ply:SteamID()
    if not _G.chatStats.players then
        _G.chatStats.players = {}
    end
    _G.chatStats.players[steamID] = (_G.chatStats.players[steamID] or 0) + 1

    -- Track message length
    local msgLength = string.len(msg)
    if not _G.chatStats.avgLength then
        _G.chatStats.avgLength = 0
        _G.chatStats.totalLength = 0
        _G.chatStats.messageCount = 0
    end

    _G.chatStats.totalLength = _G.chatStats.totalLength + msgLength
    _G.chatStats.messageCount = _G.chatStats.messageCount + 1
    _G.chatStats.avgLength = _G.chatStats.totalLength / _G.chatStats.messageCount
end)

ShouldSpawnClientRagdoll

Purpose

Decides if a corpse ragdoll should spawn for a player. Return false to skip ragdoll creation.

When Called

This hook is triggered when: - A player dies and ragdoll creation is being considered - Before ragdoll spawning occurs - During death processing - When ragdoll spawn permissions are evaluated

Parameters

  • client (Player): Player that died.

Returns

  • boolean (boolean): False to skip ragdoll.

Realm

Server

Example Usage

-- Disable ragdolls for bots
hook.Add("ShouldSpawnClientRagdoll", "NoBotRagdoll", function(ply)
    -- Don't create ragdolls for bots
    if ply:IsBot() then
        return false
    end

    -- Don't create ragdolls for players with no character
    if not ply:getChar() then
        return false
    end

    return true
end)

-- Check if player has ragdoll permission
hook.Add("ShouldSpawnClientRagdoll", "CheckPermission", function(ply)
    -- Check if player has ragdoll enabled
    if ply:getChar() and not ply:getChar():getData("ragdollEnabled", true) then
        return false
    end

    -- Don't create ragdolls in certain areas
    local pos = ply:GetPos()
    local mapName = game.GetMap()

    -- Check for no-ragdoll zones
    if mapName == "gm_flatgrass" then
        return false
    end

    return true
end)