> For the complete documentation index, see [llms.txt](https://docs.menanak47.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.menanak47.com/plugins/ak47_lib/events/client.md).

# Client

The `ak47_lib` provides unified client events that trigger across all supported frameworks (ESX, QBCore, Qbox). This allows you to listen for core player state changes without writing framework-specific event handlers.

#### **`ak47_lib:OnPlayerLoaded`**

Triggered when the player's character has completely loaded into the server and spawned. This event also safely fires if your resource is restarted while the player is already loaded in the server, ensuring your script always catches the active player state.

```lua
--- @param PlayerData table The full framework-specific player data object
--- @param resourceName string|nil The name of the resource if triggered by a resource restart
AddEventHandler('ak47_lib:OnPlayerLoaded', function(PlayerData, resourceName)
    print("Player has successfully loaded!")
    
    -- Example: Initialize script data or spawn UI elements
    Lib47.PlayerLoaded = true
    
    -- If you need to check framework-specific data
    if Lib47.Framework == 'qb' or Lib47.Framework == 'qbx' then
        print("Citizen ID: " .. PlayerData.citizenid)
    elseif Lib47.Framework == 'esx' then
        print("Identifier: " .. PlayerData.identifier)
    end
end)
```

#### **`ak47_lib:OnPlayerUnload`**

Triggered on the client when a player logs out or unloads their character (e.g., returning to the character selection screen). This event is standardized and dispatched across all supported frameworks (`qb-core`, `qbx_core`, and `es_extended`).

```lua
AddEventHandler('ak47_lib:OnPlayerUnload', function()
    print("Player has logged out or unloaded.")
    
    -- Example: Clean up client-side targets, blips, active loops, or NUI elements
    Lib47.PlayerLoaded = false
end)
```

#### **`ak47_lib:OnJobUpdate`**

Triggered on the client whenever the player's job (or grade) is updated by the server.

```lua
--- @param JobInfo table The updated framework-specific job object
AddEventHandler('ak47_lib:OnJobUpdate', function(JobInfo)
    print("Player's job has been updated!")
    
    -- Note: Because the raw JobInfo varies by framework, it's highly recommended
    -- to use the built-in Lib47.GetJob() function inside this event to get a standardized table.
    
    local formattedJob = Lib47.GetJob()
    if formattedJob then
        print(string.format("New Job: %s | Grade: %s | Is Boss: %s", 
            formattedJob.label, 
            formattedJob.grade.name, 
            tostring(formattedJob.isboss)
        ))
    end
end)
```

#### **`ak47_lib:OnPlayerDataUpdate`**

Triggered on the client whenever the core player data object receives a synchronized update from the server. This often occurs when inventory items change, metadata updates, or money is added/removed.

```lua
--- @param PlayerData table The newly updated framework-specific player data object
AddEventHandler('ak47_lib:OnPlayerDataUpdate', function(PlayerData)
    -- This event fires frequently depending on the framework and server activity.
    -- Use this to dynamically update UI elements or active tracking loops.
    
    if Lib47.Framework == 'esx' then
        -- Example: Checking updated accounts in ESX
        for i=1, #PlayerData.accounts, 1 do
            if PlayerData.accounts[i].name == 'bank' then
                print("Updated Bank Balance: $" .. PlayerData.accounts[i].money)
            end
        end
        
    elseif Lib47.Framework == 'qb' or Lib47.Framework == 'qbx' then
        -- Example: Checking updated metadata in QBCore/Qbox
        print("Updated Hunger Level: " .. PlayerData.metadata["hunger"])
    end
end)
```
