Full Example Resource
A small, complete roadside-encounter-style resource — "an injured traveler on the road, tend their wounds, get paid" — built entirely on wc_lib. Runs unmodified on VORP or RSG.
this resource will run unmodified on —
Toggle above doesn't change the code below — that's the point. The same files work on both.
fxmanifest.lua
my_injured_traveler/fxmanifest.lua
fx_version "adamant"
game "rdr3"
lua54 'yes'
name 'my_injured_traveler'
shared_scripts {
'@wc_libs/init.lua',
'config.lua',
}
client_scripts {
'client.lua',
}
server_scripts {
'server.lua',
}
config.lua
my_injured_traveler/config.lua
Config = {}
Config.WebhookUrl = "https://discord.com/api/webhooks/..."
Config.RewardMoney = 25
Config.NpcModels = { "a_m_m_armtownfolk_01", "a_m_m_valrancher_01" }
client.lua
my_injured_traveler/client.lua
RegisterCommand('tendtraveler', function()
local playerPos = GetEntityCoords(PlayerPedId())
local spawnPos = playerPos + vector3(5.0, 0.0, 0.0)
local hash = wc:LoadAnyModel(Config.NpcModels)
if not hash then return end
local ped = wc:SpawnPed(hash, spawnPos.x, spawnPos.y, spawnPos.z, 0.0, true, true)
if not ped then return end
local prompt = wc:CreatePrompt("Tend Wounds [G]")
local blip = wc:CreateBlip(spawnPos.x, spawnPos.y, spawnPos.z, "Injured Traveler")
wc:Notify(nil, { title = "Someone needs help nearby." })
local inRange = false
CreateThread(function()
while true do
Wait(inRange and 0 or 300)
local near = wc:IsPlayerNearCoords(spawnPos, 3.0)
if near and not inRange then
inRange = true
wc:SetPromptVisible(prompt, true)
elseif not near and inRange then
inRange = false
wc:SetPromptVisible(prompt, false)
end
if inRange and wc:IsPromptCompleted(prompt) then
wc:SetPromptVisible(prompt, false)
wc:DeletePrompt(prompt)
wc:RemoveBlip(blip)
wc:FaceEachOther(ped)
TriggerServerEvent('my_injured_traveler:complete')
wc:DeletePed(ped)
break
end
end
end)
end, false)
server.lua
my_injured_traveler/server.lua
RegisterNetEvent('my_injured_traveler:complete', function()
local src = source
wc:AddMoney(src, Config.RewardMoney)
wc:Notify(src, {
title = "+$" .. Config.RewardMoney,
icon = 'itemtype_cash',
})
wc:SendWebhook(
src,
Config.WebhookUrl,
"Injured Traveler",
"complete",
{
{ "Money Earned", wc:FormatMoney(Config.RewardMoney) },
},
{ complete = 0x2ECC71 }
)
end)
That's the entire resource — 4 files, ~70 lines, zero direct calls to vorp_core or rsg-core. The only thing that changes between a VORP server and an RSG server is which copy of wc_libs is installed underneath — this resource never knows or cares.