Build a GameCreating Chess

2  Select and Move

Goal

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.

Chess, Chapter 2 finishedMyth project · 15.5 MB

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.

Set upWhat this chapter adds
ART (sprites, from the starter kit)
Square Highlight
Move Marks
GAME SETTINGS > Display > Rendering
Graphics APIWebGL 2 Only
SCENE Chess Table: PLACE THESE
ObjectXY
Game Rules1519.375
REMOVED
Data Structure: Show Piece Data

ART 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.

Data StructureBoard State

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).

selectedTextdefault (empty)
lastFromTextdefault (empty)
lastToTextdefault (empty)

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.

ObjectGame Rules
Data Structure
Data StructureBoard State
Logic
Select and Move

It’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.

Data StructureSides Entry

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.

forwardNumberdefault 1
pawnRankNumberdefault 2
Data TableSidesData Structure: Sides Entry
Row 0White
forward1
pawnRank2
Row 1Black
forward-1
pawnRank7

Make 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.

Data StructureDirections Entry

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.

kindTextdefault (empty)
fileStepNumberdefault 0
rankStepNumberdefault 0
stepsNumberdefault 1
firstMoveStepsNumberdefault 1
canMoveBooleandefault true
canCaptureBooleandefault true
Data TableDirectionsData Structure: Directions Entry
IMPORT CSV35 rows, from a file
FIRST ROWS3 of 35, to compare
Row 0King up
kindKing
fileStep0
rankStep1
steps1
firstMoveSteps1
canMoveYes
canCaptureYes
Row 1King up right
kindKing
fileStep1
rankStep1
steps1
firstMoveSteps1
canMoveYes
canCaptureYes
Row 2King right
kindKing
fileStep1
rankStep0
steps1
firstMoveSteps1
canMoveYes
canCaptureYes

Make 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.

Data StructureTargets Entry

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.

reachableBooleandefault false
Data TableTargetsData Structure: Targets Entry

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.

ObjectSquare
Transform
Bounding Box > SizeX 3.75, Y 3.75
Sprite
Scene Depth Draw Order5
SpriteSquare Highlight
Transform > SizeX 3.75, Y 3.75
Data Structure
Data StructureSquare Info
Logic
Report Click
Square Marks

Make 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.

Logic ComponentReport ClickAttach to: Square

When the Player clicks this Square, it tells whoever listens (the Game Rules) with "squareClicked"; the listener reads which Square it was as Other.

Attach toAny Object
When Left Is Clicked
WhenMouse Pressed on ObjectMouse button: left
1Trigger Custom Event
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.

Logic ComponentSquare MarksAttach to: 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.

Attach toAny Object
DATA STRUCTURES
Square Infoself.squareInfo
SHARED VARIABLES
NameTypeKindStarting Value
selectedColorColorConstant#f4d273
selectedAlphaNumberConstant0.44
lastMoveColorColorConstant#e9c44f
lastMoveAlphaNumberConstant0.32
When Created
WhenCreate
1Set Alpha
Alpha
0
On Position Changed
WhenpositionChangedCustom Event
1Ifself.squareInfo.name == other.boardState.selected
Then
2Change Sprite Tint Property
Value
@self.selectedColor
3Set Alpha
Alpha
@self.selectedAlpha
4Otherwise
5Ifself.squareInfo.name == other.boardState.lastFrom || self.squareInfo.name == other.boardState.lastTo
Then
6Change Sprite Tint Property
Value
@self.lastMoveColor
7Set Alpha
Alpha
@self.lastMoveAlpha
8Otherwise
9Set Alpha
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.

ObjectMove Mark
Transform
Bounding Box > SizeX 3.75, Y 3.75
Sprite
Scene Depth Draw Order7
SpriteMove Marks
Transform > SizeX 3.75, Y 3.75
Data Structure
Data StructureSquare Info
Logic
Show Move Mark

The 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.

Logic ComponentShow Move MarkAttach to: Move Mark

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.

Attach toAny Object
DATA STRUCTURES
Square Infoself.squareInfo
On Position Changed
WhenpositionChangedCustom Event
1Ifdata('Targets', self.squareInfo.name, 'reachable') == true
Then
2Set Visible
Visible
Yes
3Ifdata('Position', self.squareInfo.name, 'kind') == ""
Then
4Set Frame
Frame
0
5Otherwise
6Set Frame
Frame
1
7Otherwise
8Set Visible
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.

Logic ComponentLay Out The BoardAttach to: BoardAddDelete

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.

Attach toAny Object
DATA STRUCTURES
Lay Out The Board Dataself.layOutTheBoardData
SHARED VARIABLES
NameTypeKindStarting Value
pieceObjectObjectConstantNone
rankLabelObjectObjectConstantNone
fileLabelObjectObjectConstantNone
squareMetersNumberConstant3.75
squareObjectObjectConstantNone
moveMarkObjectObjectConstantNone
When the Scene Starts
WhenScene Start
1Declare Variable
Name
boardBottom
Value
0
2Declare Variable
Name
boardLeft
Value
0
3Change Variable
Variable
boardLeft
Value
self.transform.position.x - 4 * @self.squareMeters
4Change Variable
Variable
boardBottom
Value
self.transform.position.y - 4 * @self.squareMeters
5RepeatdataCount('Position')times
Each time
6Change Component Value
Component Value
self.layOutTheBoardData.squareName
Value
dataRow('Position', local.index)
7Square PositionFunction
Action Name
spot
square
self.layOutTheBoardData.squareName
squareMeters
@self.squareMeters
boardLeft
boardLeft
boardBottom
boardBottom
8Create Instance
Object to Create
@self.pieceObject
X
spot.x
Y
spot.y
Created As
piece
9Change Variable
Variable
piece.name
Value
self.layOutTheBoardData.squareName
10Create Instance
Object to Create
@self.squareObject
X
spot.x
Y
spot.y
Created As
square
11Change Variable
Variable
square.name
Value
self.layOutTheBoardData.squareName
12Create Instance
Object to Create
@self.moveMarkObject
X
spot.x
Y
spot.y
Created As
moveMark
13Change Variable
Variable
moveMark.name
Value
self.layOutTheBoardData.squareName
14Ifdata('Position', self.layOutTheBoardData.squareName, 'file') == 1
Then
15Create Instance
Object to Create
@self.rankLabelObject
X
spot.x
Y
spot.y
Created As
rankLabel
16Change Variable
Variable
rankLabel.name
Value
self.layOutTheBoardData.squareName
17Ifdata('Position', self.layOutTheBoardData.squareName, 'rank') == 1
Then
18Create Instance
Object to Create
@self.fileLabelObject
X
spot.x
Y
spot.y
Created As
fileLabel
19Change Variable
Variable
fileLabel.name
Value
self.layOutTheBoardData.squareName
20Trigger Custom Event
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.

ObjectBoard
Transform
Bounding Box > SizeX 30, Y 30
Sprite
SpriteWalnut Board
Transform > SizeX 30, Y 30
Data Structure
From LogicLay Out The Board
Data StructureLay Out The Board Data
Logic
Lay Out The Board
Shared Variables
pieceObjectPiece
rankLabelObjectRank Label
fileLabelObjectFile Label
squareObjectSquare
moveMarkObjectMove Mark

Open 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.

FunctionClear Targets

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.

ACTIONS
1Declare Variable
Type
Text
Name
square
2Reset Data Table
Table
Targets
3RepeatdataCount('Position')times
Each time
4Change Variable
Variable
square
Value
dataRow('Position', local.index)
5Control Data Row
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.

FunctionLook At Square

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.

PARAMETERS
NameTypeStarts at
fileNumber0
rankNumber0
sideText
canMoveBooleanYes
canCaptureBooleanYes
RETURN TYPEBoolean
ACTIONS
1Declare Variable
Type
Boolean
Name
isOnBoard
Value
false
2Declare Variable
Name
square
Value
0
3Declare Variable
Type
Boolean
Name
keepGoing
Value
false
4Iffile >= 1 && file <= 8 && rank >= 1 && rank <= 8
Then
5Change Variable
Variable
isOnBoard
Value
true
6Change Variable
Variable
square
Value
(rank - 1) * 8 + (file - 1)
7IfisOnBoard == true && data('Position', square, 'kind') == ""
Then
8Change Variable
Variable
keepGoing
Value
true
9IfkeepGoing == true && canMove == true
Then
10Set Data Cell
Table
Targets
Row
square
Column
"reachable"
Value
"true"
11IfisOnBoard == true && data('Position', square, 'kind') != "" && data('Position', square, 'side') != side && canCapture == true
Then
12Set Data Cell
Table
Targets
Row
square
Column
"reachable"
Value
"true"
13Return
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.

FunctionFollow Direction

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.

PARAMETERS
NameTypeStarts at
fromText
directionNumber0
ACTIONS
1Declare Variable
Type
Text
Name
side
2Declare Variable
Name
forward
Value
1
3Declare Variable
Name
file
Value
0
4Declare Variable
Name
rank
Value
0
5Declare Variable
Name
stepsLeft
Value
0
6Declare Variable
Type
Boolean
Name
keepGoing
Value
true
7Change Variable
Variable
side
Value
data('Position', from, 'side')
8Change Variable
Variable
forward
Value
data('Sides', side, 'forward')
9Change Variable
Variable
file
Value
data('Position', from, 'file')
10Change Variable
Variable
rank
Value
data('Position', from, 'rank')
11Change Variable
Variable
stepsLeft
Value
data('Directions', direction, 'steps')
12Ifrank == data('Sides', side, 'pawnRank')
Then
13Change Variable
Variable
stepsLeft
Value
data('Directions', direction, 'firstMoveSteps')
14WhilekeepGoing == true && stepsLeft > 0
Each time
15Change Variable
Variable
file
Operator
+=
Value
data('Directions', direction, 'fileStep')
16Change Variable
Variable
rank
Operator
+=
Value
data('Directions', direction, 'rankStep') * forward
17Change Variable
Variable
stepsLeft
Operator
-=
Value
1
18Look At SquareFunction
Action Name
squareLook
file
file
rank
rank
side
side
canMove
data('Directions', direction, 'canMove')
canCapture
data('Directions', direction, 'canCapture')
19Change Variable
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.

FunctionFind Moves

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).

PARAMETERS
fromText
ACTIONS
1Declare Variable
Type
Text
Name
kind
2Clear TargetsFunction
3Change Variable
Variable
kind
Value
data('Position', from, 'kind')
4RepeatdataCount('Directions')times
Each time
5Ifdata('Directions', local.index, 'kind') == kind
Then
6Follow DirectionFunction
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.

Logic ComponentSelect and MoveAttach to: Game Rules

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.

Attach toAny Object
DATA STRUCTURES
Board Stateself.boardState
On Square Clicked
WhensquareClickedCustom Event
1Declare Variable
Type
Text
Name
selectedSquare
2Declare Variable
Type
Text
Name
clickedSquare
3Change Variable
Variable
clickedSquare
Value
other.squareInfo.name
4Change Variable
Variable
selectedSquare
Value
self.boardState.selected
5IfselectedSquare != "" && data('Targets', clickedSquare, 'reachable') == true
Then
6Set Data Cell
Table
Position
Row
clickedSquare
Column
"kind"
Value
data('Position', selectedSquare, 'kind')
7Set Data Cell
Table
Position
Row
clickedSquare
Column
"side"
Value
data('Position', selectedSquare, 'side')
8Set Data Cell
Table
Position
Row
selectedSquare
Column
"kind"
Value
''
9Set Data Cell
Table
Position
Row
selectedSquare
Column
"side"
Value
''
10Change Component Value
Component Value
self.boardState.lastFrom
Value
selectedSquare
11Change Component Value
Component Value
self.boardState.lastTo
Value
clickedSquare
12Change Component Value
Component Value
self.boardState.selected
Value
''
13Clear TargetsFunction
14Otherwise
15Ifdata('Position', clickedSquare, 'kind') != "" && clickedSquare != selectedSquare
Then
16Change Component Value
Component Value
self.boardState.selected
Value
clickedSquare
17Find MovesFunction
from
clickedSquare
18Otherwise
19Change Component Value
Component Value
self.boardState.selected
Value
''
20Clear TargetsFunction
21Trigger Custom Event
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.

FunctionShow Piece On Square

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.

PARAMETERS
NameTypeStarts at
pieceObjectStructural
Required Components
Slot NamesquareInfo
Component TypeData Structure
Required SchemaSquare Info
ACTIONS
1Declare Variable
Type
Text
Name
kind
2Declare Variable
Type
Text
Name
side
3Change Variable
Variable
kind
Value
data('Position', piece.squareInfo.name, 'kind')
4Ifkind == ""
Then
5Set Alpha
Applies to
piece
Alpha
0
6Otherwise
7Set Alpha
Applies to
piece
8Change Variable
Variable
side
Value
data('Position', piece.squareInfo.name, 'side')
9Set Frame
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.

Logic ComponentShow PieceAttach to: PieceAddDelete

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").

Attach toAny Object
DATA STRUCTURES
Square Infoself.squareInfo
Show Piece Dataself.showPieceData
On Board Laid Out
WhenboardLaidOutCustom Event
1Declare Variable
Type
Text
Name
kind
2Change Variable
Variable
kind
Value
data('Position', self.squareInfo.name, 'kind')
3Ifkind == ""
Then
4Set Alpha
Alpha
0
5Otherwise
6Set Alpha
7Change Component Value
Component Value
self.showPieceData.side
Value
data('Position', self.squareInfo.name, 'side')
8Set Frame
Frame
data('Kinds', kind, self.showPieceData.side)
1Show Piece On SquareFunction
piece
self
On Position Changed
WhenpositionChangedCustom Event
1Show Piece On SquareFunction
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.

Play it!

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.
How it works

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.

Challenge

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.