- Learn
- Build a Game
- Pitch Shot
- 1 A Stage Stands
1 A Stage Stands
By the end of this chapter, Sunny Meadow fills your window. A golden slingshot stands in a tree stump on the left. On the right, a wooden tower three floors high holds two smiling golden notes, bobbing gently, waiting to sing.
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. Unzip it first. Then open it and compare, or start Chapter 2 from it.
To open it, right-click the downloaded file, choose Extract All... and then Extract. Start Myth Engine, choose File › Open Project... and pick the .mythproj file in the new folder. Nunito-OFL.txt beside it comes with the game.
1.1 The Idea
A meadow lies under a bright blue sky. Soft clouds drift over green hills, a river winds down to a lake, and the sun hangs high on the right. On the left, a gold tuning fork stands in a tree stump, with a red band stretched between its prongs. That’s the slingshot.
On the right stands a tower of wooden posts and planks. Two round golden notes with happy faces wait inside it, one above the other. They bob gently, each on its own beat.
Nothing sings yet. That’s Chapter 2. This chapter builds the stage they’ll sing on.
Pitch Shot has 120 stages. Each one has its own towers, its own floors of wood, stone or ice, and its own singing notes. Placing all of that by hand would mean thousands of posts and planks, one at a time. So nobody places them. When a stage begins, the game builds it.
A stage is one puzzle: its towers and its notes. Each stage belongs to a place, one of twelve painted backdrops, from Sunny Meadow to Moonlit Castle.
A tower is built of floors, from the ground up. Each floor is two supports, one at each side, with a plank laid across their tops. Posts, cubes and planks are all blocks.
How does the game know what to build? It reads the stage’s plan from tables, the way a pianist reads sheet music. The sheet makes no sound. It only says which notes, in what order. The pianist plays them. Here the tables say which towers stand, how many floors each one has, what every floor is made of, and which notes sit where. One piece of Logic reads them and builds the stage.
One part of the plan matters more than all the rest. A singing note’s height isn’t written anywhere. It follows from its pitch, how high or low the note sings. The higher a note sings, the higher it sits in its tower.
That’s the whole game in one rule. When you hear that the call is higher than a note, you aim higher. In this chapter you’ll see the notes sit, one above the other. In Chapter 2, you’ll hear why.
1.2 The Plan
Here’s how this chapter’s pieces work together, as a chain of what happens when the game runs. Read each line from left to right, and know that a name in bold is a piece you’ll make.
- The Field starts -> the Backdrop reads the stage’s place from the Stages table -> Backdrop Of The Place finds that place in the Places table and shows its painting.
- The Field starts -> Build The Stage, on Game Rules, reads the stage’s row of Stages. For each floor of each tower -> Build A Floor reads the floor’s material -> Place A Block makes each support and each plank.
- For each note of the stage -> Where A Note Sits works out its spot from its pitch -> Build The Stage makes a Singing Note there.
- A Singing Note is made -> Bob While Waiting sets it bobbing.
You’ll build them in an order that shows you something early. The meadow comes first, then the slingshot.
After that comes the quiet stretch of this chapter: the blocks, the tables and three Functions. Nothing new shows on the screen while you make them. It ends all at once, when Build The Stage goes in and the tower stands up.
1.3 Set Up
Every game starts as an empty project. The first time, an empty project is a strange thing to look at: a dark editor, a lot of buttons, and no game anywhere. It fills up faster than you’d think.
If you haven’t yet, read Before your first card, the first passage of Making what a card shows. It shows where things are in the editor. This chapter goes down its own Set up card with you, one block at a time.
In Myth, choose File > New Project…. The window that opens asks you to Choose a Starter. Pick Blank 2D. On the right, the Project Name box offers a name of its own, so type Pitch Shot over it. Myth makes a folder of that name inside the Location below it, and Browse… picks another place. Press Create Project. Your new project opens, with its one Scene in a tab.
Next comes the Starter Kit. Download it with this button.
To install it, open Myth Engine, choose File › Install Myth Pack... and pick the downloaded file.
Install it the way the line under the button says. Myth shows the Pitch Shot Starter Kit and what it adds: Adds 130 resources to this project. Press Install. Every picture and every sound in Pitch Shot is in your project now, and the font Nunito too. There’s nothing to draw.
Save as you go, with File > Save or Ctrl+S.
Here’s the whole card. The paragraphs after it go down it from the top.
100Pitch Shot144081019201080Smooth TexturesMSAA (Hardware)Myth Rigid Body-9.8#8FD3FFField · 2DART names the nineteen pictures this chapter uses: the twelve places, the slingshot, five kinds of block and the singing note. The kit brought all of them.
GLOBAL VARIABLES has one line. $stage is the number of the stage being played, and it starts at 1, the first stage in Sunny Meadow. A Global is made from a Logic Component’s canvas, so this one waits for your first Logic Component, a little later in the chapter.
Now the Game Settings. Press Game Settings, the button at the top of the Resources panel, and they open in a tab of their own. Go down the card’s GAME SETTINGS lines in its order, top to bottom. Here the order matters once, and the next paragraph says why.
Start in General, under World Scale. Pixels per Meter says 32, so type 100 over it. Myth measures your game’s world in meters, and this says how many pixels of the screen one meter takes. At 100, a Wood Post 1.12 meters tall stands 112 pixels high.
Do it before Reference Size’s Y. When you enter its Y, Myth works out how tall the screen is in meters, at the Pixels per Meter it has that moment. 1080 pixels at 100 to the meter is 10.8 meters, and everything in the Field is placed inside those 10.8 meters. Typed the other way round, the screen would come out 33.75 meters tall, and what you place would sit out of sight.
Choose Display next. In the Window group, the Title says My Game, so type Pitch Shot over it. That’s the name on your game’s window. For Initial Window Size, type 1440 into X and 810 into Y, replacing Automatic. That’s the window your game opens in.
Below, Reference Resolution holds Reference Size. Its X and Y show Default · 1024 logical px and Default · 768 logical px. Type 1920 and 1080. That’s the screen your game is laid out on, a wide one. Myth scales it to fit whatever window shows it, so the 1440 by 810 window shows all of it, a quarter smaller.
Under Rendering, Texture Filtering starts on Pixel-Art (Crisp). Pick Smooth Textures, so the painted places stay soft as they’re scaled. Anti Aliasing starts Off. Pick MSAA (Hardware), and the graphics card smooths jagged edges.
Last, choose Physics. Under Runtime, pick Myth Rigid Body in the Physics Engine list. Under Gravity, Y starts at 0, so type -9.8 to give the game a downward pull. Nothing falls in this chapter. In Chapter 4 the happy note does, and in Chapter 6 the towers come down.
There’s no OK to press here, because each change holds the moment you make it.
The SCENE block is next. Your project already has one Scene, named Scene. The card calls it Field and marks it new, but you don’t need a second one. In the Resources panel, open Scenes, right-click Scene and choose Rename “Scene”. Type Field and press Enter.
Now give the Field its own color, the light blue of a summer sky. Click its tab, the one New Project opened. Pick Select, the arrow above the preview, and click an empty spot. The Scene’s Properties appear on the left. Click the Background Color swatch, and type 8FD3FF into the HEX box. The # is there already. Press Enter, and a second click on the swatch closes the picker.
Start Scene is back in the Game Settings, under General, and it says Field · 2D already. It followed the rename.
Run the game once now. Press Play, the triangle at the top of the editor. A window of its own opens, called Pitch Shot, and it’s sky blue. That’s all there is, so far. Close it.
PLACE THESE waits until each Object exists, and the chapter comes back to it as each one is made.
1.4 Twelve Places
The world starts with its painting.
The Backdrop is one Object that can show any of the twelve places. Like most Objects in this chapter, it’s an Empty Object. Make it with Add > Object. Type Backdrop as its Name, pick Empty Object as its Object Type, and press Create.
X 19.6, Y 11.02Backdrop Sunny MeadowX 19.6, Y 11.02Give it its picture the way An Object card and its components shows: a Sprite, with Backdrop Sunny Meadow picked in the Add Sprite Component window. Then type its two sizes, 19.6 by 11.02, into the Bounding Box and into the Sprite’s own Transform. The screen is 19.2 meters wide and 10.8 tall, so the painting is a little bigger than the screen all round.
Leave the Logic at the bottom of the card for now. It comes after two tables it needs.
Now place it. Open the Field. Drag the Backdrop from Predefined Objects onto the Scene, and type X 9.6 and Y 5.4 into its World Position. That’s the middle of the screen.
Run the game. Sunny Meadow fills the window, from the hills to the lake and the sun.
It’s the right place for stage 1. But stage 11 is on a beach, and the Backdrop doesn’t know that yet. The place of each stage comes from the stage’s plan.
1.4.1 The Stages Table
Every stage is one row of the Stages table, all 120 of them, in the order they’re played. Its first row is stage 1, Low and high, in Sunny Meadow. A row says the stage’s place and name, and where its towers and notes are found in the other tables. Those come later, with the towers.
The shape of a row is a Data Structure, Stage. Make it first, as A Data Structure card shows. Its place and name are Text, so clear the 0 each one keeps, and the other five are Numbers.
One stage: its place, its name, how far apart its notes sit, and where its towers and singing notes are in the Tower Plans and Notes tables.
Then make the Stages table, as A Data Table card shows, and pick Stage in its Entry Type. 120 rows is a lot to type, so the card gives them as a file. Download pitch-shot-stages.csv from its File line, and bring it in with Import CSV. Your first three rows should match the card’s.
Sunny MeadowLow and high120102Sunny MeadowHilltop echo61122Sunny MeadowTwo voices1221421.4.2 The Places Table
The Places table pairs each place’s name with its painting. Its shape is the Data Structure Place: a name, and a backdrop.
One place: its name and its backdrop.
The name is Text, so clear its 0. The backdrop is new. It holds a picture of your project, by name, and the card calls its type Thing Sprite. A Thing is a resource of your project. In the field’s Type list, the types come in groups: Number and Text are under Values, at the top, and Sprite is further down, under Things. Pick it there. Its Value starts at None, the card’s default.
Sunny MeadowBackdrop Sunny MeadowSeaside BeachBackdrop Seaside BeachAutumn WoodsBackdrop Autumn WoodsRed Rock CanyonBackdrop Red Rock CanyonCandy HillsBackdrop Candy HillsSnowy PeaksBackdrop Snowy PeaksJungle FallsBackdrop Jungle FallsPirate CoveBackdrop Pirate CoveMushroom GroveBackdrop Mushroom GroveVolcano IsleBackdrop Volcano IsleCloud KingdomBackdrop Cloud KingdomMoonlit CastleBackdrop Moonlit CastleMake the Places table with Place as its Entry Type, and add its twelve rows by hand. Each row’s own name is Place 1 to Place 12, in the grid’s Entry column. Its name cell is the place’s name, spelled exactly as the Stages table spells it, capitals and all. Its backdrop cell is a list of your pictures, so pick the card’s there.
1.4.3 Backdrop Of The Place
Picture the Field starting. The Backdrop asks two questions. Which place is the stage being played in, and which painting goes with that place? Then it puts that painting on.
The first answer is one cell of the Stages table. data("Stages", $stage - 1, "place") reads the row for this stage, in the place column. Why $stage - 1? The table counts its rows from 0, and the game counts its stages from 1. So stage 1 is row 0.
The second answer takes a search. dataFind("Places", "name", ...) looks down the Places table’s name column for that place, and gives back the number of its row. That number is placeRow, a value the Logic makes for this one moment with Declare Variable.
What if the place weren’t there at all? Check Data Row Exists asks the table whether it has that row, and its answer is placeFound. Only when placeFound.value is true does Set Sprite change the picture, to the backdrop in that row.
Shows the backdrop of the place of the stage being played: the Sprite its row of the Places table names.
Any Object- Name
placeRow- Value
0
- Variable
placeRow- Value
dataFind("Places", "name", data("Stages", $stage - 1, "place"))
- Action Name
placeFound- Table
Places- Row
placeRow
placeFound.value == true- Sprite
data("Places", placeRow, "backdrop")
It’s your first Logic Component, so read A Logic Component card as far as its DATA STRUCTURES paragraph, then make it with Add > Logic Component. This one needs nothing from its Object, so its card has no Data Structures and no Shared Variables. Leave Attach to as it starts.
Now $stage, while you’re here. Press the + on the Globals card, down the left side of the canvas, and choose New Global…. In the Add Global window, type stage as its Name, without the $. Leave its Type on Number, type 1 into its Default, and press Add. In formulas, you’ll always type the $.
Its Event is Create, and Events: the When bars shows how to add it. Then read Actions, one at a time as far as Declare Variable, and all of Values, quote marks and all. In If, Else, Repeat and Region, read the first three paragraphs, the ones about the If. Stop where the step numbers are counted, because the rest of that passage comes with Build A Floor.
Declare Variable makes placeRow, with 0 in its Value. Type placeRow into Change Variable’s Variable box, and the card’s formula into its Value. Once you leave the Variable box, it reads self.placeRow. That’s the same value, the one Declare Variable made. Name Check Data Row Exists’s answer placeFound, so the If can read it. Pick Places in its Table list, and type placeRow into Row. Set Sprite goes on the If’s True line, the part the card marks Then, with the card’s formula in its Sprite box.
When the card is in, look at the canvas. If every block has an arrow into it and no Errors bar shows under it, the piece of Logic is whole.
Open the Backdrop, switch the list at the top right from Components to Logic, and click Backdrop Of The Place under Logic Toolbox.
Run the game. Sunny Meadow, as before. Nothing seems to change, because stage 1 is in Sunny Meadow. The Challenge at the end of the chapter lets you see the other places.
1.5 The Slingshot and the Ground
Now the slingshot, standing in its stump.
X 1.52, Y 320Slingshot ArtX 1.52, Y 3Make it the way you made the Backdrop. One line is new. Scene Depth Draw Order says what’s drawn over what, and a higher number is drawn in front. The slingshot’s 20 puts it over the meadow, which has 0. Place it at X 3, Y 2.8.
Run the game. The golden fork stands in its tree stump on the grass, its red band hanging empty.
The grass and the soil are part of the painting, and a painting can’t hold anything up. The Ground is what’s really there. It’s an invisible box, 36 meters wide and 3 deep, with no picture at all.
X 36, Y 3OffX 36, Y 30.9This one has a Collider. So make it a 2D Object, which comes with one already attached. A Collider gives an Object a body, a shape that other things can touch. Its Size is in the Collider’s Shape and Transform section, and its Friction in its Physics section.
A 2D Object starts as a Physics Object, something bumps can move. The Ground must never move, so turn Physics Object off, in the Transform’s Physics section. A line ending in On or Off is a switch.
Place it at X 9.6, Y -0.2. Its middle is under the grass, so its top edge lands at 1.3 meters, right where the painted grass is.
Run the game, and nothing new shows. That’s right. Nothing touches the Ground yet. In Chapter 4, the happy note lands on it and rolls.
1.6 The Blocks
Now the stretch where nothing shows. It’s honest work all the same, because this is where the stage’s plan takes shape, block by block and table by table. Run the game whenever you like along the way. Until Build The Stage goes in, it stays the meadow and the slingshot, and that’s how it should be.
Five kinds of block build every tower in the game. Stage 1 uses only wood, but the plan names all five, so make all five now.
X 0.24, Y 1.12On0.35X 0.24, Y 1.120.040.75On30Wood Post ArtX 0.24, Y 1.12The Wood Post is a 2D Object, with its Collider and a Sprite, and its Scene Depth Draw Order of 30 draws it in front of the slingshot.
A block is a Physics Object, so one day it can fall. Its Transform’s Physics section holds how it will tumble: its Mass, Allow Rotation and its Spin Drag. The Collider’s Physics holds how it touches things. Those numbers wait for Chapter 6, when the right shot brings a tower down. Stone is heavy, with a Mass of 2.6 for a cube, and ice slides, with a Friction of only 0.2. The Wood Post shows no Mass, because it keeps the 1 it starts with.
The last line, Fixed (no editor field), is the one that matters most. In the game, a block is held where it’s made, so nothing can push it until the right shot sets it free. Myth Engine keeps that setting, but this version of the editor has no switch for it yet. So there’s nothing to set here. Nothing touches a block in this chapter, so your towers stand perfectly still all the same. Chapter 4, where the first shot flies, says what that means for them.
The other four are made the same way. Your hands know the steps now. From card to card, only the picture, the sizes and the Physics numbers change. Those are the lines to check.
X 2.36, Y 0.221.3On0.35X 2.36, Y 0.220.040.75On30Wood Plank ArtX 2.36, Y 0.22X 0.56, Y 0.562.6On0.5X 0.56, Y 0.560.020.85On30Stone Cube ArtX 0.56, Y 0.56X 2.36, Y 0.223On0.5X 2.36, Y 0.220.020.85On30Stone Plank ArtX 2.36, Y 0.22X 0.56, Y 0.560.7On0.2X 0.56, Y 0.560.080.2On30Ice Cube ArtX 0.56, Y 0.56None of them is placed in the Field, because Build The Stage makes every one.
1.7 The Plan of a Stage
Here is the sheet music. It’s five more tables, and each one leads to the next.
A stage’s row in Stages says where its towers start in Tower Plans, and how many there are. A tower’s row there says where it stands across the screen, and where its floors start in Floors. A floor’s row names its material, wood, stone or ice. Materials says which blocks a floor of that material is made of. Block Kinds says how big each block is. And Notes holds every singing note of every stage, with its pitch and its tower.
Take stage 1. Its row says one tower, from row 0 of Tower Plans, and two notes, from row 0 of Notes. That tower stands at 13.8 meters across, with three floors, all wood. Its notes are F3 and F4.
Make them in the order below. For one of them the order matters: Materials picks its blocks from a list of your Objects, so the blocks had to come first.
1.7.1 Block Kinds
Block Kinds is the example table in A Data Table card, so that passage walks you through it. Its rows are named for the five blocks, with each one’s width and height.
Type each row’s name exactly as its Object’s name, capitals and spaces too: Wood Post, not Wood post. Later, Build A Floor finds a block’s row by that name.
One kind of block: its size.
0.241.122.360.220.560.562.360.220.560.561.7.2 Materials
A material names three things: the block that holds a floor up at each side, how many of them stand one on another, and the block laid across. A wood floor is one Wood Post at each side, under a Wood Plank. A stone floor is two Stone Cubes at each side, under a Stone Plank.
One material: the blocks a floor of it is made of.
Two of Material’s fields hold an Object, the block itself. The card calls that type Thing Object. It’s a Thing, like Place’s backdrop, but an Object this time. Pick Object under Things in the Type list, for support and for plank. Its Value starts at None, the card’s default. Leave supportsHigh as a Number.
Wood Post1Wood PlankStone Cube2Stone PlankIce Cube2Wood PlankMake the Materials table and pick Material in its Entry Type. Add the three rows by hand, wood, stone and ice, all lowercase. The Floors file names its materials that way, so the names must match letter for letter. A support or plank cell is a list of your Objects, so pick the card’s block in it. That’s why the blocks came first. Notice that ice is held up by Ice Cubes, but its plank is a Wood Plank.
1.7.3 Floors
Every floor of every tower is one row of Floors, 925 of them. Each row has one field, material, and its name says which stage, tower and floor it is.
One floor of a tower: what it is made of.
woodwoodwoodMake the Floor Data Structure, then the Floors table, with Floor as its Entry Type. Import its file, pitch-shot-floors.csv, as you did the Stages.
1.7.4 Tower Plans
A tower’s row says where it stands across the screen, x, in meters, and which rows of Floors are its floors. Its roof names a material for two cubes on its top floor, or nothing at all. Stage 1’s tower has no roof, so its roof cell is empty.
One tower of a stage: where it stands, which rows of the Floors table are its floors, and its roof.
13.80313.43413.972Make the Tower Plan Data Structure and the Tower Plans table, and import pitch-shot-tower-plans.csv.
1.7.5 Notes
The last table holds the singing notes, 470 of them, every note of every stage.
A note has three fields. Its pitch is the name a musician would give it, such as F3. Its midi is the same note as a number, counted one piano key at a time, black keys too. F3 is 53. F4 is 65, twelve keys higher. That’s the same note, one octave up. Its tower says which tower of the stage it sits in, counting from 0.
One singing note of a stage: the pitch it sings and the tower it sits in.
F3530F4650F sharp3540Make Note Spot, then the Notes table with Note Spot as its Entry Type, and import pitch-shot-notes.csv.
The whole plan is in your project now, and when you run the game, none of it shows. It’s sheet music, waiting for someone to play it.
1.8 Building a Tower
Now the hands that build. Two small Functions do it, one inside the other. A Function is a small piece of Logic with one job, which other Logic calls by name. A Function card shows how to make one.
This part uses more kinds of Action than the Backdrop did. So go back to Actions, one at a time and read the rest of it, from Some Actions hand back an answer to the end. It covers answers, Functions and Create Instance.
1.8.1 Place A Block
The smallest job comes first. Place A Block makes one block, of the kind it’s told, at the spot it’s told.
Its kind is a new sort of Parameter. It doesn’t hold a number or a word. It holds an Object, such as Wood Post, and so does Material’s support field. That’s how one Create Instance can make every kind of block in the game. It makes whichever block kind names.
A Function has no Object of its own. But every Action works on some Object, Create Instance too. So whoever calls Place A Block hands it one, builder, and Create Instance runs on it. The block still appears at x and y, no matter where the builder stands. In this game, the builder is always Game Rules.
Creates one block of a tower: the block Object named kind, its middle at x, y (meters).
- Applies to
builder- Object to Create
kind- X
x- Y
y- Variable Name
newBlock
Make it with Add > Function. Its PARAMETERS go on its Start block, and the Add Parameter window’s Type list has Object in it twice.
- For builder, pick the Object at the very end of the list. That one is handed an Object itself.
- For kind, pick the Object under Things, the one the card calls Thing Object. Its Default is a list, and Wood Post is the card’s pick.
- The last two, x and y, are Numbers.
Now its one Action, Create Instance. Its Applies To is a list, so pick builder in it. Object to Create is a list too. Its last choice, From a Value (Variable, Data Table, Expression), turns it into a box. Type kind there. Then type x and y into X and Y, and newBlock into Variable Name.
1.8.2 Build A Floor
One floor is two supports and a plank. Build A Floor is handed the floor’s material, and it looks that material up in Materials.
The material names the support block, supportKind, and Block Kinds says how tall it is, supportHeight. Then it builds. First the left side: a Repeat stacks as many supports as the material’s supportsHigh, supportSpread to the left of the tower’s middle. On the right it does the same. Last of all, it lays the plank across the tops of the two supports.
Both lookups find a row by its name. data() takes a row’s number, counted from 0, or the name in its Entry column. Here material is wood, so data("Materials", material, "support") reads the wood row. That cell holds an Object, and it comes out as the Object’s name, Wood Post. So supportKind is a Text. The same name then finds the post’s row in Block Kinds, and Place A Block’s kind takes it too.
A Repeat runs its steps a set number of times. That number is its Count, and here it’s the material’s supportsHigh: 1 for wood, 2 for stone. Inside it, local.index says which time round it is, counting from 0. Read the rest of If, Else, Repeat and Region now, up to the Region, for the Count box and the way in.
The heights are the one fiddly part. local.index does them. The first time round, local.index is 0, so the support’s middle is half a block up from the floor’s bottom. The second time round it’s 1, a block and a half up, so the second support stands on the first. That’s the local.index + 0.5 on the card. The plank goes in so that its top is the top of the floor.
Look at the four Declare Variables at the top of the card: supportKind, supportHeight, plankKind and plankHeight. They’re its working values, made fresh each time it’s called. Look at each Place A Block. It’s the Function you made, called with this floor’s values.
Builds one floor of a tower from its material (a row of the Materials table): a support at each side, supportSpread from the middle of the tower, and a plank across them, standing on floorBottom (meters).
- Type
Text- Name
supportKind
- Name
supportHeight- Value
0
- Type
Text- Name
plankKind
- Name
plankHeight- Value
0
- Variable
supportKind- Value
data("Materials", material, "support")
- Variable
supportHeight- Value
data("Block Kinds", supportKind, "height")
data("Materials", material, "supportsHigh")times- x
towerX - supportSpread- y
floorBottom + supportHeight * (local.index + 0.5)- builder
builder- kind
supportKind
data("Materials", material, "supportsHigh")times- x
towerX + supportSpread- y
floorBottom + supportHeight * (local.index + 0.5)- builder
builder- kind
supportKind
- Variable
plankKind- Value
data("Materials", material, "plank")
- Variable
plankHeight- Value
data("Block Kinds", plankKind, "height")
- x
towerX- y
floorBottom + floorHeight - plankHeight / 2- builder
builder- kind
plankKind
Make it with Add > Function. Its builder is the Object at the end of the Type list, as before, and material is a Text that starts at wood, typed bare. Two of the Declare Variables are Text, so pick Text in their Type list. They have no Value.
Place A Block is in the Action List’s Functions group. On its block, builder is a list, so pick builder. kind is a box, so type supportKind or plankKind.
The second Repeat comes after the first one, not inside it, so it goes on the main line with Connect to sequence. Steps 8 and 10 go inside their Repeats, with Add inside Repeat on each. Steps 11 to 13 are on the main line again.
1.9 The Singing Notes
Now the notes themselves.
X 0.84, Y 0.8335Singing Note ArtX 0.84, Y 0.83Bob While WaitingNote StateMake it the way you made the slingshot. Its Scene Depth Draw Order, 35, keeps each note in front of the blocks, which have 30, so no plank ever hides one. Its Data Structure and its Logic come last in the chapter, with Bob While Waiting. Like the blocks, it isn’t placed, because Build The Stage makes each note.
1.9.1 Where A Note Sits
Here’s the rule the whole game rests on. Let’s take it slowly.
Stage 1 has two notes, F3 and F4, which the Notes table holds as 53 and 65. The stage’s row in Stages says 12 semitones per floor. A semitone is one step from a piano key to the next, so that’s one floor for every twelve keys.
F3 is the lowest note of the stage, so it sits in the first floor, floor 0. F4 is twelve keys higher. Twelve keys at twelve keys a floor is one floor. So F4 sits in floor 1, right above F3.
That’s floorNumber. It’s how far a note is above the stage’s lowest, divided by semitonesPerFloor and rounded to the nearest whole floor. Finding the lowest note takes no searching, because each stage’s notes are in the table from low to high. Its first note is its lowest.
Next, floorNumber becomes a height in meters. It starts at groundHeight, the top of the grass, 1.3 meters up. It adds one floorHeight for every floor, then noteAboveFloor, so the note sits up off the plank. Across is simpler. A note sits in the middle of its tower, at the tower’s x from Tower Plans.
The answer comes back as two numbers at once, x and y. Its shape is a small Data Structure, Where A Note Sits Result, named on the card’s RETURN TYPE line. The last step, Return, hands back noteX and noteY in it, the answer to where.
What the Function "Where A Note Sits" returns (its former Outputs).
Works out where a singing note of the stage being played sits, from its pitch: a higher note sits higher. noteRow is its row of the Notes table; x and y are the middle of the note (meters).
- Name
pitch- Value
0
- Name
lowestPitch- Value
0
- Name
semitonesPerFloor- Value
1
- Name
floorNumber- Value
0
- Name
tower- Value
0
- Name
towerRow- Value
0
- Name
noteX- Value
0
- Name
noteY- Value
0
- Variable
pitch- Value
data("Notes", noteRow, "midi")
- Variable
lowestPitch- Value
data("Notes", data("Stages", $stage - 1, "firstNote"), "midi")
- Variable
semitonesPerFloor- Value
data("Stages", $stage - 1, "semitonesPerFloor")
- Variable
floorNumber- Value
round((pitch - lowestPitch) / semitonesPerFloor)
- Variable
tower- Value
data("Notes", noteRow, "tower")
- Variable
towerRow- Value
data("Stages", $stage - 1, "firstTower") + tower
- Variable
noteX- Value
data("Tower Plans", towerRow, "x")
- Variable
noteY- Value
groundHeight + floorNumber * floorHeight + noteAboveFloor
- x
noteX- y
noteY
Make Where A Note Sits Result first, two Numbers. Then make the Function with Add > Function. Its four PARAMETERS are Numbers, and so are its eight Declare Variables. Pick its Return Type as A Function card shows. Then the Return block has a box for x and one for y. round() rounds a number to the nearest whole one.
1.10 Build The Stage
Now the one who reads the music. It lives on Game Rules, an Object with no picture at all.
Singing NoteMake Game Rules as an Empty Object, and leave it empty for now. Place it at X 0, Y 10.8, which is the top-left corner of the screen, out of the way. With nothing to show, it could stand anywhere.
1.10.1 Build The Stage
When the Field starts, Build The Stage finds the stage’s row in Stages and builds it, tower by tower, and each tower floor by floor, from the ground up.
Each tower starts at the top of the grass. Floor by floor, Build A Floor lays one down, and the next floor’s bottom goes up by one floorHeight, so each floor stands on the last.
There’s a Repeat inside a Repeat here, one for the towers and one for the floors. Each has its own local.index, and a step reads the one it sits closest inside. So in step 10, local.index counts towers. In step 15, inside the inner Repeat, it counts floors.
A tower may have a roof, two cubes on its top floor. Stage 1’s tower has none. Its roof cell is empty, and an empty cell names no row of Materials. Check Data Row Exists asks. Only when roofFound.value is true does a roof go on.
Then the notes. For each note of the stage, Where A Note Sits finds its spot, and Create Instance makes a Singing Note there.
Look on the card for its SHARED VARIABLES: singingNote, the Object it makes, and the stage’s five measurements. Look for its two Regions, Towers and Singing Notes, colored frames around the two halves. And look for noteSpot, the name its Where A Note Sits call answers by, and the two answers it gives, noteSpot.x and noteSpot.y.
When the Field starts, builds the stage being played from the Stages, Tower Plans, Floors and Notes tables: every tower, floor by floor from the ground up, and every singing note where its pitch puts it.
Any Object- Name
tower- Value
0
- Name
towerRow- Value
0
- Name
towerX- Value
0
- Name
floorRow- Value
0
- Name
floorBottom- Value
0
- Type
Text- Name
roofKind
- Name
row- Value
0
- Label
"Towers"- Color
#C27A3A
data("Stages", $stage - 1, "towerCount")times- Variable
tower- Value
local.index
- Variable
towerRow- Value
data("Stages", $stage - 1, "firstTower") + tower
- Variable
towerX- Value
data("Tower Plans", towerRow, "x")
- Variable
floorBottom- Value
@self.groundHeight
data("Tower Plans", towerRow, "floorCount")times- Variable
floorRow- Value
data("Tower Plans", towerRow, "firstFloor") + local.index
- towerX
towerX- floorBottom
floorBottom- floorHeight
@self.floorHeight- supportSpread
@self.supportSpread- builder
self- material
data("Floors", floorRow, "material")
- Variable
floorBottom- Operator
+=- Value
@self.floorHeight
- Action Name
roofFound- Table
Materials- Row
data("Tower Plans", towerRow, "roof")
roofFound.value == true- Variable
roofKind- Value
data("Materials", data("Tower Plans", towerRow, "roof"), "support")
- x
towerX - @self.roofSpread- y
floorBottom + data("Block Kinds", roofKind, "height") / 2- builder
self- kind
roofKind
- x
towerX + @self.roofSpread- y
floorBottom + data("Block Kinds", roofKind, "height") / 2- builder
self- kind
roofKind
- Label
"Singing Notes"- Color
#E8B923
data("Stages", $stage - 1, "noteCount")times- Variable
row- Value
data("Stages", $stage - 1, "firstNote") + local.index
- Action Name
noteSpot- noteRow
row- groundHeight
@self.groundHeight- floorHeight
@self.floorHeight- noteAboveFloor
@self.noteAboveFloor
- Object to Create
@self.singingNote- X
noteSpot.x- Y
noteSpot.y- Variable Name
newNote
Make it with Add > Logic Component. Its Shared Variables come first, with the + on the Shared Variables card, as A Logic Component card shows. All six are Constant. singingNote is an Object, with Object in the Type list, and its Starting Value stays None. The other five are Numbers, the stage’s measurements in meters.
Its Event is Scene Start. Build its steps first, and the Regions last. The seven Declare Variables go at the top. roofKind is the one Text, with no Value.
Step 17 adds a floor’s height on, with an Operator of +=. Click the = slot and pick += from its list. Type @self.floorHeight into Value, as the Change Variable paragraph of Actions, one at a time says.
The bars at the left of the card show where each step sits. Steps 10 to 14 go inside the outer Repeat, and steps 15 to 17 inside the inner one. Steps 18 and 19 come after the inner Repeat, still inside the outer one, so add them with Add inside Repeat on the outer Repeat. Steps 20 to 22 go on the If’s True line. The second big Repeat, step 24, is on the main line again.
The Build A Floor block works like the Place A Block blocks did. Its builder is a list, so pick self. On the Where A Note Sits block, type noteSpot into its Action Name. And in Create Instance, pick @self.singingNote in the Object to Create list.
Now the two Regions. The end of If, Else, Repeat and Region shows how. Click the first big Repeat and make the Towers Region around it. Then click the second and make Singing Notes. Type each Label without its quote marks, the one place where a card’s quotes stay out. In the Color’s HEX box the # is there already, as it was for the sky, so type C27A3A and E8B923.
Attach Build The Stage to Game Rules, in Logic mode. Then switch back to Components. Under Variables, singingNote has a Value button that reads None. Press it, and pick Singing Note.
Run the game.
A wooden tower stands on the right, three floors high. Two golden notes sit inside it, the lower one in the first floor, and the other one floor up. F3 and F4. Nobody placed a single post.
1.11 Bob While Waiting
The notes are in their places, but they hold still as stones. A note waiting to sing should look alive.
Picture a note floating up by three pixels, then down by three, and up again, slow as breathing. It remembers where it was made, homeY, and swings around that height. Tween does the gliding, one swing at a time.
What turns up into down? One number, swingDirection. It’s 1 on the way up and -1 on the way down. It flips after every swing.
Both numbers belong to the note, and each note keeps its own. They live in a small Data Structure the note carries, Note State. Bob While Waiting reads them as self.noteState.homeY and self.noteState.swingDirection, and changes them with Change Component Value.
If every note started at once, they’d bob together in step, like a row of soldiers. So each one waits a different part of a swing before its first. Generate Random Number picks a number from 0 to 1, named startOffset, and the timer’s first delay is that much of a swing. On the card, startOffset.value is the number it picked.
What one singing note keeps: where it swings and which way it swings now.
Moves this singing note gently up and down around where it was placed, each note starting at its own moment.
Any Objectself.noteState- Component Value
self.noteState.homeY- Value
self.transform.position.y
- Action Name
startOffset- Minimum
0- Maximum
1
- Timer Name
"bob"- Repeat Every (s)
@self.secondsPerSwing- First Delay (s)
startOffset.value * @self.secondsPerSwing
- Value
self.transform.position.y- Target
self.noteState.homeY + @self.bobMeters * self.noteState.swingDirection- Duration
@self.secondsPerSwing- Ease
Quad in Out
- Component Value
self.noteState.swingDirection- Value
-self.noteState.swingDirection
Make Note State first. Its two fields are Numbers, and swingDirection starts at 1. Then the Logic. You’ve seen this card before. It’s the example in A Logic Component card, so its parts are familiar: Note State on the Data Structures card, and the two Shared Variables, both Constant Numbers.
Tween comes from Advanced Mode, so choose Settings > Advanced Mode at the top of the editor first. On the block, type self.transform.position.y, the note’s height, into its Value box. Its Ease list starts at Linear, so pick Quad in Out. Each swing then starts slowly, speeds up and slows again, and the note seems to float.
It has two Events, side by side on the canvas. The second, the Recurring Timer, asks for its timer’s name the way Events: the When bars shows: Type a timer name…, then bob. Start Recurring Timer’s Timer Name takes the same name, bare.
Attach Bob While Waiting to the Singing Note. It brings Note State with it, and the note’s card shows that line, From Logic Bob While Waiting.
Run the game. The two notes bob, gently, each on its own beat.
Watch for each of these.
- The window is called Pitch Shot. Sunny Meadow fills it: green hills, a river running down to a lake, the sun high on the right.
- On the left, the golden slingshot stands in its tree stump, on the grass, its red band empty.
- On the right, one wooden tower stands three floors high. Each floor is two posts with a plank across their tops.
- Two golden notes sit inside the tower. The lower one is in the first floor, and the other is one floor above it.
- The notes bob up and down by about three pixels, taking 1.43 seconds a swing. Watch them for a while: they never fall into step.
- Close the game and run it again. The same stage stands, and the notes start their bobbing at different moments than before.
- Nothing sings, and nothing answers a click. Not yet.
The Field starts, and the Backdrop finds its place and puts on that painting. Game Rules reads stage 1’s row and builds its tower, floor by floor, two posts and a plank at a time. Each note’s pitch says how high it sits, and each one bobs on its own beat.
Underneath it is one idea. The stage is written down, and the game builds what’s written. Nothing about stage 1’s tower lives in the Logic. In Chapter 7, when you win a stage, the same Logic reads the next row and builds the next stage.
And a higher note sits higher, in every stage of the game.
1.12 If It Didn’t Work
Something may be a little off the first time. That’s normal, and it’s how everyone learns where things live in the editor. Run the game, watch what it does, and think it through, one piece at a time.
Myth won’t run the game, and says Can’t run yet? Read its message, because it names the Logic Component and what’s wrong.
Sky blue, and nothing else at all? Perhaps Pixels per Meter went in after Reference Size’s Y, so check that it says 100. Next, type 1000 into Reference Size’s Y and press Enter. After that, type 1080 and press Enter again. Each new Y value measures the screen again, at the Pixels per Meter it has now.
The wrong place, or Sunny Meadow on every stage? Then Backdrop Of The Place isn’t finding the place it was asked for. Perhaps it isn’t attached to the Backdrop. Or a name in the Places table is spelled a little differently from the Stages table. Sunny meadow, with a small m, is not Sunny Meadow. Then look at each row’s backdrop cell, which should name that place’s own painting.
The meadow, but no tower and no notes? Then Build The Stage never ran at all, so look for why. Is Game Rules placed in the Field, and is Build The Stage in its Attached Logic? Look for a block with no arrow into it, and join it with Connect to sequence.
The notes, but no tower? Look at Place A Block. Its Object to Create should be the box holding kind, and its Applies To should say builder. Then look at the Materials table. Each support and plank cell should name a block.
A tower with no notes? Look at Build The Stage’s Create Instance, whose Object to Create should be @self.singingNote. Then open Game Rules: its singingNote Value should say Singing Note, not None.
Both notes in the same floor? Look at floorNumber in Where A Note Sits, and count its brackets: the whole difference, pitch - lowestPitch, is divided before it’s rounded.
Posts sunk halfway into the grass, or floating? Look at the y of the two Place A Block calls inside Build A Floor’s Repeats, and the + 0.5 in each. Then look at the row names in Block Kinds: each one should match its Object’s name letter for letter.
Notes hidden behind the planks? The Singing Note’s Scene Depth Draw Order should be 35, more than the blocks’ 30.
Notes that stand still? Perhaps the timer’s name differs. The When bar says bob, and so does Start Recurring Timer’s Timer Name. A note that drifts higher and higher? Its Target should start from self.noteState.homeY, as the card’s does.
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.
The plan holds all 120 stages, and your game can build any of them already. Open Backdrop Of The Place, where you made $stage. On its Globals card, the pencil beside $stage opens it again, with its Default. Change it from 1 to 2. Run the game. Then try 11, the first stage of the second place, and 120, the very last. Watch which place stays, how many towers stand, and how the notes climb. Try 8 too. Its tower wears a roof, two stone cubes on its top floor, so you can see Check Data Row Exists say yes. Put it back to 1 before Chapter 2.
Still stuck? Search the manual, or ask in the Myth Engine Discord (opens a new tab).
A meadow, a slingshot, a tower and two notes, waiting. In Chapter 2, they find their voices.
