Quick answer: The floor object needs the Physics behavior with Immovable set to Yes. The Solid behavior does not interact with the Physics system. Also check for collision polygon gaps, excessive gravity, and enable framerate-independent stepping to prevent fast objects from tunneling through thin surfaces.

Here is how to fix Construct 3 physics objects falling through the floor. You add the Physics behavior to a sprite, press play, and the object drops right through the floor as if it does not exist. The floor is sitting there, clearly visible, but the physics engine does not seem to care. This is one of the most frequently asked questions in the Construct 3 community, and it almost always comes down to how the Physics behavior interacts — or fails to interact — with other objects.

The Symptom

You have a sprite with the Physics behavior. When the layout starts, the object falls under gravity. You have a floor object positioned below it. The falling object passes straight through the floor and continues falling off the bottom of the layout.

You might have the Solid behavior on the floor, which normally stops Platform or custom movement objects. But the physics object ignores it. Or you have Physics on the floor too, but it gets pushed away instead of staying in place. In some cases the object appears to land on the floor briefly before clipping through, especially at low framerates or when the object is moving fast.

What Causes This

There are five common causes:

1. Floor missing Physics behavior or not set to Immovable. This is the most frequent cause. The Physics behavior operates in its own physics world (Box2D under the hood). It only recognizes collisions with other objects that also have the Physics behavior. If your floor only has the Solid behavior, the physics engine does not know it exists. Even if the floor does have Physics, it needs the Immovable property set to Yes. Otherwise it is a dynamic body that gets knocked around by the falling object.

2. Collision polygon gaps. The collision polygon on the floor or the falling object does not fully cover the visible sprite. If there is a gap between the two collision polygons at the point of contact, the objects will not collide. This is especially common with irregularly shaped sprites where the auto-generated collision polygon is too loose or too tight.

3. World gravity too high. The default physics gravity in Construct 3 is 10 (in physics units). If you increase this significantly, objects accelerate so fast between simulation steps that they can skip past thin floors entirely. This is the tunneling problem.

4. Small or fast objects tunneling. Even at normal gravity, a small object or a fast-moving projectile can travel far enough in a single physics step to pass completely through a thin surface. The physics engine checks positions at discrete intervals, and if the object is on one side in step N and past the other side in step N+1, no collision is detected.

5. Framerate-dependent stepping. By default, Construct 3 physics uses framerate-dependent stepping. On machines with low framerates or during lag spikes, the time between physics steps increases, making tunneling more likely.

The Fix

Step 1: Add Physics behavior to the floor and set Immovable.

// In the Properties panel for your floor object:
Behaviors → Add → Physics
Physics → Immovable: Yes

// Or set it via events at runtime:
Event
  Condition: System → On start of layout
  Action: Floor → Set immovable → Yes

Do NOT use the Solid behavior for physics collision. Solid is for the Platform behavior and custom movement. Physics lives in its own simulation world and only sees other Physics objects.

Step 2: Fix collision polygons.

// Open the image editor for both objects:
1. Double-click the sprite to open the image editor
2. Click the collision polygon tool (the polygon icon)
3. For the floor: use "Set to bounding box" for a simple rectangle
4. For the falling object: ensure the polygon tightly fits the shape
5. Check that no edges have gaps or inverted points

// For simple rectangular floors, you can also use:
Physics → Collision mask: Bounding box

Using "Bounding box" for the collision mask on simple rectangular objects eliminates polygon edge issues entirely.

Step 3: Enable framerate-independent stepping.

// In Project Properties:
Project Properties → Physics → Stepping mode: Framerate independent

// This makes the physics simulation run at a fixed timestep
// regardless of the actual framerate, preventing tunneling
// during lag spikes.

Framerate-independent stepping runs the physics simulation at a consistent rate (typically 60 steps per second) even if the rendering framerate drops. This prevents the "skip past the floor during a lag spike" problem.

Step 4: Reduce gravity and cap velocity for extreme cases.

// Lower world gravity if objects accelerate too fast
Event
  Condition: System → On start of layout
  Action: Set gravity to 5

// Cap maximum falling speed to prevent tunneling
Event
  Condition: System → Every tick
  Condition: FallingObject → Physics velocity Y > 800
  Action: FallingObject → Set velocity → (FallingObject.Physics.VelocityX, 800)

For very fast projectiles like bullets, consider skipping physics collision entirely and using line-of-sight or raycast checks instead, which do not suffer from tunneling.

Step 5: Increase floor thickness.

// If tunneling persists, make the floor thicker.
// A floor that is 4px tall can be tunneled through.
// A floor that is 64px tall almost never will be.

// You can use a tall floor sprite and position it so only
// the top edge is visible in the layout:
Floor sprite: 800 x 64 pixels
Position Y: Layout height - 32

Why This Works

Physics Immovable tells the Box2D engine that this body has infinite mass and should never move in response to forces or collisions. It becomes a static body in physics terms — objects collide with it and bounce off, but it stays fixed in place. Without this, both objects are dynamic bodies with finite mass, and the collision pushes the lighter one aside.

Correct collision polygons ensure that the contact detection has accurate geometry to work with. Box2D resolves collisions based on polygon overlap. If the polygons do not cover the visible area, the physics simulation sees empty space where your eyes see solid floor.

Framerate-independent stepping decouples the physics timestep from the rendering framerate. With framerate-dependent stepping, a frame that takes 100ms means the physics jumps 100ms forward in one step — potentially moving a fast object many pixels past a thin wall. Fixed stepping subdivides that into smaller incremental steps, catching collisions along the way.

Velocity capping is a brute-force safety net. If an object cannot move faster than the thickness of the thinnest wall divided by the physics timestep, tunneling is physically impossible.

"If your floor has Solid but not Physics, the physics engine literally does not know it exists. They are two separate collision worlds that do not talk to each other."

Related Issues

If your events are not triggering correctly when physics objects collide, check our guide on event sheet conditions not working. For tilemap-based levels where the player walks through tiles, see tilemap collision not working — tilemaps use a different collision system from Physics. If you are trying to save and restore physics state, see save/load not working for physics-specific serialization issues.

Physics behavior only collides with Physics behavior. Solid is a different world entirely.