Build a GameCreating Pacific Wings

9  Kill Chain

Goal

Shoot enemies down quickly, one after another, and the points multiply. Each quick shoot-down counts for more than the last, up to four times, and the score shows it in color: cream, then yellow, orange and red. Wait too long, and the chain breaks.

The game as it is at the end of this chapter. Click the game, then press Enter to start.

If your game and this chapter part ways, here is the chapter’s finished project. Open it and compare, or start Chapter 10 from it.

Pacific Wings, Chapter 9 finishedMyth project · 1.7 MB

To open it, start Myth Engine, choose File › Open Project... and pick the downloaded file.

9.1 The Idea

Fly into the V of five Enemy Fighters with your guns open. The first one flashes white and breaks up, and SCORE climbs by its points, as it always has.

The second goes before the first one’s explosion has faded. This time the score climbs twice as far, and the word SCORE turns yellow. A third, and it’s orange. A fourth, and the score is red, and every enemy counts four times over. After that, the sky is empty for a moment. The red fades back to cream.

That’s a kill chain: shoot-downs that follow each other quickly. Each one gives the chain a fresh 1.5 seconds. It’s like keeping a balloon up in the air: every tap buys it another moment, and if nobody taps it in time, it drops.

Since Chapter 3, an enemy has been worth the same whenever you shoot it down. Now it matters how fast you are.

The chain’s place lives in one new Global, $chainRow. It points at one row of a small table, the way $weaponLevel did in Chapter 8. Each row holds a multiplier, the number the points are multiplied by, and a color for the score.

9.2 The Plan

Here’s how the pieces work together, one chain to a line.

  • An enemy is shot down -> Score adds its points, times the chain’s multiplier, and sends shotDownScored.
  • The message shotDownScored arrives -> Kill Chain moves $chainRow down one row, up to the last, and starts its killChain timer over.
  • The killChain timer rings, 1.5 seconds after the last shoot-down -> Kill Chain sets the chain back to row 0.
  • The chain’s row changes -> Kill Chain Color paints Score Text in that row’s color.

9.3 Set Up

Nothing new comes from the Starter Kit this time, since the chapter is all Logic and one table.

Set upWhat this chapter adds
GLOBAL VARIABLES
$chainRowNumberstarts at 0

GLOBAL VARIABLES has one new row, $chainRow. It starts at 0, as $weaponLevel does, so make it the same way, from a Globals card, with its own name.

9.4 The Chain

First the table, then the points, then the clock that breaks the chain.

9.4.1 Kill Chain Multipliers

Data StructureKill Chain Multipliers Entry

One row of the "Kill Chain Multipliers" Data Table.

multiplierNumberdefault 1
scoreColorColordefault #fff4cf
Data TableKill Chain MultipliersData Structure: Kill Chain Multipliers Entry
Row 0x1
multiplier1
scoreColor#fff4cf
Row 1x2
multiplier2
scoreColor#ffe066
Row 2x3
multiplier3
scoreColor#ffab40
Row 3x4
multiplier4
scoreColor#ff6a3d

This is the chain, written down. Four rows, one for each step. Row 0 is no chain at all, a multiplier of 1, in the cream the score has always been. Each row after it multiplies by one more, and warms the color.

Make it as Weapon Levels was made. The table makes Kill Chain Multipliers Entry, and its two fields are the columns. multiplier is a Number, with a Value of 1. scoreColor is a Color. That’s a new one. Pick Color in its Type list, and give it the card’s #fff4cf, the cream the score has always been.

Add Row four times. Then double-click each row’s name in the Entry column, and type x1, x2, x3 and x4. Those names are for you. The chain finds a row by its number, counting from 0, as Fighter Guns found a weapon level. Last, double-click each row’s two cells and type them from the card. A Color cell shows its code, such as #ffe066, and takes one the same way.

9.4.2 Score

Logic ComponentScoreAttach to: Game RulesAddDelete

Adds the points of every enemy shot down (times the kill-chain multiplier), and of every pickup collected, to $score.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
wingCannonsPointsNumberConstant250
repairCratePointsNumberConstant100
On Enemy Shot Down
WhenenemyShotDownCustom Event
1Declare Variable
Name
multiplier
Value
1
2Change Variable
Variable
multiplier
Value
data('Kill Chain Multipliers', $chainRow, 'multiplier')
3Change Variable
Variable
$score
Operator
+=
Value
other.enemyStats.points * multiplier
Value
other.enemyStats.points
4Trigger Custom Event on Object
Custom Event
shotDownScored
On Game State Changed
WhenGame State Changed
1Ifevent.current == "mission-failed"
Then
2Set Logic State
Logic Component
Score
State
Disable
On Wing Cannons Collected
WhenwingCannonsCollectedCustom Event
1Change Variable
Variable
$score
Operator
+=
Value
@self.wingCannonsPoints
On Repair Crate Collected
WhenrepairCrateCollectedCustom Event
1Change Variable
Variable
$score
Operator
+=
Value
@self.repairCratePoints

Score learns to multiply. When an enemy is shot down, it first reads the multiplier from the chain’s row. Then it adds the enemy’s points times that multiplier. Last of all, it tells Game Rules that this shoot-down has been counted, with a new message, shotDownScored.

That order matters. The shoot-down is scored first, and only then does the chain move on. So the first enemy of a chain counts once. The second counts twice, because the first one moved the chain. Each shoot-down is paid at the step the ones before it reached.

The multiplier lasts one shoot-down, so it’s a Declare Variable, the first step: a Number named multiplier, with a Value of 1. The next step gives it the chain’s row.

The new steps go in front of the old one, so the old one has to step aside first. On the canvas, find On Enemy Shot Down. Right-click its Change Variable, and choose Disconnect from Flow. That one block slides off, and the line under the Event is empty.

Now add the Declare Variable from the Action List, and join it with Connect to Sequence. It becomes the first step. A Change Variable comes next, joined the same way. Type multiplier into its Variable box, and the card’s data() into its Value. Then right-click the old step, and choose Connect to Sequence. It joins after the new ones. Add * multiplier to the end of its Value.

Last, add Trigger Custom Event on Object from the Action List, and join it. It starts on Self, which is Game Rules here. Type shotDownScored into its Custom Event box.

9.4.3 Kill Chain

Logic ComponentKill ChainAttach to: Game Rules

Each shoot-down moves $chainRow, the kill chain's row of the Kill Chain Multipliers table, to the next row (up to the last); chainSeconds after the last shoot-down it goes back to the first row.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
chainSecondsNumberConstant1.5
On Shot Down Scored
WhenshotDownScoredCustom Event
1If$chainRow < (dataCount('Kill Chain Multipliers') - 1)
Then
2Change Variable
Variable
$chainRow
Operator
+=
Value
1
3Start Recurring Timer
Timer Name
"killChain"
Repeat Every (s)
@self.chainSeconds
Ring Once
Yes
On the Kill Chain Timer
WhenRecurring TimerTimer name: killChain
1Change Variable
Variable
$chainRow
Value
0

Kill Chain is the clock, and it does two small things.

When shotDownScored arrives, it moves $chainRow one row down the table, unless it’s already on the last. The If counts the rows with dataCount(), as in Weapon Level, so the last row is one less than the count. Then it starts a timer, killChain, set to ring once, chainSeconds from now. A named timer is always a Recurring Timer, and Ring Once makes it ring a single time.

That timer is the whole trick. Each shoot-down starts it again, and a timer started again starts over. So as long as you keep shooting, it never gets to ring. An enemy breaks up. Half a second goes by, then a whole one. Another breaks up, and the timer’s count starts over from nothing.

Stop shooting, and it rings. 1.5 seconds after the last shoot-down, Kill Chain sets $chainRow back to 0. The chain is broken.

Make it as an Empty Logic Component, with the Shared Variable chainSeconds. shotDownScored is in the Add Event list now, since Score sends it.

Its If’s condition is typed whole, brackets and all, and its one step goes on the True line with Add Inside Then. That Change Variable wants += · Add. Start Recurring Timer comes from the Action List, so Connect to Sequence joins it after the whole If, on the main line. Type "killChain" into Timer Name, with its quote marks, @self.chainSeconds into Repeat Every, and pick Yes for Ring Once.

For the second Event, pick Recurring Timer in Add Event, choose Type a timer name…, and type killChain. Its Change Variable sets $chainRow back to 0.

ObjectGame RulesAddDelete
Collider(as it is added)
Logic
Score
Planes
Mission Failed Screen
Mission Start
Pause
Best Score
Play Again
Stages
Weapon Level
Supply Drops
Kill Chain
Shared Variables
fighterFighter
milestoneMilestone
wingCannonsWing Cannons
repairCrateRepair Crate

Attach Kill Chain to Game Rules.

Run the game, and fly into the V of five. Hold Space and sweep across them. Watch the score. Each enemy in a quick run adds more than the one before.

9.5 The Color

The chain works now, but only the numbers show it. The score should show it too.

9.5.1 Kill Chain Color

Logic ComponentKill Chain ColorAttach to: Score Text

Colors this text by the kill chain: the scoreColor of the chain's row of the Kill Chain Multipliers table.

Attach toAny Object
COMPONENTS
self.textText / UI
On Variable Changed · Chain Row
WhenVariable ChangedGlobal Variable: chainRow
1Change Component Value
Component Value
self.text.color
Value
data('Kill Chain Multipliers', $chainRow, 'scoreColor')

Kill Chain Color sits on Score Text, and it doesn’t watch the clock or count anything. It waits for one thing: $chainRow to change. When it does, it reads the scoreColor from the chain’s row, and sets the text’s color to it. Nothing else touches the color.

So the chain and the color never talk to each other. They both read the same row.

Make it as an Empty Logic Component. It needs the Text / UI of the Object it’s on, so the Logic can reach the text’s color. Press the + on its Components card, and pick Text / UI under Component types. The row reads self.text.

Add Variable Changed, and pick chainRow in its second window. Its one step is Change Component Value. Type self.text.color into its Component Value box, and pick it in the list that opens. Its Value is the card’s data(), reading scoreColor this time.

ObjectScore TextAddDelete
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 32, Y 32
Text / UI
TextSCORE {$score}
Font Size15
EmphasisBold
Color#FFF4CF
Text BoundsWrap to Width
Transform > Size X240
UI Interaction
Element TypeText
Groupflight
EventmenuChoice
Logic
Show the Flight HUD
Kill Chain Color

Open Score Text, and attach Kill Chain Color in Logic. It has nothing to set.

Save, and run the game.

Fly into the V of five and sweep your guns across it. SCORE turns yellow, then orange, then red, as the enemies break up one after another. Let the sky go quiet. A moment later, the score is cream again, as if nothing had happened.

Play it!

Watch for each of these, one at a time.

  • Shoot down one enemy, and wait. The score climbs by its points, as before, and SCORE stays cream.
  • Shoot down two quickly. The second adds twice its points, and SCORE turns yellow.
  • Keep the chain going. The third turns it orange, and the fourth red.
  • After the fourth, the chain stays red. A fifth quick shoot-down still counts four times over, and never more than that.
  • Stop shooting. About 1.5 seconds after the last shoot-down, SCORE goes back to cream.
  • Catch a pickup mid-chain. It adds its own points, with no multiplier.
How it works

An enemy is scored, and the chain moves on a row. A timer starts over. When it finally rings, the chain goes back to the top. And the score’s color follows the row, all by itself.

The idea underneath is one you met in Chapter 8: keep what changes in a table, and point at it. Here three pieces of Logic share one row. Score takes its multiplier, and Kill Chain Color takes its color. Kill Chain only moves the finger.

And the chain counts rows, not multipliers. Give two rows the same multiplier one day, and the chain still climbs through both, and the color still changes.

9.6 If It Didn’t Work

A kill chain is fast, so it can be hard to see what went wrong. Shoot one enemy at a time first, and watch.

Press Play, and a window called Can’t run yet opens? Its message names the piece and what’s wrong with it, so fix that, and press Play again.

The score stops climbing when an enemy breaks up? Look at Score’s first step. Its Value should name the table exactly, Kill Chain Multipliers, in quote marks, and its Variable should be multiplier. Then check that the old step is joined after the new ones, not left loose.

Every enemy counts once, however fast you shoot? Maybe Kill Chain never hears the message. Score’s last step and Kill Chain’s Event must both read shotDownScored, letter for letter. And Kill Chain belongs on Game Rules.

The chain climbs, but never breaks? Look at the two timer names, Start Recurring Timer’s killChain and the Event’s killChain. They must match, and Ring Once should be Yes.

The chain breaks at red, mid-run? Perhaps Start Recurring Timer is inside the If, on its True line. At the top of the chain the If is false, so no shoot-down starts the timer over. It belongs below the whole If, on the main line.

The points multiply, but the color stays cream? Look in Score Text’s Logic for Kill Chain Color, and then at its Event’s block, which should name chainRow.

Each of these is one fix. Make it, run the game again, and you’re back with the chapter. The catch-up download in the Goal is this chapter’s game, finished, if you’d like to compare.

Challenge

Make the chain your own. Open Game Rules, and under Variables, type 3 into chainSeconds’ Value. How does the chain feel when it’s this forgiving? Or give the table a fifth row, x5, with a multiplier of 5 and a color you choose. Kill Chain reaches it with no change at all. Put things back before Chapter 10.

Still stuck? Search the manual, or ask in the Myth Engine Discord (opens a new tab).

Your score has a temper now: it warms as you get quick, and cools when you wait. In Chapter 10, your Fighter learns to slow down, on purpose.