Project Car Crash: real-time permanent deformation
A chassis that keeps its dents. The body deforms, holds the new shape, and does not spring back.
Most driving games treat a car as a rigid shell. It bounces off a wall, maybe swaps in a pre-baked damaged mesh, and drives on. Real cars do something very different: they crumple, absorb the energy, and keep the new shape. This project is about doing that second thing in real time, with a car body that deforms plastically under impact and carries the damage for the rest of its life.Why a crash is hard in real time
A convincing crash sits between two extremes. A rigidbody keeps the distance between every pair of points fixed, so it can never dent. A fluid has no shape memory at all. A car chassis lives in the middle: thin sheet metal folds, buckles, and then stays folded. Reproducing that at sixty simulation steps per second, while the same body is also resolving collisions with the world and with other cars, is the core challenge. The budget is a few milliseconds per frame, and the result has to stay stable no matter how hard the player hits something.The chassis as a softbody
The body is modelled as a network of mass points connected by springs, a softbody. Each point carries a share of the car's mass, and each connection resists being stretched or compressed away from its rest length. Solve that network every frame and you get something that flexes and pushes back like a physical object rather than a rigid block. The visible mesh is skinned to this network, so the panels follow the simulation the way skin follows bone.Making damage permanent
An ordinary spring is elastic: stretch it and it pulls straight back to where it started. That is the opposite of what a crashed car does. The insight is that permanence is not a property of the force, it is a property of the rest state. When a connection is strained past a yield point during a hard enough impact, its rest length is rebaked to the deformed length. The dent becomes the new neutral shape, and from then on the spring is perfectly content in its crushed position with no memory of the original. The rest length is only ever allowed to move in the crushing direction, never back out, which is exactly how folded metal behaves and also stops the body from slowly healing itself over time.Dynamic stiffness
A car is not uniformly soft, and it should not deform the same way for a gentle nudge as for a full speed impact into a wall. Both of those facts come down to stiffness that changes with the situation. So stiffness and damping are not constants: they respond to the energy of the impact. When a hit lands, the affected region softens, and that softening spreads outward from the contact point with a smooth falloff, so the deformation blends into the surrounding metal instead of leaving a sharp crater. The spread is also biased slightly along the direction of the impact, so a hit pushes the surface inward the way a real dent forms rather than expanding as a neat sphere. This dynamic stiffness is the heart of the system, and it is where most of the tuning effort goes.Real physics, plus a little pragmatism
It is tempting to reach for a proper continuum model, the kind of finite element plasticity you would run offline in an engineering tool. In practice that is both too expensive for a real-time frame budget and too numerically twitchy once you add fast collisions and stacking. So the model is an honest hybrid. The backbone is physically motivated: masses, springs, dampers, energy. On top of that sits a layer of engineered behaviour, the yield thresholds, how far a hit propagates, how quickly a region gives way, and that layer exists to make the result stable, controllable, and good looking. It is a game-grade approximation, not a certification-grade simulation, and being honest about that distinction is what keeps the scope sane.A native layer on top of Jolt
Collision detection and the rigidbody solve are handled by the Jolt physics engine, which is fast and robust and something I did not want to reinvent. Everything specific to the deformable car, the softbody network, the impact bookkeeping, and the per-connection stiffness control, runs in a custom layer written in native C++ that sits on top of Jolt. There are two reasons it has to be native. The first is throughput: one car is hundreds of mass points and close to a thousand connections, all updated every physics step, and that work does not belong in a scripting language. The second is control. Reading impact energy back out of the solver and pushing fresh stiffness and damping into individual constraints every frame is not something a stock engine exposes cheaply, and doing it well is most of the engineering. The key optimisation turns out to be restraint: only the constraints near an active impact are touched each frame, and an update short-circuits the moment nothing has actually changed, because the real cost is not the arithmetic, it is talking to the solver.Cars as data, not code
None of the numbers above live in code. Each vehicle is described by a data file: how the mass is distributed, how stiff and how damped each region of the body is, how the parts connect, and how readily each region yields. That separation matters more than it sounds. A new car, or a retune of an existing one, becomes an authoring task rather than a programming task, and the same engine drives a flimsy hatchback and a heavy sedan purely by swapping data. It also turns the least glamorous part of physics work, the endless tuning, into something you can iterate on in seconds without a rebuild.The result is a body that takes a hit, folds, and keeps the scar. The next piece of the puzzle is what happens when the damage is severe enough that the car stops being a single object, when doors, bonnets, and bumpers tear away and go their own way. That is the subject of the next article.