09-17-2025, 10:35 AM
Here's some code I wrote for the framework of an ULTRAKILL-type boss
Code:
-- Boss AI Framework (Advanced)
local Boss = {}
Boss.__index = Boss
-- A Boss requires an initial state, a health pool, and a set of attack patterns.
function Boss.new(options)
local boss = {
name = options.name or "Cyber-Fiend",
current_health = options.max_health or 1000,
max_health = options.max_health or 1000,
state = "Idle",
attack_cooldown_timer = 0,
current_phase = 1,
active_target = options.player, -- The player instance.
position = options.position,
attack_patterns = {
-- Phase 1 (100% - 51% health)
{
{name = "bullet_hell", cooldown = 5, duration = 3},
{name = "laser_beam", cooldown = 10, duration = 2},
},
-- Phase 2 (50% - 1% health)
{
{name = "bullet_hell", cooldown = 4, duration = 2},
{name = "laser_beam", cooldown = 8, duration = 2.5},
{name = "charge_attack", cooldown = 6, duration = 1.5},
},
-- Death animation, or other final action
{
{name = "self_destruct", cooldown = 0, duration = 5},
}
}
}
setmetatable(boss, Boss)
return boss
end
-- Main update loop. This should be called every frame by your game engine.
function Boss:update(dt)
-- Check if the boss is dead
if self.current_health <= 0 then
self:die()
return
end
-- Update boss phase based on health
self:update_phase()
-- State machine logic
if self.state == "Idle" then
self:idle_state(dt)
elseif self.state == "Attacking" then
self:attacking_state(dt)
elseif self.state == "TakingDamage" then
self:taking_damage_state(dt)
end
end
-- A simple function to simulate taking damage.
function Boss:take_damage(amount)
if self.state ~= "Dying" then
self.current_health = self.current_health - amount
print(self.name .. " took " .. amount .. " damage. Health: " .. self.current_health)
-- Trigger a visual or audio effect for taking damage
self.state = "TakingDamage"
-- Add screen shake or hit-stop effects here
end
end
-- Handle the boss's death.
function Boss:die()
self.state = "Dying"
-- Trigger explosion, fall animation, loot drop, etc.
print(self.name .. " has been defeated!")
-- Clean up enemy from the game world
end
-- Internal function to check and update the boss's current phase.
function Boss:update_phase()
local health_percentage = self.current_health / self.max_health
if health_percentage <= 0.5 and self.current_phase == 1 then
self.current_phase = 2
print("Boss enters Phase 2! Prepare for new attacks.")
-- Trigger special phase change animations or effects.
elseif health_percentage <= 0 and self.current_phase < 3 then
self.current_phase = 3
end
end
-- Defines the Idle state behavior.
function Boss:idle_state(dt)
-- Wait for player to be in range
local distance_to_player = self:distance_to(self.active_target.position)
if distance_to_player < 500 then -- Chase range
self.state = "Attacking"
self.attack_cooldown_timer = 0
end
end
-- Defines the Attacking state behavior.
function Boss:attacking_state(dt)
self.attack_cooldown_timer = self.attack_cooldown_timer + dt
local current_patterns = self.attack_patterns[self.current_phase]
local attack_chosen = false
-- Iterate through available attacks and trigger if cooldown is ready
for _, attack in ipairs(current_patterns) do
if self.attack_cooldown_timer >= attack.cooldown then
self:execute_attack(attack)
self.attack_cooldown_timer = 0 -- Reset cooldown for next attack
attack_chosen = true
break -- Only do one attack at a time
end
end
-- If no attack was chosen, continue to move or wait
if not attack_chosen then
self:chase_player()
end
end
-- Defines the TakingDamage state behavior.
function Boss:taking_damage_state(dt)
-- Can add hit stun logic here
self.state = "Attacking" -- Resume attacking after being hit
end
-- Placeholder for specific attack logic.
function Boss:execute_attack(attack)
if attack.name == "bullet_hell" then
print(self.name .. " initiates a bullet hell attack!")
-- Call a function in your game engine to spawn many projectiles
elseif attack.name == "laser_beam" then
print(self.name .. " fires a devastating laser beam!")
-- Call a function in your game engine for a large, single-line attack
elseif attack.name == "charge_attack" then
print(self.name .. " charges the player!")
-- Move the boss rapidly toward the player's last known position
elseif attack.name == "self_destruct" then
print(self.name .. " self-destructs in a massive explosion!")
-- Trigger a large explosion effect and kill the player if they are nearby
end
end
-- Movement logic to chase the player.
function Boss:chase_player()
local dir_x = self.active_target.position.x - self.position.x
local dir_y = self.active_target.position.y - self.position.y
-- Normalize direction vector and move the boss
local distance = math.sqrt(dir_x*dir_x + dir_y*dir_y)
if distance > 1 then
self.position.x = self.position.x + dir_x / distance
self.position.y = self.position.y + dir_y / distance
end
end
-- Simple distance calculation.
function Boss:distance_to(target_pos)
return math.sqrt( (self.position.x - target_pos.x)^2 + (self.position.y - target_pos.y)^2 )
end
return BossO
y g g
d
r
a
s
i
l
What miracle is this? This giant tree.
It stands ten thousand feet high
But doesn't touch the ground. Yet it stands.
Its roots must hold the sky.
0
y g g
d
r
a
s
i
l
What miracle is this? This giant tree.
It stands ten thousand feet high
But doesn't touch the ground. Yet it stands.
Its roots must hold the sky.
0