Quick answer: Collision detection in Construct 3 depends on collision polygons, not the visible sprite image. The most common cause of missed collisions is a collision polygon that does not cover the expected area, followed by objects on different layers with different parallax rates, wrong use of Solid behavior, and high-speed objects tunneling through each other between frames.
Your player sprite walks straight through an enemy. A bullet passes through a wall. A collectible coin sits right on top of the player but the "On collision" event never fires. Collision detection failures are among the most frustrating bugs in Construct 3 because the visual overlap is obvious, yet the engine insists no collision has occurred. The root cause is almost always a mismatch between what you see on screen and what the collision system is actually testing.
The Symptom
You have two objects on the layout. Visually, they clearly overlap at runtime. But your collision event — whether "On collision with another object", "Is overlapping another object", or "Is overlapping at offset" — never triggers. The event's actions never run.
Alternatively, the collision triggers inconsistently: sometimes it works, sometimes the objects pass right through each other. This intermittent version is especially common with fast-moving objects like bullets or falling objects.
In some cases, the collision works in one direction but not the other. The player can collide with an enemy from the left but not from the right, or from above but not below. This typically points to an asymmetric collision polygon.
What Causes This
There are six common causes, and you may be dealing with more than one simultaneously:
1. Collision polygon does not match the sprite. Every sprite in Construct 3 has a collision polygon that defines its collidable area. By default, the engine generates a bounding box or a convex hull around the opaque pixels, but this automatic polygon often does not match what you expect. If your sprite has large transparent regions, the collision polygon might be much smaller than the visible image. If you edited the animation frames but did not update the collision polygon, the polygon might correspond to an older version of the sprite.
2. Confusing Solid behavior with collision detection. Many developers assume that the Solid behavior is required for collision detection. It is not. The Solid behavior only affects movement behaviors (Platform, 8-Direction, Bullet, Car) by telling them to treat the object as impassable. The "On collision" and "Is overlapping" conditions work between any two objects with collision polygons, regardless of whether either has the Solid behavior. Conversely, if you add Solid to an object expecting it to enable collision detection, it does nothing for event-based collision checks.
3. Objects on different layers with different parallax. If Object A is on a layer with parallax (scroll rate) 100,100 and Object B is on a layer with parallax 50,50, their screen positions may appear to overlap but their world positions do not. Collision detection operates on world coordinates, not screen coordinates. Two objects that look like they are touching on screen can be hundreds of pixels apart in world space if their layers have different scroll rates.
4. Object on a layer with collisions disabled. Each layer in Construct 3 has a "Initially visible" property but also behaviors tied to the layout. If you use effects or special setups that disable a layer's participation in the collision system, objects on that layer will not collide. Additionally, invisible objects (opacity 0 or visible set to false) can still collide unless you explicitly filter them out — so the inverse assumption is also wrong.
5. High-speed tunneling. When an object moves faster than its own width per frame, it can "teleport" past another object between collision checks. At 60 FPS, if a bullet moves 800 pixels per tick and a wall is 32 pixels wide, the bullet can be on one side of the wall in one frame and on the other side in the next frame. The collision check at each frame finds no overlap because the objects were never overlapping at the exact moment of the check.
6. Collision cells and large objects. Construct 3 uses a spatial partitioning grid (collision cells) to optimize collision detection. If an object is extremely large — bigger than the collision cell size — it might not be tested against nearby objects correctly. This is rare with default settings but can occur with very large sprites or custom cell sizes.
The Fix
Step 1: Inspect and fix the collision polygon. Open the sprite in the Animations editor. Select the collision polygon tool (the blue outline icon). Verify the polygon covers the area you expect. Use "Set to bounding box" for a quick rectangular collision area, or manually edit the polygon points.
// To verify collision polygons at runtime, you can use
// the debug overlay. In Preview, press F6 (or the
// debugger shortcut) and check "Show collision polygons"
// under the Layout section.
// Alternatively, add a debug event:
+ System: Every tick
-> Text: Set text to
"Player bbox: " & Player.BBoxLeft & ","
& Player.BBoxTop & " to "
& Player.BBoxRight & "," & Player.BBoxBottom
Important: if your sprite has multiple animation frames, each frame can have a different collision polygon. Either set the same polygon for all frames (right-click the polygon and select "Apply to all animations" or "Apply to whole animation"), or ensure each frame's polygon is correct.
Step 2: Use the correct collision condition for your use case. Understand the difference between the collision conditions:
// "On collision" - TRIGGER, fires once when overlap starts
+ Player: On collision with Coin
-> Coin: Destroy
-> System: Add 1 to score
// "Is overlapping" - CONDITION, true every tick while overlapping
+ Player: Is overlapping DamageZone
-> Player: Subtract 1 from health
// "Is overlapping at offset" - checks at a different position
+ Player: Is overlapping SolidWall at offset (1, 0)
-> Player: Set animation to "push"
"On collision" only fires once per overlap. If two objects start overlapping and stay overlapping, the trigger fires once and does not repeat until they separate and overlap again. If you need continuous detection, use "Is overlapping" instead.
Step 3: Verify both objects are on the same layer or compatible layers. Check the layer properties for both objects and confirm their parallax (scroll rate) values match.
// Debug layer positions:
+ System: Every tick
-> DebugText: Set text to
"Player world pos: " & Player.X & "," & Player.Y
& newline &
"Enemy world pos: " & Enemy.X & "," & Enemy.Y
& newline &
"Distance: " & distance(Player.X, Player.Y,
Enemy.X, Enemy.Y)
// If the distance is large but objects look close on
// screen, you have a parallax mismatch.
// Fix: set both layers to the same scroll rate,
// or move objects to the same layer.
Step 4: Fix high-speed tunneling. For fast-moving objects like bullets, you have several options:
// Option A: Use the Bullet behavior's built-in
// "Step" property. Set the step size smaller than
// the target object's width. The Bullet behavior
// will move in smaller increments and check for
// collisions at each step.
// In the Bullet behavior properties:
// Speed: 1200
// Set "Stepping mode" to "Enabled (max 5 steps)"
// Option B: Manual sweep using Is Overlapping At Offset
+ System: Every tick
+ Bullet: Is overlapping Wall at offset
(Bullet.Bullet.dx * dt, Bullet.Bullet.dy * dt)
-> Bullet: Destroy
-> System: Create object Explosion
at (Bullet.X, Bullet.Y)
// Option C: Increase the collision polygon size
// of the target object. A wider wall is harder to
// tunnel through.
Step 5: Handle the Solid behavior correctly. If you want Platform or 8-Direction movement to stop at walls, add the Solid behavior to the walls, not to the player. Do not confuse this with event-based collision detection.
// For platformer collision with walls:
// Wall object -> Add behavior -> Solid
// Player object -> Add behavior -> Platform
// The Platform behavior automatically stops at Solid objects.
// For event-based collision (damage, pickups, triggers):
// No Solid behavior needed on either object.
+ Player: On collision with Spike
-> Player: Subtract 1 from health
-> Player: Set position to (SpawnX, SpawnY)
Why This Works
Construct 3's collision system operates on collision polygons, not on visual pixels. The polygon is the mathematical shape the engine tests for overlap. If the polygon is wrong, the engine is testing the wrong shape — it does not matter what the sprite looks like on screen.
Layer parallax creates a gap between visual position (where you see the object) and world position (where the engine knows the object is). Collision tests use world position. When layers scroll at different rates, two objects can appear to be at the same spot while their world coordinates are far apart.
Tunneling is a fundamental limitation of discrete collision detection. The engine checks positions at fixed intervals (once per tick). If an object moves far enough between checks, it can skip past another object entirely. The Bullet behavior's stepping mode addresses this by subdividing movement into smaller increments, each checked for collisions.
The Solid behavior is a modifier for movement behaviors, not a collision enabler. It tells movement behaviors "this object is a wall, stop here." Event-based collision conditions ("On collision", "Is overlapping") are independent of Solid and test any pair of objects with collision polygons.
"When collisions fail, the first thing I check is the collision polygon. Open the animation editor, click the polygon tool, and see where the engine thinks the object's boundary is. Nine times out of ten, the polygon is wrong."
Related Issues
If your objects are disappearing after layout transitions rather than failing to collide, see object not found after layout change for persistence fixes. For animation-related issues where an object is supposed to change sprites on collision but does not, check animation not changing on trigger. Audio that should play on collision but remains silent may be hitting the autoplay policy — see audio not playing on first touch. And if collision data you are trying to save for later analysis is not persisting, Local Storage data not persisting covers the async storage pitfalls.
Collision polygon, not the sprite image. Always check the polygon first.