Introduction
The shared files in rsg-core contain all the core configuration data for your server including jobs, items, vehicles, gangs, weapons, and utility functions. These files are shared between client and server, making the data accessible on both sides without additional network calls.
Location: resources/[framework]/rsg-core/shared/
Shared files are loaded on both client and server automatically. Changes require a server restart!
Core Features
๐ฆ Centralized Configuration
- Jobs: Define all server jobs with grades and payments
- Items: Configure inventory items with properties and metadata
- Vehicles: Set up vehicle shops and pricing
- Gangs: Create gang hierarchies and structures
- Weapons: Define weapon properties and ammo types
- Utilities: Helper functions for common operations
๐ Shared Access
- Client & Server: Data available on both sides
- No Network Calls: Instant access without events
- Consistent Data: Single source of truth
- Easy Management: Edit in one place, affects everywhere
โ๏ธ Flexible System
- Add Custom Jobs: Create new job types
- Define Items: Add new items with decay, quality, etc.
- Vehicle Categories: Organize vehicles by type
- Gang System: Set up gang hierarchies
- Utility Functions: String manipulation, math helpers
Utility Functions
Location
File: rsg-core/shared/main.lua
Starter Items
Define default items for new players:
RSGShared.StarterItems = {
bread = { amount = 5, item = 'bread' },
water = { amount = 5, item = 'water' },
}
Customization:
-- Give different starter items
RSGShared.StarterItems = {
bread = { amount = 10, item = 'bread' },
water = { amount = 10, item = 'water' },
bandage = { amount = 3, item = 'bandage' },
dollar = { amount = 50, item = 'dollar' } -- Starting cash if using money items
}
String Functions
RandomStr
Generate random string of specified length:
RSGShared.RandomStr(length)
Example:
local randomString = RSGShared.RandomStr(8)
-- Result: "aBcDeFgH"
-- Use for unique IDs
local transactionId = 'TXN_'.. RSGShared.RandomStr(12)
-- Result: "TXN_XyZ123AbCdEf"
RandomInt
Generate random number string:
RSGShared.RandomInt(length)
Example:
local randomNumber = RSGShared.RandomInt(6)
-- Result: "482719"
-- Use for PINs, codes
local pinCode = RSGShared.RandomInt(4)
-- Result: "1234"
SplitStr
Split string by delimiter:
RSGShared.SplitStr(str, delimiter)
Example:
local parts = RSGShared.SplitStr("John,Doe,30", ",")
-- Result: { "John", "Doe", "30" }
-- Parse player names
local fullName = "John Marston"
local names = RSGShared.SplitStr(fullName, " ")
local firstname = names[1] -- "John"
local lastname = names[2] -- "Marston"
Remove whitespace from string:
Example:
local clean = RSGShared.Trim(" Hello World ")
-- Result: "Hello World"
-- Useful for user input
local playerInput = " John "
local cleanName = RSGShared.Trim(playerInput)
-- Result: "John"
FirstToUpper
Capitalize first letter:
RSGShared.FirstToUpper(value)
Example:
local capitalized = RSGShared.FirstToUpper("john")
-- Result: "John"
-- Format names
local firstname = RSGShared.FirstToUpper(string.lower("JOHN"))
-- Result: "John"
Round number to decimal places:
RSGShared.Round(value, numDecimalPlaces)
Example:
local rounded = RSGShared.Round(3.14159, 2)
-- Result: 3.14
-- Round money
local price = 123.456
local finalPrice = RSGShared.Round(price, 2)
-- Result: 123.46
-- Round to integer
local wholeNumber = RSGShared.Round(3.7)
-- Result: 4
Vehicle Functions
Toggle vehicle extras:
RSGShared.ChangeVehicleExtra(vehicle, extra, enable)
Example:
-- CLIENT SIDE
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
-- Enable extra 1
RSGShared.ChangeVehicleExtra(vehicle, 1, true)
-- Disable extra 2
RSGShared.ChangeVehicleExtra(vehicle, 2, false)
Set multiple vehicle extras:
RSGShared.SetDefaultVehicleExtras(vehicle, config)
Example:
-- CLIENT SIDE
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
-- Configure extras
local extraConfig = {
[1] = true, -- Enable extra 1
[2] = false, -- Disable extra 2
[3] = true -- Enable extra 3
}
RSGShared.SetDefaultVehicleExtras(vehicle, extraConfig)
Items Configuration
Location
File: rsg-core/shared/items.lua
Item Structure
Complete item definition with all properties:
RSGShared.Items = {
['bread'] = {
name = 'bread', -- Item identifier (must match key)
label = 'Bread', -- Display name
weight = 100, -- Weight in grams
type = 'item', -- Type: 'item' or 'weapon'
image = 'consumable_bread_roll.png', -- Image in rsg-inventory/html/images
unique = false, -- Each item takes own slot if true
useable = true, -- Can be used (needs callback)
shouldClose = true, -- Close inventory on use
combinable = nil, -- Crafting combinations (optional)
description = 'Fresh baked bread', -- Tooltip description
decay = 300, -- Decay time in minutes (optional)
delete = true, -- Auto-delete at 0% quality (optional)
info = { -- Default metadata (v2.7.3+)
quality = 100
}
},
}
Item Properties Reference
| Property | Type | Required | Description |
|---|
name | string | Yes | Item spawn name (must match table key) |
label | string | Yes | Display name in inventory |
weight | number | Yes | Item weight in grams |
type | string | Yes | 'item' or 'weapon' |
image | string | Yes | Image filename (in rsg-inventory/html/images) |
unique | boolean | Yes | If true, items donโt stack |
useable | boolean | Yes | If true, item can be used |
shouldClose | boolean | Yes | Close inventory when used |
description | string | Yes | Item tooltip text |
decay | number | No | Minutes from 100% to 0% quality |
delete | boolean | No | Auto-remove at 0% quality |
combinable | table | No | Crafting recipe combinations |
ammotype | string | Weapons | Ammo type for weapons |
info | table | No | Default metadata (v2.7.3+) |
Item Type Examples
Consumable Food
['bread'] = {
name = 'bread',
label = 'Bread',
weight = 100,
type = 'item',
image = 'consumable_bread_roll.png',
unique = false,
useable = true,
shouldClose = true,
description = 'Fresh baked bread',
decay = 300, -- 5 hours
delete = true
},
['cooked_meat'] = {
name = 'cooked_meat',
label = 'Cooked Meat',
weight = 400,
type = 'item',
image = 'consumable_meat_cooked.png',
unique = false,
useable = true,
shouldClose = true,
description = 'Perfectly cooked meat',
decay = 480, -- 8 hours
delete = true
},
['pickaxe'] = {
name = 'pickaxe',
label = 'Pickaxe',
weight = 2000,
type = 'item',
image = 'tool_pickaxe.png',
unique = false,
useable = true,
shouldClose = true,
description = 'Mining pickaxe for extracting ore',
decay = 10080, -- 7 days
delete = false -- Keep broken tool
},
['lasso'] = {
name = 'lasso',
label = 'Lasso',
weight = 500,
type = 'item',
image = 'tool_lasso.png',
unique = false,
useable = true,
shouldClose = true,
description = 'Rope lasso for catching animals or people'
},
Money Items
['dollar'] = {
name = 'dollar',
label = 'Dollars',
weight = 1,
type = 'item',
image = 'dollar.png',
unique = false,
useable = false,
shouldClose = false,
description = 'US Dollar currency'
},
['blood_dollar'] = {
name = 'blood_dollar',
label = 'Bloodstained Dollars',
weight = 1,
type = 'item',
image = 'bloodmoney.png',
unique = false,
useable = false,
shouldClose = false,
description = 'Blood-stained money from illegal activities'
},
Weapon Items
['weapon_revolver_cattleman'] = {
name = 'weapon_revolver_cattleman',
label = 'Cattleman Revolver',
weight = 1000,
type = 'weapon',
ammotype = 'AMMO_REVOLVER',
image = 'weapon_revolver_cattleman.png',
unique = true,
useable = false,
description = 'A reliable six-shooter revolver'
},
['ammorevolver'] = {
name = 'ammorevolver',
label = 'Revolver Ammo',
weight = 10,
type = 'item',
ammotype = 'AMMO_REVOLVER',
image = 'ammo_revolver.png',
unique = false,
useable = false,
description = 'Ammunition for revolvers'
},
-- v2.7.3+ Feature
['bottle'] = {
name = 'bottle',
label = 'Glass Bottle',
weight = 200,
type = 'item',
image = 'item_bottle.png',
unique = false,
useable = true,
shouldClose = true,
description = 'An empty glass bottle',
info = {
liquid = 'empty',
volume = 0,
maxVolume = 500
}
},
['horse_brush'] = {
name = 'horse_brush',
label = 'Horse Brush',
weight = 300,
type = 'item',
image = 'tool_horsebrush.png',
unique = false,
useable = true,
shouldClose = true,
description = 'Brush for grooming horses',
decay = 20160, -- 14 days
delete = false,
info = {
durability = 100,
uses = 0
}
},
Jobs Configuration
Location
File: rsg-core/shared/jobs.lua
Job Structure
Complete job definition:
RSGShared = RSGShared or {}
RSGShared.ForceJobDefaultDutyAtLogin = true -- Force duty state on login
RSGShared.Jobs = {
unemployed = {
name = 'unemployed',
label = 'Civilian',
defaultDuty = true,
offDutyPay = false,
grades = {
['0'] = {
name = 'Freelancer',
payment = 3
}
}
},
vallaw = {
name = 'vallaw',
label = 'Valentine Law Enforcement',
type = 'leo',
defaultDuty = false,
offDutyPay = false,
grades = {
['0'] = { name = 'Recruit', payment = 10 },
['1'] = { name = 'Deputy', payment = 25 },
['2'] = { name = 'Sheriff', isboss = true, payment = 50 }
}
},
}
Job Properties
| Property | Type | Required | Description |
|---|
name | string | Yes | Internal job identifier |
label | string | Yes | Display name |
type | string | No | Job category ('leo', 'medic') |
defaultDuty | boolean | Yes | Auto clock-in on login |
offDutyPay | boolean | Yes | Pay when off-duty |
grades | table | Yes | Grade/rank levels |
Grade Properties
| Property | Type | Required | Description |
|---|
name | string | Yes | Grade display name |
payment | number | Yes | Paycheck amount |
isboss | boolean | No | Access to boss menu |
Default Jobs
The framework includes these jobs by default:
Law Enforcement (type = 'leo'):
vallaw - Valentine Law Enforcement
rholaw - Rhodes Law Enforcement
blklaw - Blackwater Law Enforcement
strlaw - Strawberry Law Enforcement
stdenlaw - Saint Denis Law Enforcement
Medical (type = 'medic'):
valmedic - Valentine Medic
sdmedic - Saint Denis Medic
Civilian:
unemployed - Default job for all players
Creating Custom Jobs
-- Example: Blacksmith job
blacksmith = {
name = 'blacksmith',
label = 'Blacksmith',
type = 'crafting',
defaultDuty = true,
offDutyPay = false,
grades = {
['0'] = { name = 'Apprentice', payment = 15 },
['1'] = { name = 'Journeyman', payment = 30 },
['2'] = { name = 'Master Smith', isboss = true, payment = 60 }
}
},
-- Example: Rancher job
rancher = {
name = 'rancher',
label = 'Rancher',
type = 'farming',
defaultDuty = true,
offDutyPay = true, -- Ranchers always get paid
grades = {
['0'] = { name = 'Ranch Hand', payment = 20 },
['1'] = { name = 'Foreman', payment = 40 },
['2'] = { name = 'Ranch Owner', isboss = true, payment = 80 }
}
},
Vehicles Configuration
Location
File: rsg-core/shared/vehicles.lua
Vehicle Structure
RSGShared = RSGShared or {}
RSGShared.Vehicles = RSGShared.Vehicles or {}
local Vehicles = {
CART01 = {
name = 'Wooden Cart 1',
brand = 'Unknown',
model = 'CART01',
price = 100,
category = 'carts',
hash = joaat('CART01'),
shop = 'valentine_stable'
},
A_C_HORSE_AMERICANPAINT_GREYOVERO = {
name = 'American Paint - Grey Overo',
brand = 'Horse',
model = 'A_C_HORSE_AMERICANPAINT_GREYOVERO',
price = 500,
category = 'horses',
hash = joaat('A_C_HORSE_AMERICANPAINT_GREYOVERO'),
shop = 'valentine_stable'
},
}
-- Auto-populate RSGShared.Vehicles table
for i = 1, #Vehicles do
RSGShared.Vehicles[Vehicles[i].model] = {
spawncode = Vehicles[i].model,
name = Vehicles[i].name,
brand = Vehicles[i].brand,
model = Vehicles[i].model,
price = Vehicles[i].price,
category = Vehicles[i].category,
hash = joaat(Vehicles[i].model),
shop = Vehicles[i].shop
}
end
Vehicle Properties
| Property | Type | Description |
|---|
name | string | Display name |
brand | string | Manufacturer/breed |
model | string | Spawn code |
price | number | Purchase price |
category | string | Category for shops |
hash | number | Model hash (auto-calculated) |
shop | string | Shop identifier |
Vehicle Categories
Common categories:
'horses' - Horse mounts
'carts' - Wagons and carts
'coaches' - Stagecoaches
'boats' - Watercraft
Gangs Configuration
Location
File: rsg-core/shared/gangs.lua
Gang Structure
RSGShared = RSGShared or {}
RSGShared.Gangs = {
none = {
label = 'No Gang',
grades = {
['0'] = { name = 'Unaffiliated' }
}
},
odriscoll = {
label = 'O\'Driscoll Boys',
grades = {
['0'] = { name = 'Recruit' },
['1'] = { name = 'Enforcer' },
['2'] = { name = 'Shot Caller' },
['3'] = { name = 'Boss', isboss = true }
}
},
}
Default Gangs
none - No gang affiliation
odriscoll - OโDriscoll Boys
lemoyne - Lemoyne Raiders
murfree - Murfree Brood
skinner - Skinner Brothers
laramie - Laramie Gang
dellobo - Del Lobo Gang
night - Night Folk
foreman - Foreman Brothers
anderson - Anderson Boys
watson - Watsonโs Boys
Creating Custom Gangs
-- Example: Custom gang
mystic_gang = {
label = 'Mystic Riders',
grades = {
['0'] = { name = 'Prospect' },
['1'] = { name = 'Member' },
['2'] = { name = 'Road Captain' },
['3'] = { name = 'Vice President' },
['4'] = { name = 'President', isboss = true }
}
},
Weapons Configuration
Location
File: rsg-core/shared/weapons.lua
Weapon Structure
RSGShared = RSGShared or {}
RSGShared.Weapons = {
[`weapon_revolver_cattleman`] = {
name = 'weapon_revolver_cattleman',
label = 'Cattleman Revolver',
weapontype = 'Revolver',
ammotype = 'AMMO_REVOLVER',
damagereason = 'Shot with Cattleman Revolver'
},
[`weapon_rifle_boltaction`] = {
name = 'weapon_rifle_boltaction',
label = 'Bolt Action Rifle',
weapontype = 'Rifle',
ammotype = 'AMMO_RIFLE',
damagereason = 'Shot with Bolt Action Rifle'
},
}
Weapons must also be defined in shared/items.lua as inventory items with type = 'weapon'!
Best Practices
Restart Required: All shared file changes require a full server restart to take effect
Unique Keys: Ensure all items, jobs, and gangs have unique identifiers (names)
Test Thoroughly: Test all new jobs, items, and vehicles before deploying to production
Configuration Tips
- Consistent Naming: Use lowercase with underscores (
my_custom_item)
- Clear Labels: Use descriptive display names
- Balanced Payments: Keep job payments balanced for economy
- Weight System: 1000g = 1kg, keep items realistic
- Image Files: Ensure all images exist in rsg-inventory/html/images
Common Mistakes
โ Donโt:
-- Mismatched key and name
['my_item'] = {
name = 'myitem', -- WRONG! Should match key
-- ...
}
-- Forgetting quotes on grade keys
grades = {
[0] = { name = 'Grade' } -- WRONG! Should be '0'
}
โ
Do:
-- Matching key and name
['my_item'] = {
name = 'my_item', -- Correct!
-- ...
}
-- Proper grade key format
grades = {
['0'] = { name = 'Grade' } -- Correct!
}
Next Steps
Need help? Join the RSG Framework Discord!