8.4 — Boss Attacks: Patterns & Phases
The boss can be hurt (8.3) and does not care. Today it answers back: two attacks, each with a telegraph a player can read, and every timing number in one phase table.
The boss can be hurt and it does not answer back. Give it two attacks — one that travels across the arena and one that is its own body — and hold every timing number in a phase table, so Phase 3 is a change of values rather than a rewrite. As one problem it is not startable: an attack is three timed beats, and neither attack exists in this project yet.
First, before any code: cut that into parts small enough that you could look each one up on its own.
- Name the three beats, and give each one a numberwhat does this part do?Read: the three-beat table in this lesson's first activity, and the fight arithmetic you wrote in 8.1
- Build the travelling attack as a prefab of its ownwhat does this part do?Read: 3.2 — Projectiles: Instantiate, Fire, Destroy: the four things its Build Lab checks — the muzzle offset, the heading, the speed knob and the lifetime
- Re-point the damage at the playerwhat does this part do?Read: the damage knob you declared on the projectile in 3.4, and the refactor that moved the signed-amount method onto
StatManager.Instancein 5.3 - Build the body attack out of the chase comparison you already ownwhat does this part do?Read: 4.3 — Chase: The Aggro Radius (the comparison that names a direction), and 4.4 for the contact damage the charge deals
- Decide what schedules the attack — and what stops itwhat does this part do?Read: the scheduling table in this lesson, and the state machine you built in 4.5
- Hold the numbers in a phase table, and read the row on phase entrywhat does this part do?Read: the phase-value table in this lesson, and the guarded phase entry you wrote in 8.2
Every part above is a problem you have already solved once, pointed at a new target: part two is your own bullet, part four is your own chase, part five is your own state machine, and part six is 8.2's guard with a table behind it. The genuinely new part is the first one — deciding the numbers before writing them — because the player experiences an attack as a length of time, not as a line of code. Get the split right and the code is transcription.
The test for a finished split: does the part name something you could point at — a prefab, a field, a method, a row of a table? "Make the boss attack" points at nothing. "Where the travelling attack is spawned" points at one line in one method, and that is a part.
Your turn
Pick two of the parts above and say in one line what each one actually does.
Both attacks need a telegraph and a recovery, and only one of them needs a heading. Which part above carries the difference between them — and what does that tell you about how much of the second attack is genuinely new?
Pick one number from your table that must never change between phases, and say what the fight stops being if it does.
A boss that damages you is trivial to build: a number on a timer, subtracted from your health. It is also unplayable, because the player's only response is to take the hit and hope. Every attack a player can answer has three parts, and all three are timing rather than geometry:
| Beat | What the boss is doing | What the player is doing | What the designer fixes |
|---|---|---|---|
| Telegraph | Announcing the attack — a wind-up pose, a colour flash, a sound. | Reading it, and starting the correct response. | How long the tell lasts: too short is unfair, too long is boring. |
| Strike | Committing — the wave travels, the body charges. | Executing the answer: jumping, sidestepping, or already being elsewhere. | What the answer is, and whether it is physically possible. Your spec's counterplay sentence lives or dies here. |
| Recovery | Unable to act — the boss is committed and vulnerable. | Closing in, if the window is long enough to reach it. | How long the boss is helpless. More than any other number, this sets the pace. |
Socratic: Why Timing Is the Whole Design
- Write your spec's first attack as three numbers: telegraph seconds, strike seconds, recovery seconds. What is the player's damage window, expressed as one of those three?
- If the telegraph is shorter than a human's reaction time, what is the attack actually testing — skill, or luck? Look up a typical human reaction time and compare it to your number.
- If the recovery is longer than the telegraph, what does the fight become? Name a game you have played that does this deliberately.
A telegraph is a promise made in advance. These three come from worlds where being early is the difference between a warning and an incident.
Example 1 — A level crossing (the barrier drops long before the train arrives):
// The barrier comes down eight seconds before the train. The eight
// seconds is not slack - it is the whole safety system.
Example 2 — A press interlock (the cycle cannot be interrupted, only entered):
// Once the press cycle starts it completes. The operator's only
// decision was made before the cycle began.
Example 3 — A two-minute warning (the same event, announced earlier each time):
// Same warning, same meaning, but the window to react is smaller.
// That is how a sport escalates without changing its rules.
Predict Before Building
- The two-minute warning escalates by shrinking the window without changing the rules. Which of your three beats will Phase 3 shorten, and what is the floor below which it must not go?
- The press interlock says the decision is made before the cycle begins. In your boss's charge, at what exact moment is the player's decision made — and can they change their mind after it?
- The level crossing's eight seconds is a fixed, knowable number. Does the player need to know the number, or only to see the barrier move? What does that tell you about whether your telegraph should be a timer or a visual?
-
Project window →
Assets/Prefabs. There is no attack to drag in — no shockwave, nothing named after a boss anywhere in this project. Right-click → Create → Prefab, name it something you will recognize, then Inspector → Sprite Renderer → Sprite →Assets/Artwork/Character/Enemy/Turret_Bullet.png. - Inspector → Add Component → Rigidbody 2D with Body Type = Kinematic and Gravity Scale = 0 — this world has no "down" — then Add Component → Circle Collider 2D, tick Is Trigger, and size the circle in the Scene view until the green outline covers the art. A collider sized from the import bounds will not match a scaled sprite.
- Hierarchy → the boss in your arena, right-click → Create Empty, and name it for its job (the muzzle). Scene view → drag it to the boss's front edge, clear of the boss's own collider, then Inspector → drag it into the spawn-point slot on your attack script.
-
Inspector → Tag on the attack prefab. Read your own 3.4 callback in
Projectile.csbefore you set anything: theTurret_Projectileprefab ships taggedEnemy, and assuming beats reading here. - Scene view → drag a spare copy of the attack to the height it will travel at, and compare that height with the player's jump apex from 6.1. If the arc cannot clear the collider, one of those two numbers is wrong — and an attack nobody can jump is one nobody can answer.
- Once the code half is done — Inspector → Game view: press Play and watch one attack from the player's seat. Can you see the telegraph coming, and is the recovery long enough for one swing from 8.3? Then change a number while the game is running and watch the fight's pace change with it.
| API | What it is | What you get | What it costs |
|---|---|---|---|
Instantiate(Object original, Vector3 position, Quaternion rotation) |
The spawn, from 3.2. | A clone at the muzzle, handed a heading the moment it exists. | The clone cannot know where the player is, so a projectile that guesses its own direction flies into a wall. |
OnTriggerEnter2D(Collider2D other) and other.CompareTag("Player") |
The hit report and the identity check, from 2.1 and 3.4. | A hit on the player, and silence on walls, the floor, and the boss that fired it. | Exact tag spelling, and a callback name that must agree with the collider's trigger setting — get either wrong and you get silence, not an error. |
The signed-amount method on StatManager.Instance |
The one method that changes the player's health: 2.2's, moved onto the singleton in 5.3. | Damage through the same door healing uses, with a positive number. | The manager is not in this scene — it is a scene away and still alive — so this reaches across a scene load to hurt the player. |
Destroy(Object obj) |
Cleanup, from 3.2. | One shot, one hit: the attack goes on contact, or on its lifetime timer if it hits nothing. | Both are needed: contact alone leaves strays drifting forever, and a lifetime alone lets one wave hit twice. |
Two decisions are left: what fires the attack, and where the numbers live. Each has a cost that shows up later:
| What fires the attack | What it looks like | What it costs, and what it buys |
|---|---|---|
(a) A clock in Update() |
A float holding the last attack time, compared against Time.time — exactly the shape from 3.3. |
Every attack's state lives in one method, so it fires mid-charge or after the boss is gone unless each case is guarded. The quickest to have working. |
| (b) A coroutine | A method that waits, telegraphs, strikes, recovers and loops — reading top to bottom like the attack itself. | You must keep the handle to stop it: an interrupted coroutine leaves the boss in its last pose, and an unstopped one spawns a wave a second after the boss dies. |
| (c) A state machine | The pattern from 4.5: an enum, one state per frame, transitions on conditions — telegraph, strike and recover become three states. | The most structure up front and the most places to get a transition wrong. In exchange, "vulnerable during recovery" becomes a property of the machine rather than a flag you must set. |
| Where the phase numbers live | What it looks like | What it costs, and what it buys |
|---|---|---|
| (a) Fields, reassigned on phase entry | The phase entry method assigns new values to the attack interval, the movement speed and the rest, depending on which phase it is. | The numbers are buried in code, so tuning Phase 3 means editing a script, and two phases sharing a value must both be written out. The fastest of the three to write. |
| (b) One table, indexed by phase | An array or list of small records — a row per phase, a column per number — and one reader that looks up the current phase's row. | You must design the row's shape before you know every column you need, and changing that shape later touches every row. In exchange the whole difficulty curve sits in one place to tune. |
| (c) One asset per phase | A ScriptableObject asset per phase, holding that phase's numbers and referenced by the boss. |
A whole new kind of Unity asset to learn, and three files to keep straight on disk. In exchange the fight is tunable in the Inspector without opening the code. |
- What does the player see during the telegraph — a thing on screen, not a variable — and how long does it last? Is that longer than a human reaction time, and must the player start moving in it, or already be moving?
- Write the counterplay sentence with numbers in it: "the player ___s; it works because the attack is ___ and their ___ is ___." Which of those numbers comes from an earlier lesson, and which did you invent today?
- What does a mistake cost in the player's health, and what fraction of their maximum is that? If a hit takes most of it, the fight allows almost no mistakes and your spec's fight length is a fantasy.
- How long is the recovery window, and how many swings does 8.3's cooldown fit inside it? Less than one, and the fight cannot be won.
- List every number that changes per phase: attack interval, travel speed, telegraph length, recovery length, movement speed. Which must not change, whatever happens — and what breaks if it does?
- Where is the table stored, and how does the boss read its phase's row? Which numbers change at Phase 2, and which at Phase 3 — and why does one that changes at both need two steps?
- Phase 3 adds a new attack as well as faster numbers. What in your table says "this attack is available from Phase 3", and what happens if you forget that guard?
- The phase entry from 8.2 is guarded so it fires once per crossing. Does your table read happen there, or every frame, and what is the cost of each?
Choose, Then Justify
- Which scheduling approach did you choose, and which of the three costs did you accept?
- If you chose a coroutine, what stops it when the boss dies? What is the visible symptom in the scene if you forget?
- If you chose a state machine, name the three or four states and write the transition condition on each arrow. Which arrow is the one the player is watching for?
Checkpoint — before moving on, you must be able to:
- Name the three beats of an attack and say which one is the player's damage window
- Defend your choice of scheduling approach, and say what one of the other two would have cost you
- Say the counterplay sentence for each attack with real numbers in it, including your own jump height and walk speed
- Explain what the phase table changes and what it must never change
- Beat your own boss, and quote the fight time
- Commit and push
Reference Docs
Need a deeper explanation? These pages cover the same concepts:
- Unit 8: Boss Fight — attack patterns and telegraphs
- Enemy State Machines — the machine your boss extends
- Unity + C# Quick Reference — coroutines,
Timeand instantiation
Next: 8.5 — Win, Lose & the Death Loop, where the fight has to end.
Saved on this device only — the Dashboard tracks your progress.