- Learn
- Build a Game
- Chess
- 2 Select and Move
2 Select and Move
By the end of this chapter, a click on a Piece lights its Square and marks every Square it may go to. A click on a mark moves it there. Every Kind moves its own way, and a Piece can capture.
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.
To open it, start Myth Engine, choose File › Open Project... and pick the downloaded file.
2.1 The Idea
The Board is set. Thirty-two Pieces wait on it, and none of them answers a click.
By the end of this chapter, the Board answers. Click White’s Pawn on e2, and its Square turns light gold, while two small dots appear in front of it, on e3 and e4. Click e4. The Pawn is there. The Square it left and the Square it reached both glow a soft yellow, so you can see what happened.
Every Kind moves its own way. A Rook slides along its File or its Rank, and a Bishop along the diagonals. A Knight jumps in an L, over anything in its path. When an enemy Piece stands in reach, a ring goes around it instead of a dot. Moving there is a Capture, and the enemy Piece leaves the Board.
There are no turns yet. Either Side may move, as often as you like. The rules that keep a game fair come in Chapter 3.
So here’s this chapter’s real question. How does the game know where a Piece may go?
Think how you’d find out yourself, with a finger on a real Board. Take a Rook on a1. You’d put your finger on a1 and slide it up the File, one Square at a time. a2 is empty, so the Rook may stop there. a3 is empty too. Now your finger meets a Piece. If it’s an enemy, the Rook may take it, and that’s as far as it goes. If it’s the Rook’s own, it can’t even stop there. After that, you’d go back to a1 and slide to the right.
The game does the same thing. Each line a Piece can move along is one row of the Directions table. The row says how far one step goes across and how far up, and how many steps the Piece may take. A King has eight Directions, one step each. A Rook has four, up to seven steps each. A Knight’s eight are its L-shaped jumps, one step each, so nothing in between matters.
Follow Direction is your finger. It walks one Direction from the Piece, Square by Square, until it leaves the Board, meets a Piece, or runs out of steps. Every Square the Piece may reach, it marks in Targets, a table with one row for each Square and one Yes or No: may the selected Piece go here?
And the Move itself? It’s a change to the seating chart, Position, from Chapter 1. The Piece’s kind and side are copied into the row of the Square it moves to, and its old row is emptied. A Piece already standing there is written over. Every Piece looks at its seat again, and shows what it finds. The picture follows the table, as it did in Chapter 1.
In Chapter 1, Show Piece made a see-through Piece solid again, a step that changed nothing you could see. This chapter is where it starts to matter.
2.2 The Plan
Here’s how this chapter’s pieces work together. As in Chapter 1, read each line from left to right, and know that a name in bold is a piece you’ll make yourself. Most of these names are new, so read the lines once for the shape. Come back after The click, and they’ll mean a great deal more than they do now.
- You click a Square -> that Square’s Report Click sends squareClicked.
- The Game Rules hear it -> Select and Move decides what the click means. On a Piece, it selects it and asks Find Moves where it may go. On a marked Square, it makes the Move in Position.
- Find Moves takes each of the Piece’s rows in Directions -> Follow Direction walks that way -> Look At Square marks each Square the Piece may reach in Targets.
- Select and Move sends positionChanged -> each Square’s Square Marks shows light gold or soft yellow. Each Move Mark’s Show Move Mark shows a dot, a ring or nothing. Each Piece’s Show Piece shows what Position says now.
You’ll build it from the ground up. First comes what the Game Rules remember, then a Square and a Move Mark on every Square of the Board. Next comes the Logic that finds where a Piece may go, and then the click. The Pieces learn to follow the table last.
You’ll run the game twice on the way, each time with part of it working. The chapter says what to look for, so you’ll know that half-working is right at that moment.
2.3 Set Up
This chapter’s Set up card is short.
WebGL 2 OnlyART names two more pictures from the kit. The first is a plain white square, the size of a Square, and a tint will color it gold or yellow. Move Marks holds two frames: a small, see-through dot in frame 0, and a thin ring in frame 1, both a deep green.
One Game Setting comes next. Open the Game Settings, choose Display, and find Graphics API under Rendering. It starts on WebGPU (Default, Falls Back to WebGL 2). Pick WebGL 2 Only. These two pictures are drawn from shapes, not pixels. On some computers, WebGPU draws a picture like that as a red and black checkerboard, and WebGL 2 draws it right everywhere.
PLACE THESE puts the Game Rules in the Scene. You’ll make the Game Rules in the first part, and place it there.
REMOVED names Show Piece Data, the small Data Structure Show Piece keeps in Chapter 1. Show Piece stops using it at the end of this chapter, so it goes then, in the last part.
2.4 What the Game Rules Remember
First comes the part of the game nobody sees.
The Game Rules is an Object with no picture at all. It’s the one that decides. A Square reports a click, and the Game Rules judge it. To judge, they need to remember a few things between clicks: which Piece is selected, and which two Squares the last Move touched. That’s their Board State, a Data Structure like Square Info.
What the Game Rules remember about the game besides the Position table. selected: the Square of the selected Piece (empty when none is selected). lastFrom and lastTo: the two Squares of the last Move (empty before the first Move).
Make it with Add > Data Structure, as you made Square Info, and give it its three Text fields. All three start empty, so clear the 0 each new Text field keeps. Empty means two things here: nothing is selected, and no Move has been made yet.
Now the Game Rules themselves.
Board StateIt’s an Empty Object, with one component: a Data Structure, switched to Board State in its Data Structure list. The Logic on its card, Select and Move, comes later in the chapter. Leave it for now.
Place it in the Scene the way you placed the Board, at X 15 and Y 19.375, the Board’s middle. Where it stands doesn’t change anything, because there’s nothing of it to see.
The next table knows which way is forward. White’s Pawns march up the Board, and Black’s march down toward White. Sides has a row for each Side. Its forward is 1 for White and -1 for Black, so one step “up” becomes a step down for Black. Its pawnRank is the Rank a Side’s Pawns start on, 2 or 7. A Pawn there may take two steps.
One row of the "Sides" Data Table, which follows it. One row per Side. forward: the way its Pawns move along the Ranks (1 = up, toward Rank 8; -1 = down). pawnRank: the Rank its Pawns start on.
12-17Make it with Add > Data Table, as you made Kinds. Its Sides Entry gets two Number fields, forward and pawnRank, each with the card’s default in its Value, and then come the two rows.
Next, Directions, the heart of how Pieces move. Each row is one Direction for one Kind. Its fileStep is how far one step goes across, and its rankStep how far up. Its steps is how many steps the Piece may take that way, and firstMoveSteps how many from its starting Rank. That’s 2 for a Pawn moving forward, and the same as steps for everything else.
The last two columns are for the Pawn, the one Kind that moves one way and captures another. Its forward row has canMove Yes and canCapture No: it may step onto an empty Square, never onto a Piece. Its two diagonal rows are the other way round. They only capture.
One row of the "Directions" Data Table, which follows it. Every way each Kind of Piece moves, one row per direction. kind: the Kind. fileStep and rankStep: one step, in Files and Ranks (a Pawn's rankStep is turned round for Black by its Side's forward). steps: how many steps it may take in one Move (7 slides across the Board). firstMoveSteps: the same, for a Piece on its Side's Pawn Rank (a Pawn's first Move may be two Squares). canMove: it may step onto an empty Square. canCapture: it may step onto an enemy Piece, taking it. A Piece stops at the first Piece in its way.
King0111YesYesKing1111YesYesKing1011YesYesMake its columns first, in Directions Entry, as you did for Position. Its kind is a Text, and the next four are Numbers. Both canMove and canCapture are Booleans, a yes or a no, so pick Boolean in their Type list. Their Value turns into a switch, and the card’s default, true, is the switch on. Download chess-directions.csv from the card’s File line and press Import CSV. It brings 35 rows: eight for the King, eight for the Queen, four each for the Rook and the Bishop, eight for the Knight and three for the Pawn.
The last table starts empty, and stays that way in the editor.
One row of the "Targets" Data Table, which follows it. The Squares the selected Piece may move to: one row per Square, a1 to h8, in the same order as the Position table, made by Clear Targets (the table has no rows of its own). reachable: yes when the selected Piece may move there. Find Moves fills it, after Clear Targets has made every Square unreachable.
Targets has one column, reachable, a Boolean whose default is false, and no rows at all. So Targets Entry gets one field, with its switch off. The game gives the table a row for every Square each time a Piece is selected, and that comes later in the chapter.
2.5 A Square Under Every Piece
Now every Square of the Board gets two Objects of its own.
A Piece can’t tell you it was clicked when there’s no Piece there, and you’ll want to click empty Squares to move onto them. So each Square gets a Square, an Object as big as the Square, lying on the wood under its Piece. It’s what you click. A click reaches every Object under the pointer, and the Piece has nothing listening for one, so the Square hears it. It also shows the gold and the yellow.
X 3.75, Y 3.755Square HighlightX 3.75, Y 3.75Square InfoMake it as you made the Piece: an Empty Object, a Bounding Box of 3.75 by 3.75, the card’s white square in its Sprite at the same size, and its Square Info. Its Scene Depth Draw Order is 5. That puts it over the Board, at 0, and under the Pieces, at 10.
Its two Logic Components come next. Attach each to the Square once it’s made.
2.5.1 Report Click
When you click a Square, it has one job: to say so.
Report Click listens for a left click on its own Square, and rings a bell for everyone who listens, squareClicked. It doesn’t decide anything. It doesn’t even say which Square it is, and it doesn’t need to. Whoever hears a message can ask who sent it, and that’s how the Game Rules will know.
When the Player clicks this Square, it tells whoever listens (the Game Rules) with "squareClicked"; the listener reads which Square it was as Other.
Any Object- Custom Event
squareClicked
Its card is the shortest yet: one Event, one step. The Event is Mouse Pressed on Object, and a second window asks for the mouse button, left. Events: the When bars shows both windows. Its one step is a Trigger Custom Event, with squareClicked typed into it.
2.5.2 Square Marks
When the Board changes, each Square checks whether it’s special.
It starts by hiding. When a Square is made, Square Marks turns it fully see-through, so the plain white square never covers the wood. After that it waits for positionChanged, the message the Game Rules send after every click.
When the message comes, the Square compares its own name with the Game Rules’ Board State. Is it the selected Square? Then it takes the light gold, at an Alpha of 0.44, a little less than half there. Otherwise, was it one of the last Move’s two Squares? Then it takes the soft yellow, at 0.32. Anything else, and it hides again.
How does a Square read the Game Rules’ Board State? Through other. When a message arrives, other is the Object that sent it. Here that’s the Game Rules, so other.boardState.selected is their selected Square.
Shows the highlight on this Square after every change (the Game Rules send "positionChanged" and are its Other): a tint when its Piece is selected or it was part of the last Move. The colors, and how strongly each shows, are its Parameters.
Any Objectself.squareInfo- Alpha
0
self.squareInfo.name == other.boardState.selected- Value
@self.selectedColor
- Alpha
@self.selectedAlpha
self.squareInfo.name == other.boardState.lastFrom || self.squareInfo.name == other.boardState.lastTo- Value
@self.lastMoveColor
- Alpha
@self.lastMoveAlpha
- Alpha
0
Look on the card for its four Shared Variables: the two colors, and how strongly each shows. And look for other, which you won’t find among them. You don’t make other at all. Look at the Event’s block on the canvas: under Event Variables it lists other, by itself. For a message, it’s the Object that sent it.
Its DATA STRUCTURES row is Square Info, as in Chapter 1. Its first Event is Create. It asks nothing more. The second is a Custom Event, positionChanged, and nothing sends that yet. So make it with Add Custom Event…, as you made boardLaidOut in Chapter 1.
The color goes on with Change Sprite Tint Property. Its Property list starts on Color, the one you want, so type only its Value, the Shared Variable with its @.
Steps 4 and 5 are new. They’re an Otherwise that asks a question of its own, and on the canvas they’re one block, an Else If. Right-click the first If and choose Add Else If, then type step 5’s condition into it, || and all. Its steps go in with its own Add Inside Then. Step 8, the last Otherwise, belongs to the Else If, so right-click the Else If and choose Add Else. If, Else, Repeat and While has a paragraph on it.
Now attach both Logic Components to the Square. There’s nothing to set on the Square for other, because whatever sends the message fills it in when it arrives.
The Square is done. Its partner is smaller.
X 3.75, Y 3.757Move MarksX 3.75, Y 3.75Square InfoThe Move Mark sits at 7, over the Square and under the Piece, so a ring goes around a Piece instead of over it. It carries a Square Info too.
2.5.3 Show Move Mark
After every click, each Move Mark asks one question: may the selected Piece come to my Square? Its own row of Targets answers. On an empty Square, a yes shows the dot, frame 0, and over a Piece it shows the ring, frame 1.
Shows whether the selected Piece may move to this Move Mark's Square, after every change (the Game Rules send "positionChanged"): a dot on an empty Square, a ring around a Piece it may take, and nothing on any other Square. It reads the Targets table, which the Game Rules fill when a Piece is selected.
Any Objectself.squareInfodata('Targets', self.squareInfo.name, 'reachable') == true- Visible
Yes
data('Position', self.squareInfo.name, 'kind') == ""- Frame
0
- Frame
1
- Visible
No
Its first If asks a yes or no question: is this Square’s reachable true? Set Visible’s Visible is a list, Yes or No.
Mind the two Elses. Step 3’s If goes inside the first If’s Then, after Set Visible. Each If gets its own Else. Step 5 belongs to step 3, and step 7 to step 1, so right-click the right If when you choose Add Else. Then attach it to the Move Mark.
2.5.4 Lay Out The Board
Now the Board makes the new Objects, sixty-four of each.
It already walks down Position and makes a Piece on each Square it comes to. Now, on the same Square, it makes a Square and a Move Mark too, and gives each one the Square’s name. It’s the same two steps as the Piece’s, twice more.
Makes the Objects that show each Square of the Board when the Scene starts: for every row of the Position table (one Square, a1 to h8), a Piece Object, a Square and a Move Mark are made on that Square (Square Position), and each is given the Square's name (its Square Info); a Square in the left column also gets a Rank Label, and one in the bottom row a File Label. Then it says "boardLaidOut". pieceObject, squareObject, moveMarkObject: the Objects made on each Square; rankLabelObject, fileLabelObject: the labels. squareMeters: how wide one Square is.
Any Objectself.layOutTheBoardData- Name
boardBottom- Value
0
- Name
boardLeft- Value
0
- Variable
boardLeft- Value
self.transform.position.x - 4 * @self.squareMeters
- Variable
boardBottom- Value
self.transform.position.y - 4 * @self.squareMeters
dataCount('Position')times- Component Value
self.layOutTheBoardData.squareName- Value
dataRow('Position', local.index)
- Action Name
spot- square
self.layOutTheBoardData.squareName- squareMeters
@self.squareMeters- boardLeft
boardLeft- boardBottom
boardBottom
- Object to Create
@self.pieceObject- X
spot.x- Y
spot.y- Created As
piece
- Variable
piece.name- Value
self.layOutTheBoardData.squareName
- Object to Create
@self.squareObject- X
spot.x- Y
spot.y- Created As
square
- Variable
square.name- Value
self.layOutTheBoardData.squareName
- Object to Create
@self.moveMarkObject- X
spot.x- Y
spot.y- Created As
moveMark
- Variable
moveMark.name- Value
self.layOutTheBoardData.squareName
data('Position', self.layOutTheBoardData.squareName, 'file') == 1- Object to Create
@self.rankLabelObject- X
spot.x- Y
spot.y- Created As
rankLabel
- Variable
rankLabel.name- Value
self.layOutTheBoardData.squareName
data('Position', self.layOutTheBoardData.squareName, 'rank') == 1- Object to Create
@self.fileLabelObject- X
spot.x- Y
spot.y- Created As
fileLabel
- Variable
fileLabel.name- Value
self.layOutTheBoardData.squareName
- Custom Event
boardLaidOut
This is your first Changes card, so read Changes cards before you start. The green lines are what to add.
Add the two new Shared Variables with the + on its Shared Variables card, as you added the first four: squareObject and moveMarkObject, each an Object, Constant, starting at None.
Steps 10 to 13 are a Create Instance and a Change Variable for the Square, then the same for the Move Mark. On the card they follow step 9. In your editor, add each with the Repeat’s Add Inside Repeat, and Connect to Sequence joins it at the end of the Repeat’s line, after the second If. That’s all right here. Each of these steps makes one Object and names it, and the order they come in changes nothing on the Board. The Created As names are square and moveMark. From step 10 on, your numbers and the card’s part ways in this one Logic, and nowhere else in the chapter.
The rest is the same as the Piece’s two steps in Chapter 1. Each Value is self.layOutTheBoardData.squareName, and each Variable box names the new Object: square.name, then moveMark.name.
X 30, Y 30Walnut BoardX 30, Y 30Lay Out The BoardLay Out The Board DataPieceRank LabelFile LabelSquareMove MarkOpen the Board, and look under Variables. Its two new Shared Variables wait at None. Press each one, and pick Square and Move Mark, as the Board’s card says.
Run the game. The Board looks as it did, with one difference: a faint green dot sits on every Square, even under the Pieces. Every Move Mark starts out showing its first frame, and nothing has told them to hide. Nothing sends positionChanged yet, and in this chapter nothing will until the first click. The dots will go then. In Chapter 3, the game sends positionChanged as it starts, and the dots are gone before you see them.
2.6 Where a Piece May Go
Now the four pieces that answer this chapter’s question. They’re all Functions, and each one does a single job when it’s asked. You’ll make them from the smallest up, because each one calls the one before.
2.6.1 Clear Targets
Before the game marks where a Piece may go, it wipes out the marks of the last one.
Think of a slate wiped clean before the next sum. Whatever the last Piece could reach, Clear Targets forgets it. It throws the old rows away and lays down a fresh one for every Square, in Position’s order. Every fresh row says No. Nobody can go anywhere, until the next Piece is looked at.
Makes every Square unreachable: the Targets table is emptied, then gets one row for each Square of the Position table, a1 to h8 in the same order, with reachable no (the column's default). The Targets table has no rows of its own; Clear Targets makes them, each time it is used.
- Type
Text- Name
square
- Table
Targets
dataCount('Position')times- Variable
square- Value
dataRow('Position', local.index)
- Action Name
addedRow- Table
Targets- Row
square
Two of its steps come from Advanced Mode, so turn that on if you haven’t, as Before your first card shows. Reset Data Table puts a table back the way you made it in the editor, and Targets was made with no rows. Control Data Row adds the row its Row box names. Its Operation list already says Add or Update, the one you want, so leave it. The Values box stays empty. The row takes the defaults.
It’s a Function, as in Chapter 1: a Start block and an End block on its canvas, with your Actions joined in between. It has no Parameters and no Return Type. Its first step declares square, a Text that starts empty. Reset Data Table and Control Data Row each have a Table list, so pick Targets there. Inside the Repeat, type local.index as the card has it.
2.6.2 Look At Square
Now the smallest question. Here’s one Square: may the Piece go there?
Look At Square is handed a Square by its file and rank, which might be off the Board. It’s also handed the moving Piece’s Side, and the two Yes or No values from Directions, canMove and canCapture.
It works it out in four small moves. First, is the Square on the Board at all? It is when both its file and its rank are 1 to 8, and then isOnBoard becomes Yes. Second, it finds the Square’s row number, square. Third, is the Square on the Board and empty? A Piece could pass through it, so keepGoing becomes Yes, and when canMove is Yes too, the Square gets marked. Last, does an enemy Piece stand there? If canCapture is Yes, that Square gets marked as well.
It hands back one answer, keepGoing. Yes means the Square was empty, so a Rook or a Bishop may go on past it.
How does a Square become a row number? Position’s rows run a1, b1, c1, and on across each Rank. So the row is (rank - 1) * 8 + (file - 1), counting from 0. a1 is row 0, b1 is row 1, and a2 is row 8. Clear Targets made Targets’ rows in the same order, so one number finds one Square in both tables.
Looks at one Square a Piece could step onto. file and rank: the Square (they may be off the Board). side: the Side of the moving Piece. canMove: it may step onto an empty Square. canCapture: it may take an enemy Piece there. It marks the Square in the Targets table when the Piece may go there. keepGoing (returned): yes when the Square is on the Board and empty, so a sliding Piece may go on past it.
- Type
Boolean- Name
isOnBoard- Value
false
- Name
square- Value
0
- Type
Boolean- Name
keepGoing- Value
false
file >= 1 && file <= 8 && rank >= 1 && rank <= 8- Variable
isOnBoard- Value
true
- Variable
square- Value
(rank - 1) * 8 + (file - 1)
isOnBoard == true && data('Position', square, 'kind') == ""- Variable
keepGoing- Value
true
keepGoing == true && canMove == true- Table
Targets- Row
square- Column
"reachable"- Value
"true"
isOnBoard == true && data('Position', square, 'kind') != "" && data('Position', square, 'side') != side && canCapture == true- Table
Targets- Row
square- Column
"reachable"- Value
"true"
- Value
keepGoing
Its PARAMETERS go on its Start block, as Square Position’s did. canMove and canCapture are Booleans, with a Yes or No for their Default. Its RETURN TYPE is Boolean, a yes or a no, picked in the Function’s own card. The last step, a Return, hands back keepGoing.
Set Data Cell is the third Advanced Mode Action, the one that writes into a table while the game runs. It has a place for each of the card’s lines: Table, Row, Column and Value.
Its Table is a list, so pick Targets. Its Row is square, bare, the row number this Function worked out a step before. Its Column is "reachable", in quote marks. A column’s name is a word, and a word in a box goes in quote marks. Typed bare, reachable turns red. The box takes it for a name of something this Function made, and it has none. The Value is a word too, "true". A Boolean cell takes the word true.
2.6.3 Follow Direction
This is the chapter’s one hard piece, so take it slowly. It’s your finger on the Board.
Follow Direction is handed the Piece’s Square, from, and one row of Directions, direction. First it reads what it needs. It reads the Piece’s side, and the Side’s forward from Sides. It reads the Piece’s file and rank, its starting point, and the row’s steps, as stepsLeft.
One check comes next. If the Piece stands on its Side’s pawnRank, stepsLeft becomes the row’s firstMoveSteps. For a Pawn moving forward, that’s 2. For every other row it’s the same number as steps, so nothing changes.
Now the walk. A While runs its panel again and again, for as long as its condition holds: keepGoing is Yes, and stepsLeft is more than 0. Each time round, four things happen. The file moves by fileStep. The rank moves by rankStep times forward, so a Black Pawn’s step up goes down. stepsLeft drops by one. And Look At Square, named squareLook, judges the new Square, marks it if the Piece may go there, and hands back keepGoing.
Take a Rook on a1, walking up. Its rankStep is 1, its steps 7. The first time round, rank goes from 1 to 2, onto a2. There’s a White Pawn on a2, so Look At Square marks nothing and hands back No. The While stops. The Rook has nowhere to go that way, which is right.
Now put that Pawn on a4, out of the way. a2 is empty, marked, and keepGoing stays Yes. a3 is the same. On a4 stands the Pawn, and the walk stops there. The Rook may go to a2 or a3.
And a Knight? Its row has steps 1. It jumps straight to its Square, and the While stops after one time round, because stepsLeft is 0. What stood between doesn’t matter, because nothing ever looked there.
Follows one direction a Piece moves in, Square by Square, marking each Square it may go to in the Targets table, until it leaves the Board, meets a Piece, or has taken as many steps as the Directions table allows. from: the Piece's Square (a1 to h8). direction: the row (0 = first) of the Directions table.
- Type
Text- Name
side
- Name
forward- Value
1
- Name
file- Value
0
- Name
rank- Value
0
- Name
stepsLeft- Value
0
- Type
Boolean- Name
keepGoing- Value
true
- Variable
side- Value
data('Position', from, 'side')
- Variable
forward- Value
data('Sides', side, 'forward')
- Variable
file- Value
data('Position', from, 'file')
- Variable
rank- Value
data('Position', from, 'rank')
- Variable
stepsLeft- Value
data('Directions', direction, 'steps')
rank == data('Sides', side, 'pawnRank')- Variable
stepsLeft- Value
data('Directions', direction, 'firstMoveSteps')
keepGoing == true && stepsLeft > 0- Variable
file- Operator
+=- Value
data('Directions', direction, 'fileStep')
- Variable
rank- Operator
+=- Value
data('Directions', direction, 'rankStep') * forward
- Variable
stepsLeft- Operator
-=- Value
1
- Action Name
squareLook- file
file- rank
rank- side
side- canMove
data('Directions', direction, 'canMove')- canCapture
data('Directions', direction, 'canCapture')
- Variable
keepGoing- Value
squareLook.value
Its first six steps declare what it works with, and two of them don’t start at 0. The forward one starts at 1, and keepGoing is a Boolean starting at true, so the While runs the first time.
The While’s condition is one box on its block, keepGoing == true && stepsLeft > 0, and If, Else, Repeat and While shows where its panel’s Actions go. Steps 15 and 16 have += in their Operator list, so the step is added on. Step 17’s says -=.
Step 18 calls Look At Square, from the Functions group, with squareLook in its Action Name box. Each of its Parameters is a box on the block, canMove and canCapture too, so type the card’s formulas into them. Step 19 reads its answer as squareLook.value. A Function that hands back one yes or no calls it value. That’s how the walk learns whether it may go on past this Square or must stop here.
2.6.4 Find Moves
Last, the one that starts it all. Here’s a Piece: find everywhere it may go.
Find Moves first clears every mark the last Piece left, with Clear Targets. It reads the Piece’s kind. Then it goes down the whole Directions table. For every row whose kind matches, it calls Follow Direction. A Rook has four such rows, so four walks, one up, one right, one down and one left. A King has eight short ones.
Finds every Square the Piece on one Square may move to (by how its Kind moves; Check and the special Moves come later) and marks them in the Targets table, clearing the marks of any Piece looked at before. from: the Piece's Square (a1 to h8).
- Type
Text- Name
kind
- Variable
kind- Value
data('Position', from, 'kind')
dataCount('Directions')timesdata('Directions', local.index, 'kind') == kind- from
from- direction
local.index
Its If compares two words, the row’s kind and the Piece’s. Step 6’s direction is local.index, the number of the row the Repeat is on. That’s the Directions row Follow Direction walks.
Four Functions, and you can’t see any of them yet. Nothing has asked.
2.7 The Click
Now the piece that asks.
2.7.1 Select and Move
A click arrives, and Select and Move decides what it means. There are three answers.
It reads two things first: clickedSquare, the Square you clicked, and selectedSquare, the Square of the Piece already selected. The clicked Square is other, the Object that sent squareClicked, so its name is other.squareInfo.name.
Is a Piece selected, and may it go to the clicked Square? Then it’s a Move. Four Set Data Cells change the seating chart. The clicked Square’s row takes the selected Piece’s kind and side, and the selected Square’s row is emptied. If an enemy Piece stood on the clicked Square, its row was written over. That’s the whole Capture. The Board State then remembers the Move’s two Squares as lastFrom and lastTo, nothing is selected any more, and Clear Targets wipes the marks.
Otherwise, did you click a Piece that isn’t already selected? Then it’s selected, and Find Moves marks where it may go.
Otherwise, you clicked an empty Square nobody can reach, or the selected Piece again. Either way, the selection clears.
Then, whatever happened, it sends positionChanged. Every Square, every Move Mark and every Piece looks again.
Decides what a click on a Square means. A click on a Square the selected Piece may move to moves it there (taking any Piece on it) and remembers the Move; a click on another Piece selects it and finds where it may move; any other click clears the selection. Then it tells everyone "positionChanged". Its Other is the clicked Square.
Any Objectself.boardState- Type
Text- Name
selectedSquare
- Type
Text- Name
clickedSquare
- Variable
clickedSquare- Value
other.squareInfo.name
- Variable
selectedSquare- Value
self.boardState.selected
selectedSquare != "" && data('Targets', clickedSquare, 'reachable') == true- Table
Position- Row
clickedSquare- Column
"kind"- Value
data('Position', selectedSquare, 'kind')
- Table
Position- Row
clickedSquare- Column
"side"- Value
data('Position', selectedSquare, 'side')
- Table
Position- Row
selectedSquare- Column
"kind"- Value
''
- Table
Position- Row
selectedSquare- Column
"side"- Value
''
- Component Value
self.boardState.lastFrom- Value
selectedSquare
- Component Value
self.boardState.lastTo- Value
clickedSquare
- Component Value
self.boardState.selected- Value
''
data('Position', clickedSquare, 'kind') != "" && clickedSquare != selectedSquare- Component Value
self.boardState.selected- Value
clickedSquare
- from
clickedSquare
- Component Value
self.boardState.selected- Value
''
- Custom Event
positionChanged
It’s a Logic Component for the Game Rules. Its DATA STRUCTURES row is Board State, read as self.boardState. other is the clicked Square, and as in Square Marks, the Event’s block lists it by itself. Its Event is the squareClicked that Report Click sends, so it’s on the list already.
Its first If joins two questions with &&. Set Data Cell is the same Action as in Look At Square, and its places fill the same way. Pick Position in the Table list. The Rows are clickedSquare and selectedSquare, bare, the two names this Event declares. The Columns are "kind" and "side", in quote marks. And '' in a Value is an empty word, as in Show Piece, so it empties the cell.
Change Component Value sets one field of the Game Rules’ Board State, as the card’s paths say: self.boardState.lastFrom, lastTo and selected. Actions, one at a time has a paragraph on it. Its Values are bare too, the same two names, or '' for nothing selected. Step 15’s If sits inside the first If’s Else. Step 21, the Trigger Custom Event, comes after the whole first If, on the line that runs down from the Event. Add it from the Action List, and Connect to Sequence joins it there.
Then attach Select and Move to the Game Rules.
Run the game, and click White’s e2 Pawn. The dots all over the Board vanish. e2 turns light gold, and two dots appear, on e3 and e4. Your four Functions have made their first walk.
Now click e4. The gold goes. e2 and e4 both turn a soft yellow, the last Move’s two Squares. But look at the Pawn, which is still standing on e2.
That isn’t a mistake. The table says the Pawn is on e4. Click e4 again, and the game selects it there, with a dot on e5. Click e2, and nothing is selected, because the table says e2 is empty. The game knows exactly where the Pawn is. Nobody has told the Pieces to look again.
2.8 The Pieces Follow
The Pieces look at their seats when boardLaidOut arrives, and that comes once, at the start. Now they need to look after every click as well.
2.8.1 Show Piece On Square
Show Piece’s eight steps already show one Piece on its Square. Rather than copying them into a second Event, they move into a Function of their own, so any Event can call it.
Show Piece On Square is handed one Piece, piece. It does exactly what Show Piece did. It reads the kind on the Piece’s Square, and makes the Piece see-through if there’s none, or solid with the right frame if there is. The only change is who it works on. Where Show Piece said self, the Function says piece.
Shows the Piece that stands on one Square of the Board: the frame of the Piece Set art that the Kinds table gives for its Kind and Side, or nothing (fully transparent) when the Square is empty. piece: the Piece Object to show it with; its Square Info names its Square, which is its row in the Position table.
squareInfoData StructureSquare Info- Type
Text- Name
kind
- Type
Text- Name
side
- Variable
kind- Value
data('Position', piece.squareInfo.name, 'kind')
kind == ""- Applies to
piece- Alpha
0
- Applies to
piece
- Variable
side- Value
data('Position', piece.squareInfo.name, 'side')
- Applies to
piece- Frame
data('Kinds', kind, side)
Its one Parameter is piece. It’s an Object, so add it on the Start block, then press the pencil beside it. Its window takes the card’s lines under it: Structural, and a Required Component, a Data Structure that is a Square Info, in a slot named squareInfo. A Function card shows where each one goes. Then its two Declares, kind and side, both Text. Each Set Alpha and Set Frame has an Applies to list, and in each one you pick piece, so they work on the Piece the Function was handed.
Here is where Chapter 1’s promise is kept. When the e2 Pawn moves to e4, the see-through Piece that has waited on e4 since the start reads its seat. A Pawn sits there now. Its second Set Alpha makes it solid, and its Set Frame shows the Pawn. On e2, the Pawn’s own Piece reads an empty seat, and turns see-through.
2.8.2 Show Piece
Now Show Piece itself shrinks to almost nothing.
Shows the Piece that stands on this Piece Object's Square: once the Board is laid out (Lay Out The Board sends "boardLaidOut"), and again after every Move (the Game Rules send "positionChanged").
Any Objectself.squareInfoself.showPieceData- Type
Text- Name
kind
- Variable
kind- Value
data('Position', self.squareInfo.name, 'kind')
kind == ""- Alpha
0
- Component Value
self.showPieceData.side- Value
data('Position', self.squareInfo.name, 'side')
- Frame
data('Kinds', kind, self.showPieceData.side)
- piece
self
- piece
self
The red lines go. On its canvas, right-click the Declare and choose Delete. Delete the Change Variable and the If the same way, and the If’s Then and Else panels go with it. On the Data Structures card, press the bin beside Show Piece Data. In their place, add Show Piece On Square from the Functions group, join it, and pick self in its piece list.
Now a second Event. Press Add Event and find positionChanged, on the list already, and give it the same one step.
Show Piece Data has no job left. Right-click it in the Resources and choose Delete, as the Set up card’s REMOVED line says.
Run the game, and click e2, then e4. The Pawn is on e4.
Click a Knight, and two dots appear in front of it, past the Pawns. Click a Bishop, and nothing lights but its own Square, because its own Pawns block every diagonal. Move a Pawn out of the way, and try again.
Your Board answers now.
Watch for each of these.
- At the start, faint dots sit on every Square. The first click clears them. In Chapter 3 they’re gone from the start.
- Click White’s e2 Pawn. e2 turns light gold, and dots appear on e3 and e4.
- Click e4. The Pawn moves there, and e2 and e4 turn a soft yellow.
- Click the Knight on g1. Dots appear on f3 and h3, over the Pawns.
- Click the Rook on a1. Only a1 lights, because its own Pawn and Knight block it both ways.
- Click a Piece, then the same Piece again. The gold and the dots go.
- Move a Pawn until an enemy Piece stands diagonally in front of it. A ring goes around that Piece. Click the ring, and the enemy Piece is gone.
- Click e7, then e5. Black moves too, whenever you like, because turns don’t come until Chapter 3.
A click goes up from a Square. The Game Rules decide. Finding where a Piece may go is a walk. It goes one Direction at a time, Square by Square, until the Board ends, a Piece is in the way, or the steps run out. A Move is four cells of Position. One message follows, and every Square, mark and Piece looks again.
Underneath it all is Chapter 1’s idea, taken one step further. Nothing on the Board moves by itself. The table changes. The picture follows.
2.9 If It Didn’t Work
This chapter has many small pieces, and one of them may be a little off. That’s expected, and it’s how everyone learns. Run the game, click, and watch what it does, and think it through.
A block drawn in red, with a number on the Errors bar? Open the bar. It names the block and what it misses, and most often it’s a quote mark. A Column is a word, so it wants its quote marks: "reachable", "kind", "side". A Row goes bare.
A click on a Piece, and nothing lights at all? If the dots on every Square vanish at your first click, Select and Move is running, but it found no Piece where you clicked. Look at its step 3. Its Value should read other.squareInfo.name, the clicked Square’s name.
The whole Board covered in white before the first click, with the wood gone? Square Marks’ When Created Event isn’t hiding the Squares. Look for it, with its Set Alpha of 0, and for a block with no arrow into it.
The Squares light, but the Pawn stays on e2 after its Move? Show Piece isn’t hearing positionChanged yet. Perhaps it has no second Event, or its When bar says something a letter off. It must match Select and Move’s Trigger Custom Event, capital C.
The Pawn on e4, but another Pawn still on e2? The old Square wasn’t emptied. Look at Select and Move’s steps 8 and 9, the two Set Data Cells whose Row is selectedSquare.
A Rook’s dots run up the File, right past its own Pawn? The walk never learns to stop. Look at Follow Direction’s last step, keepGoing set from squareLook.value, and check that it’s joined inside the While.
The gold, but no dots anywhere? Look at the Directions table: its kind column must spell each Kind as Position does, King or Pawn, with a capital. Perhaps Look At Square’s Row has quote marks around it. Typed so, it names a row called square, and Targets has none. It should read square, bare.
White’s Pawns marked toward their own side? Look at the Sides table: forward is 1 for White and -1 for Black.
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.
Directions is only a table, so the Pieces move however its rows say. Give the King a ninth row, two Squares straight up, and watch it leap. Or let the Knight keep going: set its steps to 7, and it rides its L across the whole Board. Put the rows back before Chapter 3. And think about a Piece chess never had, and what its rows would be.
Still stuck? Search the manual, or ask in the Myth Engine Discord (opens a new tab).
The Pieces move now, every one its own way. In Chapter 3, they learn to wait their turn.
