Vehicle Params & Script Editor
Last updated
May be stale
This page was last updated ago, on 25 August 2026. Check what it says against the code before relying on it.
Runtime helpers for reading and writing Source vehicle physics (VehicleParams), plus a
developer in-game editor for iterating on vehicle scripts. This is also the foundation future
vehicle-modification plugins should build on (item-meta upgrades such as springs, turbo, engine
kits, etc.).
Why this exists
CityRP cars get their handling from Valve KeyValues scripts under scripts/vehicles/**/*.txt,
applied with SetKeyValue("vehiclescript", ...) before Spawn/Activate. Editing those files
and restarting is slow when overhauling content.
GMod exposes Vehicle:GetVehicleParams / Vehicle:SetVehicleParams for live tuning after spawn.
Those APIs are the right place for:
- A build/dev editor that applies changes immediately and exports a
.txtscript body - Item-meta modifiers that stack on top of the script baseline at spawn time
Core library
Shared library: core/libraries/sh_vehicleparams.lua → cityrp.vehicleparams
| API | Purpose |
|---|---|
IsTunableVehicle(ent) |
prop_vehicle_jeep guard |
GetEditableParams(veh) |
GetVehicleParams with speed fields converted to MPH |
SetEditableParams(veh, params) |
Converts those MPH speeds back to HU/s, then SetVehicleParams |
CaptureBaseline(veh) / RestoreBaseline(veh) |
Snapshot / restore script defaults on the entity |
RegisterModifier(id, apply, priority?) |
Register a named runtime modifier |
ResolveModifiers(entries) |
Turn {id, data} requests into an ordered apply list |
ApplyModifiers(veh, modifiers, context?) |
Re-apply from baseline + modifier list |
CollectModifiersFromMeta(item, meta, veh?) |
Built-in meta → entries, plus collect hook |
ApplyFromItemMeta(veh, item, meta) |
Spawn-time entry point |
SerializeKeyValues(params, header?) |
Export a "Vehicle" KeyValues block for scripts |
BuildEditorSections(params) / ApplyEditorValues(...) |
Schema-driven editor helpers |
MPH vs HU/s
GetVehicleParams returns engine.maxSpeed / maxRevSpeed / boostMaxSpeed in hammer units per
second. Since 2021, SetVehicleParams uses the same units (HU/s), not miles per hour — the
older wiki note that Set expects MPH is stale, and passing MPH numbers back in makes a car crawl
and bounce. Vehicle .txt scripts still store those fields in MPH.
The library always works in MPH on the editable side (GetEditableParams / modifiers / editor /
export). SetEditableParams converts back to HU/s before writing. Conversion factor: 17.6 HU/s
per MPH.
Spawn integration
Vehicles plugin SpawnVehicle captures a baseline immediately after Activate, then calls
ApplyFromItemMeta. Re-applying modifiers always starts from that baseline so stacking stays
deterministic.
In-game editor
Plugin: core/plugins/vehiclescript_editor/
| Command | !vehiclescript |
| Access | Developer only (/ flag / IsDeveloperOnly) |
| Target | Vehicle you are sitting in, otherwise the jeep under your crosshair |
Actions:
- Apply — write the form values to the live entity via
SetVehicleParams - Reset — restore the captured script baseline
- Export — serialize a
"Vehicle"KeyValues block todata/cityrp/vehicle_scripts/<name>.txtand copy it to the clipboard
Sounds ("Vehicle_Sounds") are not edited here; paste the exported "Vehicle" block into the
existing script file and keep the sounds section as-is.
Item-meta modifiers (foundation)
base_vehicle already declares springs and turbo. Those fields are no longer display-only:
spawn applies them through the modifier registry.
| Meta field | Modifier id | Effect (intentionally mild) |
|---|---|---|
springs (−10…10) |
springs |
Scales axle spring constant / max body force (~±50% at extremes) |
turbo (bool) |
turbo |
Enables torque boost and raises boost force / duration / max speed |
Adding a future upgrade
cityrp.vehicleparams.RegisterModifier("engine_upgrade", function(params, context)
local tier = tonumber(context.data) or 1
params.engine.horsepower = (params.engine.horsepower or 0) * (1 + 0.1 * tier)
params.engine.maxSpeed = (params.engine.maxSpeed or 0) * (1 + 0.05 * tier)
end, 70)
hook.Add("CityRP.VehicleParams.CollectModifiers", "my_vehicle_mods", function(entries, item, meta, veh)
local tier = cityrp.itemmeta.GetField(item, meta, "engine_upgrade")
if tier then
table.insert(entries, {id = "engine_upgrade", data = tier})
end
end)
Prefer a dedicated plugin for player-facing upgrade shops/items. Keep the apply math in
RegisterModifier so the editor, spawn path, and future systems share one code path.
Collect hook
CityRP.VehicleParams.CollectModifiers(entries, item, meta, veh) — append {id=..., data=...}
tables to entries. Unknown ids are skipped with a debug log line.
Testing
On the build/dev server as a developer:
- Spawn a car, look at it, run
!vehiclescript - Raise
HorsePower/MaxSpeed, Apply, drive - Reset, confirm script feel returns
- Export, confirm clipboard +
data/cityrp/vehicle_scripts/ /giveitem <you> <car> 1 meta:springs=5;turbo=1— spawn and confirm stiffer suspension / boost
Related
- Item Metadata Schema —
springs/turboonbase_vehicle - Modern APIs — vehicle networking caveats
- Hotwiring — engine start flow (independent of physics params)