Build a GameCreating Sky Ace

2  Machine Guns

Goal

Hold Space, and gold rounds stream up from the Fighter, with a flash at its nose and the sound of gunfire. A bar along the bottom of the window shows the gun level. By the end of this chapter, your Fighter fires.

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.

Sky Ace, Chapter 2 finishedMyth project · 5.7 MB

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

2.1 The Idea

The Fighter flies over an empty sea, and it can’t fight. In this chapter it gets its guns.

Hold Space. Two gold rounds leap from between the propellers, side by side. Two more follow, and two more, until a ladder of gold climbs the whole window. A spark flashes at the nose with every pair. The guns rattle. Let go, and the ladder stops growing, and its last rungs climb out of sight at the top.

Each time the guns fire, the rounds that leave them together are a volley. How many depends on the gun level. It runs from 1 to 4. At level 1, a volley is two rounds side by side. At level 4 it’s six, and the outer two lean out like the edges of a fan.

The gun level is a Global Variable, $gunLevel, one number the whole game shares. The guns read it. So does the bar at the bottom of the window. It starts at 1, and it stays there in this chapter, because the pickups that raise it come in Chapter 8.

Holding a key is one long moment, but the guns fire in beats. If the Fighter fired at every step of the game’s clock, the rounds would pour out as one solid gold bar. So the guns wait between volleys. That wait is a cooldown, and it works like a named stopwatch. Fire, start the stopwatch, and don’t fire again until it has run down. The Fighter’s is called fireRate. It runs for 0.11 seconds, so the guns fire about nine volleys a second.

Where does each round come out, and which way does it fly? Gun Patterns knows. It’s a Data Table with one row for every round of every gun level. The guns read it the way a waiter reads the seating chart at a wedding: down the whole list, picking out every guest at one table. Every row with the right gun level gets a round.

And two small jobs get a Function of their own, a piece of Logic that does its one job whenever another piece of Logic asks for it. One fires a volley, and the other shows a pip.

2.2 The Plan

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

  • Fire is held -> Fighter Guns checks its fireRate cooldown -> when it’s ready, Fighter Guns starts the cooldown again and fires.
  • Fighter Guns fires -> Fighter Gunfire plays, a Muzzle Flash bursts at the nose, and Fire a Volley fires one volley.
  • Fire a Volley goes down Gun Patterns -> each row of the gun level now -> an MG Round appears at that row’s place and flies its way.
  • An MG Round leaves the window -> Remove When Out of View removes it.
  • A Power Pip appears, or $gunLevel changes -> Show Gun Level asks Show Pip For Gun Level -> the pip shows only while the gun level is at least its own.

2.3 Set Up

This chapter adds one control and one shared number: Space and J become the trigger, and the whole game gets a gun level. The new pictures and the gunfire sound came with the Starter Kit, so they’re in your project already.

Set upWhat this chapter adds
ART (sprites, from the starter kit)
MG Round Art
FX Spark
HUD Bottom Bar Art
Power Pip Art
SOUNDS (from the starter kit)
Fighter Gunfire
COMMANDS (Game Settings > Input Manager)
FireButton
KeybindingsSpace, J
GLOBAL VARIABLES
$gunLevelNumberstarts at 1
SCENE Gameplay: PLACE THESE
ObjectXY
HUD Bottom Bar095
Power Pip-6886
Power Pip-3286
with Per Instance Variables > Level = 2
Power Pip486
with Per Instance Variables > Level = 3
Power Pip4086
with Per Instance Variables > Level = 4

Start with the trigger, the card’s COMMANDS block. Open the Game Settings and choose Input Manager, where you renamed Fly in Chapter 1. Press Add Command, and Myth Engine asks for a Command Name. Type Fire. Its Input Type is already Button, so leave it, and press Add Command again to make it.

Fire arrives with one empty row that reads No Input Assigned. Click it, then press Space. The row shows Space. Add Keybinding gives Fire a second row, so click its No Input Assigned too, and press J. Making what a card shows has these steps too, under The Set up card.

Next on the card is GLOBAL VARIABLES, the gun level. It waits a few minutes. A Global Variable is made on a Logic Component’s canvas, and any Logic Component will do. The game keeps the Global, not that Logic. So you’ll make it in the first one you build here, Remove When Out of View.

PLACE THESE puts the bottom bar and its four pips on the screen. They come last, once they exist.

2.4 The Rounds

First, the thing the guns fire.

An MG Round is a short gold slug, rounded at the tip. Its picture is 3 meters across, like the Fighter’s, and most of it is empty. The Collider is the slug alone, a quarter of a meter wide and three-quarters long. When enemies arrive in Chapter 3, only that small box can hit them.

Its Collision is Sensor. A Sensor notices what it overlaps, but it never blocks anything. Nothing holds a round in at the edge of the world, so it can fly out of the window. The Scene Depth Draw Order is 35, a little above the Fighter’s 30, so a round leaving the guns passes over the Fighter’s nose.

Make it the way you made the Fighter, as a 2D Object. It comes with its Collider but no Sprite, so attach one from Rendering. This time, leave the Physics Object switch on. Leave its Logic for now, too, because its Logic Component comes next.

ObjectMG Round
Transform
Bounding Box > SizeX 3, Y 3
Sprite
Scene Depth Draw Order35
SpriteMG Round Art
Transform > SizeX 3, Y 3
Collider
CollisionSensor
Shape and Transform > SizeX 0.25, Y 0.75
Logic
Remove When Out of View

You won’t see a round for a while. The guns need their table, their Function and their trigger first. Keep going. Once the trigger is in, you’ll hold Space, and there they’ll be.

2.4.1 Remove When Out of View

A round that leaves the top of the window doesn’t stop there. It flies on through the empty world above, and the game keeps moving it, step after step. Fire for a minute, and more than a thousand rounds would be up there, climbing forever. Nobody would see them. The game would still carry every one.

Remove When Out of View is the cleanup. Its Event, When Leaving the View, runs once, at the moment its Object leaves the window. Its one Action removes that Object for good. You may have met this card already, on the Making page.

Make it with Add > Logic Component, and leave its Starter on Empty Logic Component. Then give it its Event.

Press Add Event, the + in the canvas’s toolbar, and Myth lists every kind of Event, with a filter at the top. Type Leave View there, the kind on the card’s When bar. Pick it and press OK. Events: the When bars has more on that list.

A green block lands on the canvas, Leave View, with Mode 1 beside it and End below. The card’s heading, When Leaving the View, is the name Myth gives that Event. They’re the same Event.

Now its one Action. The Action List on the right holds every Action, in groups that start closed. So type Destroy Instance into the search box at its top, and click it. It’s the book’s first Action. Watch where it lands.

The new block sits beside the line, with no arrow running to it, and a block like that does nothing. Right-click it and choose Connect to sequence. An arrow runs to it from Mode 1, and it reads Destroy Instance on Self. Actions, one at a time shows the rest of the canvas.

Logic ComponentRemove When Out of ViewAttach to: MG Round

Removes this Object once it has left the view, so nothing that has flown away keeps costing time.

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

While it’s open, make the gun level. Down the left of the canvas sits a small card named Globals. Press the + on it and choose New Global…. The window’s Type is already Number, so give it the Name gunLevel and the Default 1, and press Add. The $ on the card isn’t part of the name. Every piece of Logic in your game can read it now.

Last, open MG Round, switch the list to Logic, and attach Remove When Out of View. Every round will clean up after itself now, and nobody playing Sky Ace will ever see it happen.

2.5 The Gun Patterns

Next, where each round comes out.

Look down at the Fighter from above. At gun level 1, two rounds leave the nose side by side, a little more than half a meter apart. Level 2 has three, one in the middle and one to each side. Level 3 has four, spread wider. Level 4 keeps those four and adds a gun near each wingtip. Those two lean a few degrees outward.

Every one of those rounds is a row in Gun Patterns, and a row has four numbers. The gunLevel column says which level the round belongs to. Next, offsetX says how far left or right of the Fighter’s middle it appears, in meters. Left is below 0. The offsetY column says how far ahead of the middle, and it’s 1.375 in every row, the nose. Last, direction says which way the round flies, in degrees.

Directions count from pointing right, and they turn counterclockwise as the number grows. So straight up is 90. The two wing rounds have 98 and 82. The left one leans a little to the left, and the right one a little to the right. Each leans out past its own wing.

A Data Table card shows how to make the table. Make it first. It makes its own Data Structure, Gun Patterns Entry, and that’s the next card. Its four fields are the table’s four columns. The grid’s Entry column is a different thing. It’s where each row’s name goes: Level 1 Left, Level 1 Right, and so on.

A new table has no rows, so you’ll add all fifteen with Add Row. That looks like a lot of typing. But most of it types itself. Give Gun Patterns Entry its four fields first, each with the default on its card, and each new row starts with all four. After that, most rows need only a gunLevel and an offsetX. Two need a direction too. On the table’s card, every offsetY is the default, and so is every direction but those two. Your eyes can skip those lines.

Data StructureGun Patterns Entry

One row of the "Gun Patterns" Data Table.

gunLevelNumberdefault 1
offsetXNumberdefault 0
offsetYNumberdefault 1.375
directionNumberdefault 90
Data TableGun PatternsData Structure: Gun Patterns Entry
Row 0Level 1 Left
gunLevel1
offsetX-0.28125
offsetY1.375
direction90
Row 1Level 1 Right
gunLevel1
offsetX0.28125
offsetY1.375
direction90
Row 2Level 2 Left
gunLevel2
offsetX-0.5
offsetY1.375
direction90
Row 3Level 2 Middle
gunLevel2
offsetX0
offsetY1.375
direction90
Row 4Level 2 Right
gunLevel2
offsetX0.5
offsetY1.375
direction90
Row 5Level 3 Outer Left
gunLevel3
offsetX-0.6875
offsetY1.375
direction90
Row 6Level 3 Inner Left
gunLevel3
offsetX-0.25
offsetY1.375
direction90
Row 7Level 3 Inner Right
gunLevel3
offsetX0.25
offsetY1.375
direction90
Row 8Level 3 Outer Right
gunLevel3
offsetX0.6875
offsetY1.375
direction90
Row 9Level 4 Wing Left
gunLevel4
offsetX-1.125
offsetY1.375
direction98
Row 10Level 4 Outer Left
gunLevel4
offsetX-0.6875
offsetY1.375
direction90
Row 11Level 4 Inner Left
gunLevel4
offsetX-0.25
offsetY1.375
direction90
Row 12Level 4 Inner Right
gunLevel4
offsetX0.25
offsetY1.375
direction90
Row 13Level 4 Outer Right
gunLevel4
offsetX0.6875
offsetY1.375
direction90
Row 14Level 4 Wing Right
gunLevel4
offsetX1.125
offsetY1.375
direction82

Fifteen rows, four gun levels. The guns will only ever use one level’s rows at a time.

2.6 One Volley

Now the Function that reads the table.

2.6.1 Fire a Volley

Fire a Volley fires one volley, and then it’s done, though Fighter Guns will ask for another about nine times a second. It goes down Gun Patterns one row at a time, and at each row it asks one question. Is this row’s gunLevel the gun level now? If it is, a round appears at the row’s place, turns to the row’s direction, and flies off. If not, nothing happens. After the last row, the volley is complete.

So the Function is a Repeat with an If inside it. A Repeat runs the Actions in its panel a set number of times, its Count. Here the Count is dataCount("Gun Patterns"), the number of rows in the table. Each time round, local.index says which row it’s on, counting from 0, the way the card numbers the rows. And data("Gun Patterns", local.index, "gunLevel") reads one cell: table, row, column.

The If compares that cell with $gunLevel. When they match, three Actions run. First, Create Instance makes the round, from Caller, the Fighter. Caller is its Applies To.

Its Position Relative To list has two choices, World and Self, and here it’s Self. This Self isn’t a Parameter. It means the Object in Applies To. So the row’s X and Y count from the Fighter’s middle, wherever it has flown.

The next two Actions work on created, the new round. Set Direction turns it. Set Speed sends it off. Myth aims both at created as soon as you add them, so there’s nothing to pick there.

The PARAMETERS are what the Function needs from whoever calls it. Caller is the Object that fires, round is the round it fires, and speed is how fast it flies. The round Parameter asks only for a Transform. That’s the Required Components line under it. Every Object has a Transform, so any Object at all could be fired from here.

This card holds the chapter’s hardest idea, so take it one block at a time. Make it with Add > Function, and give it the card’s name. Then begin on its Start block, with the + beside Parameters. A Function card shows how to make Caller, and round starts the same way. Each is the last Object in the Type list. Type its name in the window’s Name box, and the row keeps it.

Both come with Structural already chosen. Caller needs nothing more, which is why its line on the card stops there. Each row of the Start block has a small pencil. Press round’s, then Add Required Component, and pick Transform in the new row’s Component Type. Its Slot Name fills itself in. The speed Parameter is a Number, at the top of the Type list. Give it the card’s name and Default in the window.

There’s one more Object in the Type list, higher up, among the plain values. That one is another kind. It holds an Object’s name as a plain value, like a number or a word. Fighter Guns uses it in a moment.

Then the blocks. The Repeat’s Count is a box on the Repeat block itself, under its name, and it starts at 1. Type the card’s count over it. If, Else, Repeat and While shows how the panels fill, and local.index goes in exactly as the card spells it.

Create Instance’s Applies To is a list on its block. A Function has no self, so that list holds only its Object Parameters, and it starts on the first one. It reads Caller already.

FunctionFire a Volley

Fires one machine-gun volley: a round for each Gun Patterns row of the current gun level, at that row's place and direction.

PARAMETERS
NameTypeStarts at
CallerObject
roundObjectStructural
Required Components
Slot Nametransform
Component TypeTransform
speedNumber32.813
ACTIONS
1RepeatdataCount("Gun Patterns")times
Each time
2Ifdata("Gun Patterns", local.index, "gunLevel") == $gunLevel
Then
3Create Instance
Applies To
Caller
Object to Create
round
Position Relative To
Self
X
data("Gun Patterns", local.index, "offsetX")
Y
data("Gun Patterns", local.index, "offsetY")
4Set Direction
Applies To
created
Direction
data("Gun Patterns", local.index, "direction")
5Set Speed
Applies To
created
Speed
speed

Why a Function, when Fighter Guns could hold these Actions itself? Because a volley is a job worth naming, and more than one gun will want it. In Chapter 8, Rapid Guns fires its volleys through this same Function, only faster.

2.7 Pulling the Trigger

Now the trigger.

The Muzzle Flash is six tiny sparks thrown upward from the nose, each one white, gold or orange. They’re small and quick, so in the game they read as one bright spark at the nose. In about a tenth of a second they’re gone. A Particle Effect card shows its three pages, and where each of its lines goes.

Two of its lines may puzzle you. Emit Every (ms) is for an effect that sprays all the time, and this one never does. It only bursts, when Fighter Guns asks. So type its 0, and let the reading under the box go by. Thousands of particles a second is what it would pour out if it ever ran on its own. Starting Rotation holds one switch, Random Spin. Turn it on, and each spark starts at an angle of its own.

Particle EffectMuzzle Flash
Emitter
Emission > Emit Every (ms)0
Emission > Burst Count6
Emitter Shape > Emit Shapepoint
Motion
Lifecycle > Each Particle Lives (ms)min 50, max 120
Motion > Speed (m/s)min 0.938, max 3.75
Motion > Angle (Deg)min 70, max 110
Appearance
Appearance > Particle SpriteFX Spark
Appearance > Color SourceMultiple Colors
Appearance > Multiple Colors#FFFBE0, #FFD166, #FF9F43
Appearance > Glow1.3
Appearance Over Life > Scalestart 0.55, end 0
Appearance Over Life > Starting RotationRandom Spin On

2.7.1 Fighter Guns

Hold Space, and Fighter Guns wakes up at every step of the game’s clock. On most of those steps, it does nothing at all.

Make it the way you made Remove When Out of View, with its SHARED VARIABLES first, because its blocks read them. Each is a value the Fighter keeps for these guns. Press the + on the canvas’s Shared Variables card once for each row. The window’s Kind starts on Changeable, so pick Constant, as the card has it. A Logic Component card shows the rest.

Four rows are Numbers. The first, round, is the round these guns fire, so its Type is Object. Its Starting Value stays at None, as on the card. The Fighter picks its own round, in a moment.

The roundSpeed of 32.813 is more than three times as fast as the Fighter flies. A round crosses the whole window in less than a second.

Now the Event. While Fire Is Held is a Command Held Event, and it runs at every step for as long as Fire is held down. When you add it, Myth Engine asks next which Command. Pick Fire, and press OK.

At each step, Fighter Guns first asks the fireRate cooldown whether it has run down. Check Cooldown Ready hands back the answer as machineGunsReady. That name goes in the block’s Action Name, its last box, after the word as. Type it over the name of Myth’s that waits there.

Next, an If looks at machineGunsReady.value. True means fire. When it’s false, the step ends there, and the guns wait for the next one. Type the card’s condition whole into the If’s one box.

Firing takes four Actions, in order. Start Cooldown winds the fireRate stopwatch back up, for @self.fireRateSeconds. Control Sound plays Fighter Gunfire. Burst Particles throws a Muzzle Flash at muzzleFlashY, which is 1.375 meters up from the Fighter’s middle. That’s the nose. Last comes the Function call. It asks Fire a Volley for one volley, with self as the Caller.

On the call’s block, the fields are Fire a Volley’s Parameters, by the names you gave them: Caller, round and speed. Caller starts on self, as the card has it, and speed is a box for @self.roundSpeed.

The call’s round is a list. It holds self and the Variables that Fighter Guns keeps for an Object. Pick @self.round there, the Fighter’s own round.

Burst Particles has two more lines. A Z Index Offset of 2 puts the sparks in front of the Fighter. And its Count, muzzleFlashCount, says how many sparks fly. When that box holds a value, it wins over the effect’s own Burst Count. Both say 6 here, so they agree.

The name fireRate is one you make up. Type it bare in both Cooldown Key boxes, as the card gives it, and the block draws it between quote marks. Check Cooldown Ready and Start Cooldown must spell it the same way, or they’d be two different stopwatches. The sound and the particle effect are lists, so pick Fighter Gunfire and Muzzle Flash there.

Logic ComponentFighter GunsAttach to: Fighter

While Fire is held, fires a machine-gun volley each time the fireRate cooldown is ready: the rounds of the Gun Patterns rows for the current gun level.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
roundObjectConstantNone
roundSpeedNumberConstant32.813
fireRateSecondsNumberConstant0.11
muzzleFlashCountNumberConstant6
muzzleFlashYNumberConstant1.375
While Fire Is Held
WhenCommand HeldCommand: Fire
1Check Cooldown Ready
Action Name
machineGunsReady
Cooldown Key
fireRate
2IfmachineGunsReady.value == true
Then
3Start Cooldown
Cooldown Key
fireRate
Seconds
@self.fireRateSeconds
4Control Sound
Sound
"Fighter Gunfire"
5Burst Particles
Particles
"Muzzle Flash"
Y
@self.muzzleFlashY
Count
@self.muzzleFlashCount
Z Index Offset
2
6Fire a VolleyFunction
caller
self
round
@self.round
speed
@self.roundSpeed

Now give the Fighter its guns. This is a Changes card. Everything on it is there already, except the green lines. Attach Fighter Guns. Then switch the list back to Components. Under Shared Variables, round’s Value is a button that reads None. Press it and pick MG Round, the round these guns fire. Changes cards explains the marks.

ObjectFighterAddDelete
Transform
Bounding Box > SizeX 3, Y 3
Physics > Physics ObjectOff
Sprite
Scene Depth Draw Order30
SpriteFighter Art
Transform > SizeX 3, Y 3
Collider
Shape and Transform > PositionX 0, Y -0.094
Shape and Transform > SizeX 0.656, Y 0.75
Tags and Interactions > InteractionsCollide Only With
Logic
Top-down Controls
Keep Inside Box
Fighter Guns
Shared Variables
moveSpeed10.313
minimumX1.313
maximumX21.188
minimumY7.188
maximumY30
roundMG Round

Before you play, save your project with Ctrl+S, as at the end of each part. Play runs whatever the editor holds, and it doesn’t save for you. Then press Play, and remember that Alt+F4 brings you back. Hold Space.

Gold rounds climb the window two by two, with a spark at the nose and the rattle of the guns. Let go, and they stop. That’s your Fighter, firing.

2.8 The Power Pips

Last, the bar along the bottom of the window.

The HUD Bottom Bar is a dark strip as wide as the window, edged in thin gold. It sits on the screen, like the frame, and the sea slides under it. A Power Pip is a small bar of orange light, 30 by 10 pixels, and four of them sit inside the bar, one for each gun level. They light up from left to right.

Both are screen Objects. Make them the way you made the Screen Frame in Chapter 1, as an Empty Object with Space Window / UI first. Their Screen Anchor is Bottom Center, the middle of the screen’s bottom edge. The pip’s Scene Depth Draw Order of 102 is above the bar’s 100, so each pip is drawn on the bar.

The pip’s card ends with its Logic, Show Gun Level, which you haven’t made yet. Leave it for now. It comes right after the pip’s own Function, Show Pip For Gun Level.

ObjectHUD Bottom Bar
Transform
Presentation > SpaceWindow / UI
Presentation > Screen AnchorBottom Center
Presentation > Render LayerUI
Bounding Box > SizeX 128, Y 128
Sprite
Scene Depth Draw Order100
SpriteHUD Bottom Bar Art
Transform > SizeX 720, Y 70
ObjectPower Pip
Transform
Presentation > SpaceWindow / UI
Presentation > Screen AnchorBottom Center
Presentation > Render LayerUI
Bounding Box > SizeX 128, Y 128
Sprite
Scene Depth Draw Order102
SpritePower Pip Art
Transform > SizeX 30, Y 10
Logic
Show Gun Level

One Power Pip Object makes all four pips. You’ll place it four times. Each placement says which gun level it stands for, and two pieces of Logic do the rest.

2.8.1 Show Pip For Gun Level

Show Pip For Gun Level is one question with two answers. Is the gun level at least this pip’s level? Then show the pip. If not, hide it.

Watch what at least does when the gun level is 3. Pips 1, 2 and 3 all pass, and pip 4 stays dark. So the pips fill from the left, one by one, as the level climbs. The Making page uses this very card as its example of a Function, so you may know it already.

Its Otherwise is the book’s first Else, the Actions for when the answer is no. Right-click the If, and choose Add Else. Its passage If, Else, Repeat and While, on the Making page, shows what comes next.

FunctionShow Pip For Gun Level

Shows the pip while the gun level is at least the pip's level, and hides it otherwise.

PARAMETERS
NameTypeStarts at
CallerObject
levelNumber1
ACTIONS
1If$gunLevel >= level
Then
2Set Visible
Applies To
Caller
Visible
true
3Otherwise
4Set Visible
Applies To
Caller
Visible
false

2.8.2 Show Gun Level

Show Gun Level decides when to ask. Its first Event runs once, When Created, as the pip appears. The second, On Variable Changed · Gun Level, is a Variable Changed Event, which runs by itself at the end of any step in which $gunLevel changed. When you add it, Myth Engine asks which Global Variable. Pick gunLevel, and press OK.

So a pip never checks the gun level step after step. It waits for a change, and then it answers once. Both Events call the same Function, with this pip as the Caller and its own level.

That level is the card’s PER INSTANCE VARIABLES. Each pip keeps its own. Press the + on the canvas’s Per Instance Variables card, and give it the card’s Name, Type and Starting Value. In each call, Caller starts on self already, and the level box takes self.level.

This is the book’s first Logic Component with two Events. Both sit on the one canvas, each with its own line, from its own Mode 1 down to its own End. Add the second with the toolbar’s + too.

Logic ComponentShow Gun LevelAttach to: Power Pip

Shows this power pip while the gun level is at least its level (1 to 4).

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
levelNumber1
When Created
WhenCreate
1Show Pip For Gun LevelFunction
caller
self
level
self.level
On Variable Changed · Gun Level
WhenVariable ChangedGlobal Variable: gunLevel
1Show Pip For Gun LevelFunction
caller
self
level
self.level

Attach Show Gun Level to Power Pip.

Now place them, from PLACE THESE on the Set up card at the top of this chapter. Drag HUD Bottom Bar onto the Scene, and type X 0 and Y 95 into its Screen Offset (px). That’s the middle of the screen, 95 pixels up from the bottom.

Next, drag in Power Pip four times, and give each one the X and Y on its row. All four have Y 86.

The line under three of the rows, such as with Per Instance Variables > Level = 2, is that placement’s own level. The first pip has none, because 1 is where Level starts. Select the placement, and find Logic near the bottom of its Properties. In Show Gun Level’s section, under Per Instance Variables, type the line’s value into the Level box. The section then counts it, 1 override. A placement’s own values has more on these lines.

Run the game. The bar sits across the bottom of the window, and one small pip glows in it. The other three are waiting for Chapter 8.

Play it!

Watch for each of these.

  • The bar runs across the bottom of the window, dark with a thin gold edge, and one orange pip glows in it, left of the middle.
  • Hold Space. Two gold rounds leave the nose side by side, and the guns rattle.
  • A small spark flashes at the nose with every pair.
  • The pairs come about nine to a second, evenly spaced, a ladder of gold up the window.
  • A round crosses the whole window in less than a second, and disappears under the frame at the top.
  • Let go of Space. The firing stops at once, and the last rounds fly on out of sight.
  • Fly while you hold Space. New rounds always leave from the nose, wherever the Fighter goes.
  • Hold J instead. It fires as well.
  • Press Alt+F4, and you’re back in the editor.
How it works

Space is held, and a cooldown keeps the beat. Fire a Volley reads the table and fires the rows of one gun level. Rounds that leave the window are removed, and the pips wait for the gun level to change.

Underneath it all is one idea. The shape of every volley lives in a table. Fire a Volley doesn’t know what level 4 looks like, only how to read a row. Change a row in Gun Patterns, and the volley changes with it, while the Logic stays exactly as it is.

2.9 If It Didn’t Work

Something may be a little off the first time. That’s normal. This chapter has the book’s first blocks, and every one of them has to be joined. Run the game, watch what it does, and think it through one piece at a time.

Holding Space does nothing at all? Perhaps a block never joined the line. Look for a block with no arrow into it on the canvases of Fighter Guns and Fire a Volley, and join it with Connect to sequence. Check, too, that Fighter Guns is in the Fighter’s Attached Logic, and that its Event’s Command is Fire. Then read the If’s condition in Fighter Guns against the card.

A red block, and a number on the Errors bar? Look at the names. A Cooldown Key takes fireRate bare, and the block adds its own quote marks. The word true needs none. A name with @self. in front, such as @self.fireRateSeconds, has to be one of the Shared Variables, spelled the same way.

The next questions wait for your call. The spark and the gunfire come, but no rounds? So Fighter Guns works, and the trouble is in Fire a Volley. Is the gun level’s Default 1? Do the first two rows of Gun Patterns have gunLevel 1? Is Create Instance’s Object to Create round, and the call’s round @self.round?

The rounds appear and hang in the air? Look at Set Speed. Its Applies To should be created, and its Speed should be speed.

One solid gold stream, with no gaps? Nothing is holding the guns back between volleys, so look at the cooldown. Start Cooldown may be missing from the If, or its key may be spelled differently from Check Cooldown Ready’s. Both Cooldown Key boxes should read fireRate, with the same capital R.

The rounds fly sideways or backward? The direction column’s default is probably not 90. Set it, and fix the rows that took the old one.

The rounds come out of the Fighter’s middle? Look at the offsetY column first: every row should have 1.375, the nose, and a 0 there puts the rounds in the middle. Create Instance’s Position Relative To should be Self as well.

All four pips are lit? Perhaps each pip’s Level box, under Logic, still holds 1, where it starts. Give them 1, 2, 3 and 4, from left to right. Or perhaps Show Gun Level isn’t attached to Power Pip, so nothing ever hides a pip.

No pip at all? Look at the first Set Visible in Show Pip For Gun Level. Its Visible should say true, and false or Yes there hides every pip.

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

Challenge

The table is yours to play with. One thing first: Chapter 3 starts from the card’s table and a gun level of 1. So note what you change, and put it back before you go on. Or start Chapter 3 from this chapter’s catch-up download.

Set the gun level’s Default to 4, and fly. Six rounds fan out, the outer two leaning away, and all four pips glow. Try 2 and 3 as well.

Then give the Fighter a gun of your own. Add a row to Gun Patterns for gun level 1 that fires from behind the Fighter, straight back down the screen. Directions count from pointing right, turning counterclockwise as they grow, and 90 is straight up. So which one is straight down?

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

Your Fighter fires now, and there’s nothing in the sky to hit. In Chapter 3, the Zero Fighters come.