Quick answer: Enable Viewports in Room Properties, make Viewport 0 visible, and either set the Object Following property to your player object or use camera_set_view_target(view_camera[0], obj_player) in code. The camera defaults to position (0, 0) with no target assigned.
Here is how to fix GameMaker camera not following the player. You create a room bigger than the viewport. You place your player object. You run the game and the view is stuck at the top-left corner. The player walks off-screen and the camera never moves. GameMaker’s camera system requires explicit setup — viewports must be enabled, a camera must be assigned, and a follow target must be configured. None of this happens automatically.
The Symptom
The game window shows the top-left corner of the room and never moves. The player walks off the visible area and disappears. The room is larger than the window but the view does not scroll.
Variant: the camera follows but jerks or lags. Or the camera follows horizontally but not vertically. Or the camera works in one room but not another. Or the view size does not match the window size, causing stretched or letterboxed graphics.
What Causes This
Viewports not enabled. GameMaker rooms have a “Enable Viewports” checkbox that is off by default. Without it, the entire room is drawn at once (or clipped to the window) with no camera system active.
Viewport 0 not visible. Even with viewports enabled, each individual viewport (0–7) has its own Visible checkbox. Viewport 0 must be checked for the primary camera to function.
No follow target assigned. The camera associated with a viewport needs a target object to follow. Without one, it stays at its initial position (0, 0). This can be set in Room Properties or via camera_set_view_target().
Camera view size is wrong. If the camera view width/height matches the room size, the camera has nowhere to scroll. The view must be smaller than the room for scrolling to occur.
Code overriding room settings. If you create a new camera in code with camera_create() and assign it to view_camera[0], it replaces the room’s camera settings. The new camera starts at (0, 0) with no target unless you configure it.
The Fix
Method 1: Room Properties (no code). Open the room in the Room Editor. In the left panel:
- Click Viewports and Cameras
- Check Enable Viewports
- Select Viewport 0
- Check Visible
- Set Camera Properties > Camera Width/Height (e.g. 640x360 for a 16:9 view)
- Set Viewport Properties > Viewport Width/Height to match the window size (e.g. 1280x720)
- Under Object Following, set Object to your player object
- Set Horizontal Border and Vertical Border to half the camera size for centered following
The horizontal and vertical border values control how close to the edge the player can get before the camera starts scrolling. Set to half the camera width/height for centered following, or smaller for a dead zone.
Method 2: Code-based setup. In a controller object’s Create event:
/// obj_camera Create event
// Get the default camera for viewport 0
var cam = view_camera[0];
// Set the camera size (game resolution)
camera_set_view_size(cam, 640, 360);
// Set the follow target
camera_set_view_target(cam, obj_player);
// Ensure viewport is enabled
view_enabled = true;
view_visible[0] = true;
This uses the room’s existing camera (view_camera[0]) rather than creating a new one. Setting view_enabled and view_visible[0] in code overrides the room settings, so it works even if you forgot to check the boxes in the editor.
Method 3: Smooth camera with lerp. The built-in Object Following snaps the camera rigidly. For smooth, cinematic following:
/// obj_camera Step event
var cam = view_camera[0];
var cam_w = camera_get_view_width(cam);
var cam_h = camera_get_view_height(cam);
// Target: center camera on player
var target_x = obj_player.x - cam_w / 2;
var target_y = obj_player.y - cam_h / 2;
// Smooth follow with lerp (0.1 = smooth, 0.3 = snappy)
var curr_x = camera_get_view_x(cam);
var curr_y = camera_get_view_y(cam);
var new_x = lerp(curr_x, target_x, 0.1);
var new_y = lerp(curr_y, target_y, 0.1);
// Clamp to room bounds
new_x = clamp(new_x, 0, room_width - cam_w);
new_y = clamp(new_y, 0, room_height - cam_h);
camera_set_view_pos(cam, new_x, new_y);
The lerp factor controls how fast the camera catches up. Lower values (0.05) create a floaty, cinematic feel. Higher values (0.2–0.3) feel responsive. A value of 1.0 is instant (same as rigid following).
Clamping to Room Bounds
Without clamping, the camera can scroll past the room edges, showing empty space. The clamp in the example above prevents this. For rooms with non-zero origins or rooms that should allow some overshoot (for screen shake), adjust the bounds:
// Allow 16px overshoot for screen shake
new_x = clamp(new_x, -16, room_width - cam_w + 16);
new_y = clamp(new_y, -16, room_height - cam_h + 16);
Common Pitfall: Camera in Wrong Room
Room-level viewport settings are per-room. If you set up viewports in room_level1 and then go to room_level2 via room_goto(), the second room has its own viewport settings. Either configure every room’s viewports individually, or use a persistent controller object that sets up the camera in its Create event (checking that it runs in every room).
/// obj_camera Create event (persistent object)
if (!instance_exists(obj_player)) {
// No player in this room — don't set up camera
exit;
}
view_enabled = true;
view_visible[0] = true;
camera_set_view_target(view_camera[0], obj_player);
“Enable viewports. Make viewport 0 visible. Assign a follow target. Three settings and the camera scrolls.”
Related Issues
For general GameMaker rendering issues, see Best Bug Tracking for Solo Developers. For view scaling and resolution management, check the GameMaker documentation on display and surface functions.
Enable viewports, viewport 0 visible, set follow target. Use lerp in the Step event for smooth follow. Clamp to room bounds.