Skip to content

ChassisApi

public static partial class ChassisApi

Namespace Chassis.Api

Public entry point for other mods: read and change the seat profiles Chassis uses per vehicle code.

Precedence, last one wins: a profile a mod registers with Register, the JSON file in UserData/Chassis/<code>.json. The file wins so a player or the debug console can always correct a mod’s values. Changes take effect on the next seat change; Changed tells seated rigs to re-read now.

public static Func<LandVehicle, OwnerRecord> ResolveUnknownOwner

Type: OwnerRecord

Host: asked once for a player-owned vehicle that has no record yet, for example one bought before Chassis kept owners. Return the owner and lock state to import, or null to let the vehicle belong to the host.

public static IEnumerable<string> GaugeSources { get; }

Added in 1.2.0

Every gauge source by name: the built-in ones and those mods registered. A gauge, a switch’s ControlProfile.Source and VehicleTelemetry.Get read them.

Value Built in, with their units: “speed” (km/h or mph by the player’s setting), “speed_kmh”, “speed_mph”, “speed_raw” (vanilla’s signed km/h without the display factor), “rpm” (800 idle to 6000), “throttle” (-1 to 1), “handbrake”, “brake”, “reverse”, “lights”, “hazard” (each 0 or 1), “indicator” (-1, 0, 1), “indicator_left” and “indicator_right” (1 in the lit half of the flash), “steer” (-1 to 1), “steer_deg” (front wheel degrees), “clock” (HHMM), “clock_hours” (0 to 12), “clock_minutes” (0 to 60), “odometer” and “trip” (km or miles by the player’s setting), “odometer_km”, “trip_km”, “occupied” and “driver” (0 or 1).

public static bool UsesMph { get; }

Added in 1.2.0

True when the player set speeds and distances to miles (preference SpeedUnit = mph).

public static bool FirstPersonActive { get; }

The local player looks through the eyes of their seated body (key V).

public static KeyCode FirstPersonKey { get; }

The key that switches the first-person view, for a mod’s own key hints.

public static float LocalDriverThrottle { get; }

Added in 1.3.0

The local driver’s own throttle this physics step, before mods add to it in their own UpdateThrottle postfix. Chassis records it first; a pusher mod adds the pusher’s input after that, so a seated body’s hands follow only the driver’s keys.

public static string LocalPlayerCode { get; }

The local player’s code, empty before the player exists.

public static string Folder { get; }

Folder of the JSON profiles.

public static IEnumerable<string> Codes { get; }

Every vehicle code that has a profile.

public static event Action<ControlUse> ControlUsed

Type: ControlUse

Added in 1.2.0

Raised on every peer after any switch was used, built-in actions included.

public static event Action<LandVehicle, bool> HeadlightsChanged

Added in 1.2.0

Raised on every peer when a vehicle’s headlights go on (true) or off (false).

public static event Action<LandVehicle, bool> BrakeChanged

Added in 1.2.0

Raised on every peer when a vehicle’s brakes go on (true) or off (false).

public static event Action<LandVehicle, bool> ReverseChanged

Added in 1.2.0

Raised on every peer when a vehicle starts (true) or stops (false) driving backwards.

public static event Action<LandVehicle, bool> DriverChanged

Added in 1.2.0

Raised on every peer when someone takes the wheel (true) or the driver’s seat empties (false); players and NPCs.

public static event Action<bool> FirstPersonChanged

Raised on this peer with the new state whenever the local first-person view turns on or off.

public static event Action<LandVehicle, string> TuningChanged

Added in 1.3.0

Raised on every peer with the car and the key after its tuning changed (”*”: everything at once).

public static event Action<LandVehicle, int> IndicatorChanged

Raised on every peer with the vehicle and the new side when an indicator changes: -1 left, 1 right, 0 off, 2 hazard lights.

public static event Action OwnersChanged

Raised on every peer after the host’s owner and lock records arrived and something changed.

public static event Action<string> Changed

Raised with the vehicle code after a profile was registered, loaded or edited.

public static void SetInterior(
string code,
Func<LandVehicle, GameObject> build,
Action<ChassisProfile> configure = null)

Types: ChassisProfile

Added in 1.2.0

Builds a mod’s own interior into every vehicle that uses the profile code, in place of the base interior’s seats, dashboard and wheel. The lining and the tinted glass of InteriorProfile stay; set InteriorProfile.Lining to false or InteriorProfile.Glass to null in configure to drop them. Call it on every peer; the same code again replaces the factory and rebuilds the vehicles that have one.

Parameter
codeThe profile code, e.g. “shitbox” or a mod’s own code from Assign.
buildMakes the interior for one vehicle. Chassis parents the object to the vehicle’s frame and keeps its local position, rotation and scale, so place it in the frame’s space (x right, y up, z forward, metres).
configureChanges the profile to match the new interior: ChassisProfile.Steering, ChassisProfile.Gauges, ChassisProfile.Controls, the driver’s hands. It runs once on every profile object of this code: the one there now, the one Chassis fits for a vanilla car the first time one is seen, and one from a JSON file. Null leaves the profile as it is.

Example

An interior from an AssetBundle prefab for the Shitbox, with its own wheel and speedometer:

ChassisApi.SetInterior("shitbox",
vehicle => UnityEngine.Object.Instantiate(myCockpitPrefab),
profile =>
{
profile.Steering = new SteeringProfile { Path = "MyCockpit/Wheel", Axis = Vector3.forward, Ratio = 8f, Max = 300f };
profile.Gauges.Clear();
profile.Gauges.Add(new GaugeProfile { Name = "speedo", Path = "MyCockpit/SpeedoNeedle", Source = "speed_kmh", Max = 160f });
});
public static bool RemoveInterior(string code)

Added in 1.2.0

Ends SetInterior: the vehicles of this code get the base interior again. False when there was none.

Changes a configure callback made to the profile stay until the profile is reloaded (Reload).

public static void RegisterGaugeSource(
string name,
Func<LandVehicle, float> read)

Added in 1.2.0

Adds a gauge source of a mod’s own: a fuel level, a battery, a siren state. read runs for every gauge that shows it, every frame, on every peer; keep it cheap and return the same value on every peer. NaN or an exception reads as not valid. The same name again replaces the source; a built-in name throws.

Parameter
nameYour own unique name, e.g. “mymod.fuel”.
readThe value for one vehicle, in a unit of your choice; gauges map it with Min and Max.

Example

ChassisApi.RegisterGaugeSource("mymod.fuel", vehicle => MyFuel.LitresIn(vehicle));
profile.Gauges.Add(new GaugeProfile { Name = "fuel", Path = "FuelNeedle", Source = "mymod.fuel", Min = 0f, Max = 40f, From = -60f, To = 60f });
public static bool RemoveGaugeSource(string name)

Added in 1.2.0

Removes a source a mod registered; false for a built-in or unknown name.

public static GaugeReading ReadGauge(LandVehicle vehicle, string source)

Types: GaugeReading

Added in 1.2.0

One source’s current value for a vehicle.

Parameter
sourceA name from GaugeSources.
public static VehicleTelemetry Telemetry(LandVehicle vehicle)

Types: VehicleTelemetry

Added in 1.2.0

A snapshot of everything Chassis knows about the vehicle’s driving state right now.

public static void ResetTrip(LandVehicle vehicle)

Added in 1.2.0

Sets a vehicle’s trip distance back to 0 for every peer; the host decides.

public static void RegisterControlAction(
string action,
Action<ControlUse> handler)

Types: ControlUse

Added in 1.2.0

Gives a switch action of a mod’s own a handler. Switches whose ControlProfile.Action has this name call it on every peer once the host passed the use on; do world changes only where ControlUse.IsHost is set. Chassis keeps and saves the state of toggles and knobs itself; read it with ControlValue. The same name again replaces the handler.

Parameter
actionYour own unique name, e.g. “mymod.siren”; built-in names throw.

Example

ChassisApi.RegisterControlAction("mymod.siren", use =>
{
if (use.Value > 0.5f) MySiren.Start(use.Vehicle); else MySiren.Stop(use.Vehicle);
});
public static bool RemoveControlAction(string action)

Added in 1.2.0

Removes a mod’s switch action handler; false when there was none.

public static void UseControl(
LandVehicle vehicle,
string control,
float? value = null)

Added in 1.2.0

Uses a switch as if the local player clicked it, without the reach check: a button fires, a toggle flips, a knob goes to value (or back to its default when that is null).

Parameter
controlA ControlProfile.Name from the vehicle’s profile.
valueKnob: the new value. Toggle: 0 or 1, or null to flip. Ignored for a button.
public static float ControlValue(LandVehicle vehicle, string control)

Added in 1.2.0

A switch’s state: 0 or 1 for a toggle, the knob’s value, 0 for a button.

A switch with a ControlProfile.Source reports that source’s value.

FitSeat(LandVehicle, int, Transform, Transform, float)

Section titled “FitSeat(LandVehicle, int, Transform, Transform, float)”
public static SeatProfile FitSeat(
LandVehicle vehicle,
int seatIndex,
Transform frame,
Transform steeringPivot = null,
float hipHeight = 0.15f)

Types: SeatProfile

A first seat profile for one of a vehicle’s vanilla seats: the body sits on the seat, faces the vehicle’s front, holds the steering wheel (or rests the hands on the lap without one) and puts the feet into the footwell. A starting point for a new vehicle; fine-tune it with chassis profile set and save it.

Parameter
vehicleVehicle whose Seats entry the profile is for.
seatIndexIndex into LandVehicle.Seats.
frameModel frame the profile’s points are in (the transform at ChassisProfile.Frame).
steeringPivotSteering wheel pivot for “wheel” hands, or null for hands on the lap.
hipHeightHips above the vanilla seat transform, in metres.

FitSeat(LandVehicle, int, Vector3, Transform, Transform, float)

Section titled “FitSeat(LandVehicle, int, Vector3, Transform, Transform, float)”
public static SeatProfile FitSeat(
LandVehicle vehicle,
int seatIndex,
Vector3 seatPoint,
Transform frame,
Transform steeringPivot = null,
float hipHeight = 0.15f)

Types: SeatProfile

As FitSeat, for a body that sits somewhere else than the vanilla seat: a mod’s own chair on a vehicle it built over a vanilla one.

Parameter
seatPointWorld point the hips rest on, minus hipHeight.
public static bool PoseAsPusher(
Player player,
LandVehicle vehicle,
bool glide = true)

Added in 1.3.0

Poses a player’s body behind a vehicle with the hands on the handles from ChassisProfile.Push. For the local player the key hints switch to the pusher’s keys. Returns false with the reason logged when the vehicle has no push profile or the body cannot be posed.

Parameter
glidetrue eases the body into the pose over a moment, false puts it there at once.
public static void ReleasePusher(Player player)

Added in 1.3.0

Lets go: the body of a player posed with PoseAsPusher moves on its own again.

public static LandVehicle PushedBy(Player player)

Added in 1.3.0

The vehicle a player is posed behind, or null.

public static void RegisterOccupantDown(
string name,
Func<OccupantDown, bool> keepSeated)

Types: OccupantDown

Added in 1.2.0

Decides what happens to an NPC that dies or is knocked out in its seat, for example from a gunshot through the window. Return true to keep the body slumped in the seat; the car then stops where it is. Return false for vanilla: the NPC falls out next to the car as a ragdoll. The NPC stays seated when any handler returns true. Runs on the host only; clients follow the host. A knocked-out NPC that wakes up in its seat sits up again.

Parameter
nameYour handler’s name, e.g. “mymod.gta-style”; registering the same name again replaces it.
public static bool RemoveOccupantDown(string name)

Added in 1.2.0

Removes a handler added with RegisterOccupantDown; false when there was none by that name.

AddKeyHint(string, string, Func<KeyHintContext, bool>, params KeyCode[])

Section titled “AddKeyHint(string, string, Func<KeyHintContext, bool>, params KeyCode[])”
public static void AddKeyHint(
string id,
string label,
Func<KeyHintContext, bool> show,
params KeyCode[] keys)

Types: KeyHintContext

Added in 1.1.0

Adds a line to the key hints at the bottom left while the local player sits in or pushes a vehicle, below First Person and Horn and above Indicators. show runs every frame and picks the vehicles and seats the key works in; null shows it in every vehicle. The same id again replaces the entry. Letters follow the keyboard layout, so KeyCode.Y shows the key labelled Y.

Parameter
idYour own unique id, e.g. “mymod.siren”.
labelThe text next to the key, e.g. “Siren”.
showWhether the line shows for the vehicle and seat in KeyHintContext; null shows it always.
keysOne key or several shown side by side, e.g. KeyCode.LeftArrow, KeyCode.RightArrow.

Example

A siren key only for the driver of the mod’s own vehicle:

ChassisApi.AddKeyHint("mymod.siren", "Siren", c => c.Driver && ChassisApi.CodeOf(c.Vehicle) == "mymod_cruiser", KeyCode.H);

AddKeyHint(string, string, Func<KeyHintContext, bool>, Func)

Section titled “AddKeyHint(string, string, Func<KeyHintContext, bool>, Func)”
public static void AddKeyHint(
string id,
string label,
Func<KeyHintContext, bool> show,
Func<KeyCode> key)

Types: KeyHintContext

Added in 1.1.0

Adds a key hint whose key can change while the game runs, for a key from a mod’s preferences. The key is read every frame and the hint follows it.

Parameter
idYour own unique id, e.g. “mymod.siren”.
labelThe text next to the key, e.g. “Siren”.
showWhether the line shows for the vehicle and seat in KeyHintContext; null shows it always.
keyRead every frame, e.g. () => myKeyEntry.Value for a MelonPreferences entry.
public static bool RemoveKeyHint(string id)

Added in 1.1.0

Removes a key hint a mod added; false when there was none with that id.

public static void RegisterTuningPart(TuningPart part)

Types: TuningPart

Added in 1.3.0

Adds or replaces a tuning part. Register the same parts on every peer; cars that carry it rebuild.

public static bool RemoveTuningPart(string id)

Added in 1.3.0

Removes a tuning part; cars that carry it show the stock part until it is registered again.

public static TuningPart TuningPartById(string id)

Types: TuningPart

Added in 1.3.0

The registered part with this id, or null.

public static List<TuningPart> TuningParts(
LandVehicle vehicle,
string slot = null)

Types: TuningPart

Added in 1.3.0

The registered parts that fit this car, optionally only one slot.

public static bool InstallPart(LandVehicle vehicle, string partId)

Added in 1.3.0

Installs a part into its slot, replacing what was there.

public static bool RemovePart(LandVehicle vehicle, string slot)

Added in 1.3.0

Takes the part out of a slot; the car shows the stock part again.

public static string InstalledPart(LandVehicle vehicle, string slot)

Added in 1.3.0

The part id in a slot, or null for stock.

public static bool SetPaint(
LandVehicle vehicle,
Color colour,
string finish = TuningFinish.Classic,
bool secondary = false)

Types: TuningFinish

Added in 1.3.0

Paints the body (or the second paint of parts) in any colour with a finish from TuningFinish.

public static bool ClearPaint(LandVehicle vehicle, bool secondary = false)

Added in 1.3.0

Back to the vanilla paint.

public static bool SetRimColor(
LandVehicle vehicle,
Color? colour,
string finish = TuningFinish.Metal)

Types: TuningFinish

Added in 1.3.0

Rim colour; null for the stock rim colour.

public static bool SetXenon(LandVehicle vehicle, Color? colour)

Added in 1.3.0

Headlight colour; null for the stock headlights.

public static bool SetNeon(
LandVehicle vehicle,
Color? colour,
string sides = "fblr")

Added in 1.3.0

Underglow in a colour on the given sides (“fblr”: front, back, left, right); null switches it off.

public static bool SetWindowTint(LandVehicle vehicle, Color? tint)

Added in 1.3.0

Window glass colour with its alpha as the darkness; null for the profile’s tint. Needs the base interior.

public static bool SetTyreSmoke(LandVehicle vehicle, Color? colour)

Added in 1.3.0

Drift smoke colour; null for the stock white. The smoke shows on the driver’s screen, as in vanilla.

public static bool SetHorn(LandVehicle vehicle, string sound)

Added in 1.3.0

Horn sound from RegisterSound; null or empty for the profile’s horn.

public static bool SetTuning(LandVehicle vehicle, string key, string value)

Added in 1.3.0

Sets any tuning key; an empty value removes it.

public static string GetTuning(LandVehicle vehicle, string key)

Added in 1.3.0

The value of one tuning key, or null.

public static Dictionary<string, string> Tuning(LandVehicle vehicle)

Added in 1.3.0

A copy of every tuning key of a car.

public static TuningStats TuningStatsOf(LandVehicle vehicle)

Types: TuningStats

Added in 1.3.0

The driving factors of all parts on the car together.

public static bool ClearTuning(LandVehicle vehicle)

Added in 1.3.0

Puts the whole car back to stock.

public static void Assign(LandVehicle vehicle, string code)

Gives one vehicle the profile of another code. For mods that build their vehicle on a vanilla one (a “veeper” under a camper van): without this, the profile would follow the vanilla code to every vehicle of that kind. Call it on every peer; it holds until Unassign or until the vehicle is gone.

Parameter
codeThe profile code to use, e.g. “mymod_camper”; it may be registered before or after this call.
public static void Unassign(LandVehicle vehicle)

Ends an Assign: the vehicle uses the profile of its own vehicle code again.

public static string CodeOf(LandVehicle vehicle)

The profile code a vehicle uses: the assigned one, else its vehicle code.

public static ChassisProfile For(LandVehicle vehicle)

Types: ChassisProfile

The profile a vehicle uses, or null when Chassis leaves it to vanilla.

public static void RegisterSound(string name, AudioClip clip)

Makes a clip available to profiles by name (HornProfile.Clip, HornProfile.Chirp).

Parameter
nameThe name profiles use, e.g. “mymod_horn”. The same name again replaces the clip. “chassis.click” (a cabin switch moves), “chassis.tick” and “chassis.tock” (the indicator relay) replace the built-in cabin sounds.
public static void Honk(LandVehicle vehicle, bool flash = false)

Sounds the horn of a vehicle on every peer, and with flash blinks its headlights twice. The host allows it when the local player sits in the vehicle or owns it. Every vehicle has a horn; the key is G.

Parameter
flashtrue also blinks the headlights twice.
public static void SetIndicator(LandVehicle vehicle, int side)

Switches the indicator of a vehicle for every peer: -1 left, 1 right, 0 off, 2 hazard lights. The keys are the left and right arrows.

Parameter
side-1 left, 1 right, 0 off, 2 both sides (hazard lights).
public static int Indicator(LandVehicle vehicle)

The side a vehicle signals: -1 left, 1 right, 0 off, 2 hazard lights.

public static bool IndicatorLit(LandVehicle vehicle)

Whether the indicator of a vehicle is in the lit half of its flash right now; for mods that draw their own lamps.

public static void SetPart(LandVehicle vehicle, string part, bool open)

Opens or closes a lid from the profile for every peer.

Parameter
partA PartProfile.Name from the vehicle’s profile, e.g. “boot”; case is ignored.
opentrue opens the lid, false closes it.
public static bool PartOpen(LandVehicle vehicle, string part)

Whether a lid is held open by SetPart.

public static void SetStorageEnd(LandVehicle vehicle, bool front)

Tells every peer which end the vehicle’s storage is opened from, for lids with PartProfile.Storage. Vanilla storage counts as “rear” until a mod says otherwise.

Parameter
fronttrue for storage opened at the front, false for the rear.
public static string OwnerOf(LandVehicle vehicle)

Player code of the owner, or empty when the vehicle has no record (not player owned, or not synced yet).

public static bool IsMine(LandVehicle vehicle)

True when the local player owns the vehicle.

public static bool IsLocked(LandVehicle vehicle)

True when the vehicle is locked; false when it has no owner record.

public static void SetLocked(LandVehicle vehicle, bool locked)

Locks or unlocks a vehicle the local player owns. A locked vehicle lets in its owner, and others only while the owner sits inside. There is no key for it: locking is up to mods (Yesla’s app) and this call.

public static bool SetOwner(LandVehicle vehicle, string playerCode)

Host only: gives a vehicle a new owner. Returns false on a client or for a vehicle that is not player owned.

Parameter
playerCodeThe new owner’s Player.PlayerCode, the same kind of value as LocalPlayerCode.
public static ChassisProfile Get(string vehicleCode)

Types: ChassisProfile

The profile for a vehicle code, or null when Chassis leaves that vehicle to vanilla.

Parameter
vehicleCodeA code like “shitbox”; see ChassisProfile.Code for the list.
public static bool Register(ChassisProfile profile)

Types: ChassisProfile

Adds or replaces a profile from code. A JSON file for the same code still wins; returns false when one does.

Parameter
profileThe profile; its ChassisProfile.Code must be set.
public static string Save(string vehicleCode)

Writes the current profile of a vehicle code to its JSON file; from then on the file wins.

Returns The full path of the written file, UserData/Chassis/<code>.json.

public static void NotifyChanged(string vehicleCode)

Tells seated rigs that a profile changed in place, so they re-read it this frame.

public static int Reload()

Drops every loaded profile and reads the profiles mods registered and the files again.