Valve Developer Union

Understanding Source's Physics Constraints

(January 22, 2018)


One of the major selling points of the Source engine are its physics. Source makes prime use of the Havok physics engine in realistically simulating props and objects, most notably in Half-Life 2's Ravenholm chapter, where physics traps are common, and the player's newly-acquired Gravity Gun becomes a vital part of their arsenal.

A Ravenholm blade trap slicing a zombie in half
A Ravenholm blade trap slicing a zombie in half

In particular, those physics traps are built using a class of entities known as physics constraints. Physics constraints allow props and other entities to be attached to one another and simulate each other in a variety of interesting and realistic ways. Some of them (such as the pulley constraint) are analogous to the classical simple machines, while others (like the "keep upright" constraint) modify physical properties of the entity in question.

A bit of background is required to understand the mechanics behind Source's physics engine.

VPhysics and QPhysics

Source actually has two different physics systems at play: the familiar VPhysics system, which is added by the Havok engine, and QPhysics, which is what players and ground NPCs use. QPhysics are a much simpler, legacy system originally implemented in Quake, because real-time physics calculations involving players and NPCs would be too costly at runtime. (This is why moving NPCs with the Physgun in Garry's Mod is so wonky and limited.) You don't need to worry about QPhysics much; just know that QPhysics objects can't be constrained with the entities discussed in this guide.

Props, ragdolls, vehicles, and flying NPCs such as helicopters use VPhysics instead. VPhysics objects can be rotated any which way and shoved around realistically by way of forces. The two major forces that Source's Havok simulates are linear force (where objects are pushed, pulled, and shoved against one another) and rotational force (also called torque). The simulation is mostly concerned with the defined weight of objects, the rate at which they move, and the resulting calculations of forces when those objects collide with others.

Understanding physics constraints

A few things are true about nearly all of the physics constraints listed below:

  1. The objects don't need to touch or be anywhere near one another when defined as attached.
  2. If only one object is specified, the constraint entity itself becomes the second entity.
  3. All constraints are breakable through player-created forces. Setting the force and torque limits to 0 will make the constraint unbreakable, however. The I/O system can still be used to detach the two objects from one another.
  4. Any constraint can be assigned to a phys_constraintsystem, which accounts for all constraints assigned to it in physics calculations, rather than solving for each separately. If you encounter any jiggling between entities in a large system of constraints, place a phys_constraintsystem in the world and assign each constraint to it using the constraintsystem or "Constraint System Manager" keyvalue.

Summarizing the physics constraints

Listed below are all of the physics constraints available in Source, in increasing order of complexity.

Tip

I mean, it's a physics sandbox, right?

There's a good chance you've already played with physics constraints, if you've built anything in Garry's Mod before. The Toolgun's constraints work identically to the equivalent placeable entities in Hammer. You can use them to test and debug any physics contraptions you'd like to add to your own maps, before you actually create them. (The screenshots in this section were taken in Garry's Mod using the Toolgun's constraints.)

phys_constraint

The most basic physics constraint, phys_constraint attaches two entities to each other rigidly. The entities will move with one another, but the distance between them cannot change. (This is equivalent to the Weld tool in Garry's Mod.)

phys_constraint holding two boxes together
phys_constraint holding two boxes together

phys_ragdollconstraint

The ragdoll constraint will act as a "pin" and keep a ragdoll attached to another object, much like the normal phys_constraint. Restrictions on how far the ragdoll can rotate along each axis can also be set.

phys_ragdollconstraint keeping a Combine soldier suspended in midair
phys_ragdollconstraint keeping a Combine soldier suspended in midair

phys_lengthconstraint

The length constraint is like phys_constraint, but with a specifiable amount of give between the entities. If the "Keep Rigid" spawnflag is set, the entities will be stuck the same distance apart, though they'll be able to rotate around their origins, unlike phys_constraint. (This is equivalent to the Rope tool in Garry's Mod.)

phys_ballsocket

The ball socket constraint creates an elbow joint for the two specified entities to swivel around. This joint allows for a full 360° range of movement, as it has no physical presence. There's no way to restrict the range of movement around this entity.

phys_ballsocket constraining two boxes to itself
phys_ballsocket constraining two boxes to itself

phys_ballsocket is different than most other physics constraints in that the entities are attached to it, rather than attached to each other. (This is equivalent to the Ball Socket tool in Garry's Mod.)

phys_slideconstraint

The slide constraint restricts entities to move along a single axis. Friction can be set so the object resists movement on that axis slightly. (This is equivalent to the Slider tool in Garry's Mod.)

phys_slideconstraint with a force being applied phys_slideconstraint reacting to the force
Left: phys_slideconstraint with a force being applied
Right: phys_slideconstraint reacting to the force

phys_hinge

The hinge constraint restricts entities to rotate along a single axis. The entities constrained won't be able to move around unless the constraint is broken. Friction can be set so that the constraint resists movement slightly, in the same way that a rusty door hinge might have more resistance than a new one. (This is equivalent to the Axis tool in Garry's Mod.)

A phys_hinge object A phys_hinge object being rotated
Left: A phys_hinge object
Right: A phys_hinge object being rotated

A great example of phys_hinge in action is with Ravenholm's spinning blade traps. A phys_motor was used to apply torque to the blade traps, which spin on one single axis with enough force to chop oncoming zombies in half.

phys_hinge being used in d1_town_01
phys_hinge being used in d1_town_01

phys_spring

The spring constraint will stretch and deform with the forces placed upon it. This constraint has many options, though the big three are the Spring Axis keyvalue, which determines where the other end of the spring is, the Spring Length keyvalue, which determines the normal (at rest) length of the spring, and the Spring Constant keyvalue, which determines its stiffness.

A box connected to a phys_spring being dragged The phys_spring reacting to the force and bringing the box with it
Left: A box connected to a phys_spring being dragged
Right: The phys_spring reacting to the force and bringing the box with it

In this sample map, yanking down on the box and letting go will cause it to shoot back up, as if it's attached to a spring being stretched before recoiling. (This is equivalent to the Garry's Mod Elastic tool with the "Stretch Only" setting disabled.)

phys_pulleyconstraint

It's best to imagine the pulley constraint as a rope through two points. The first point is the origin of the phys_pulleyconstraint entity itself, and the second point is defined in Hammer as a blue helper ball. The rope is constrained through these two points, and the objects attached will pull one another, much like two ends of a pulley.

One box connected to the pulley being dragged The other box comes along for the ride
Left: One box connected to the pulley being dragged
Right: The other box comes along for the ride

In these pictures, you can see the two points on the ground, where the rope takes a sharp bend. When one func_physbox is pulled, the other one is pulled with it, and the rope is fed through the two points. (This rope is visualized using the Pulley tool in Garry's Mod for your convenience. The phys_pulleyconstraint has no visual presence, like the other physics constraints.)

phys_keepupright

A special constraint, phys_keepupright tries to keep the specified entity facing a particular direction. This constraint can't break, but it can be turned on and off with the I/O system. (This is equivalent to the "Keep Upright" option in the context menu for any props you might happen to spawn.)

The former Source SDK featured a demonstration map for each physics constraint; for convenience, these maps are supplied below in a separate download. They're worth a look if you're curious as to how to set one up, or would like to see them in action for yourself.

↓ Download Physics Constraint Demonstration Maps ↓