Build a GameCreating Pacific Wings

2  Machine Guns

Goal

One Fighter flies over an empty sea, and it has no guns. By the end of this chapter, it does. Hold Space, and pale blue tracers stream north from its nose, each with a small flash and the rattle of machine guns.

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 3 from it.

Pacific Wings, Chapter 2 finishedMyth project · 1.2 MB

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

2.1 The Idea

The sea is still empty, and the Fighter still waits low in the middle of it. Steer, and it flies. But a fighter with no guns is only out sightseeing.

This chapter arms it. Hold Space, and a tracer leaves the tip of the Fighter’s nose: a thin rod of pale blue light with a brass end. It races north. Another follows it, then another, a dotted line for as long as you hold the key. The guns rattle, and a tiny burst of sparks flashes at the nose with every tracer.

Most of that you’ll make yourself. The tracer is a new Object, the Fighter Tracer, and the guns are a Logic Component called Fighter Guns. The tracer’s picture and the rattle come ready-made, from the Starter Kit: the Fighter Tracer Art and a sound called Machine Guns. Space reaches the guns through a new Command, Fire, the way your arrow keys reach the Fighter through Move.

Three new ideas make it all work.

The tracers need a place to start. A Coordinate is a named point on an Object, and the Fighter gets one at the tip of its nose, called Center Muzzle. Wherever the Fighter flies, its Center Muzzle goes along, so the tracers always leave from the nose.

And the guns need to wait between tracers. Left alone, they’d fire at every step of the game, many times a second, and the tracers would run together into one solid line. So they wait with a cooldown. A cooldown is a named stopwatch. You start it with a number of seconds, and at any moment you can ask whether it has run out.

This one is called fireRate, and there’s nothing to make for it. One Action starts it, another asks about it, and the shared name is all they need. A stopwatch that has never been started counts as run out. So the first tracer leaves the moment you press Space.

The flash is a particle effect called Gun Muzzle, a spray of tiny sparks that bursts, fades and is gone.

There’s nothing to shoot at yet. The first enemies arrive in Chapter 3. Until then the tracers fly off the top of the screen, and one quiet piece of Logic, Remove When Out of View, clears them away.

2.2 The Plan

Here’s how the pieces work together. Read each line from left to right.

  • Space is held -> Fire is held -> at every step, Fighter Guns asks its fireRate cooldown whether it has run out.
  • It has -> a Fighter Tracer appears at the Center Muzzle, already flying north -> Gun Muzzle flashes there -> Machine Guns plays -> the cooldown starts again.
  • It hasn’t -> nothing happens at this step. The guns ask again at the next one.
  • A tracer leaves the view -> Remove When Out of View takes it away.

2.3 Set Up

The tracer’s picture and the gun’s sound are in your project already, from the Starter Kit: the Fighter Tracer Art and Machine Guns. The one new thing on this card is a Command. And there’s no PLACE THESE this time. The guns make every tracer while the game runs, so there’s nothing to place by hand.

Set upWhat this chapter adds
ART (sprites, from the starter kit)
Fighter Tracer Art
SOUNDS (from the starter kit)
Machine Guns
COMMANDS (Game Settings > Input Manager)
FireButton
KeybindingsSpace

In Chapter 1, Move arrived by itself. Fire you make yourself. Open the Game Settings and choose Input Manager. Under the list of Commands, press Add Command.

A small window asks for a Command Name and an Input Type. Type Fire. The Input Type is already on Button, which is right: a Button is either down or up, and that’s all the guns need to know. Press the window’s own Add Command.

Fire joins the list under Move, with one empty row that reads No Input Assigned. Click it, and press Space. The row now reads Space, the card’s Keybindings line.

2.4 The Tracer

First, the thing the guns fire.

A tracer’s picture is 0.72 meters tall, a quarter of the Fighter’s length, with a thin rod of light down its middle. Its card has a Collider, so it’s a 2D Object, like the Fighter. Make it the way you made the Fighter: Add > Object, with Fighter Tracer as its Name and 2D Object as its Object Type.

One line on its card is new to you: Collision, Sensor. A tracer has to fly into an enemy, not bounce off one.

Here’s its card. Go down it from the top, as you did for the Fighter. Leave the Logic at the bottom for the next piece.

ObjectFighter Tracer
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

The Transform’s Bounding Box comes first. Next is the picture: open Rendering in the Component Toolbox and click Sprite. This time the Add Sprite Component window opens on the Fighter Art, the first picture in its list. Open that list and pick the Fighter Tracer Art, then press Add Sprite.

Type 52 into Scene Depth (Draw Order). That’s higher than the Fighter’s 40, so a tracer is drawn over the plane, as Chapter 1 promised. The Sprite’s own Transform > Size comes after it, as it did on the Fighter.

The Collider comes last. Near the top of its Properties is Collision, with three choices: Solid, Sensor and Off. It starts on Solid. Pick Sensor.

A Sensor feels what it touches but never blocks or pushes it. The enemies of Chapter 3 still need to know a tracer touched them, and a Sensor tells them. That’s its whole job.

Its shape is a Capsule, a sliver down the middle of the rod, and its Position stays at 0, 0.

2.4.1 Remove When Out of View

Every tracer has a short life. It leaves the Fighter’s nose, streaks north, and is off the top of the screen in about half a second. After that it can never matter again. But it’s still in the game, flying north where no one can see it. Hold Space for a minute, and hundreds of them would be out there.

Remove When Out of View clears them away. Myth tells an Object when it has completely left every camera’s view. That’s the Leave View Event. Under it is one Action, Destroy Instance, and the tracer is gone.

Nobody playing will ever see this piece work. But without it, the game would slowly fill up with tracers. Every enemy and every pickup will use it too, since they all leave the screen sooner or later.

Logic ComponentRemove When Out of ViewAttach to: Fighter Tracer

Removes this Object once it has left every camera view.

Attach toAny Object
When Leaving the View
WhenLeave View
1Destroy Instance

Make it with Add > Logic Component, with Remove When Out of View as its Name, and leave the Starter on Empty Logic Component. Press Add Event, the + in the canvas’s toolbar. Type Leave View into the filter, pick it, and press OK. A green block named Leave View lands on the canvas, with Mode 1 beside it and End below.

Find Destroy Instance in the Action List on the right, and click it. Its block lands a little to one side, with no arrow into it, and so will every block you add. Right-click it and choose Connect to Sequence. It joins the line under Mode 1, right above End. Actions, one at a time shows the same moves in more detail.

Now attach it. Open the Fighter Tracer, pick Logic in the list above its preview, and click Remove When Out of View under Compatible Logic. That’s the card’s last line.

The tracer is ready, and nothing fires it yet.

2.5 The Muzzle Flash

Every time the guns fire, a pinch of sparks bursts from the nose and is gone.

It’s a particle effect called Gun Muzzle: a handful of sparks at a time, each living about a tenth of a second, spraying north in a narrow fan. They’re pale yellow, gold and orange, and they shrink to nothing as they fly.

Make it with Add > Particle. In the Create Particle window, type Gun Muzzle as its Name, and leave the Starter on Blank Particle. The card lists only what’s different from a blank effect.

Particle EffectGun Muzzle
Emitter
Emission > Burst Count8
Emitter Shape > Emit Shapepoint
Motion
Lifecycle > Each Particle Lives (ms)min 70, max 170
Motion > Speed (m/s)min 0.938, max 3.594
Motion > Angle (Deg)min 70, max 110
Appearance
Appearance > Color SourceMultiple Colors
Appearance > Multiple Colors#FFF8D2, #FFD166, #FF9F43
Appearance > Glow1.2
Appearance Over Life > Scalestart 0.58, end 0
Appearance Over Life > Size Variation (0–1)0.35
Appearance Over Life > Starting RotationRandom Spin On

The card’s three groups are the editor’s three pages, though the editor lists Appearance before Motion. Pick a page in that list, at the right end of the preview’s toolbar.

On Emitter, Burst Count starts at 24; make it 8. That’s how many sparks Gun Muzzle bursts when an Action asks for a burst without giving a count of its own. Emit Shape starts on circle. Pick point, so every spark starts from the same spot.

On Motion, Each Particle Lives is in the Lifecycle section, which starts closed, so open it first. Speed is a pair of boxes under a slider. Angle (Deg) is a dial, with a Min and a Max box under it. Type 70 and 110, and the dial’s narrow wedge points straight up, north.

On Appearance, pick Multiple Colors in Color Source. Two rows of color appear. The card’s codes go into the rows in its order, the first code in the top row. Click a row’s swatch, and type its code into the HEX box. Press Add Color for a third row, and give it the last code the same way. Glow is a slider that starts at 1. Drag it, or click it and press the right arrow key twice, until it reads 1.2. Scale’s start and end come next, and then Size Variation, which is a single box: type 0.35. Last comes the Random Spin switch under Starting Rotation.

Your sparks are ready too, waiting for something to set them off.

2.6 The Guns

Now the Fighter gets its guns. Its card has changed since Chapter 1, and a Changes card shows how.

ObjectFighterAddDelete
Transform
Bounding Box > SizeX 2.88, Y 2.88
Sprite
Scene Depth Draw Order40
SpriteFighter Art
Transform > SizeX 2.88, Y 2.88
Collider
Shape and Transform > ShapeCapsule
Shape and Transform > PositionX 0, Y -0.09
Shape and Transform > SizeX 0.698, Y 1.733
Coordinate
NameCenter Muzzle
Local PositionX 0, Y 1.193
Logic
Vertical Shooter Controls
Fighter Guns
Shared Variables
moveSpeed7.8
scrollSpeed2.25
tracerFighter Tracer

Two parts are new, both marked Add: a Coordinate, and Fighter Guns under Logic. Everything else is there already, from Chapter 1.

The Coordinate comes first. Open the Fighter, open Core in the Component Toolbox, and click Coordinate. The Fighter gets its first one, named Coordinate 1, and its Properties open on the left. Type Center Muzzle over its Name.

On the card, Local Position sits one step in under that Name, because it belongs to that one Coordinate. Its X stays 0, and Y gets 1.193. Y counts upward from the Fighter’s middle, the same way it does on the route. In the preview, the Coordinate’s small ring jumps from the middle of the plane to its propeller, right at the tip of the nose.

The Logic line comes once Fighter Guns exists.

2.6.1 Fighter Guns

Hold Space. A tracer leaves the nose, then another, then another, evenly spaced, a dotted line racing north. Let go, and the line stops.

The guns never fire on their own. As long as Fire is held, Myth runs Fighter Guns at every step of the game. That’s a Command Held Event.

So at every step, the guns ask one question: has the stopwatch run out? The stopwatch is the cooldown named fireRate, and the answer gets a name of its own, fireRateReady. An If reads it.

When the stopwatch has run out, the guns fire once. A tracer appears at the Center Muzzle, already racing north, sparks burst there, and the guns rattle. Then the stopwatch starts again. Until it runs out, there’s nothing to do but wait.

The numbers are its Shared Variables. The first sets the pace: at a fireRateSeconds of 0.14, about seven tracers leave every second. Each one flies at tracerSpeed, 17.5 meters a second. That’s more than twice as fast as the Fighter steers, so a tracer leaves the plane far behind. The flash shows muzzleFlashParticles sparks, 5 of them. The guns give that count when they ask for a burst, so it wins over Gun Muzzle’s own 8. The 8 you typed there stays all the same. It keeps your Gun Muzzle the same as the finished game’s.

This is the longest card you’ve built so far, so take it one block at a time.

Logic ComponentFighter GunsAttach to: Fighter

While Fire is held, fires a Fighter Tracer north from the Center Muzzle every fireRateSeconds.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
tracerObjectConstantNone
fireRateSecondsNumberConstant0.14
tracerSpeedNumberConstant17.5
muzzleFlashParticlesNumberConstant5
While Fire Is Held
WhenCommand HeldCommand: Fire
1Check Cooldown Ready
Action Name
fireRateReady
Cooldown Key
"fireRate"
2IffireRateReady.value == true
Then
3Create Instance
Object to Create
@self.tracer
Position Relative To
Self
Self Position
Coordinate
Coordinate
Center Muzzle
Launch Speed
@self.tracerSpeed
Launch Angle
90
4Burst Particles
Particles
Gun Muzzle
Position Relative To
Coordinate
Coordinate
Center Muzzle
Count
@self.muzzleFlashParticles
Z Index Offset
2
5Control Sound
Sound
Machine Guns
6Start Cooldown
Cooldown Key
"fireRate"
Seconds
@self.fireRateSeconds

Make it with Add > Logic Component, with Fighter Guns as its Name and the Starter on Empty Logic Component.

The SHARED VARIABLES come first. Press the + on the Shared Variables card, down the left side of the canvas. The Add Shared Variable window asks for a Name, a Kind, a Type and a Starting Value. The Kind starts on Changeable. All four of these are Constant, so pick that each time.

The first is the tracer the guns fire. Type tracer as its Name, and pick Object in the Type list, under Things, among the kinds that run from A to Z. Its Starting Value becomes a button that reads None. Leave it, and press Add. Each Object that carries the guns will pick its own tracer. Then add the three numbers. Each is a Number with the card’s Starting Value, and in the Logic each one reads with an @ in front, as @self.tracerSpeed does.

Before the Events, attach Fighter Guns to the Fighter. Open the Fighter, pick Logic in the list above its preview, and click Fighter Guns under Compatible Logic. It joins Attached Logic. Then switch the list back to Components. At the top of the Properties, under Variables, the Fighter has four new Shared Variables, From Logic: Fighter Guns. The three numbers are already the card’s. The tracer’s Value is a button that reads None. Press it and pick Fighter Tracer, the Changes card’s tracer line.

Back in Fighter Guns, press Add Event, and type Command Held into the filter. Pick it, and press OK. A second window lists your Commands: pick Fire, and press OK.

Now the Actions, block by block. Two passages of Making what a card shows, Actions, one at a time and If, Else and Repeat, show where everything is. Every block lands apart from the line, as Destroy Instance did. Join each one with Connect to Sequence the moment it’s in, before you fill it in.

Check Cooldown Ready comes first. Its Action Name is the last box, after the word as, and it says cooldownReadyResult. Type fireRateReady over it. Its Cooldown Key shows "cooldown", in quote marks, though that’s only how the block draws a name. Type "fireRate" there, with its quote marks, as the card gives it.

Then the If, which you’ll find in the Action List’s Logic group. Its condition is the one box on it. Click the box, type fireRateReady.value == true exactly as the card spells it, and press Enter.

Create Instance goes on the If’s True line. To put it there, right-click the If and choose Add Inside Then. A window opens with every Action in it. Pick Create Instance. Press OK. Its block lands apart, like every other block, so join it with Connect to Sequence first. It joins the True line. Then fill it in. In its Object to Create list, pick @self.tracer, the guns’ own tracer. Set Position Relative To to Self, then Self Position to Coordinate. A Coordinate box appears. Type Center Muzzle into it, spelled as on the Fighter. Type @self.tracerSpeed into Launch Speed, and 90 into Launch Angle, which in Myth points straight up the screen, north.

For the other three, right-click the If and choose Add Inside Then again. Pick the Action and press OK. Each one lands apart too. Join it with Connect to Sequence, and it takes its place under the one before.

Two of those three, Burst Particles and Start Cooldown, arrive pointing at the new tracer. Their Applies to, the list after the word on, reads created. The card gives them no Applies to line. That means Self, the Fighter, so open each one’s Applies to list and pick Self.

Start Cooldown shows why it matters. Left on created, it would start the stopwatch on the new tracer instead of on the Fighter. The guns would never wait, and a tracer would leave at every step.

In Burst Particles, pick Gun Muzzle in the Particles list. Position Relative To is Coordinate, and Center Muzzle goes into its Coordinate box, typed as in Create Instance.

Count is @self.muzzleFlashParticles, and Z Index Offset is 2. The 2 draws the sparks a little in front of the Fighter, so the flash shows over its nose.

In Control Sound, pick Machine Guns in its Sound list. In Start Cooldown, the Cooldown Key is "fireRate", spelled exactly as in Check Cooldown Ready, and Seconds is @self.fireRateSeconds.

Save with File > Save. Then press Play, the triangle at the top of the editor, and hold Space.

Your Fighter has guns.

Play it!

Watch for each of these, one at a time.

  • Hold Space. Pale blue tracers leave the tip of the Fighter’s nose and race north in a dotted line.
  • Each one starts with a tiny burst of sparks at the nose, pale yellow fading to orange.
  • The guns rattle while you hold the key. That’s Machine Guns.
  • Count them. About seven tracers leave every second.
  • Let go of Space, and the firing stops at once. The last tracers fly on, off the top of the screen.
  • Fly and fire together. The tracers always leave from the nose, wherever the Fighter is.
  • Slide sideways while you fire. Each tracer flies straight north from where it left, so the line leans behind the plane.
How it works

A named point at the nose. A stopwatch called fireRate, and a tracer that clears itself away when it leaves the view. A pinch of sparks. Fighter Guns ties them together, one tracer each time the stopwatch runs out.

In Chapter 1, Vertical Shooter Controls steered, scrolled and leaned the Fighter at every step. Fighter Guns runs at every step too, while Fire is held, and at most of those steps it does nothing at all. It asks its question and waits. The cooldown decides which steps fire. That’s how a game waits without stopping: it keeps asking, and the clock answers.

2.7 If It Didn’t Work

A first try at a long card often goes a little wrong. That’s normal. Run the game, hold Space, and watch what the guns do.

Press Play, and a window called Can’t run yet opens instead of the game? Myth checks your Logic before running it, and this time it found a slip, so the game waits until you fix it. Fighter Guns shows red in the Resources too, and the Errors bar under its canvas counts the slips. The window’s message names Fighter Guns and says what’s wrong, in one of these ways:

  • It says a Coordinate is missing on Object “Fighter”. Center Muzzle is spelled one way in a block and another on the Fighter. Make them match.
  • It points at the If, at a name it doesn’t know. The If is asking for fireRateReady, so the Action Name in Check Cooldown Ready has to read fireRateReady too.

Fix it, close the window, and press Play again.

Nothing fires at all? Perhaps the guns never hear the key. Open the Input Manager and look for Fire, with Space in its row. Next, check Fighter Guns’ Event. It should be Command Held, with Fire as its Command. Last, open the Fighter and pick Logic in the list above its preview. Fighter Guns should be in its Attached Logic.

Sparks and a rattle, but no tracers? Create Instance never joined the line, so it’s still beside the If’s True line, with no arrow into it. Right-click it and choose Connect to Sequence. It joins after Start Cooldown, and the guns fire as they should. Missing the sparks or the rattle instead? Look for that block with no arrow into it, and join it the same way.

A solid line of tracers, one at every step? The guns aren’t waiting. Look at Start Cooldown. Its Applies to should be Self, not created. If it already says Self, compare its Cooldown Key with the one in Check Cooldown Ready: both are fireRate, spelled the same.

The tracers come further apart than in the Goal’s game, two or three in the air instead of three or four? Start Cooldown’s Seconds still says 0.2, where it starts. Type @self.fireRateSeconds.

The tracers don’t fly at all? They hang where they leave the nose, and the plane flies on without them, so they trail down the screen behind it. Create Instance’s Launch Speed is empty. Type @self.tracerSpeed.

The tracers fly sideways, to the right? Create Instance’s Launch Angle is still 0, where it starts. Type 90.

The tracers start in the middle of the plane, not at its nose? Look at the Fighter’s Center Muzzle. Its Local Position Y should be 1.193. Then look at Create Instance: Self Position should be Coordinate, with Center Muzzle in its box.

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 guns are yours to tune, on the Fighter, in the Values of Fighter Guns’ Shared Variables. Give fireRateSeconds 0.05, and hold Space to watch a stream pour out. Give it 0.5, for a slow, careful gun. Give tracerSpeed 6, then fly north while you fire, and watch the Fighter catch up with its own tracers. Find the guns you like best. Then put the card’s numbers back, because Chapter 3 starts from them, the same as the finished game.

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

The Fighter flies and fires over an empty sea. In Chapter 3, the first enemies wait along the route.