Boss AI with a Finite State Machine
Boss behavior should be driven by a finite state machine (FSM) running on the server. Each state represents a distinct behavior: Idle, Chase, MeleeAttack, RangedAttack, SpecialAbility, Staggered, PhaseTransition, and Death. The FSM evaluates transition conditions each frame — if the player is within melee range and the attack cooldown has elapsed, transition from Chase to MeleeAttack. If health drops below a phase threshold, transition to PhaseTransition. Store the current state and expose a method to force transitions. Keep the FSM modular so you can reuse it across multiple bosses with different state configurations. A simple implementation uses a table mapping state names to enter/update/exit functions, with a central update loop that calls the current state's update function each heartbeat.
- Idle — boss waits in arena, plays idle animation, transitions to Chase when player enters aggro range
- Chase — pathfinds toward player, transitions to MeleeAttack when in range or RangedAttack when at distance
- MeleeAttack — plays attack animation, spawns hitbox at HitFrame marker, returns to Chase on animation end
- PhaseTransition — boss is invulnerable, plays cinematic animation, changes moveset, resumes Chase
- Death — plays death animation, drops loot, triggers post-fight events
Phase Systems and Escalation
The best boss fights get harder as they progress. Implement phases by dividing the boss health bar into segments — for example, Phase 1 at 100-60% health, Phase 2 at 60-30%, and Phase 3 at 30-0%. Each phase transition triggers a cinematic moment (the boss roars, the arena changes, new attacks unlock) and modifies the boss's behavior table. In Phase 1, the boss might use only basic melee swings with long cooldowns. Phase 2 adds a ranged projectile and reduces cooldowns by 30%. Phase 3 adds an area-of-effect slam and increases movement speed. Store phase data in a configuration table so designers can tune values without touching the FSM code. The phase transition itself should make the boss temporarily invulnerable and play a dramatic animation, giving the player a brief rest and signaling that the fight is escalating.
Telegraphed Attacks and Fairness
Players must be able to read and react to boss attacks. Every attack needs a telegraph — a visual warning that gives the player time to dodge or block. Telegraphs typically have three components: a wind-up animation (the boss raises its weapon), a visual indicator (a red zone on the floor showing the area of effect), and an audio cue (a charging sound). The telegraph duration should scale inversely with difficulty — 1.5 seconds for Phase 1 attacks, 0.8 seconds for Phase 3. Use beam parts or decal projections for floor indicators. Color-code them: red for damage zones, yellow for knockback zones, blue for safe zones during area attacks. The golden rule is that every player death should feel like the player's fault, not unfair randomness. If players complain an attack is unfair, the telegraph is too short or too subtle.
Boss Health Bars and UI
Boss health bars belong at the top or bottom of the screen as a ScreenGui, not as a BillboardGui above the boss's head (those are for regular enemies). Create a Frame with a nested Frame for the health fill, a TextLabel for the boss name, and optional phase markers. Animate health changes with TweenService — tween the fill bar width over 0.3 seconds for a smooth drain effect. Add a secondary "damage preview" bar in a lighter color that drains slightly behind the main bar, showing the player exactly how much damage they just dealt. Display phase thresholds as subtle notch marks on the health bar so players can anticipate transitions. Hide the health bar during cinematic sequences and phase transitions, then reveal it again when combat resumes.
- Main fill bar — TweenService with EasingOut, 0.3 second duration
- Damage preview bar — trails behind the main bar by 0.5 seconds, drains linearly
- Boss name label — centered above the bar with a shadow outline for readability
- Phase notches — thin white lines at 60% and 30% positions (or wherever your phases trigger)
Arena Design and Music
The arena is part of the boss fight design. Enclose the fight area so the player cannot simply run away. Add environmental hazards that the boss triggers in later phases — falling rocks, fire patches, crumbling floor sections. These create spatial pressure and force the player to move. For music, trigger a dedicated boss track when the fight begins and crossfade from ambient music over 2 seconds. Change the track on phase transitions — many games speed up the tempo or add layers in later phases. Use SoundService:SetDistanceFactor if you want positional audio for boss attacks, or play combat SFX as children of the boss model for automatic spatial falloff. A well-designed arena with matched music elevates the fight from a stat check to a memorable experience.
Persistence: Saving Boss Defeat State
Once a player defeats a boss, you usually want that to persist across sessions. Use a DataStore (or ProfileStore for more robust handling) to save a table of defeated boss IDs keyed to each player. On join, load the player's save data and check each boss spawn against the defeated list — if the boss is marked as defeated, skip spawning it and activate any post-boss content (unlocked doors, bonfires, NPC dialogue). This should be server-authoritative: the client never writes defeat data directly. The server marks the boss as defeated only after confirming health reached zero through the boss FSM's Death state. This prevents exploits where clients fire a fake "boss defeated" event.
