API Reference

Exports, events, state bags, and server-side admin events for integrating with tAFK.

Lua API

Client exports

All exports live on exports['tAFK'] and operate on the local player.

IsAFK

Returns whether the local player is currently in the AFK cinematic.

local afk = exports['tAFK']:IsAFK()
-- true | false

No parameters. Reflects real-time state — true from the moment the fade-in completes to the moment any input exits.

StartAFK

Triggers AFK manually on the local player. Equivalent to /afk when already valid.

local started = exports['tAFK']:StartAFK()
-- true  — entered AFK (will fade in over 1s)
-- false — system disabled or not in a vehicle

Sets the internal manualAFK flag, which bypasses the idle-input sensitivity during fade-in (so the user's mouse movement from triggering the command doesn't instantly cancel).

StopAFK

Exits AFK immediately. No-op if not currently AFK.

exports['tAFK']:StopAFK()

Returns nothing. Fires tafk:stateChanged(false) and clears the state bag.

ToggleAFK

local isAfkNow = exports['tAFK']:ToggleAFK()
-- true  — was off, now on
-- false — was on, now off; OR system disabled / no vehicle

Does the right thing based on current state. Fires the appropriate event and state-bag write.

IsAFKEnabled

local enabled = exports['tAFK']:IsAFKEnabled()
-- true | false

Reflects the session enable state, which respects the player's persistent tafk:playerDisabled KVP at boot. Different from IsAFK()IsAFKEnabled says whether the system can trigger; IsAFK says whether it is triggering.

SetAFKEnabled

local ok = exports['tAFK']:SetAFKEnabled(false)  -- suppress tAFK for this session
-- true on valid input; false if arg isn't a boolean

Session-only switch. Pass false to disable auto and manual triggers and stop an in-progress cinematic. Pass true to re-enable. Does not persist to KVP — for persistent player preferences, use the /tafk dialog.


Client events

tafk:stateChanged

Fires on the local client every time AFK state changes.

AddEventHandler('tafk:stateChanged', function(isAfk)
  if isAfk then
    -- entering AFK
  else
    -- leaving AFK
  end
end)

Single argument: boolean. Fires before the state bag is written, so handlers see the new local state but remote clients may not yet have received the bag update.

Cross-client awareness — use the state bag

tafk:stateChanged is a local event on one client only. To react to another player's AFK status, read Player(src).state.afk or subscribe to the state-bag change handler.


State bags

LocalPlayer.state.afk

Replicated player-state bag, set on AFK enter/exit and on resource start:

-- Set internally by tAFK — do not write from other scripts
LocalPlayer.state:set('afk', true, true)

Readable from any client or the server:

-- Client, any other client
local ok = Player(playerServerId).state.afk   -- true | false | nil

-- Server
local ok = Player(source).state.afk

-- State-bag change handler (any script)
AddStateBagChangeHandler('afk', nil, function(bagName, key, value, reserved, replicated)
    local playerId = GetPlayerFromStateBagName(bagName)
    -- playerId is the server ID; handle transitions
end)

nil means the player hasn't loaded tAFK yet (e.g., disconnected or resource not started). Treat nil as "not AFK" for most purposes.


Server-side admin events

All admin events are registered via exports['tLib']:RegisterAdminEvent(...), which gates on the tlib.admin ACE before the handler runs. Non-admins can trigger these events but the handler returns immediately.

Admin menus fire these from the client, but external scripts can too.

tafk:admin:updateSetting

TriggerServerEvent('tafk:admin:updateSetting', key, value)
-- key:   'timeoutSeconds' | 'minDurationMs' | 'maxDurationMs' | 'beatAnchorMs'
--      | 'musicVolume'    | 'useMusic'      | 'hideHudInAFK'
-- value: coerced to the expected type server-side

Unknown keys log a warning and no-op.

tafk:admin:upsertSequence

Create or update a global sequence.

TriggerServerEvent('tafk:admin:upsertSequence', {
    id = 'custom_hero_shot',
    name = 'Hero Shot',
    enabled = true,
    vehicles = { '*' },
    start = { offset = { x = 0, y = 4, z = 1 }, rotation = { x = 0, y = 0, z = 180 }, fov = 45, dof = {...} },
    ['end'] = { ... },
})

If an entry with the same id exists, it's replaced. Otherwise appended. Validated via tafkValidateSequence — failures toast back to the admin with the specific error.

tafk:admin:upsertVehicleSequence

Same as above but written into data.json.vehicleConfigs[<model>].sequences via the Discovery instance.

TriggerServerEvent('tafk:admin:upsertVehicleSequence', 'bati801', seqObject)

tafk:admin:toggleSequence, tafk:admin:deleteSequence

TriggerServerEvent('tafk:admin:toggleSequence', 'seed_01', false)  -- disable
TriggerServerEvent('tafk:admin:deleteSequence', 'seed_01')         -- permanent

No music track events

Music is discovered from the audio/ folder at resource start (see Configuration → Music tracks). There are no register/toggle/delete events — drop files into audio/ and restart the resource.


Client config events

tafk:request_config

Client → server. Triggers the server to send its current config to this client. Useful if your script loads late.

TriggerServerEvent('tafk:request_config')
-- server replies with TriggerClientEvent('tafk:config_receive', src, mergedData)

tafk:config_receive

Server → client. Carries the full data.json contents.

RegisterNetEvent('tafk:config_receive', function(data)
    -- data = { version, settings, sequences, musicTracks, ... }
end)

tAFK registers this internally — only subscribe from another resource if you need to mirror the config.

tafk:vcfg:config_receive

Per-vehicle configs from Discovery. Payload is { [model] = { sequences = [...] } }.

RegisterNetEvent('tafk:vcfg:config_receive', function(vehicleConfigs)
    -- keyed by lowercase model name
end)

Auto-requested on resource start via tafk:vcfg:config_request.


Deprecation note

If you're upgrading from the legacy tommys-afk resource:

OldNew
exports['tommys-afk']:IsAFK()exports['tAFK']:IsAFK()
exports['tommys-afk']:StartAFK()exports['tAFK']:StartAFK()
AddEventHandler('tommys-afk:stateChanged', ...)AddEventHandler('tafk:stateChanged', ...)
(none)Player(src).state.afk

The resource name, all export names, and the event name changed. Update any integration code — there's no compatibility shim.

On this page

Need help?

Ask on Discord