Defold includes a modified version of the Box2D physics engine (version 2.1) for 2D physics simulations and the Bullet physics engine (version 2.77) for 3D physics. It allows you to simulate Newtonian physics interactions between different types of collision objects. This manual explains how this works.

Collision objects

A collision object is a component you use to give a game object physical behaviour. A collision object has physical properties like weight, restitution and friction and its spatial extension is defined by one or more shapes that you attach to the component. Defold supports the following types of collision objects:

Static objects
Static objects never move but a dynamic object that collides with a static object will react by bouncing and/or sliding. Static objects are very useful for building level geometry (i.e. ground and walls) that does not move. They are also cheaper performance-wise than dynamic objects. You cannot move or otherwise change static objects.
Dynamic objects
Dynamic objects are simulated by the physics engine. The engine solves all collisions and applies resulting forces. Dynamic objects are good for objects that should behave realistically but you cannot directly manipulate the position and orientation of a dynamic object. The only way to affect them is indirectly, by applying forces.
Kinematic objects
Kinematic objects register collisions with other physics objects, but the physics engine do not perform any automatic simulation. The job of resolving collisions, or ignoring them, is left to you. Kinematic objects are very good for player or script controlled objects that require fine grained control of the physical reactions, like a player character.
Triggers are objects that register simple collisions. They are good for objects that just need to register a hit (like a bullet) or as part of game logic where you want to trigger certain actions when an object reaches a specific point. Trigger are computationally cheaper than kinematic objects and should be used in favor of those if possible.

Adding a collision object component

A collision object component has a set of Properties that sets its type and physics properties. It also contains one or more Shapes that define the whole shape of the physics object.

To add a collision object component to a game object:

  1. In the Outline view, right click the game object and select Add Component ▸ Collision Object from the context menu. This creates a new component with no shapes.
  2. Right click the new component and select Add Shape ▸ Box / Capsule / Sphere. This adds a new shape to the collision object component. You can add any number of shapes to the component. You can also use a tilemap or a convex hull to define the shape of the physics object.
  3. Use the move, rotate and scale tools to edit the shapes.
  4. Select the component in the Outline and edit the collision object’s Properties.

Physics collision object

Collision object properties

The identity of the component.
Collision Shape
This property is used for tile map geometry that does not use ordinary primitive shapes. See below for more information.
The type of collision object: Dynamic, Kinematic, Static or Trigger. If you set the object to dynamic you must set the Mass property to a non zero value. For dynamic or static objects you should also check that the Friction and Restitution values are good for your use-case.
Friction makes it possible for objects to slide realistically against each other. The friction value is usually set between 0 (no friction at all—a very slippery object) and 1 (strong friction—an abrasive object). However, any positive value is valid.

The friction strength is proportional to the normal force (this is called Coulomb friction). When the friction force is computed between two shapes (A and B), the friction values of both objects are combined by the geometric mean:

\[F_{combined} = \sqrt{ F_A \times F_B }\]

This means that if one of the objects has zero friction then the contact between them will have zero friction.

The restitution value sets the “bounciness” of the object. The value is usually between 0 (inelastic collision—the object does not bounce at all) and 1 (perfectly elastic collision—the object’s velocity will be exactly reflected in the bounce)

Restitution values between two shapes (A and B) are combined using the following formula:

\[R = \max{ \left( R_A, R_B \right) }\]

When a shape develops multiple contacts, restitution is simulated approximately because Box2D uses an iterative solver. Box2D also uses inelastic collisions when the collision velocity is small to prevent bounce-jitter

Linear damping
Linear damping reduces the linear velocity of the body. It is different from friction, which only occurs during contact, and can be used to give objects a floaty appearance, like they are moving through something thicker than air. Valid values are between 0 and 1.

Box2D approximates damping for stability and performance. At small values, the damping effect is independent of the time step while at larger damping values, the damping effect varies with the time step. If you run your game with a fixed time step, this never becomes an issue.

Angular damping
Angular damping works like linear damping but reduces the angular velocity of the body. Valid values are between 0 and 1.
Locked rotation
Setting this property totally disables rotation on the collision object, no matter what forces are brought to it.
The name of the collison group the object should belong to. You can have 16 different groups and you name them as you see fit for your game. For example “players”, “bullets”, “enemies” and “world”. If the Collision Shape is set to a tile map, this field is not used but the groups names are taken from the tile source.
The other groups this object should collide with. You can name one group or specify multiple groups in a comma separated list. If you leave the Mask field empty, the object will not collide with anything.

Collision shapes

A collision component can either use several primitive shapes or a single complex shape. The primitive shapes are box, sphere and capsule. A complex shape can either be created from a tilemap component or from a convex hull shape.

Box shape

A box has a position, rotation and dimensions (width, height and depth):

Box shape

Sphere shape

A sphere has a position, rotation and diameter:

Sphere shape

Capsule shape

A capsule has a position, rotation, diameter and height:

Sphere shape

Tilemap collision shape

Defold includes a feature allowing you to easily generate physics shapes for a tile map. The Tilemap manual explains how to add collision groups to a tile source and assign tiles to collision groups (example).

To add collision to a tile map:

  1. Add the tilemap to a game object by right-clicking the game object and selecting Add Component File. Select the tile map file.
  2. Add a collision object component to the game object by right-clicking the game object and selecting Add Component ▸ Collision Object.
  3. Instead of adding shapes to the component, set the Collision Shape property to the tilemap file.
  4. Set up the collision object component Properties as usual.

Tilesource collision

Note that the Group property is not used here since the collision groups are defined in the tile map’s tile source.

Convex hull shape

Defold includes a feature allowing you to create a convex hull shape from three or more points. You can use an external tool such as the Defold Polygon Editor or the Physics Body Editor to create a convex hull shape.

  1. Create convex hull shape file (file extension .convexshape) using an external editor.
  2. Instead of adding shapes to the collision object component, set the Collision Shape property to the convex shape file.

The shape will not be drawn in the editor. You can enable Physics debugging at runtime to see the shape.

Scaling collision shapes

It is possible to let the collision object and its shapes inherit the scale of the game object. Check the Allow Dynamic Transforms checkbox in the Physics section of game.project to enable this. Note that only uniform scaling is supported and that the smallest scale value will be used if the scale isn’t uniform.

Rotating collision shapes in 3D physics

Collision shapes in 3D physics can be rotated around all axis.

Rotating collision shapes in 2D physics

Collision shapes in 2D physics can only be rotated around the z-axis. Rotation around the x or y axis will yield incorrect results and should be avoided, even when rotating 180 degrees to essentially flip the shape along the x or y axis. To flip a physics shape it is recommended to use physics.set_hlip(url, flip) and physics.set_vlip(url, flip).

Units used by the physics engine simulation

The physics engine simulates Newtonian physics and it is designed to work well with meters, kilograms and seconds (MKS) units. Furthermore, the physics engine is tuned to work well with moving objects of a size in the 0.1 to 10 meters range (static objects can be larger) and by default the engine treats 1 unit (pixel) as 1 meter. This conversion between pixels and meters is convenient on a simulation level, but from a game creation perspective it isn’t very useful. With default settings a collision shape with a size of 200 pixels would be treated as having a size of 200 meters which is well outside of the recommended range, at least for a moving object. In general it is required that the physics simulation is scaled for it to work well with the typical size of objects in a game. The scale of the physics simulation can be changed in game.project via the physics scale setting. Setting this value to for instance 0.02 would mean that 200 pixels would be treated as a 4 meters. Do note that the gravity (also changed in game.project) has to be increased to accommodate for the change in scale.

Group and mask

The physics engine allows you to group your physics objects and filter how they should collide. This is handled by named collision groups. For each collision object you create two properties control how the object collides with other objects, Group and Mask.

For a collision between two objects to register both objects must mutually specify each other’s groups in their Mask field.

Physics collision group

The Mask field can contain multiple group names, allowing for complex interaction scenarios.

Runtime properties

A physics object has a number of different properties that can be read and changed using go.get() and go.set():

The angular damping value for the collision object component (number). API reference.
The current angular velocity of the collision object component (vector3). API reference.
The linear damping value for the collision object (number). API reference.
The current linear velocity of the collision object component (vector3). API reference.
The defined physical mass of the collision object component (number). API reference.

Collision messages

When two objects collide, the engine will broadcast messages to all components in both objects:


This message is sent for all collision objects. It has the following fields set:

the id of the instance the collision object collided with (hash)
the world position of the instance the collision object collided with (vector3)
the collision group of the other collision object (hash)

The collision_response message is only adequate to resolve collisions where you don’t need any details on the actual intersection of the objects, for example if you want to detect if a bullet hits an enemy. There is only one of these messages sent for any colliding pair of objects each frame.


This message is sent when one of the colliding objects is dynamic or kinematic. It has the following fields set:

world position of the contact point (vector3).
normal in world space of the contact point, which points from the other object towards the current object (vector3).
the relative velocity of the collision object as observed from the other object (vector3).
the penetration distance between the objects – non negative (number).
the impulse the contact resulted in (number).
(not currently used!) life time of the contact (number).
the mass of the current collision object in kg (number).
the mass of the other collision object in kg (number).
the id of the instance the collision object is in contact with (hash).
the world position of the other collision object (vector3).
the collision group of the other collision object (hash).

For a game or application where you need to separate objects perfectly, the "contact_point_response" message gives you all information you need. However, note that for any given collision pair, several "contact_point_response" messages can be received each frame, depending on the nature of the collision. See below for more information.

Trigger messages

Triggers are light weight collision objects. Thay are similar to ray casts in that they read the physics world as opposed to interacting with it.

In a trigger collision "collision_response" messages are sent. In addition, triggers also send a special "trigger_response" message when the collision begins and ends. The message has the following fields:

the id of the instance the collision object collided with (hash).
true if the interaction was an entry into the trigger, false if it was an exit. (boolean).

Resolving kinematic collisions

Using kinematic collision objects require you to resolve collisions yourself and move the objects as a reaction. A naive implementation of separating two colliding objects looks like this:

function on_message(self, message_id, message, sender)
  -- Handle collision
  if message_id == hash("contact_point_response") then
    local newpos = go.get_position() + message.normal * message.distance

This code will separate your kinematic object from other physics object it penetrates, but the separation often overshoots and you will see jitter in many cases. To understand the problem better, consider the following case where a player character has collided with two objects, A and B:

Physics collision

The physics engine will send multiple "contact_point_response" message, one for object A and one for object B the frame the collision occurs. If you move the character in response to each penetration, as in the naive code above, the resulting separation would be:

  • Move the character out of object A according to its penetration distance (the black arrow)
  • Move the character out of object B according to its penetration distance (the black arrow)

The order of these is arbitrary but the result is the same either way: a total separation that is the sum of the individual penetration vectors:

Physics separation naive

To properly separate the character from objects A and B, you need to handle each contact point’s penetration distance and check if any previous separations have already, wholly or partially, solved the separation.

Suppose that the first contact point message comes from object A and that you move the character out by A’s penetration vector:

Physics separation step 1

Then the character has already been partially separated from B. The final compensation necessary to perform full separation from object B is indicated by the black arrow above. The length of the compensation vector can be calculated by projecting the penetration vector of A onto the penetration vector of B:


\[l = vmath.project(A, B) \times vmath.length(B)\]

The compensation vector can be found by reducing the length of B by l. To calculate this for an arbitrary number of penetrations, you can accumulate the necessary correction in a vector by, for each contact point, and starting with a zero length correction vector:

  1. Project the current correction against the contact’s penetration vector.
  2. Calculate what compensation is left from the penetration vector (as per the formula above).
  3. Move the object by the compensation vector.
  4. Add the compensation to the accumulated correction.

A complete implementation looks like this:

function init(self)
  -- correction vector
  self.correction = vmath.vector3()

function update(self, dt)
  -- reset correction
  self.correction = vmath.vector3()

function on_message(self, message_id, message, sender)
  -- Handle collision
  if message_id == hash("contact_point_response") then
    -- Get the info needed to move out of collision. We might
    -- get several contact points back and have to calculate
    -- how to move out of all of them by accumulating a
    -- correction vector for this frame:
    if message.distance > 0 then
      -- First, project the accumulated correction onto
      -- the penetration vector
      local proj = vmath.project(self.correction, message.normal * message.distance)
      if proj < 1 then
        -- Only care for projections that does not overshoot.
        local comp = (message.distance - message.distance * proj) * message.normal
        -- Apply compensation
        go.set_position(go.get_position() + comp)
        -- Accumulate correction done
        self.correction = self.correction + comp

Ray casts

Ray casts are used to read the physics world along a linear ray. To cast a ray into the physics world, you provide a start and end position as well as a set of collision groups to test against.

If the ray hits a physics object you will get information about the object it hit. Rays intersect with dynamic, kinematic and static objects. They do not interact with triggers.

function update(self, dt)
  -- request ray cast
  local my_start = vmath.vector3(0, 0, 0)
  local my_end = vmath.vector3(100, 1000, 1000)
  local my_groups = { hash("my_group1"), hash("my_group2") }

  local result = physics.raycast(my_start, my_end, my_groups)
  if result then
      -- act on the hit (see 'ray_cast_response' message for all values)

Ray casts will ignore collision objects that contain the starting point of the ray. This is a limitation in Box2D.


Defold supports joints for 2D physics. A joint connects two collision objects using some kind of constraint. The supported joint types are:

  • Fixed (physics.JOINT_TYPE_FIXED) - A rope joint that restricts the maximum distance between two points. In Box2D referred to as a Rope joint.
  • Hinge (physics.JOINT_TYPE_HINGE) - A hinge joint specifies an anchor point on two collision objects and moves them so that the two collision objects are always in the same place, and the relative rotation of the collision objects is not restricted. The hinge joint can enable a motor with a defined maximum engine torque and speed. In Box2D referred to as a Revolute joint.
  • Spring (physics.JOINT_TYPE_SPRING) - A spring joint keeps two collision objects at a constant distance from each other. The spring joint can be made soft like a spring with a frequency and damping ratio. In Box2D referred to as a Distance joint.
  • Slider (physics.JOINT_TYPE_SLIDER) - A slider joint allows for relative translation of two collision objects along a specified axis and prevents relative rotation. In Box2D referred to as a Prismatic joint.

Creating joints

Joints can currently only be created programmatically using physics.create_joint():

Editor support for creating joints is planned but no release date has been decided.

-- connect two collision objects with a fixed joint constraint (rope)
physics.create_joint(physics.JOINT_TYPE_FIXED, "obj_a#collisionobject", "my_test_joint", vmath.vector3(10, 0, 0), "obj_b#collisionobject", vmath.vector3(0, 20, 0), { max_length = 20 })

The above will create a fixed joint with id my_test_joint connected between the two collision object obj_a#collisionobject and obj_b#collisionobject. The joint is connected 10 pixels to the left of the center of collision object obj_a#collisionobject and 20 pixels above the center of collision object obj_b#collisionobject. The maximum length of the joint is 20 pixels.

Destroying joints

A joint can be destroyed using physics.destroy_joint():

-- destroy a joint previously connected to the first collision object
physics.destroy_joint("obj_a#collisionobject", "my_test_joint")

Reading from and Updating joints

The properties of a joint can be read using physics.get_joint_properties() and set using physics.set_joint_properties():

function update(self, dt)
    if self.accelerating then
        local hinge_props = physics.get_joint_properties("obj_a#collisionobject", "my_hinge")
        -- increase motor speed by 100 revolutions per second
        hinge_props.motor_speed = hinge_props.motor_speed + 100 * 2 * math.pi * dt
        physics.set_joint_properties("obj_a#collisionobject", "my_hinge", hinge_props)

Get joint reaction force and torque

The reaction force and torque applied to a joint can be read using physics.get_joint_reaction_force() and physics.get_joint_reaction_torque().

Caveats and common issues

Collection proxies
Through collection proxies it is possible to load more than one top level collection, or game world into the engine. When doing so it is important to know that each top level collection is a separate physical world. Physics interactions (collisions, triggers, ray-casts) only happen between objects belonging to the same world. So even if the collision objects from two worlds visually sits right on top of each other, there cannot be any physics interaction between them.
Collisions not detected
If you have problems with collisions not being handled or detected properly then make sure to read up on physics debugging in the Debugging manual.

Did you spot an error or do you have a suggestion? Please let us know on GitHub!