Here's a vehicle sim I wrote mainly to learn the engine and to learn a bit more about vehicle dynamics. I'm not an expert at all so take everything I say with a grain of salt. One thing I tried to focus on is to avoid using 'fake forces'. The quality of handling takes a hit, but I'm confident I can make it all work with some assists sprinkled on top. There won’t be any code in these posts—at least for now. I think it’s more interesting to focus on the actual physics and how everything ties together. I had a hard time finding simple, digestible resources online, so part of this is just me writing it all down to better understand it myself—and maybe help someone else who’s trying to figure this stuff out too.
At the core of the system is the suspension. A lot of implementations out there use a single line trace from the wheel hub downward (relative to the car) to find the contact point. The length of the trace also tells you how much the suspension is compressed, and based on that, you apply a spring force in the opposite direction.
The result of this is a floating car that oscillates up and down forever, so we add a damper to counteract the forces and bring the car to an equilibrium—between gravity pushing down and the suspension spring pushing up.
Another useful bit of information we get from all this is how much load there is on each tire. This load will be used in later calculations to determine how much grip we can produce per tire.
Cylinders
Laylad, one of the Facepunch devs, was nice enough to add an easy way to do cylinder traces—something that, for some reason, isn’t available in most engines. With proper cylinder traces, you can avoid tires clipping into curbs. It’s honestly not super important for handling, but I’m glad we get to have nice little things like this :)
Since we're not using actual physics body representations for the tires, we have to calculate all the friction forces ourselves. Tires are very good at generating forces, but they have a limit—if you exceed that limit, you're sliding or skidding.
Most serious implementations use fancy formulas to calculate these forces based on many inputs. I've simplified mine quite a bit while still trying to stay realistic. The most popular formula is the Pacejka model, but it has too many parameters for my taste.
The goal is to calculate the lateral and longitudinal forces. Lateral force is used for cornering, and longitudinal force is used for accelerating and braking. The relationship between tire load, vehicle direction, and throttle/brake input is a complex one, but I'll give a quick outline of how I handle it below.
Load
Gravity pushes down on your car, and the suspension pushes back. This creates a certain amount of load on each tire. Generally, the higher the load, the more grip the tire can generate—but only up to a point. The relationship isn’t linear; you can’t keep adding weight and expect more grip forever. Eventually, each additional kilogram adds less and less grip, until it barely makes a difference.
Lateral
Lateral forces are sideways forces generated when the car tries to corner. They're based on something called the slip angle—in simple terms, the angle between where the tire is pointing and where the vehicle is actually moving. Technically, it’s the dot product between the tire’s forward direction and the vehicle’s velocity direction.
The higher the slip angle, the more lateral force the tire can generate—again, up to a point. This relationship isn’t linear either. There's a peak slip angle where the force is at its maximum, and beyond that, it drops off sharply.
The fancy Pacejka formula models all of this very accurately, but I chose to base mine on a curve asset instead. It works pretty well—I just wish S&Box let me go beyond 1.0 on the horizontal axis. Right now, I have to map and scale the curve manually, and it’s a little gross.
Longitudinal
I hate typing this word—but it’s similar to the lateral force calculation, except this one is based on the difference between the tire’s angular velocity and what it would be if the tire were just rolling normally. This is called the slip ratio, and it’s around 0.0 when your car is simply rolling without any throttle or brake input.
If you go full throttle or slam the brakes, the slip ratio increases—positive under acceleration, negative under braking. From this ratio, we can calculate a longitudinal force. And just like before, it’s a nuanced, non-linear relationship.
This part is actually a lot of fun to tweak. If done right, you get satisfying burnouts, donuts, and fancy launches.
In a real car, if you apply too much throttle or brake while cornering, you’ll likely spin out. That’s because you’re asking too much of the tire. As I mentioned earlier, we have a grip budget—it’s based on the load on the tire. You can’t generate more force than that budget allows, so we need to find a way to combine the lateral and longitudinal forces without exceeding it.
A common method is to normalize both forces and then add them together. From there, you normalize the result again and scale the original forces. This effectively clips the magnitude of the combined forces.
The result is that you have to balance the demands you’re placing on your tires. If you exceed the grip circle, you’ll start sliding. In the current build, it’s pretty easy to spin out because of this. You can try it: get some speed, enter a corner, and then go full throttle mid-turn. Your tires will already be working hard to generate lateral force, and when you ask them to also generate longitudinal force, you’ll go beyond the limit and start sliding.
In real cars, assists exist to save you from yourself. One of the most common is traction control—it limits how much throttle actually reaches the tires, regardless of how much throttle you think you’re applying.
There’s a bunch of other stuff going on under the hood that I’ll probably cover in future posts. Here’s a quick brain dump of things I haven’t talked about yet:
Input filtering (to smooth out throttle, brake, and steering)
Slopes (and why your car slowly slides down them...)
Steering assist (since most people use a gamepad or keyboard instead of a proper wheel)
Engine simulation (RPM, torque curves, rev limiters, all that good stuff)
Differential (makes donuts and off-roading actually work)
Gearbox (manual, auto, neutral, reverse—it’s all in there)
Drag
DownforceInertia
Sounds! (this one deserves its own post)
…and probably some stuff I’ve already forgotten. If there's anything you're curious about, feel free to ask—I might already have it working and just haven't written it down yet.