Server Events
Server-side events for Dime Skills
Server Events
All server-side events that can be triggered or listened to in Dime Skills.
dime_skills:addXP
Adds XP to a player's skill (client → server).
TriggerServerEvent('dime_skills:addXP', skill, amount)Parameters
skill(string): Skill name/identifieramount(number): XP amount to add
Example
-- Client-side trigger
TriggerServerEvent('dime_skills:addXP', 'mining', 15)
-- After completing action
RegisterNetEvent('mining:oreCollected', function(oreType)
local xpAmounts = {
copper = 5,
iron = 10,
gold = 20
}
local xp = xpAmounts[oreType] or 5
TriggerServerEvent('dime_skills:addXP', 'mining', xp)
end)Server-side Handling
-- The event is handled internally
-- But you can listen to it for logging/analytics
RegisterNetEvent('dime_skills:addXP', function(skill, amount)
local _source = source
print(('Player %d gained %d XP in %s'):format(_source, amount, skill))
end)Security
This event is protected by safety checks (rewardMax). Don't disable safety checks in production.
- Server validates the XP amount
- Checks against
rewardMaxin config - Logs suspicious activity if Debug enabled
- May block excessive XP grants
Usage
Use this event when:
- Player completes an action
- Rewarding from client-side systems
- Integrating with minigames
- Activity-based progression
For server-side XP grants, use the export exports.dime_skills:addEXP() instead for better control.
dime_skills:removeXP
Removes XP from a player's skill (client → server).
TriggerServerEvent('dime_skills:removeXP', skill, amount)Parameters
skill(string): Skill name/identifieramount(number): XP amount to remove
Example
-- Client-side trigger
TriggerServerEvent('dime_skills:removeXP', 'driving', 25)
-- After failed action
RegisterNetEvent('crafting:craftFailed', function(itemName)
-- Small penalty for failure
TriggerServerEvent('dime_skills:removeXP', 'crafting', 10)
end)
-- Death penalty
AddEventHandler('gameEventTriggered', function(name, args)
if name == 'CEventNetworkEntityDamage' then
local victim = args[1]
if victim == PlayerPedId() and IsEntityDead(victim) then
-- Lose XP on death
TriggerServerEvent('dime_skills:removeXP', 'strength', 30)
end
end
end)Server-side Handling
-- Listen for XP removal (for logging)
RegisterNetEvent('dime_skills:removeXP', function(skill, amount)
local _source = source
print(('Player %d lost %d XP in %s'):format(_source, amount, skill))
end)Security
XP removal is capped at reduceMax from skill config.
- Server validates the amount
- Checks against
reduceMax - Prevents excessive XP loss
- Can cause level downs
Usage
Use this event for:
- Failure penalties
- Death penalties
- Punishment systems
- Balancing mechanics
For server-side XP removal, use exports.dime_skills:remoEXP() for direct control.
dime_skills:saveSkills
Forces a save of all player skills (server-only).
TriggerEvent('dime_skills:saveSkills')This is a server-only event. Calling from client will result in player kick.
Parameters
None
Example
-- Force save all skills
TriggerEvent('dime_skills:saveSkills')
-- Before server shutdown
AddEventHandler('txAdmin:events:serverShuttingDown', function()
print('Saving all skills before shutdown...')
TriggerEvent('dime_skills:saveSkills')
Wait(5000) -- Give time to save
end)
-- Periodic backup
CreateThread(function()
while true do
Wait(1800000) -- 30 minutes
print('Performing periodic skill save...')
TriggerEvent('dime_skills:saveSkills')
end
end)
-- Admin command
RegisterCommand('saveskills', function(source)
if source == 0 then -- Console only
TriggerEvent('dime_skills:saveSkills')
print('Skills saved successfully')
end
end, true)Behavior
When triggered:
- Iterates through all loaded players
- Saves each player's skills to database
- Logs operation time (if Debug enabled)
- Ensures data persistence
Security
- Server-only: Cannot be called from client
- Source Check: Validates source == 0 or nil
- Kick Protection: Drops players who try to trigger it
Usage
Use this event for:
- Manual backups
- Before server restart
- Scheduled saves
- Admin tools
- Testing
Skills are automatically saved on player disconnect and resource stop. Manual saves are usually not needed.
dime_skills:craftItemSuccess
Triggered after successful item crafting in ox_inventory.
TriggerEvent('dime_skills:craftItemSuccess', source, itemData)Parameters
source(number): Player's server IDitemData(table): Craft recipe data
itemData Structure:
{
name = 'item_name',
label = 'Item Label',
skills = {
required = {
crafting = 5,
chemistry = 3
},
reward = {
crafting = 10,
chemistry = 5
}
},
-- ... other recipe data
}Example
-- Hook into crafting system
RegisterNetEvent('ox_inventory:craftComplete', function(itemName, recipe)
-- Trigger skill rewards
TriggerEvent('dime_skills:craftItemSuccess', source, recipe)
-- Additional logging
print(('Player %d crafted %s'):format(source, itemName))
end)
-- Custom crafting integration
RegisterNetEvent('mycrafting:success', function(recipeData)
local itemData = {
name = recipeData.item,
skills = {
reward = {
crafting = recipeData.xpReward or 10
}
}
}
TriggerEvent('dime_skills:craftItemSuccess', source, itemData)
end)Behavior
When triggered:
- Checks if
craftingSkillsis enabled in config - Validates
itemData.skills.rewardexists - Awards XP for each skill in rewards
- Triggers skill notifications
Integration
This event works with the ox_inventory hook:
-- Automatic integration (built-in)
exports.ox_inventory:registerHook('craftItem', function(payload)
local itemData = payload.recipe
local source = payload.source
-- Check requirements (handled automatically)
-- On success, trigger reward event
return true
end, {print = false})Usage
Use this event for:
- ox_inventory integration
- Custom crafting systems
- Skill rewards after crafting
- Custom XP calculations
If craftingSkills = true in config, this is automatically handled. Manual triggering is for custom systems.
Usage Examples
Custom Skill Progression System
-- Progressive difficulty with skill checks
RegisterNetEvent('mining:attemptMine', function(nodeId, difficulty)
local skill = exports.dime_skills:grabSkill(source, 'mining')
if not skill or skill.level < difficulty then
TriggerClientEvent('ox_lib:notify', source, {
type = 'error',
description = ('Mining level %d required'):format(difficulty)
})
return
end
-- Success - grant XP based on difficulty
local xpReward = difficulty * 5
exports.dime_skills:addEXP(source, 'mining', xpReward)
-- Grant resources
TriggerClientEvent('mining:grantReward', source, nodeId)
end)Death Penalty System
-- Configurable death penalties
local deathPenalties = {
strength = 20,
stamina = 15,
shooting = 10
}
AddEventHandler('playerDied', function(playerId, killer, deathReason)
for skill, xpLoss in pairs(deathPenalties) do
exports.dime_skills:remoEXP(playerId, skill, xpLoss)
end
TriggerClientEvent('ox_lib:notify', playerId, {
type = 'error',
title = 'Death Penalty',
description = 'You lost skill XP from dying'
})
end)Crafting Integration Example
-- Custom crafting system with skill rewards
RegisterNetEvent('crafting:craftItem', function(itemName)
local recipes = {
weapon_pistol = {
required = { weaponary = 10 },
reward = { weaponary = 15 }
},
lockpick = {
required = { crafting = 5 },
reward = { crafting = 10 }
}
}
local recipe = recipes[itemName]
if not recipe then return end
-- Check requirements
for skill, level in pairs(recipe.required) do
local playerSkill = exports.dime_skills:grabSkill(source, skill)
if not playerSkill or playerSkill.level < level then
TriggerClientEvent('ox_lib:notify', source, {
type = 'error',
description = 'Insufficient skill level'
})
return
end
end
-- Grant item (your inventory system)
-- ...
-- Award skill XP
for skill, xp in pairs(recipe.reward) do
exports.dime_skills:addEXP(source, skill, xp)
end
end)Admin Tools
-- Admin commands for skill management
RegisterCommand('giveskillxp', function(source, args)
-- giveskillxp <player_id> <skill> <amount>
if source ~= 0 and not IsPlayerAceAllowed(source, 'command.admin') then
return
end
local targetId = tonumber(args[1])
local skill = args[2]
local amount = tonumber(args[3])
if targetId and skill and amount then
local success = exports.dime_skills:addEXP(targetId, skill, amount)
if success then
print(('Granted %d XP in %s to player %d'):format(amount, skill, targetId))
else
print('Failed to grant XP')
end
end
end, true)
RegisterCommand('setskill level', function(source, args)
-- setskilllevel <player_id> <skill> <level>
if source ~= 0 and not IsPlayerAceAllowed(source, 'command.admin') then
return
end
local targetId = tonumber(args[1])
local skill = args[2]
local level = tonumber(args[3])
if targetId and skill and level then
exports.dime_skills:setLevel(targetId, skill, level)
print(('Set %s to level %d for player %d'):format(skill, level, targetId))
end
end, true)Event Logging System
-- Log all skill changes
local skillLogs = {}
RegisterNetEvent('dime_skills:addXP', function(skill, amount)
local playerId = source
local citizenId = getPlayerIdentifier(playerId)
table.insert(skillLogs, {
timestamp = os.time(),
player = citizenId,
skill = skill,
amount = amount,
type = 'gain'
})
end)
RegisterNetEvent('dime_skills:removeXP', function(skill, amount)
local playerId = source
local citizenId = getPlayerIdentifier(playerId)
table.insert(skillLogs, {
timestamp = os.time(),
player = citizenId,
skill = skill,
amount = amount,
type = 'loss'
})
end)
-- Save logs periodically
CreateThread(function()
while true do
Wait(600000) -- 10 minutes
if #skillLogs > 0 then
-- Save to database or file
print(('Logged %d skill changes'):format(#skillLogs))
skillLogs = {}
end
end
end)Best Practices
Security
- Validate Source: Always validate the event source
- Check Permissions: Use ACE permissions for admin events
- Rate Limiting: Implement cooldowns to prevent spam
- Sanitize Input: Validate all parameters
Performance
- Batch Operations: Group multiple XP grants when possible
- Async Operations: Use callbacks for database queries
- Cache Data: Don't query skills repeatedly
- Debounce Saves: Don't save too frequently
Error Handling
- Check Returns: Always check export return values
- Graceful Failure: Handle errors without breaking gameplay
- Log Errors: Use Debug mode during development
- Inform Players: Give feedback on failures
Integration
- Use Exports: Prefer exports over events for server-side code
- Event Documentation: Document custom event usage
- Compatibility: Test with different frameworks
- Version Checking: Ensure compatible versions
Event Flow Diagram
Client Action → TriggerServerEvent('dime_skills:addXP')
↓
Server Receives Event
↓
Validate Parameters & Safety Checks
↓
Update Player Skills (exports.dime_skills:addEXP)
↓
Update Database
↓
TriggerClientEvent('dime_skills:sendPlayerSkills')
↓
TriggerClientEvent('dime_skills:skillNotify')
↓
Client Updates UI & Shows NotificationRelated
- Client Events - Client-side events
- Server Exports - Server functions
- Configuration - Config options