Page
About
This is a multipurpose handling system that will allow you to do the finest adjustments on vehicles parameters with an easy to use user interface, developer tool and advanced Drift Mode. The system will suit any type of server, no matter if it is a roleplay (where it could be used as a tuning tablet), freeroam, drift or racing where it could serve as a utility for players to freely adjust their cars or just as a developer tool with a feature that generates an XML code to just copy and drop into your server files.
For a roleplay server it can open variety of new scenarios, making each individual vehicle feel unique. You want Ford Mustang be stable on the road. With good skills you will be able to achieve it. You want it to be as drift car? Do it!
With our unique and advanced Drift System, you can make any upgraded car slide sideways easily. On top of that each player can configure the drift mode that suits them.
Installation
Installation difficulty
🟠⚫⚫⚫⚫
1 - Add the script
Download the resource from cfx keymaster;
Unzip the resource archive;
Add the script to your
resources
folder;Add
db_qbcore.sql
ordb_esx.sql
(depending on your framework) to your database, or do not add any sql, but in such case make sure to setConfig.UseDatabaseHandlingSaving
and Config.UseDatabasePresetsSaving tofalse
;Add the resource to your server start file (
server.cfg
) by writingensure sb-handlingtuning
. Make sure it is started after any dependencies you will be using.
2 - Adjust configs
Adjust files found in the /configs
folder to fit your server.
Make sure to go through all options in /configs/config.lua
and read the commented code to adjust the config to fit your server.
Most important settings are under the Framework
section.
3 - Save Standard Vehicles handlings
This step is not necessary but highly recommended and it only needs to be done once.
After the resource is started join the game;
Make sure you have admin permissions for the resource;
Make sure you have added all your addon vehicles to
Config.AddonVehicles
table in theconfigs/config.lua
file before doing next step;Use command
/fetchstandard
in client side and wait until all vehicles are loaded (you will see an amount of them increasing);
If you will not do this, the script might set incorrect values to vehicles and show incorrect values in the tabled UI.
If you will not add all your addon vehicles models to Config.AddonVehicles
script will try to do that automatically when car is spawned, but it might aswell corrupt the data.
Config
Config = {}
-- 88888888b dP
-- 88 88
-- a88aaaa 88d888b. .d8888b. 88d8b.d8b. .d8888b. dP dP dP .d8888b. 88d888b. 88 .dP
-- 88 88' `88 88' `88 88'`88'`88 88ooood8 88 88 88 88' `88 88' `88 88888"
-- 88 88 88. .88 88 88 88 88. ... 88.88b.88' 88. .88 88 88 `8b.
-- dP dP `88888P8 dP dP dP `88888P' 8888P Y8P `88888P' dP dP `YP
Config.Framework = 'qbcore' -- qbcore/esx/exm/other
Config.MySQLScript = 'MySQL' -- MySQL / oxmysql
Config.NotificationSystem = 'qbcore' -- qbcore / esx / custom
-- Identifier used to save/load player's presets in database
Config.PlayerIdentifier = 'license' -- license / steam / discord / ip
Config.UseDatabaseHandlingSaving = true
Config.UseDatabasePresetsSaving = true
Config.UseVstancer = true
-- Owned vehicles table in database information.
-- tableName - Name of table in which all owned vehicles are stored
-- ownerColumn - Owned vehicles owner column in DB table
-- plateColumn - Vehicle plate column in DB table
if Config.Framework == 'qbcore' then
Config.OwnedVehiclesDataTable = {
tableName = 'player_vehicles', ownerColumn = 'citizenid', plateColumn = 'plate' -- QBCore
}
elseif Config.Framework == 'esx' or Config.Framework == 'exm' then
Config.OwnedVehiclesDataTable = {
tableName = 'owned_vehicles', ownerColumn = 'owner', plateColumn = 'plate' -- ESX
}
else
Config.OwnedVehiclesDataTable = {}
Config.UseDatabaseHandlingSaving = false
Config.UseDatabasePresetsSaving = false
end
-- .d888888
-- d8' 88
-- 88aaaaa88a .d8888b. .d8888b. .d8888b. .d8888b. .d8888b.
-- 88 88 88' `"" 88' `"" 88ooood8 Y8ooooo. Y8ooooo.
-- 88 88 88. ... 88. ... 88. ... 88 88
-- 88 88 `88888P' `88888P' `88888P' `88888P' `88888P'
-- Admins and their checks
Config.Admins = {
{type = 'identifier', data = 'steam:*'},
{type = 'frameworkgroup', data = 'god'},
{type = 'frameworkgroup', data = 'superadmin'},
{type = 'frameworkgroup', data = 'admin'},
{type = 'ace', data = 'handlingtuning'},
{type = 'ace', data = 'acommands'},
}
-- NOT recommended for RolePlay server
-- If set to true players will be able to fully adjust their vehicle
-- and make it as crazy fast as they want.
Config.AllowEveryoneFullAccess = false
-- Limited editing allows for all players to use the tablet, but only adjust vehicles handling values for limited number
-- You can adjust how much of each field can be changed by editing configs/config.js Min / Max > changeLimit
--
-- For example if vehicle's standard mass is 2000, Min.changeLimit is 200 and Max.changeLimit is 500,
-- then player will have 1800 - 2500 to play around with, as 2000 - 200 = 1800, 2000 + 500 = 2500.
--
-- THIS WILL NOT AFFECT TABLET VALUES FOR ADMINS - TABLET DEV USAGE
Config.AllowLimitedEditing = true
-- If value in config.js is not added, this will be used instead
Config.DefaultChangeLimit = 0.1
-- Name of inventory item
-- FOR QBCORE:
-- ADD TO qb-core/shared.lua > QBShared.Items
-- ['tunertablet'] = {['name'] = 'tunertablet', ['label'] = 'Tuner Tablet', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'tablet.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Tablet used to adjust vehicle handling data'},
-- FOR ESX/EXM:
-- ADD TO database
-- INSERT INTO `items` (name, label)
-- VALUES ('tunertablet', 'Tuning Tablet');
Config.TabletItemName = 'tunertablet'
-- Command for admins full tablet access
Config.TabletCommand = 'tablet'
-- If you want any field to not be accessible by any regular player add it here
Config.BlacklistedFields = {
'nMonetaryValue',
'fPetrolTankVolume',
}
-- Handling groups and their parameters.
-- Params define what car modification(s) is/are needed for the value to be changable.
-- Available mods names: Engine, Suspension, Transmission, Spoiler, FrontBumper, RearBumper, Armor
Config.HandlingGroups = {
{
Label = 'Engine', Params = {
Engine = 2,
Suspension = false,
Transmission = false,
Spoiler = false,
FrontBumper = false,
RearBumper = false,
}
},
{
Label = 'Suspension', Params = {
Engine = false,
Suspension = 3,
Transmission = false,
Spoiler = false,
FrontBumper = false,
RearBumper = false,
}
},
{
Label = 'Stance', Params = {
Engine = false,
Suspension = 3,
Transmission = false,
Spoiler = false,
FrontBumper = false,
RearBumper = false,
}
},
{
Label = 'Traction', Params = {
Engine = false,
Suspension = 2,
Transmission = false,
Spoiler = false,
FrontBumper = false,
RearBumper = false,
}
},
{
Label = 'Aero', Params = {
Engine = false,
Suspension = false,
Transmission = false,
Spoiler = 1,
FrontBumper = 1,
RearBumper = 1,
}
},
{
Label = 'Damage', Params = {
Engine = false,
Suspension = false,
Transmission = false,
Spoiler = false,
FrontBumper = false,
RearBumper = false,
Armor = 4,
}
},
{
Label = 'Brakes', Params = {Brakes = 4}
},
{ -- Other is needed.
Label = 'Other', Params = {}
},
}
-- Scores to be displayed in diagram for the tablet
local handlingConfig = {}
Citizen.CreateThread(function()
Citizen.Wait(100)
if not IsDuplicityVersion() then
handlingConfig = exports[GetCurrentResourceName()].getHandlingConfig()
Config.ScoreValues = {
{label = 'Aero', field = 'fDownforceModifier', max = handlingConfig.fDownforceModifier.Max.value},
{label = 'TopSpeed', field = 'fInitialDriveMaxFlatVel', max = handlingConfig.fInitialDriveMaxFlatVel.Max.value},
{label = 'Braking', field = 'fBrakeForce', max = handlingConfig.fBrakeForce.Max.value},
{label = 'Acceleration', field = {'fInitialDriveForce', 'fDriveInertia'}, max = handlingConfig.fInitialDriveForce.Max.value + handlingConfig.fDriveInertia.Max.value},
}
end
end)
-- If you want specific field to require specific mod add it here
-- Available mods names: Engine, Suspension, Transmission, Spoiler, FrontBumper, RearBumper, Armor
Config.RequirementsForFields = {
fSuspensionRaise = {
Transmission = 4
}
}
-- Your addon vehicles models
Config.AddonVehicles = {
'bmwe3',
'x6m',
'c63coupe',
'RS72020',
'mach1',
'z419',
'635',
'rs7',
'rs615',
'rmodrs7',
'e21',
'bmwe32',
'e34touring',
'e34',
'e36prb',
'bmwe39',
'm3kean',
'rmodmi8lb',
'm2',
'm3f80',
}
Config.MaximumFetchBuffer = 3
-- 888888ba oo .8888b dP 8888ba.88ba dP
-- 88 `8b 88 " 88 88 `8b `8b 88
-- 88 88 88d888b. dP 88aaa d8888P 88 88 88 .d8888b. .d888b88 .d8888b.
-- 88 88 88' `88 88 88 88 88 88 88 88' `88 88' `88 88ooood8
-- 88 .8P 88 88 88 88 88 88 88 88. .88 88. .88 88. ...
-- 8888888P dP dP dP dP dP dP dP `88888P' `88888P8 `88888P'
Config.DriftModeEnabled = true
-- Modifications required for Drift mode to be enabled
Config.DriftGroupParams = {
Engine = 2,
Suspension = 3,
Transmission = 2,
}
-- Drift mode parameters.
-- label, description - what is displayed in tablet under the Drift group configuration
-- formula - formula used to calculate changes for the field when vehicle is moving sideways
Config.DriftModeFields = {
fInitialDriveForce = {
label = 'Drive Force multiplier on slide',
description = 'How much of drive force will be increased when vehicle slides',
formula = function(defaultValue, speed, angle, multiplier)
local result = defaultValue + angle/15
return result
end},
fSteeringLock = {
label = 'Steering lock multiplier on slide',
formula = function(defaultValue, speed, angle, multiplier)
local result = math.max(defaultValue, math.min(defaultValue + angle, 70.0))
return result
end},
fTractionCurveMin = {
label = 'Traction decrease multiplier on slide',
formula = function(defaultValue, speed, angle, multiplier)
local result = math.max(defaultValue - angle/17, 1.0)
return result
end},
fDriveBiasFront = {
label = 'Drive bias multiplier on slide',
formula = function(defaultValue, speed, angle, multiplier)
local result = math.max(defaultValue, 0.2)
return result
end},
}
table.has = function(t, e)
for _,v in ipairs(t) do
if e == v then
return true
end
end
return false
end
table.count = function(t)
local count = 0
for _,__ in pairs(t) do
count = count + 1
end
return count
end
table.clone = function(t)
if type(t) ~= 'table' then return t end
local meta = getmetatable(t)
local target = {}
for k,v in pairs(t) do
if type(v) == 'table' then
target[k] = table.clone(v)
else
target[k] = v
end
end
setmetatable(target, meta)
return target
end
How to use
Option 1 - Full access
You can use the handling tuning system with full access using a chat command /tablet
. For players to have access to the command you need to give access using any of Config.Admins
permissions. This will allow players to access all the features of the system including:
All handling parameters to be adjusted without any limit (in the range set in
config.js
);Change parameters in all groups on any vehicle, without needing to upgrade the vehicle first;
Access Drift mode on any vehicle;
Ability to generate and copy XML file of vehicle's handling;
Access to either Minimal or Tablet UIs;
Adjust owned vehicles and have their values saved to database.
Option 2 - Limited access
Recommended for RP servers. You can allow players to use an inventory item to access the Tablet UI and adjust their vehicles in a limited range, which depends on original vehicle handling. This method will allow players to access their, or others vehicles to their liking and will include:
A limited parameters range (limits can be set in
config.js
);Access to Drift mode if vehicle meets upgrades requirements;
Access to all handling groups if vehicle meets upgrades requirements;
Access to either Minimal or Tablet UIs;
Adjust owned vehicles and have their values saved to database.
API
API exports functions and events (client side):
openTablet(fullAccess) / openMinimal(fullAccess)
Opens tablet or minimal UI.
Paremeters:
fullAccess
- boolean(true/false) Full access will allow player to generate XML code of the handling, adjust the values without any limits. See more in https://github.com/daZepelin/sb-handlingtuning/blob/gitbook/docs/handling-tuning.md#how-to-use
-- TABLET UI
-- Full Access
exports['sb-handlingtuning']:openTablet(true)
-- Limited Access
exports['sb-handlingtuning']:openTablet(false)
-- MINIMAL UI
-- Full Access
exports['sb-handlingtuning']:openMinimal(true)
-- Limited Access
exports['sb-handlingtuning']:openMinimal(false)
setDriftMode(toggle)
Sets Drift Mode either enabled or disabled.
Parameters:
toggle
- boolean(true/false) Enable disable the drift mode of a vehicle player is currently sitting in.
-- Enable
exports['sb-handlingtuning']:setDriftMode(true)
-- Disable
exports['sb-handlingtuning']:setDriftMode(false)
setVehicleHandlingValue(key, value, vehicle)
Use instead of natives for vehicle handling (SetVehicleHandlingField, SetVehicleHandlingFloat, SetVehicleHandlingInt, SetVehicleHandlingVector). If you have any script that uses these natives replace them with this export.
Parameters:
key
- string vehicle handling field (e.gnInitialDriveGears
,fInitialDriveForce
);value
- number value for field to set;vehicle
- vehicle handler (optional, default vehicle player is in).
Example to replace in other script:
--SetVehicleHandlingFloat(currentVehicle, "CHandlingData", "fClutchChangeRateScaleDownShift", 0.0)
exports['sb-handlingtuning']:setVehicleHandlingValue('fClutchChangeRateScaleDownShift', 0.0, currentVehicle)
resetHandling()
Resets handling to standard vehicle values.
exports['sb-handlingtuning']:resetHandling()
SetFrontCamber(vehicle, value) / SetRearCamber(vehicle, value)
Sets vehicle front / rear camber for stance.
exports['sb-handlingtuning']:SetFrontCamber() -- Sets front Camber
exports['sb-handlingtuning']:SetRearCamber() -- Sets rear Camber
SetFrontWheelOffset(vehicle, value) / SetRearWheelsOffset(vehicle, value)
Sets vehicle front / rear wheels offset for stance.
exports['sb-handlingtuning']:SetFrontWheelOffset() -- Sets fron wheels ofsset
exports['sb-handlingtuning']:SetRearWheelsOffset() -- Sets rear wheels offset
Common Issues / FAQ
Why I can not see all options?
You probably are using tablet with limited access. In Config.Groups
you can set that for example Engine
group would require engine level 4 upgrade installed on the vehicle. So you either want to install all the upgrades or open tablet using /tablet
command. See more information in https://github.com/daZepelin/sb-handlingtuning/blob/gitbook/docs/handling-tuning.md#how-to-use
Why I can not toggle Drift Mode?
I do not use any framework, will handling system work on my server?
Yes, the system has build in options to work without any framework and any other scripts. To make it work you would need to set Config.Framework
and Config.NotificationSystem
to 'custom'
. The framework implementation only allows owned vehicles to save their handlings.
I change handling values, but they make no effect, when I reload tablet they get back to default
This most likely happens because you have some other script that changes handling values and interrupts sb-handlingtuning functionality. Make sure you do not have any other handling editors, tuning tablets or engine swap scripts installed in your server.
Mostly often it is qb-vehiclefailure
or fivem-realisticvehicle
resources that affect braking force.
Changelog
v1.0.0.3
Fixed some of database issues and loading on esx and mysql-async scritpts;
Fixed pressing E and Q fading in the minimal UI even if the tablet UI is on;
Fixed some UI errors.
v1.0.1 - v1.0.1.2
Fixes on key presses causing UI errors;
Created and added more errors handlers for easier debugging;
Fixed some sql queries to work with older mysql-async versions;
Fixed issue that caused break on saving presets and generating xml files;
Adjusted the way standard vehicles are being loaded. Now it might take longer, but will more likely not break and get stuck.
v1.0.1.3
Added API export functions. How to use them you can find in https://github.com/daZepelin/sb-handlingtuning/blob/gitbook/docs/handling-tuning.md#api;
Fixed some issues with server callbacks.
v1.0.2
Changed json to longtext in sql queries, as for some db versions it was causing issues;
Fixed issue where drift mode values were resetting when not intended;
Added missing handling fields, that had their groups missing;
Drift group values were saving some not needed values to standard values;
Added tablet command name config;
Added api for setting handling values, now the system will be easier to implement to other of your systems.
v1.0.3
Added wheels stancer tuning to the tablet. You can adjust wheels base width and camber. For now this is only synced with players inside the car. Also created api for that;
Added drifting heat. If drift mode is on this will reduce the tires grip after drifting and will gradually get back to normal grip if not drifting anymore. This should help initiate next slide after being in drift;
Fixed tablet icons and property description element;
Fixed some issues with drift mode, which was not activating in some cases.
Was this helpful?