Build a GameCreating Pacific Wings

3  The First Enemies

Goal

The Fighter has guns, and nothing to shoot. By the end of this chapter, Enemy Fighters wait along the route and come at you as you reach them. Hit one, and it flashes white, a burst of flak opens over it, and it breaks up in an explosion. Each one is worth 100 points. The game counts them out of sight until Chapter 5, which puts the score on the screen.

The game as it is at the end of this chapter. Click the game to play.

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

Pacific Wings, Chapter 3 finishedMyth project · 1.3 MB

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

3.1 The Idea

Fly north, and for the first time, something is out there. Two olive-green planes slide into the top of the view with their noses to the south, yellow at the wingtips. One more follows between them, and two more behind. These are Enemy Fighters.

Each one waits on the route where it was placed, and it doesn’t move until the view reaches it. Then it comes straight down at you.

This is the scroll you couldn’t see in Chapter 1. The enemies hold still on the route while the view moves north over them, like a picture frame over the sea. It carries your Fighter up to them.

Hold Space and hit one. It flashes white for a blink, a burst of flak opens over it, and it breaks up in an explosion with the crack of Plane Break. That’s 100 points.

An Enemy Fighter has three numbers of its own: it flies at 3.7 meters a second, one hit brings it down, and it’s worth 100 points. Chapter 6 brings two more kinds of enemy, each with its own three.

So the numbers don’t go into the Logic. They go into a Data Table, a spreadsheet the game reads while it plays, with one row for each kind of enemy. This one is called Enemy Types.

The table’s columns come from a Data Structure called Enemy Stats. It’s a small form with three blanks. Every enemy carries its own filled-in copy of speed, health and points.

The rules are the same for all of them. Each enemy waits, flies south, takes hits and breaks up, so the rules are written once, as Logic Components, and every kind of enemy carries the same ones. What marks a plane as an enemy is a Tag, Enemy Aircraft. A Tag is a word stuck on an Object, like a label on a jar, and your tracers break on anything that wears this one.

An enemy’s health is one of those numbers. Each tracer that hits takes one away. Myth watches any field named health, with no Logic of yours asking it to. When one reaches 0, Myth sends a message, noMoreHealth. The enemy breaks up.

The score belongs to the whole game, not to one enemy. So it’s a Global Variable, called $score. An enemy never touches it.

Instead, a shot-down enemy sends a message, enemyShotDown. A new Object with no picture, Game Rules, hears it and adds the enemy’s points. That kind of message is a Custom Event. It works like a bell rung in one room and heard in another.

You won’t see the score yet. Its words go in hidden, and Chapter 5 shows them with the rest of the flight’s display. The game keeps the score all the same.

3.2 The Plan

Here’s how the pieces work together, one chain of events to a line. Most of these names are new. Each is a piece this chapter builds. Glance at the plan now, and come back to it as you go. Each line starts with something that happens in the game, and the pieces after the arrows answer it, from left to right.

  • The view reaches an Enemy Fighter -> Fly South When Seen sends it south at its speed, 3.7 from its row of Enemy Types.
  • A Fighter Tracer touches it -> Breaks on Hit removes the tracer, and Takes Hits takes 1 from its health, bursts Flak Burst and flashes it white with Tint Sprite.
  • Its health reaches 0 -> Myth sends noMoreHealth -> Shot Down sends enemyShotDown, plays Plane Break, bursts Plane Explosion and removes it.
  • enemyShotDown -> Score, on Game Rules, adds that enemy’s points to $score.
  • An enemy flies off the bottom of the view -> Remove When Out of View takes it away, as it does the tracers.

3.3 Set Up

The Enemy Fighter’s picture and the Plane Break sound are in your project already, from the Starter Kit. One block on this card is new, GLOBAL VARIABLES. PLACE THESE has new lines too: a placement on the screen, marked hidden, and a with line under it.

Set upWhat this chapter adds
ART (sprites, from the starter kit)
Enemy Fighter Art
SOUNDS (from the starter kit)
Plane Break
GLOBAL VARIABLES
$scoreNumberstarts at 0
SCENE Route: PLACE THESE
ObjectXY
Enemy Fighter6.87518.75
Enemy Fighter13.12518.75
Enemy Fighter1022.188
Enemy Fighter7.18824.063
Enemy Fighter12.81324.063
Game Rules00
Score Text136-23hidden
with Z-Index = 10002

GLOBAL VARIABLES has one line, $score. A Global belongs to the whole project, not to one Logic Component. You make it from one, though. Score, the Logic that keeps the score, makes it at the end of this chapter.

PLACE THESE waits until its Objects exist, and each part of this chapter places its own.

3.4 The Enemy’s Numbers

Every enemy carries three numbers, and they come first.

An Enemy Fighter’s speed, 3.7, is a little under half as fast as your Fighter steers. Its health of 1 means one hit. Its 100 points go to the score. Those numbers need a form to sit in, and a table to hold them.

Data StructureEnemy Stats

What every enemy carries. Each enemy kind takes its values from its own row of Enemy Types.

speedNumberdefault 0
healthNumberdefault 1
pointsNumberdefault 0

Make the form with Add > Data Structure, and name it Enemy Stats. It opens with no fields at all. The sentence under the name on the card is its Description, if you’d like to type it. Press Add Field once for each line on the card. Each new field is called localVariable, a Number that starts at 0, so type the card’s name over it: speed, then health, then points. Spell health exactly that way. That’s the name Myth watches, as The idea said. Last, give health a Value of 1.

Data TableEnemy TypesData Structure: Enemy Stats
Row 0Enemy Fighter
speed3.7
health1
points100

Now the table, with Add > Data Table, named Enemy Types. Near the top of its left panel is the Entry Type list. It’s on Enemy Types Entry, a Data Structure the new table made for its own rows. Pick Enemy Stats there instead. The table’s columns turn into speed, health and points. Enemy Types Entry stays under Data Structures, unused, and it does no harm where it is, so leave it.

Press Add Row. The new row is named Row, and its cells start at Enemy Stats’ own values, so its health says 1 already. Double-click Row in the Entry column, and type Enemy Fighter over it. That name matters, because the Enemy Fighter will find its row by it.

Double-click the speed cell and type 3.7. Then points, 100. The card counts its rows from Row 0. The editor numbers them from 1. So your first row in the editor is the one the card calls Row 0.

3.5 The Enemies

Now the planes themselves. Every kind of enemy carries the same Logic, so the first piece of it comes first.

3.5.1 Fly South When Seen

An Enemy Fighter sits on the route where you placed it, and nothing happens to it until the camera brings it into view. Then it heads south and keeps going.

That moment is an Event of its own, Enter View, which Myth runs once, when the Object first comes into a camera’s view. Under it is one Action. Set Velocity gives the plane a Y Velocity of @self.speed, and since Y counts upward, the minus sends it south.

Only the Y Velocity is set. The X Velocity stays empty, which keeps whatever sideways speed the enemy has, so the Aces of Chapter 6 can slide from side to side as they come.

Logic ComponentFly South When SeenAttach to: Enemy Fighter

Starts this Object flying south at its speed when it first comes into view.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
speedNumberConstant3.7
When Entering the View
WhenEnter View
1Set Velocity
Y Velocity
-@self.speed

Make it the way you made Remove When Out of View. A Logic Component card has the steps, if you’d like them again. Its one Shared Variable is speed. It’s Constant, a Number, and it starts at 3.7. Add Enter View. Add Set Velocity, join it, and type @self.speed into its Y Velocity box.

That 3.7 is only where speed starts. Each kind of enemy sets its own, from its row, as you’ll see on its card.

The Enemy Fighter comes next. It’s the plane you’ll see: olive green with yellow wingtips, 2.48 meters across, a little smaller than your Fighter.

ObjectEnemy Fighter
Transform
Bounding Box > SizeX 2.48, Y 2.48
Sprite
Scene Depth Draw Order30
SpriteEnemy Fighter Art
Transform > SizeX 2.48, Y 2.48
Transform > Rotation (deg)Z -180
Collider
Shape and Transform > ShapeEllipse
Shape and Transform > SizeX 1.453, Y 1.046
Data Structure
Data StructureEnemy Stats
Input SourceData Table
Data TableEnemy Types
RowEnemy Fighter
Tags
Object TagsEnemy Aircraft
Logic
Fly South When Seen
Remove When Out of View
Takes Hits
Shot Down
Shared Variables
speed > KindExpression
speed > ExpressionobjectComponentProperty("self","enemyStats","speed")

Its card has a Collider, so it’s a 2D Object. Make it with Add > Object, named Enemy Fighter, and go down its card from the top, as you did for the tracer.

The Transform’s Bounding Box comes first, 2.48 by 2.48. Next is the picture. The Add Sprite Component window opens on the Fighter Art, so pick the Enemy Fighter Art in its list. Type 30 into Scene Depth (Draw Order). That’s under the Fighter’s 40, so an enemy slips under your plane.

The card’s Size goes into the Sprite’s own Transform too, and below it is one more line, Rotation (deg). Every picture in the kit faces north, and an enemy flies the other way. Type -180 into the Z of Rotation (deg), and the plane turns around in the preview, nose to the south.

The Collider is an Ellipse, a flat oval over the body of the plane.

Next comes the plane’s own copy of Enemy Stats. Open the Data group in the Component Toolbox and click Data Structure. Enemy Stats is attached at once, since it’s the only one you have. Select it in Attached Components. Its Input Source is on Object Values, which means the numbers typed right here. Pick Data Table instead.

Two more lists appear. Data Table is on Enemy Types already, the only table you have, and Row says (Choose a row). Pick Enemy Fighter. That line ties the plane to its row, and its Values show the row’s numbers now, each one marked from Enemy Types · Enemy Fighter.

Next is the Tag. Click Tags, in the same Data group. Its Properties have a list that reads Select a Tag…. No Tag exists yet, so choose Create New Tag… there, and press Add Selected Tag, the + beside the list. The Create Tag window asks for the Tag. Type Enemy Aircraft, press OK, and the plane wears it.

Now its Logic. Pick Logic in the list above the preview, and click Fly South When Seen and Remove When Out of View under Compatible Logic. The card’s other two, Takes Hits and Shot Down, come later in this chapter.

The card’s last lines are speed’s. Switch the list back to Components. At the top of the Properties, under Variables, speed is there now, From Logic: Fly South When Seen, at 3.7. Pick Expression in its Kind list, and an Expression box takes the Value’s place. Type objectComponentProperty("self","enemyStats","speed") into it, as the card spells it, quote marks and all. It looks long. It only reads one field of the plane: on self, in enemyStats, the speed. So each enemy flies at the speed in its own copy of Enemy Stats.

Now place five of them, from PLACE THESE. Open Route, pick Place, and drag an Enemy Fighter from Predefined Objects onto the Scene. Pick Select, click it, and type its X and Y into its World Position. Do the same for the other four.

They make a small formation: two side by side at 18.75, one between them a little further north, and two more behind at 24.063. The view starts out 15 meters tall, so all five wait above it, out of sight. Remove When Out of View leaves them alone up there. It acts only when something that was in the view leaves it.

Save, and run the game. For a moment, the sea is empty. Then two Enemy Fighters slide into the top of the view and come straight down, and your tracers fly through them. That’s next. Hold still, and the one in the middle may stop against your nose and ride along in front of it. That’s expected. Nothing crashes until Chapter 4.

If they come into view and hang there instead, If it didn’t work, at the end of this chapter, has the places to look.

3.6 Hits

Now the tracers can hit something.

3.6.1 Breaks on Hit

A tracer that hits an enemy is used up. It’s gone at once. The enemy decides what the hit does to it.

Breaks on Hit waits for one moment, Collision Enter: this Object starts touching another. Its block has a Collision Target list, which names the other Object. It can name a Tag instead, and it counts for everything that wears the Tag, so this one counts for every kind of enemy.

Logic ComponentBreaks on HitAttach to: Fighter Tracer

Removes this tracer when it touches an enemy.

Attach toAny Object
When Starting to Hit Anything Tagged Enemy Aircraft
WhenCollision EnterObject: tag:Enemy Aircraft
1Destroy Instance

Make it the way you made Remove When Out of View. Add Collision Enter. On its block, the Collision section starts closed, so click its heading to open it. Its Collision Target list says Any Object. Pick Tagged Enemy Aircraft, under Tags at the end of the list, and Myth renames the Event to the card’s heading. Add Destroy Instance and join it.

Then attach Breaks on Hit to the Fighter Tracer, which is the one change on the tracer’s card.

ObjectFighter TracerAddDelete
Transform
Bounding Box > SizeX 0.72, Y 0.72
Sprite
Scene Depth Draw Order52
SpriteFighter Tracer Art
Transform > SizeX 0.72, Y 0.72
Collider
CollisionSensor
Shape and Transform > ShapeCapsule
Shape and Transform > SizeX 0.146, Y 0.529
Logic
Remove When Out of View
Breaks on Hit

Run the game, and fire at an enemy. A tracer that hits one is gone now, and the enemy flies on, because nothing takes its hits yet.

Every hit throws a burst of flak: a puff of pale yellow, orange and dark red sparks that spreads every way and slows as it goes.

Particle EffectFlak Burst
Emitter
Emission > Burst Count30
Motion
Lifecycle > Each Particle Lives (ms)min 180, max 620
Motion > Speed (m/s)min 2.188, max 8.906
Forces > Dragx 1.05, y 1.05
Appearance
Appearance > Color SourceMultiple Colors
Appearance > Multiple Colors#FFF4C7, #FFD166, #FF7B45, #8B2F36
Appearance > Glow1.4
Appearance Over Life > Scalestart 0.92, end 0
Appearance Over Life > Size Variation (0–1)0.55
Appearance Over Life > Starting RotationRandom Spin On

Make it the way you made Gun Muzzle, and name it Flak Burst. It has four colors, so press Add Color twice. One line is new. Forces > Drag is in the Motion page’s Forces section, and it takes an x and a y, 1.05 in each. Drag slows each spark as it flies, so the burst opens and stops. Emit Shape stays on circle, with the small Emit Radius every new particle effect starts with, so the sparks start inside a small circle around the hit. Use Angle stays on, with its dial open all the way round, so they fly every way.

3.6.2 Tint Sprite

A hit makes the enemy flash white for an instant. Then it settles to a faint peach. Both are the same small job: paint the picture with a color.

So the job is written once, as a Function, a small piece of Logic that does one job when another piece of Logic asks. Tint Sprite is handed three things: the Object to paint, the color, and a mode. In solid mode, the color covers every pixel of the picture. That’s the white flash. In multiply mode, it colors the art and keeps its detail, which makes the peach.

FunctionTint Sprite

Tints the target's sprite: color and mode ("multiply" colors the art, "solid" paints every visible pixel).

PARAMETERS
NameTypeStarts at
targetObject
colorColor#ffffff
modeTextmultiply
ACTIONS
1Change Sprite Tint Property
Applies to
target
Value
color
2Change Sprite Tint Property
Applies to
target
Property
Mode
Value
mode
3Change Sprite Tint Property
Applies to
target
Property
Enabled
Value
true

Make it with Add > Function, named Tint Sprite. A Function has no Events. Its Actions hang in one line on the canvas, and they run each time another piece of Logic calls it.

Its PARAMETERS come first, on its Start block, with the + beside Parameters. The Add Parameter window asks for a Name, a Type and a Default. A Function has no self. Every Object it works on is handed to it, like target here, the Object to paint. Name it target, and pick the Object at the very end of the Type list. Then add a Color named color. It starts at #FFFFFF. Last comes a Text named mode, whose Default is multiply, typed with no quote marks around it.

The three Actions are all Change Sprite Tint Property. The first block lands apart, as it would in a Logic Component, and Connect to Sequence starts the line with it. Join the other two the same way. In each, open Applies to and pick target. Its Property list starts on Color, which is right for the first one, so type color into its Value box. In the second, pick Mode and type mode. The third takes Enabled and true, which turns the tint on.

3.6.3 Takes Hits

When a tracer touches an enemy, its health drops by one, and a burst of flak opens over it. It flashes white for 0.07 seconds, a blink. Afterwards, it keeps a faint peach tint for as long as it flies. On the card, the flash takes three steps. Paint it white, wait, paint it peach.

Takes Hits changes the enemy’s health, so it needs to know the enemy carries Enemy Stats. That’s the DATA STRUCTURES line on its card.

Logic ComponentTakes HitsAttach to: Enemy Fighter

Each Fighter Tracer that hits takes one health and flashes the enemy white.

Attach toAny Object
DATA STRUCTURES
Enemy Statsself.enemyStats
SHARED VARIABLES
NameTypeKindStarting Value
flashColorColorConstant#ffffff
damageTintColorConstant#ffd0b8
flashSecondsNumberConstant0.07
hitParticlesNumberConstant10
When Starting to Hit Fighter Tracer
WhenCollision EnterObject: Fighter Tracer
1Change Component Value
Component Value
self.enemyStats.health
Operator
-=
Value
1
2Burst Particles
Particles
Flak Burst
Count
@self.hitParticles
Z Index Offset
2
3Tint SpriteFunction
target
self
color
@self.flashColor
mode
"solid"
4Wait
Seconds
@self.flashSeconds
5Tint SpriteFunction
target
self
color
@self.damageTint
mode
"multiply"

Make it as an Empty Logic Component. Press the + on its Data Structures card, and pick Enemy Stats under Existing Data Structures. The card’s row shows the name Myth gives it, self.enemyStats, and the Logic reads every field through that name.

Its four Shared Variables follow, two Colors and two Numbers, all Constant. A new Color starts at #FFFFFF, which is flashColor’s already. For damageTint, click the swatch, the small square of color, and type FFD0B8 into the HEX box of the picker that opens.

Add Collision Enter. This time pick Fighter Tracer, an Object, in its Collision Target list.

Change Component Value comes first. It changes one field of a component. Type self.enemyStats.health into its Component Value box, the health field of the Enemy Stats this enemy carries. Its Operator is -=, and its Value is 1, so one health comes off.

Burst Particles comes next. Pick Flak Burst in its Particles list, and make the Count @self.hitParticles, which is 10. A count on the Action wins over the effect’s own, so a hit throws ten sparks, not Flak Burst’s 30. The Z Index Offset is 2, which draws the flak a little in front of the enemy.

Tint Sprite is in the Functions group of the Action List. Its fields are its three Parameters, and they start at the Function’s own. target is a list, and a new call starts it on self, as the card has it. Type @self.flashColor over the color box’s value. The mode box shows "multiply", the Function’s Default. Type "solid" over it, with its quote marks, as the card shows it.

Wait holds the line for @self.flashSeconds. The last Tint Sprite paints @self.damageTint, with "multiply" in its mode box.

Attach Takes Hits to the Enemy Fighter, and run the game. Shoot an enemy. It flashes white and throws a burst of flak, then flies on, tinted peach. Its health is 0 now, but nothing listens for that yet.

3.7 Breaking Up

An enemy with no health left breaks up: a burst of white, yellow and orange sparks that fades to dark red, and the crack of Plane Break.

Particle EffectPlane Explosion
Emitter
Emission > Burst Count76
Emitter Shape > Emit Radius (m)0.375
Motion
Lifecycle > Each Particle Lives (ms)min 300, max 980
Motion > Speed (m/s)min 2.969, max 13.125
Forces > Dragx 1.35, y 1.35
Appearance
Appearance > Color SourceMultiple Colors
Appearance > Multiple Colors#FFFFFF, #FFE8A3, #FFB347, #E85D3F, #552D2D
Appearance > Glow1.8
Appearance Over Life > Scalestart 1.5, end 0
Appearance Over Life > Size Variation (0–1)0.65
Appearance Over Life > Starting RotationRandom Spin On

Make Plane Explosion the way you made Flak Burst. Its Emit Radius is new, under Emitter Shape on the Emitter page. At 0.375 it’s twice the one Flak Burst kept, so the explosion starts wider than the flak. There are five colors this time, so press Add Color three times.

3.7.1 Shot Down

When an enemy’s health reaches 0, Myth sends noMoreHealth by itself, in the same instant. Shot Down listens for it.

First it sends enemyShotDown, the message for Game Rules. Trigger Custom Event rings that bell for anything that listens. Its Custom Event box takes the message’s name as you type it, enemyShotDown, with no quote marks. Nothing listens yet. Game Rules will, at the end of this chapter.

After the message, the enemy breaks up where it flew: a crack, a bright burst of sparks, and it’s gone.

Logic ComponentShot DownAttach to: Enemy Fighter

When this enemy has no health left, reports enemyShotDown to Game Rules, then explodes and is removed.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
explosionParticlesNumberConstant42
On No More Health
WhennoMoreHealthCustom Event
1Trigger Custom Event
Custom Event
enemyShotDown
2Control Sound
Sound
Plane Break
3Burst Particles
Particles
Plane Explosion
Count
@self.explosionParticles
Z Index Offset
2
4Destroy Instance

Make it as an Empty Logic Component, with one Shared Variable, explosionParticles: Constant, a Number, 42.

On its card, that message is a Custom Event, noMoreHealth. You listen for it by name. Game Rules will listen for enemyShotDown the same way. The heading over it, On No More Health, is the name Myth gives that Event.

Press Add Event and type Custom into the filter. Pick Add Custom Event… and press OK. A small window asks for the Event Name: type noMoreHealth, with its capital M and H, and press its OK. The Event’s block reads On custom event noMoreHealth.

Then add its four Actions. Sound and Particles are lists, like the Particles list in Takes Hits. Pick Plane Break in Sound, then Plane Explosion in Particles. Its Count, @self.explosionParticles, wins over Plane Explosion’s own 76 the same way, so an explosion throws 42 sparks.

Attach Shot Down to the Enemy Fighter, beside Takes Hits. That’s the last Logic on its card, so run the game now and shoot one down.

Your Fighter has brought down its first enemy.

3.8 Keeping Score

Last comes the score, which is kept where the whole mission is run.

Game Rules has no picture. Nobody playing ever sees it. It runs the mission: the score now, and in later chapters the planes, the stages and the rounds.

ObjectGame Rules
Collider(as it is added)
Logic
Score

Its card names a Collider with nothing to set, marked (as it is added). A Collider on a card means a 2D Object, and this one stays exactly as Myth adds it. Nothing in the game uses it. Game Rules sits at the corner where the route begins, where nothing ever flies, so it never touches anything. Make it with Add > Object, named Game Rules. Under Score, the card has one line more, and it comes once Score is made.

3.8.1 Score

Remember enemyShotDown, the message nothing heard? This is who it was for.

Score listens for it, and when the message comes, it adds that enemy’s points to $score, 100 for an Enemy Fighter. Which enemy? The one that sent the message. Every message brings its sender along, and Score calls it other. So other.enemyStats.points is the points field of that enemy’s own Enemy Stats.

Logic ComponentScoreAttach to: Game Rules

Adds the points of every enemy shot down to $score.

Attach toAny Object
On Enemy Shot Down
WhenenemyShotDownCustom Event
1Change Variable
Variable
$score
Operator
+=
Value
other.enemyStats.points

Make it as an Empty Logic Component. The Global from the Set up card comes first: press the + on the Globals card and choose New Global…. The Add Global window has a Name, globalVariable to start, a Type on Number and a Default of 0. All it needs is a name. Type score over globalVariable, with no $, and press Add. On a card, a $ in front of a name marks a Global. Where Logic reads it, as Score does in a moment, you type the $ along with the name.

Press Add Event. The message is in the list now, because Shot Down sends it. Type enemyShotDown into the filter, pick it, and press OK. Its block lists other under Event Variables. That’s the sender.

The one Action is Change Variable, and its Variable box takes the Global by its whole name, so type $score there. Click the = after it, and pick += · Add in the list, so the Value is added on. The Value is other.enemyStats.points.

Now attach Score to Game Rules. Each message brings its own sender, so there’s nothing to set there.

The score needs words to show it. Score Text is the word SCORE and a number, in cream letters near the top left of the screen. It goes in hidden. At the end of this part, you’ll turn it on for a peek.

ObjectScore Text
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

Its Transform says Space Window / UI. So it’s a Screen UI Object. Make it with Add > Object, named Score Text, and pick Screen UI Object in the Create Object window. Those come with UI Interaction attached. This card has none, and an Object card lists every component its Object keeps. So press the red trash button on UI Interaction’s row in Attached Components. Now your Score Text matches the game’s. Chapter 5’s card adds UI Interaction back, set up for the flight’s display.

From the Rendering group, click Text / UI, and its Properties open on the left. Type SCORE {$score} into its Text box. The part in braces is a live value: while the game runs, the number follows $score.

The rest of the card goes into those Properties too. Font Size is 15. Emphasis is Bold: its row in those Properties ends in a list, so pick Bold there. For the Color, click its swatch and type FFF4CF into the HEX box, a warm cream. The bar above the preview has the same boxes, but there they style only the words you type next, so use the ones on the left.

The card’s last line, Transform > Size X, goes into the W box of Text Frame, since a text’s own Transform keeps its Size boxes grey. That box wakes up once you pick Wrap to Width in Text Bounds, above it. So pick that first, then type 240 into W.

Now place both, from PLACE THESE: open Route and pick Place. Predefined Objects is a longer list now, so type a name into its search box to find it. Game Rules goes onto the route at X 0 and Y 0, the corner where the route begins, the way you placed the enemies.

Score Text sits on the screen, not on the route. Drag it in, and pick Select. It’s listed under UI Objects in the Scene Explorer, the list on the right, so click it there. Its 136 and -23 go into Screen Offset (px), counted in pixels from the point its Screen Anchor picks. That starts on Top Left, the screen’s top-left corner. The card leaves it there. So -23 is 23 pixels down.

Near the top of its Properties, turn off Visible at Game Start. That’s the card’s hidden. Its with line is the placement’s Z-Index, under Rendering: type 10002, so the score will sit over everything in the sky.

Run the game once more. Nothing new shows, because the score is counting out of sight.

To watch it count, select Score Text in Route’s Scene Explorer, turn on Visible at Game Start, and run the game. SCORE 0 sits at the top left. Shoot an enemy down, and it turns to SCORE 100. Then turn Visible at Game Start off again, as the card has it.

Play it!

Watch for each of these, one at a time.

  • For a moment after the game starts, the sea is empty.
  • Then two olive-green Enemy Fighters slide into the top of the view, noses down, and come straight at you. One more follows between them, then two more.
  • Each one starts to move only once it’s in the view. Before that, it waits on the route.
  • Hold still, and the one in the middle comes straight for your nose. Nothing crashes yet. It stops against your plane and rides along in front of it until you shoot it. Chapter 4 changes that.
  • Hit one. It flashes white for a blink, a burst of flak opens over it, and it breaks up in an explosion with the crack of Plane Break.
  • A tracer that hits is gone. It doesn’t fly on through.
  • An enemy you miss flies off the bottom of the screen and is gone.
  • No score shows on the screen yet, because Chapter 5 brings it out.
How it works

Three numbers in a table. Rules written once, for every enemy. A plane with a picture and a Tag, reading its own row. A hit that flashes and bursts, and a message that turns a shoot-down into points.

The rules live in one place, and the numbers in another. The enemies’ Logic never knows how fast an Enemy Fighter flies, how much it can take, or what it’s worth. It reads all three from the plane’s own copy of Enemy Stats, and that copy comes from the table. So when Chapter 6’s new enemies arrive, nothing in this chapter’s Logic changes for them. They’re two more rows in Enemy Types, and two more planes wearing the Tag Enemy Aircraft.

3.9 If It Didn’t Work

A chapter this long has many places for a small slip, and finding one is part of the work. Run the game, fly up the route, and watch what the enemies do.

The enemies never come? Look in Route’s Scene Explorer for five Enemy Fighters, at Y 18.75 and more.

The enemies come into view and hang there? Then the Enemy Fighter isn’t reading its row, and its speed is Enemy Stats’ own starting value, 0. Open it, and select Enemy Stats. Input Source should say Data Table, and Row should say Enemy Fighter. Under Variables, speed’s Kind should be Expression. Its box holds the card’s line, spelled exactly. Last, Fly South When Seen should be in its Attached Logic.

The enemies show at the top of the view and fly off north again? Fly South When Seen’s Y Velocity is missing its minus. It should read @self.speed.

The enemies fly tail first? Look at the Sprite’s own Transform, where Rotation (deg) Z should be -180.

A tracer flies on through the enemy it hits? Look for Breaks on Hit on the Fighter Tracer, with Tagged Enemy Aircraft in its Collision Target. Then the Enemy Fighter’s Tags: Enemy Aircraft should be spelled the same way there.

Each hit flashes, but nothing ever breaks up? Look for Shot Down in the Enemy Fighter’s Attached Logic, and read its Event’s block: it should say On custom event noMoreHealth, spelled exactly so. Last, Takes Hits’ Change Component Value needs -= as its Operator.

No white flash, though hits break them up? Look in Takes Hits for the Wait between the two Tint Sprites. It holds the line for flashSeconds. Without it, the peach paints over the white in the same instant.

You made the score visible, and it stays at 0? Then look at Score’s Change Variable. Its Variable is $score, its Operator +=, and its Value other.enemyStats.points. Do the enemies hang in the view as well? Then look at their row, as above.

Press Play, and a window called Can’t run yet opens instead? Its message names the piece with the slip and says what’s wrong, as in Chapter 2. Suppose it points at Tint Sprite. Perhaps the second Change Sprite Tint Property still has Color in its Property list, where Mode belongs. Fix whatever the message names, close the window, and press Play again.

Each of these is one small 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

The Enemy Fighter’s numbers are yours to change, in Enemy Types. Give it a health of 3, and watch it take three hits, flashing every time and peach after the first. Give it a speed of 8, and it comes at you faster than you can steer. Make it worth more, too, and turn the score on as you did at the end of Keeping score, to watch SCORE climb. Then put everything back the way the cards have it before Chapter 4.

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

The Fighter has something to shoot at now, and the game keeps score. In Chapter 4, the enemies shoot back.