Building a Mario-like platformer in GameMaker Studio 2 (GMS2.3+/GML Visual or Code) is a classic learning project. Here's a structured roadmap.
obj_player)// Create Event
hsp = 0; vsp = 0; grav = 0.45; jump_force = -9.5; max_speed = 4.5; accel = 0.35; decel = 0.4; coyote_time = 6; jump_buffer = 6; // frames
coyote = 0; jbuf = 0; on_ground = false; state = "idle"; // idle, run, jump, fall, attack
sprite_index = spr_mario_idle; image_speed = 0.15;
// Step Event
// Input
var left = keyboard_check(vk_left) or keyboard_check(ord("A"));
var right = keyboard_check(vk_right) or keyboard_check(ord("D"));
var jump_pressed = keyboard_check_pressed(vk_space) or keyboard_check_pressed(ord("W"));
var jump_held = keyboard_check(vk_space) or keyboard_check(ord("W"));
// Jump Buffer
if (jump_pressed) jbuf = jump_buffer; else if (jbuf > 0) jbuf--;
// Horizontal
if (left) hsp = max(hsp - accel, -max_speed);
else if (right) hsp = min(hsp + accel, max_speed);
else hsp = lerp(hsp, 0, decel);
// Coyote Time
if (on_ground) coyote = coyote_time; else if (coyote > 0) coyote--;
// Jump Logic
if (jbuf > 0 && coyote > 0) {
vsp = jump_force;
on_ground = false;
coyote = 0;
jbuf = 0;
audio_play_sound(snd_jump, 10, false);
}
// Variable Jump Height (cut)
if (!jump_held && vsp < -2) vsp = -2;
// Gravity
vsp = min(vsp + grav, 16); // terminal velocity
// Collision & Move (see Section 4)
// ... collision code sets on_ground, adjusts x/y ...
// Animation State Machine
if (!on_ground) {
if (vsp < 0) state = "jump"; else state = "fall";
} else if (hsp != 0) state = "run";
else state = "idle";
sprite_index = sprite_get("spr_mario_" + state);
// Horizontal
var _x = x + sign(hsp);
repeat(abs(hsp)) {
if (!place_meeting(_x, y, obj_solid)) x = _x;
else { hsp = 0; break; }
_x += sign(hsp);
}
// Vertical
var _y = y + sign(vsp);
repeat(abs(vsp)) {
if (!place_meeting(x, _y, obj_solid)) y = _y;
else {
vsp = 0;
if (vsp > 0) on_ground = true; else on_ground = false; // head bonk
break;
}
_y += sign(vsp);
}
This pixel-perfect loop prevents sticking, allows sub-pixel precision, and feels tight.
obj_shell with high hsp, kills enemies, breaks bricks, hurts player.if (vsp > 0 && place_meeting(x, y+1, obj_enemy)) → bounce (vsp = jump_force * 0.6).vsp < 0 && place_meeting(x, y-1, obj_question)).player.state = "grow" (animation → sprite_index = spr_mario_big, bbox height ×2).obj_fireball: linear, bounces, dies on wall).// obj_camera Step
var target_x = obj_player.x;
var target_y = obj_player.y - 100; // look ahead
camera_set_view_pos(view_camera[0], lerp(camera_get_view_x(view_camera[0]), target_x, 0.1), lerp(camera_get_view_y(view_camera[0]), target_y, 0.1));
// Clamp to room bounds
obj_enemy_parent → obj_goomba, obj_koopa.Collision Functions, Tilemap Functions, State Machines.Start small: One room, Mario moves, jumps, collides, stomps one Goomba. Expand weekly.