Advanced Suspension Maker SDK

Build custom, fully-animated suspension for CarX Drift Racing Online

Hub Arm Shock Axle

Get started Browse tutorials View on GitHub

Custom Suspension — Beginner Guide (read this first)

This is the simple, click-by-click version. The deep technical details live in TUTORIAL.md — you don’t need them to make a suspension. Follow the steps in order.

Building a specific suspension type? There’s a dedicated, illustrated tutorial for each one (MacPherson, double wishbone, multilink, trailing-arm, cantilever/pushrod) in docs/tutorials/. Planned types (solid axle, long-travel, 6×6) are in ROADMAP.md.


What are we even doing?

You’re making a suspension that moves (arms swing, springs squash) on a car in CarX.

The way it works, in plain words:

You do the markers and labelling in Unity. One-click tools do the hard parts for you.

The whole flow in one picture:

Data flow: Unity to game

Words you’ll see (don’t panic)

What you need before starting

  1. The Kino content SDK Unity project open (open it with Unity Hub — it’s Unity 2023.2.20f1).
  2. Your suspension 3D model as separate rigid parts (each arm / hub / shock its own mesh).
  3. The game with the AdvancedSusp mod installed (already done).

If Unity shows a Tools ▸ KSL menu at the top, the tools are installed.


Step 1 — Put your suspension model in the scene

  1. Drag your suspension model into the Assets window, then into the Scene.
  2. Click it in the Hierarchy (left panel). This is your mesh object.

Step 2 — Place your markers (locators)

You don’t make bones. You drop empty markers (locators) at the points that matter, and the SDK turns the labelled ones into the skeleton for you (in Step 5). All markers are children of the mesh.

Here’s the pattern for one corner (you’ll repeat it for FL/FR/RL/RR). The idea: a part that swings has a chassis point (where it bolts to the body — stays still) and a hub point (where it meets the wheel — moves). The chassis point will point at the hub point.

  1. Hub marker — right-click the mesh → Create Empty, name it FL_Hub, move it (W key) to the centre of the wheel/upright.
  2. Outer points (hub end) — for each spot where an arm or the shock touches the hub, make an empty as a child of FL_Hub (right-click FL_Hub → Create Empty). Name them e.g. FL_LowerArm_end, FL_UpperArm_end, FL_Shock_low. Being children of the hub, they move + steer with the wheel — these are the Outer Targets the arms point at (Step 3).
  3. Inner pivots (chassis end) — for each arm, make an empty directly under the mesh at the spot where that arm bolts to the car body. Name them FL_LowerArm, FL_UpperArm. This is where the arm’s KSusp Bone goes, and it’s the arm’s Inner Pivot (it rotates about this point).
  4. Shock top — make an empty FL_Tophat where the shock bolts to the body. Keep it on the chassis side (NOT under the hub).

Tip: build one corner completely, then copy-paste it and move it to the other three.

Names are free-form — the SDK reads the Role + Corner you pick, not the name. But keep each name unique, and a tight convention saves you confusion (and duplicate-name warnings), especially on a multilink with lots of parts. Use this scheme:

Two rules

  1. Prefix every object with its corner: FL_ FR_ RL_ RR_. The prefix alone keeps names unique across the car.
  2. Two name shapes:
    • the bone that gets the componentRL_<Part>
    • the hub point it aims at (its Outer Target, a child of the hub) → RL_<Part>_end

So a part and its target always read as a pair: RL_ToeLink → aims at → RL_ToeLink_end.

Example — one rear (RL) multilink corner

Object Name Component
upright RL_Hub Hub (SteerCamber)
upper link RL_UpperArm Arm → RL_UpperArm_end
lower link RL_LowerArm Arm → RL_LowerArm_end
trailing arm RL_TrailingArm Arm → RL_TrailingArm_end
toe link RL_ToeLink Arm → RL_ToeLink_end
camber link RL_CamberLink Arm → RL_CamberLink_end
halfshaft / axle RL_Halfshaft Arm → RL_Halfshaft_end (pivot at the diff)
coil RL_Spring Shock
top mount RL_Tophat (Shock’s Tophat)
lower shock mount RL_Shock_low (Shock’s Lower Mount)
damper body (if any) RL_ShockBody (Shock’s Body Bone)

In one line:

RL_<Part> carries the KSuspBone; RL_<Part>_end (under RL_Hub) is the point it reaches; set Corner = RL on every component.

The _end markers and all meshes get no component. The _end target sits under the hub so it rides with the wheel; the Arm bone sits at its chassis bushing (Inner Pivot = self). Whatever you name them, the Corner dropdown is what actually maps a marker to its wheel.

Where each marker goes (front-left corner):

Where the markers go on a MacPherson corner

Step 3 — Label each marker (add KSuspBone, pick a Role)

There’s just one component. Click a marker → Add ComponentKSusp Bone, then set the Role and Corner dropdowns. The Inspector shows only the fields that role needs and explains each one — no looking anything up.

⚠️ Two components — don’t mix them up:

Names are free, but use the convention above (RL_<Part> / RL_<Part>_end). The SDK reads the Role + Corner you pick, not the name — names just need to be unique. Sticking to the scheme keeps a big multilink readable and avoids duplicate-name warnings.

The marker is… Role Then set
the hub / upright Hub Corner; Wheel Rotation = SteerCamber (steer + camber, no spin — the default)
an arm / link / tie rod / pushrod / rocker Arm Corner; Inner Pivot (chassis end — leave empty to use this marker’s spot) + Outer Target (the hub point it follows)
a shock / MacPherson strut Shock Corner; Tophat, Lower Mount (a hub point), Body (strut tube) / Spring bones, Axis
a brake / rotor bolted to the hub RidesWithHub Corner only

MacPherson note: use ONE Shock for the whole strut — assign the coil to Spring Bone and the strut tube to Body Bone (both get anchored at the Tophat and aim down at the Lower Mount). Do NOT set the strut tube to RidesWithHub — that rigidly rotates it with the hub and its top detaches from the fixed Tophat. Keep the Tophat on the body, not under the hub.

You don’t arrange anything into folders — each KSusp Bone already knows its corner.

What to set on each marker (mock Inspector):

Inspector cheat-sheet

Step 4 — Let the SDK organize it (one click)

  1. Top menu: Tools ▸ KSL ▸ Build Rig Hierarchy.
  2. Drag your rig root (the top object holding all the bones) into Rig root.
  3. Click Build Hierarchy.

It creates a neat tree (Root → Front/Rear → FL/FR/RL/RR), tucks every bone into its corner, and parents the RidesWithHub markers under the hub. You’ll see it reshuffle in the Hierarchy. (This is optional tidy-up — Attach Parts and Bake work either way.)

What the Hierarchy should look like afterwards:

Bone hierarchy tree

Step 5 — Attach the parts to the bones (one click)

A suspension is rigid metal, so there’s no skinning — each part just rides with its bone.

  1. Tools ▸ KSL ▸ Attach Parts to Bones.
  2. Parts root = the group with your mesh pieces (e.g. SUSP_LF). Bone root = the rig root.
  3. Click Attach Parts. Each part is parented under its nearest bone. Check the printed list and drag any part that landed on the wrong bone.

Either way: now moving a bone in the Scene should move the suspension. Try the rotate tool on a bone, then Ctrl+Z to undo.

Step 6 — Make the descriptor file (one click)

First click your rig root, and on the KSuspensionRoot component set two things:

Then:

  1. Tools ▸ KSL ▸ Bake Suspension Descriptor.
  2. Drag the rig root in → Bake → save it. It makes a .ksusp file (e.g. drift.ksusp).

This little file says which car it’s for and how your suspension moves — both baked inside.

Step 7 — Put it in your chassis and build the part

You’re importing this as part of your CustomChassis in the SDK:

  1. Make your suspension a child of your chassis prefab (so it ships with the chassis).
  2. Build the chassis the normal SDK way (the CarParts tool → it makes a .knpp).
  3. Install that .knpp like any custom chassis.

Step 8 — Put the descriptor in the game folder (the easy way)

Just copy your .ksusp file (e.g. drift.ksusp) into: …\CarX Drift Racing Online\kino\suspensions\

That’s it — no renaming, no config file. The car ID is baked inside the file, so the mod knows which car it’s for.

Several setups for the same car? Drop them all in (e.g. drift.ksusp, grip.ksusp, v2.ksusp). They won’t clash — the mod automatically picks the one whose bones match the chassis you actually loaded.

Don’t know the car ID? Load the car in-game and look at the KSL log — the mod prints (carId 42) for whichever car you’re in. Put that number in the rig root’s Car Id field (Step 6) and re-bake.

Want explicit control with a config file? (optional) Make `kino\suspensions\config.json`: ```json { "suspensions": [ { "carId": 42, "descriptor": "kino/suspensions/drift.ksusp" } ] } ``` Config entries win over the auto-scan. Use `"carId"` (precise) or `"car"` (name match).

Step 9 — Play and check

  1. Launch the game, load that car.
  2. Open the KSL menu, find AdvancedSusp, make sure Enable swap is on. (If you edited config.json while the game is running, click Reload config.)
  3. Drive over bumps / steer — the arms and spring should move.

If it’s not working

Open the KSL log (the dev console) and look for lines starting with [ASM.Dumper]. They tell you exactly what happened:

You see / it does Likely fix
“Could not locate the player’s car” Be loaded into a car (not in a menu).
“applied custom suspension to…” but nothing moves A bone name in the descriptor doesn’t match the bone in the model — re-bake (Step 6) after any rename.
An arm spins like a wheel On its hub’s KSusp Bone (Role Hub), set Wheel Rotation = SteerCamber (or SteerOnly), re-bake.
Hub has no camber Hub is on SteerOnly (flat yaw) — switch it to SteerCamber, re-bake.
Spring doesn’t squash On the Shock KSusp Bone, the Axis is wrong, or Tophat/Lower Mount are swapped.
Strut top detaches from the tophat Put the strut tube on the Shock’s Body Bone, not RidesWithHub; re-bake.
An arm pivots from the wrong spot Set its Inner Pivot to the chassis-end marker (Step 3).
Suspension is too wide/narrow The hub bones aren’t following — check the Hub KSusp Bone is on the hub and the Corner is right.

When in doubt: re-run Build Hierarchy → Attach Parts → Bake, then Reload config in-game.


The whole thing in 9 clicks

  1. Drop model in scene → 2. Place empty markers on the parts → 3. Add KSusp Bone + pick Role + Corner on each → 4. Build Rig Hierarchy → 5. Attach Parts → 6. set Car Id + Bake the .ksusp → 7. Put it in your chassis & build the .knpp → 8. Drop the .ksusp in kino\suspensions\ → 9. Play.