Koja Scripts
KOJA-LIB

Storage

The storage system is a reactive client-side key-value store.

Storage

The storage system is a reactive client-side key-value store. Values are lazy-loaded, can be updated from the server, and trigger callbacks when they change.

Accessing Storage

The global storage table (also available as KOJA.storage) is backed by a metatable. Simply reading a key registers an update listener for it:

local value = storage['myKey']

On the first read, the key is registered and its update event is subscribed. Subsequent reads return the cached value.

Getting a Value

-- Direct read
local myData = storage['playerStats']

-- Returns false if the key has never been set

Computed / Cached Values

Use the call syntax to compute and optionally cache a value with a timeout:

local value = storage(key, computeFunc, timeout)
ParameterTypeDescription
keystringStorage key
computeFuncfunctionCalled to produce the value if it is not cached yet
timeoutnumber?Milliseconds after which the cached value is cleared

Example

-- Compute the nearest shop once and cache it for 10 seconds
local nearestShop = storage('nearestShop', function()
    return findNearestShop(GetEntityCoords(PlayerPedId()))
end, 10000)

Reacting to Changes

Via event

Any time a key is updated (from the server or locally), koja-lib:callback_triggered fires:

AddEventHandler('koja-lib:callback_triggered', function(key, newValue, oldValue)
    if key == 'playerStats' then
        print('Stats updated:', json.encode(newValue))
    end
end)

Via key-specific event

AddEventHandler('koja-lib:update:playerStats', function(newValue)
    print('playerStats is now:', json.encode(newValue))
end)

Updating from the Server

Trigger the update event on the client to push a new value:

-- Server script
TriggerClientEvent('koja-lib:update:playerStats', source, {
    kills  = 12,
    deaths = 3,
})

The client's storage['playerStats'] will be updated and all registered callbacks will fire.

Metadata Properties

Two properties are always available on the storage object:

PropertyValue
storage.gameResult of GetGameName()
storage.resourceResult of GetCurrentResourceName()

Example — Live HUD Data

-- Server: push health every 5 seconds
CreateThread(function()
    while true do
        Wait(5000)
        for _, id in ipairs(GetPlayers()) do
            local ped = GetPlayerPed(id)
            TriggerClientEvent('koja-lib:update:health', id, GetEntityHealth(ped))
        end
    end
end)

-- Client: draw health bar
AddEventHandler('koja-lib:callback_triggered', function(key, value)
    if key == 'health' then
        -- update your HUD
    end
end)

-- Also works immediately on first read
local hp = storage['health']
  • Getting Started — Configuration and Installation for Getting Started.
  • API Reference — Client API and Server API for API Reference.
  • Frameworks — Custom Framework and Overview for Frameworks.
  • Inventory — Custom Inventory and Overview for Inventory.
  • Weapon — Utility function for reading the player's current weapon state.
  • Text UI — A small on-screen prompt that shows an action key and a label.