Quick answer: Pass prec = true to collision_line for precise checking. Better: give thin walls a collision mask at least a few pixels thick so no query can step over them.
A line-of-sight check with collision_line reports “clear” through a 1-pixel-thick wall. The query sampled past it.
Precise vs Fast
// last-but-one arg: prec (precise) — default false
var hit = collision_line(x1, y1, x2, y2, oWall, true, true);
// ^prec ^notme
With prec=false GameMaker uses bounding-box checks — fast but can miss thin shapes. prec=true does precise per-pixel/precise-mask checking.
Thicken Thin Wall Masks
The robust fix is data, not query flags: give 1-px walls a collision mask that’s at least 4–8 px thick. Then no collision query — line, rectangle, or movement — can slip through, regardless of precision flags.
Step the Line Manually
For very long rays where even precise mode is a concern, step along the line in small increments and position_meeting at each step:
var steps = point_distance(x1, y1, x2, y2);
for (var i = 0; i <= steps; i++) {
var t = i / steps;
if (position_meeting(lerp(x1, x2, t), lerp(y1, y2, t), oWall)) return true;
}
Verifying
LOS checks correctly stop at thin walls. Bullets and rays don’t tunnel. Precise mode (or thickened masks) catches every wall.
“Fast collision_line can step over thin shapes. Use prec=true, and give thin walls a real-thickness mask.”
Decouple visuals from collision — a wall can look 1px but have an 8px collision mask. Players never see the mask.