Daily Bonus Example
A complete wc_dailybonus resource — pays every character a small login reward once every 24 hours, using OnPlayerLoaded as the trigger. Tracks the last-claimed time in memory, keyed by character ID.
In-memory state resets on restart. This example keeps
LastClaim in a plain Lua table for clarity. On a real server, persist it in your database (keyed by charid) so a resource restart or crash doesn't let everyone re-claim early. Swap the two marked lines below for your own DB read/write.
fxmanifest.lua
wc_dailybonus/fxmanifest.lua
fx_version 'adamant'
game 'rdr3'
lua54 'yes'
name 'wc_dailybonus'
dependency 'wc_libs'
shared_scripts { '@wc_libs/init.lua', 'config.lua' }
server_scripts { 'server.lua' }
config.lua
wc_dailybonus/config.lua
Config = {}
Config.Reward = 15
Config.CooldownSecs = 24 * 60 * 60 -- 24 hours
server.lua
wc_dailybonus/server.lua
local LastClaim = {} -- [charid] = unix timestamp — replace with a DB table in production
wc:OnPlayerLoaded(function(source)
local player = wc:GetPlayer(source)
if not player or not player.charid then return end
local charid = tostring(player.charid)
local now = os.time()
local last = LastClaim[charid] -- <-- swap for a DB SELECT in production
if last and (now - last) < Config.CooldownSecs then
return -- already claimed today, say nothing
end
LastClaim[charid] = now -- <-- swap for a DB UPSERT in production
wc:AddMoney(source, Config.Reward, 0)
wc:Notify(source, {
variant = 'avanced',
title = ("Welcome back! +$%d daily bonus"):format(Config.Reward),
})
end)
Common mistakes
- Registering the bonus on
playerConnectingor a raw connect event instead ofOnPlayerLoaded— the character (and itscharid) isn't resolved yet at connect time. - Keying the cooldown by
sourceinstead ofcharid—sourceis a per-session slot number that gets reused, so a different player could inherit someone else's cooldown after a restart. - Not persisting
LastClaimto a database — as shipped, every resource restart resets everyone's cooldown, which is fine for a demo but not for production.