A practical, minimal boss implementation in GML (GameMaker Language).
obj_Boss)spr_Boss), set collision mask.// 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
// 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;
}
// 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;
// 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;
}
}
// 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.
invincible = true; alarm[2] = 30; — ignore damage while true.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.