Skip to content

Retro Graffiti

This section contains core flows and integration entry points.

Session pattern:

  • Start spray session.
  • Place panel.
  • Focus in editor.
  • Send layer updates.
  • Finalize or discard.

This section is for server-side integration only (framework/inventory/gang permissions).

If your server uses a different framework, inventory, progress bar, or notify system, edit these first:

  1. bridge/server.lua
  • Framework identity/admin checks
  • Inventory add/remove/has item
  • Usable item registrations
  • Gang integration hooks: Bridge.GetGangInfo(src), Bridge.IsGangLeader(src, gangInfo)
  1. bridge/client.lua
  • Progressbar adapter
  • Notification adapter

Keep core gameplay files unchanged where possible and override behavior through bridge adapters.

Primary extension point is bridge/server.lua.

Edit these functions for your server:

  1. Bridge.GetGangInfo(src)
  • Return nil if no gang
  • Return { name, label?, isboss?, grade = { level = number }? } when in gang
  1. Bridge.IsGangLeader(src, gangInfo)
  • Return true/false for leader status used by gang preset permissions

Use these exports to hook rs_graff into an existing gang framework without editing core files.

Registers an external provider resource that resolves player gang + leader status.

exports['rs_graff']:ConfigureGangProvider('my_gangs', 'GetPlayerGang', 'IsGangLeader')

Expected provider exports:

  1. GetPlayerGang(src) -> table|string|nil
  2. IsGangLeader(src, gangName) -> boolean (optional, fallback uses grade/boss flags)

Supported gang object fields:

  • name (required)
  • label (optional)
  • isboss / isBoss / leader (optional bool)
  • grade.level or gradeLevel / rank (optional number)

Disable external provider and fall back to built-in QB gang lookup:

exports['rs_graff']:ConfigureGangProvider('')

Returns current provider config:

local provider = exports['rs_graff']:GetGangProvider()
-- { resource = 'my_gangs', getGangExport = 'GetPlayerGang', isLeaderExport = 'IsGangLeader' }

Returns normalized gang info for a player:

local gang = exports['rs_graff']:GetPlayerGang(source)
-- gang = { name = 'ballas', label = 'Ballas', isboss = false, grade = { level = 2 } }

Checks gang leadership for preset management:

local isLeader = exports['rs_graff']:IsGangLeader(source)
local isSpecificGangLeader = exports['rs_graff']:IsGangLeader(source, 'ballas')

Convenience context for menu/permission gating:

local ctx = exports['rs_graff']:GetGangPresetContext(source)
-- { hasGang = true, gangName = 'ballas', isLeader = true }
-- server.lua in your gang resource
AddEventHandler('onResourceStart', function(res)
if res ~= GetCurrentResourceName() then return end
if GetResourceState('rs_graff') ~= 'started' then return end
exports['rs_graff']:ConfigureGangProvider(GetCurrentResourceName(), 'GetPlayerGang', 'IsGangLeader')
end)
exports('GetPlayerGang', function(src)
local data = GetGangDataFromYourSystem(src)
if not data or not data.name then return nil end
return {
name = data.name,
label = data.label,
isBoss = data.isBoss,
gradeLevel = data.rank
}
end)
exports('IsGangLeader', function(src, gangName)
return IsLeaderInYourSystem(src, gangName) == true
end)

Replace these names with your final public API if you choose to expose them later. These are template examples only and are not implemented by default.

-- Place a graffiti panel (if you expose it)
exports['rs_graff']:PlacePanel()
-- Enter focus/editor mode for a specific tag or panel
exports['rs_graff']:FocusPanel(panelId)
-- Admin remove
exports['rs_graff']:RemoveTag(tagId)
-- Fired when a tag is finalized
AddEventHandler('rs_graff:tagFinalized', function(tagId, data) end)
-- Fired when a tag is removed
AddEventHandler('rs_graff:tagRemoved', function(tagId) end)