Developer
Overview
ml_recoil exposes no public exports and no commands. Integration happens through four overridable hooks on the client (client/main_open.lua) and four on the server (server/server_open.lua), plus a single internal callback the client uses to fetch a server-resolved multiplier. All hooks are plain global functions you edit in place; both files are escrow-ignored.
How the multiplier flows
On weapon equip, the client reads Config.XPSystem.Type. With 'client' it calls GetClientSkillMultiplier(skillName) locally. With 'server' it triggers the callback ml_recoil:getSkillMultiplier, which runs GetPlayerSkillMultiplier(source, skillName) on the server. The returned number scales every recoil value: below 1.0 steadies the aim, above 1.0 makes recoil harder.
Client Hooks
Defined in client/main_open.lua.
GetClientSkillMultiplier(skillName): returns the local multiplier. Ships an ml_skills integration that trims 10% recoil perbetterAccuracyrank.OnWeaponEquipped(weaponHash, weaponData): fires when a configured weapon is equipped. Returnfalseto skip recoil for it.OnShotFired(weaponHash, totalMultiplier): fires after every shot with the final applied multiplier. A good place to award shooting XP.OnAimStateChanged(weaponHash, isAiming): fires when the player starts or stops aiming down sights.
1function GetClientSkillMultiplier(skillName)
2 local multiplier = 1.0
3
4 if Config.XPSystem.Enabled and GetResourceState('ml_skills') == 'started' then
5 local ok, effect = pcall(function()
6 return exports.ml_skills:GetActiveEffect('betterAccuracy')
7 end)
8 if ok and type(effect) == 'number' and effect > 0 then
9 multiplier = math.max(0.1, 1.0 - (0.1 * effect))
10 end
11 end
12
13 return multiplier
14endServer Hooks
Defined in server/server_open.lua. Used when Config.XPSystem.Type = 'server'.
GetPlayerSkillMultiplier(source, skillName): returns the multiplier for a player. Wire your own skill lookup here.ServerSkillToMultiplier(level): helper that maps a 0-100 level to a multiplier (1.5 untrained, 1.0 default, 0.5 master).ValidateWeaponAccess(source, weaponHash): returnfalseto force the maximum recoil penalty (2.0) on a player as an anti-cheat gate.LogWeaponUsage(source, weaponHash, skillName, multiplier): called once per skill lookup; hook analytics or logging here.
1function GetPlayerSkillMultiplier(source, skillName)
2 if not Config.XPSystem.Enabled then return 1.0 end
3
4 -- local level = exports.ml_skills:GetPlayerLevel(skillName, source)
5 -- return ServerSkillToMultiplier(level)
6
7 return 1.0
8endExamples
Edit OnShotFired in client/main_open.lua.
1function OnShotFired(weaponHash, totalMultiplier)
2 exports.ml_skills:RequestXp('personal', 2, 'shooting')
3endSet Config.XPSystem.Type = 'server' and edit GetPlayerSkillMultiplier.
1function GetPlayerSkillMultiplier(source, skillName)
2 if not Config.XPSystem.Enabled then return 1.0 end
3 local level = exports.ml_skills:GetPlayerLevel(skillName, source)
4 return ServerSkillToMultiplier(level)
5endReturn false from OnWeaponEquipped for the hashes you want untouched.
1function OnWeaponEquipped(weaponHash, weaponData)
2 if weaponHash == `WEAPON_REVOLVER` then return false end
3 return true
4end