Skip to content

Assembly Vehicle Tuning

Assembly vehicles can compose non-physical DriveSeat configuration from the asset's tuning/ folder. Use this when a physical assembly choice also changes runtime behavior, such as suspension values, engine sound, horsepower, gear ratios, or start/stop sounds.

The mental model for vehicle developers is:

A tuning model is a partial DriveSeat. Put only the DriveSeat children this tuning item changes inside the model.

During assembly, each selected tuning model is copied onto the assembled DriveSeat.

Asset Shape

Assembly assets may include a third top-level folder next to assembly/ and accessory/:

<asset model>
  assembly/
  accessory/
  tuning/
    frame/
      standard-4x2/
        VehicleDataPatch
      extended-6x4/
        VehicleDataPatch
    drivetrain/
      6-7/
        VehicleDataPatch
        EngineSound
        StartEngine
        StopEngine
      8-9/
        VehicleDataPatch
        EngineSound
        StartEngine
        StopEngine

Each entry under tuning/ is a Model. It is never mounted, welded, positioned, or searched for socket attachments. Its children are DriveSeat overlays.

Definition File

Declare tuning entries in a vehicle-local tuning_definitions.luau module:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Types = require(ReplicatedStorage.VehicleDef.Types)

local tuning_definition = Types.tuning_definition

return {
    tuning_definition({
        id = "frame:standard-4x2",
        path = "frame:standard-4x2",
        display_name = "Standard 4x2 Frame Tuning",
    }),

    tuning_definition({
        id = "drivetrain:8-9",
        path = "drivetrain:8-9",
        display_name = "8.9L Drivetrain Tuning",
    }),
}

The id is the stable catalog id used by package data. The path is the colon-delimited path under the asset's tuning/ folder. Matching id and path is common and convenient, but the id should stay stable if the asset path later changes.

Overlay Rules

Normal children are copied into the assembled DriveSeat by name. If the physical DriveSeat already has a child with that name, the tuning child replaces it.

Examples:

  • EngineSound replaces the default DriveSeat.EngineSound.
  • StartEngine replaces the default DriveSeat.StartEngine.
  • StopEngine replaces the default DriveSeat.StopEngine.
  • VehicleData replaces the default DriveSeat.VehicleData.

If two selected tuning models try to replace the same normal child, assembly fails. This keeps tuning composition deterministic.

VehicleDataPatch

Use VehicleDataPatch when multiple tuning items need to contribute A-Chassis tuning values. A VehicleDataPatch is a ModuleScript inside the tuning model. It should return a partial VehicleData-shaped table:

return {
    TuningValues = {
        Weight = 5346,
        Horsepower = 621,
        PeakRPM = 5250,
        Redline = 6200,
    },

    CustomTuningValues = {
        FSusDamping = 530,
        FSusStiffness = 11800,
        RSusDamping = 530,
        RSusStiffness = 11800,
    },
}

At assembly time, patch modules are copied to DriveSeat.VehicleDataPatches/<tuning_slot>. A-Chassis Tune applies them after the base DriveSeat.VehicleData.

Two patches may not write the same final tuning key. For example, if both frame and drivetrain patches write Horsepower, the vehicle errors during tune setup. Decide which tuning slot owns each key.

Use a full VehicleData module only for a coarse whole-vehicle tuning overlay. Use VehicleDataPatch for composable frame/drivetrain/etc. tuning.

Package Data

Packages select tuning entries with base_tuning:

{
    id = "standard-4x2",
    display_name = "Standard 4x2",
    vehicle_id = 1234001,
    base_assembly = {
        frame = "frame:standard-4x2",
        cab = "cab:standard",
    },
    base_accessories = {},
    base_tuning = {
        frame = "frame:standard-4x2",
        drivetrain = "drivetrain:6-7",
    },
    assignment = {
        drivetrain = "6-7",
    },
    customizations = {},
}

Customization items can change tuning alongside physical assembly:

{
    id = "8-9",
    display_name = "8.9L",
    assignment = {
        Assembly = {
            drivetrain = "drivetrain:8-9",
        },
        Tuning = {
            drivetrain = "drivetrain:8-9",
        },
    },
}

Keep the mapping explicit. Physical assembly choices create the model; tuning choices create the DriveSeat runtime behavior.

Suggested Ownership

The system does not require specific tuning slots, but vehicle authors should pick clear ownership boundaries.

For a truck like the Sierra HT:

  • frame tuning owns mass, weight brick size, suspension lengths, spring stiffness, damping, wishbone length, and frame-specific handling values.
  • drivetrain tuning owns engine sound, start/stop sounds, horsepower, RPM curve, final drive, gear ratios, drive layout, and fuel/engine behavior.

For a vehicle with only coarse variants, a single tuning slot is fine:

base_tuning = {
    driveSeat = "individual-v12",
}

Prefer fewer slots unless the vehicle actually needs independent tuning choices.