Quick answer: Don’t mix camera_set_view_* helpers with a hand-built view matrix. Pick one: either use the helpers (pos, size, angle) or set the matrix yourself — not both.

A camera should rotate with the player. camera_set_view_angle is being called every step, but the view never rotates — a manual camera_set_view_mat elsewhere is overwriting it.

Two Mutually Exclusive APIs

Calling both means whichever runs last wins. Usually the matrix overwrites the angle helper, so rotation “does nothing”.

Pick the Helper Approach

// Step event — helpers only
camera_set_view_pos(cam, x - vw/2, y - vh/2);
camera_set_view_size(cam, vw, vh);
camera_set_view_angle(cam, player_angle);

Or Build the Matrix Yourself

var mat = matrix_build_lookat(x, y, -10,  x, y, 0,
    dsin(player_angle), dcos(player_angle), 0);
camera_set_view_mat(cam, mat);

The up-vector encodes rotation. Use this if you need full control — but then drop the helper calls entirely.

Verifying

Rotate the player. The view rotates with them. Switching to the other API approach also works — as long as you only use one.

“Helpers or matrix — never both. Mixing them means one silently overwrites the other every frame.”

For simple 2D rotation, the helper API is plenty. Reach for the matrix API only when you need shear, custom projection, or precise control.