Polygon Collider Optimization: Reduce Vertices Without Losing Hit Detection
Every 2D platformer, top-down RPG, and physics puzzle relies on collision polygons — invisible shapes that tell the engine where a sprite is solid. Trace a sprite's alpha channel and you get pixel-perfect accuracy. The problem is accuracy and performance pull in opposite directions: a traced silhouette from a 128×128 character can produce 400+ vertices, and your physics engine has to evaluate every edge on every frame.
This guide covers why vertex count matters, how polygon simplification algorithms work, practical vertex budgets by platform, and how to export lean colliders into Godot 4 and Unity using the free Polygon Collider Simplifier. If you are starting from raw sprite art, trace first with the Auto Hitbox Generator, then simplify here.
Why Collision Vertex Count Matters
2D physics engines (Box2D in Godot, PhysX in Unity) test polygon-polygon intersection by checking edge pairs and vertex containment. Cost scales with total vertices in active colliders:
- CPU time per frame: More vertices = more edge tests during broad-phase and narrow-phase collision resolution
- Mobile thermal throttling: Complex colliders on dozens of enemies cause frame drops on mid-range phones
- Tunneling risk: Over-simplified colliders with sharp concavities can let fast projectiles slip through gaps
- Editor friction: Godot's CollisionPolygon2D editor becomes unusable past ~80 vertices
The goal is not the fewest vertices possible — it is the fewest vertices that still match gameplay feel. A platformer's feet need accurate ground contact; decorative hair strands do not.
Traced Polygons vs Hand-Drawn Colliders
| Approach | Pros | Cons | | --- | --- | --- | | Alpha trace | Pixel-accurate, fast to generate | Hundreds of vertices by default | | Bounding box | 4 vertices, trivial | Useless for anything non-rectangular | | Capsule / circle composite | Great for characters | Misses irregular terrain silhouettes | | Simplified trace | Accurate where it matters, cheap everywhere else | Requires tuning tolerance |
Most indie 2D games use simplified trace for environment tiles and enemies, hand-tuned boxes for player hurtboxes, and full trace only for static terrain that players stand on for long periods.
How Polygon Simplification Works
The standard algorithm is Ramer–Douglas–Peucker (RDP). Given a tolerance ε (in pixels):
- Draw a line between the first and last point of the polygon
- Find the point farthest from that line
- If the distance exceeds ε, keep that point and recurse on both sub-segments
- If not, discard all intermediate points
Higher ε = fewer vertices = less accurate silhouette. The Polygon Collider Simplifier exposes this as a tolerance slider with live preview so you can see exactly where corners get cut.
Convex vs Concave Colliders
Box2D supports concave polygons only on static bodies. Dynamic bodies (players, enemies, physics objects) must use convex shapes or decompose into multiple convex pieces. If your traced polygon is concave — a C-shaped platform, a character with arms akimbo — the engine either rejects it or splits it automatically.
Workflow tip: simplify first, then check convexity. Simplification sometimes removes concavity by filling small indentations.
Recommended Vertex Budgets
These are practical targets for shipped 2D games:
- Player character: 8–16 vertices (convex hull or capsule + feet box)
- Standard enemy: 6–12 vertices
- Static platform tile: 4–8 vertices per tile (often a trapezoid, not full trace)
- Complex boss silhouette: 20–32 vertices max, split into multiple shapes if needed
- Projectile / pickup: 4 vertices (rectangle or circle)
If your profiler shows physics above 2 ms on mobile, audit colliders first — it is faster than rewriting gameplay code.
Step-by-Step: Optimize a Collider in the Browser
Step 1: Get Your Source Polygon
Upload a PNG with transparency, or paste JSON from the Auto Hitbox Generator. The simplifier accepts traced polygon arrays directly.
Step 2: Set Tolerance
Start at ε = 2 px for 32×32 pixel art, ε = 4 px for 64×64, ε = 8 px for HD art. Watch the overlay:
- Green outline = simplified polygon
- Red dots = removed vertices
- If feet flatten or the head shrinks, lower ε
Step 3: Validate Gameplay Shapes
Toggle collision layers mentally against your game design:
- Can the player still stand on ledges?
- Do projectiles hit the visible sprite, not empty air?
- Does the hurtbox (if separate) still cover the torso?
Step 4: Export
Download Godot CollisionPolygon2D JSON, Unity PolygonCollider2D points, or raw JSON for custom pipelines. All processing runs locally in your browser — sprites never leave your machine.
Godot 4 Integration
# collision_loader.gd — paste exported JSON points
extends StaticBody2D
func _ready() -> void:
var poly := CollisionPolygon2D.new()
poly.polygon = PackedVector2Array([
Vector2(-16, 16), Vector2(16, 16),
Vector2(16, -8), Vector2(-16, -8)
])
add_child(poly)
For animated characters, attach the collider to a CharacterBody2D child node that does not scale with the sprite flip — keeps physics stable when scale.x toggles for direction.
Godot 4 tip: use Physics Layers so simplified environment colliders (layer 1) do not interact with decorative trigger zones (layer 3).
Unity Integration
// Attach to GameObject with PolygonCollider2D
public class ColliderImport : MonoBehaviour {
void Start() {
var col = GetComponent<PolygonCollider2D>();
col.points = new Vector2[] {
new(-0.16f, 0.16f), new(0.16f, 0.16f),
new(0.16f, -0.08f), new(-0.16f, -0.08f)
};
}
}
Unity's PolygonCollider2D auto-triangulates concave shapes on static colliders. For Rigidbody2D objects, enable Composite Collider 2D or manually split into convex child colliders.
Common Mistakes
- Simplifying hurtboxes and physics colliders with the same tolerance: Hurtboxes often need tighter fit (lower ε) than movement colliders
- Ignoring pivot offset: Export points relative to the sprite pivot, not the texture origin — misaligned colliders cause floating characters
- One collider for entire sprite sheet: Each animation frame with a different silhouette needs its own polygon or a conservative shared hull
- Skipping static vs dynamic rules: A 60-vertex concave trace works on a
StaticBody2Dbut breaks on aRigidBody2D
Pipeline: Hitbox → Collider → SFX
The Game Dev Lab pipeline treats collision as a two-step handoff:
- Auto Hitbox Generator — trace alpha to polygon
- Polygon Collider Simplifier — reduce vertices for shipping
- Retro SFX Generator — add impact sounds once collisions feel right
See also: Sprite Sheet Animation Guide for preparing the source art, and The Godot 4 2D Pipeline for the full browser-to-engine workflow.
FAQ
How many vertices is too many?
Above 32 vertices on a single dynamic body is a yellow flag. Above 64 is almost always unnecessary for 2D gameplay. Profile on your slowest target device, not your dev PC.
Does simplification change the collision response?
It can slightly — a simplified floor polygon with flattened corners may let the player clip a pixel into walls. Test with your actual movement speed and physics substeps (Godot default: 8; try 12 for fast platformers).
Can I use circles instead of polygons?
For round enemies and projectiles, yes — CircleShape2D / CircleCollider2D is cheaper than any polygon. Use polygons when the silhouette is irregular.
Should terrain tiles share one collider or per-tile polygons?
Per-tile simplified polygons compose cleanly in tilemaps and allow autotile-driven level generation from the Procedural Level Generator. Merge adjacent static colliders in a post-pass only if profiling demands it.
Conclusion
Polygon collider optimization is the unglamorous work that separates smooth 60 FPS platformers from stuttery prototypes. Trace for accuracy, simplify for shipping, validate with gameplay — not just the overlay. Two minutes in the browser saves hours of in-engine vertex dragging.
Simplify your colliders now: Polygon Collider Simplifier →