HT Games

Creating a Boss in GameMaker Studio 2: Step-by-Step GML Guide

A practical, minimal boss implementation in GML (GameMaker Language).

1. Create Boss Object (obj_Boss)

  • Assign Sprite (spr_Boss), set collision mask.
  • Add Create Event — initialize variables:
// obj_Boss Create Event
health = 500;
max_health = 500;
attack_timer = 0;
attack_cooldown = 120; // 2 seconds at 60 FPS
move_speed = 2;
attack_range = 200;
phase = 1; // for multi-phase bosses

2. Movement (Step Event)

// Simple patrol + chase
var target = obj_Player;
if (instance_exists(target)) {
    var dist = point_distance(x, y, target.x, target.y);
    if (dist > attack_range) {
        // Chase
        var dir = point_direction(x, y, target.x, target.y);
        x += lengthdir_x(move_speed, dir);
        y += lengthdir_y(move_speed, dir);
    } else {
        // In range → attack logic handled by alarm
    }
}
// Patrol fallback (if no player)
else {
    if (x < room_width/2) x += move_speed;
    else x -= move_speed;
}

3. Attack Pattern (Alarm 0)


// obj_Boss Alarm 0 Event
if (instance_exists(obj_Player)) {
    var dist = point_distance(x, y, obj_Player.x, obj_Player.y);
    if (dist < attack_range) {
        // Example: Shoot 3 projectiles in spread
        for (var i = -1; i <= 1; i++) {
            var p = instance_create_layer(x, y, "Instances", obj_BossProjectile);
            p.direction = point_direction(x, y, obj_Player.x, obj_Player.y) + (i * 15);
            p.speed = 8;
        }
        // Screen shake, sound
        camera_shake = 5;
        audio_play_sound(snd_BossShoot, 1, false);
    }
}
// Reset timer (adjust per phase)
alarm[0] = attack_cooldown;

4. Take Damage (Collision with Player Projectile)


// obj_Boss Collision with obj_PlayerProjectile Event
health -= other.damage; // projectile has .damage variable
if (health <= 0) {
    event_user(0); // Death event
    instance_destroy();
} else {
    // Hit feedback
    image_blend = c_red;
    alarm[1] = 5; // Reset blend
    // Phase transition?
    if (health <= max_health/2 && phase == 1) {
        phase = 2;
        attack_cooldown = 60; // Faster attacks
        move_speed = 3;
        // Visual change
        sprite_index = spr_Boss_Phase2;
    }
}

5. Death Logic (User Event 0)


// obj_Boss User Event 0 (Death)
instance_create_layer(x, y, "Instances", obj_Explosion);
instance_create_layer(x, y, "Instances", obj_BossLoot); // Drop
global.boss_defeated = true; // Trigger room transition, cutscene, etc.

6. Polish Essentials

  • Telegraphs: Flash sprite, play "charge" sound, show warning indicator before attack.
  • Invincibility frames: After hit, set invincible = true; alarm[2] = 30; — ignore damage while true.
  • Phases: Change behavior at HP thresholds (new attacks, movement, arena hazards).
  • Audio: Distinct sounds for spawn, attack, hit, death.
  • Debug: Draw health bar: draw_healthbar(x-50, y-60, x+50, y-50, health, max_health, c_black, c_red, c_green, 0, true, true);

Start simple. Add one pattern, test, iterate. Study Hollow Knight, Celeste, Katana ZERO boss design for inspiration.


https://www.htfbw.com © HT Games