- Learn
- Tutorials
- Algorithms
- Cocktail Shaker Sort
- 5 The Finished Puzzle
5 The Finished Puzzle
By the end of this chapter, Picture Puzzle is finished. Press Sort, and the computer runs the whole sort by itself, at Slow, Steady or Fast, while the pieces glide past each other instead of jumping. Choose 9, 25 or 64 pieces. Choose the Village, the Forest or the Harbor, or upload a picture of your own. Open How it works, and follow the sort line by line. When the last piece lands, the lines between the pieces disappear.
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, to open and compare. It’s the finished game, the same one the Welcome page plays.
To open it, start Myth Engine, choose File › Open Project... and pick the downloaded file.
5.1 The Idea
The Village is whole at the end of Chapter 4. It took 1478 presses of Step to get there, and your hand did every one.
This chapter hands the pressing to the game. Press Sort, and a timer starts. Every time it rings, it asks the computer for a Step, the very Step your hand asked for. The computer doesn’t sort a new way. It asks the same question about the same pairs, in the same order. So Sort ends on the same counts as Step: 1478 comparisons and 819 swaps.
A timer that rings over and over, with the same wait between rings, is a recurring timer. It’s like a metronome on a piano. It doesn’t play a note. It only keeps the beat, and the computer plays a Step on every tick. How fast it ticks is the speed: Slow, Steady or Fast.
There’s a catch, and it’s the chapter’s one hard idea. From now on, the pieces slide. Two pieces of a swap glide past each other instead of jumping. But the board changes at once. The slide only shows it, a fraction of a second later. So while the pieces glide, the next comparison has to wait, or the board would run ahead of the picture.
The game keeps that wait with a cooldown, a stopwatch with a name. Every slide starts it. While it runs, new moves wait their turn.
The rest of the chapter is everything around the sort. The game learns who plays, you or the computer, so the computer’s colors show only while it’s sorting. The board learns three sizes. The Preview learns three pictures and one of yours. And a panel called How it works explains the sort while it runs.
A board laid out back to front is the most work a sort can have. Every pair of its pieces is out of order, so it takes one swap for every pair. That’s 36 swaps on 9 pieces, 300 on 25, and 2016 on 64.
5.2 The Plan
Here’s how the new pieces work together. Come back to these lines at the end, when every name is something you’ve built.
- Two slots trade pieces -> Slide Pieces starts the pieceSlide cooldown and sends
slideStarted-> the two Pieces glide to their slots. - A press, a tap or H -> Let Player Play ->
$whoPlaysis Player, a running sort pauses, and the Outlines lose their green and amber. - Sort, or A -> Sort Timer lets the computer play and starts the pictureSort timer.
- Every ring of the timer -> Sort Timer asks Computer Sort for Steps, as many as the speed allows, while no piece slides.
- The sort ends -> Computer Sort sends
sortEnded-> Sort Timer stops the timer. - A Count Button ->
$gridSizechanges andpieceCountChosengoes out -> Arrange Board shuffles, and every Piece and Outline lays itself out for the new size. - A Picture Button, or Upload -> Use Picture sends
pictureChosen-> the Preview and the pieces show the new picture, and Arrange Board shuffles. - Every piece home and nothing sliding -> the Whole Picture covers the board.
- How it works, or F -> Lesson Panel Switch turns the Puzzle Controls off and the Lesson Panel Controls on -> the panel shows, and the puzzle waits.
5.3 Set Up
Chapter 5 brings the rest of the pictures, five Commands, a second set of keys, nine Globals and a lot of placements.
ART lists the pictures this chapter starts to use. The Starter Kit brought every one of them. Four are named Uploaded. They’re a plain dark green square for now, and the Upload button paints your own picture into them while the game runs.
COMMANDS and INPUT CONTEXTS go together, so read about both before you start. The card shows the Commands first, but the order you make them in matters here.
An Input Context is a set of keys. Your project has one already. It’s called Default, and every key you’ve made so far lives in it. This chapter renames it Puzzle Controls, and adds a second context, Lesson Panel Controls, for the How it works panel. Only one of the two is on at a time.
So make them in this order. First, rename Default to Puzzle Controls. Then, with its row selected, add Run or Pause (A), Player Plays (H), Computer Plays (C) and How It Works (F). They join Puzzle Controls. Then add the Lesson Panel Controls context. It starts Inactive at Start, and its row is selected now, so Close Panel goes into it, with its two keys, F and Escape. The Set up card shows where each of these lives.
F and Escape now have two jobs each. F opens the panel from Puzzle Controls and closes it from Lesson Panel Controls. Escape cancels a selection in one and closes the panel in the other. But the two contexts are never on at once, so a key only ever means one thing.
GLOBAL VARIABLES are nine new values, and you make them in Show Piece’s Globals card, as before. Three Texts start empty: $sortButtonLabel, $lessonPass and $lessonOutcome. Each part of the chapter says what its own Globals are for, when it uses them.
PLACE THESE is long. Don’t place anything yet. Each part places its own, once the Objects and Logic it needs exist.
AHCFF, EscapeReset, New Arrangement, Choose Piece 1, Choose Piece 2, Choose Piece 3, Choose Piece 4, Choose Piece 5, Choose Piece 6, Choose Piece 7, Choose Piece 8, Choose Piece 9, Focus Left, Focus Right, Focus Up, Focus Down, Select Focused Piece, Cancel, Step, Run or Pause, Player Plays, Computer Plays, How It WorksClose PanelSave your project, and again at the end of each part.
5.4 Pieces That Glide
First, the pieces learn to move.
Until now, an exchange was a jump. One frame the two pieces were here, and the next they were there. Now each piece starts in the other’s slot and glides home along a straight line. Your exchanges take 0.22 seconds, about a blink.
5.4.1 Slide Pieces
Slide Pieces is the start of every slide. By the time anything calls it, Board Slots has already changed. The two numbers have traded places, and each Piece shows its new piece. Slide Pieces only arranges the show.
It’s given the two slots and how many seconds the slide lasts. It writes all three into Globals, $slideFrom, $slideTo and $slideSeconds, where every Piece can read them. It starts the pieceSlide cooldown on Puzzle Rules, for those same seconds. Last, it sends slideStarted.
The cooldown’s name comes back on many cards in this chapter, always “pieceSlide”. Keep those quotes. Values, quote marks and all explains the formula slots.
Shows two slots trading pieces as a slide: each of the two pieces starts at the other slot and moves to its own over seconds. The board has already changed; the slide only shows it. While the pieceSlide cooldown of Puzzle Rules runs, new moves wait.
- Variable
$slideFrom- Value
firstSlot
- Variable
$slideTo- Value
secondSlot
- Variable
$slideSeconds- Value
seconds
- Applies to
puzzleRules- Cooldown Key
"pieceSlide"- Seconds
seconds
- Custom Event
slideStarted
5.4.2 Slide Piece
Slide Piece needs a place to keep the other slot while it sets up the glide. Make this form with the Data Structures card’s + before its Events.
What each Piece remembers while it slides: otherSlot, the other slot of the exchange, where the slide starts.
Slide Piece lives on every Piece. When slideStarted arrives, 62 of the 64 Pieces have nothing to do. Their If says no.
The two that answer are standing on $slideFrom and $slideTo. Each shows the piece that came from the other slot, so it should start there. First it works out the other slot, kept in self.slidePieceData.otherSlot. It takes $slideFrom, and if that’s its own slot, $slideTo instead.
Then it jumps to the middle of otherSlot, through Slot Center, and steps in front of the other pieces with Set Z Order. Two Tween Actions glide it home: one for position.x, one for position.y, each over $slideSeconds. Each tweens a value of the Piece’s own Transform. Leave Value Of on Component, and type or choose self.transform.position.x in the Value box, or position.y for the second. The card gives that as Value self.transform and Property position.x. Its Target is home.x or home.y, and its Duration is $slideSeconds. The engine does the gliding. Slide Piece only says where to and how long.
Its Every Step Event has two Modes. Resting does nothing, and it’s where a Piece spends most of its life. Sliding watches the pieceSlide cooldown, frame after frame. When the cooldown runs out, the piece is home. It steps back among the others, switches to Resting, and sends slideEnded.
One more Event is for a slide that’s cut short, before the piece gets home. Press Reset or Shuffle in the middle of a slide, and boardArranged arrives while the piece is still on its way. Then Control Tween ends the glide where it is, and the piece settles at once. It starts on Operation Stop and Which All, the choices it needs, so it ends both of the Piece’s tweens.
Make the Every Step Event and its two Modes before the slideStarted Actions, because Switch Mode picks them from lists.
Slides this Piece onto its slot when its slot was one of the two in a slide: it starts at the other slot and moves in a straight line to its own over slideSeconds, then stands exactly on its slot. While the Piece slides, only this Logic moves it.
Any Objectself.slotNumberself.slidePieceDataself.slotNumber.slot == $slideFrom || self.slotNumber.slot == $slideTo- Component Value
self.slidePieceData.otherSlot- Value
$slideFrom
self.slotNumber.slot == $slideFrom- Component Value
self.slidePieceData.otherSlot- Value
$slideTo
- Action Name
start- slot
self.slidePieceData.otherSlot
- Position Relative To
Screen- X
start.x- Y
start.y
- Depth Amount
1
- Action Name
home- slot
self.slotNumber.slot
- Value
self.transform- Property
position.x- Target
home.x- Duration
$slideSeconds
- Value
self.transform- Property
position.y- Target
home.y- Duration
$slideSeconds
- Event
Every Step- Mode
Sliding
- Action Name
slideDone- Applies to
@self.puzzleRules- Cooldown Key
"pieceSlide"
slideDone.value == true- Depth Amount
0
- Event
Every Step- Mode
Resting
- Custom Event
slideEnded
- Depth Amount
0
- Event
Every Step- Mode
Resting
The Piece gets Slide Piece. Its puzzleRules Shared Variable already names Puzzle Rules, and this Logic uses that same value.
Window / UIUIX 68, Y 68-1Village Pieces 64X 68, Y 68Show Piece, Lay Out Slot, Piece Pointer, Slide PieceShow Piece, Lay Out Slot, Piece PointerSlot NumberSlide PieceSlide Piece DataPuzzle Rules5.4.3 Make Player Exchange
Make Player Exchange is your exchange, and it calls Slide Pieces right after Moves counts. It gains two inputs, puzzleRules and slideSeconds, and hands both on.
The player's exchange: the pieces of two slots trade places, Moves counts it, the two pieces slide over slideSeconds, and every Piece is told.
- firstSlot
firstSlot- secondSlot
secondSlot
- Variable
$moves- Operator
+=- Value
1
- puzzleRules
puzzleRules- firstSlot
firstSlot- secondSlot
secondSlot- seconds
slideSeconds
- Custom Event
piecesExchanged
5.4.4 Player Exchange
Player Exchange decides how long your slides last. It gains a Parameter, exchangeSlideSeconds, at 0.22, and both of its calls to Make Player Exchange pass it along.
It gains one Event too, clearSelectionRequested. When the computer takes over, a half-done selection has to end, and only Player Exchange can switch its own pieceChosen back. So this Event ends the selection the way the others do: a Switch Mode to Nothing Selected, then Clear Selection. Nothing sends it yet. Let Computer Play will, in the next part.
The player exchanges two pieces: the first piece chosen is selected, the second one trades places with it (choosing the selected piece again cancels). A drag from one piece to another exchanges them at once. exchangeSlideSeconds is how long the two pieces of an exchange slide.
Any Object- Variable
$selectedSlot- Value
$chosenSlot
- Variable
$message- Value
data('Messages', 'selected', 'words')
- Event
On Piece Chosen- Mode
One Selected
- Custom Event
selectionChanged
$chosenSlot != $selectedSlot- firstSlot
$selectedSlot- secondSlot
$chosenSlot- puzzleRules
@self.puzzleRules- slideSeconds
@self.exchangeSlideSeconds
- Variable
$message- Value
""
- Event
On Piece Chosen- Mode
Nothing Selected
- firstSlot
$pressedSlot- secondSlot
$chosenSlot- puzzleRules
@self.puzzleRules- slideSeconds
@self.exchangeSlideSeconds
- Variable
$message- Value
""
- Event
On Piece Chosen- Mode
Nothing Selected
- Event
On Piece Chosen- Mode
Nothing Selected
- Event
On Piece Chosen- Mode
Nothing Selected
- Variable
$moves- Value
0
- Event
On Piece Chosen- Mode
Nothing Selected
5.4.5 Piece Press
Now the wait. A press on a piece while two pieces are still gliding would start a new exchange before the last one shows. So Piece Press asks first. Check Cooldown Ready answers whether the pieceSlide cooldown has run out. If it hasn’t, the press is ignored.
Follows one press of the pointer on a piece: released on the same piece it is a tap, released on another piece it is a drag, and released anywhere else it is forgotten. A press cut off (the game lost focus, or the touch was cut off) is forgotten too, when Input Interruptions sends selectionCanceled.
Any Object- Variable
$pressedSlot- Value
$chosenSlot
- Custom Event
selectionChanged
- Action Name
slideDone- Cooldown Key
"pieceSlide"
slideDone.value == true- Variable
$pressedSlot- Value
$chosenSlot
- Custom Event
selectionChanged
$pressedSlot >= 0$pressedSlot == $chosenSlot- Custom Event
pieceChosen
- Custom Event
piecesDropped
- Variable
$pressedSlot- Value
-1
- Custom Event
selectionChanged
- Event
On End Step- Mode
Release Seen
- Variable
$pressedSlot- Value
-1
- Custom Event
selectionChanged
- Event
On End Step- Mode
No Release
- Variable
$pressedSlot- Value
-1
- Custom Event
selectionChanged
Run the game. Tap two pieces. They glide past each other into their new slots. The Step button’s pieces still jump for now. They learn to glide two parts from here, once the speeds exist.
5.5 Who Plays
Next, the game learns whose turn it is.
When you play, the board shows your colors: blue for the focus or a press, gold for a choice. When the computer sorts, it adds green for settled slots and amber for its pair. Mixing the two is confusing. Green slots after your own exchange would mean nothing, because the computer has forgotten that board.
So the game keeps one Text, $whoPlays. It says Player or Computer, and green and amber show only while it says Computer.
5.5.1 Let Player Play
Let Player Play hands the board to you. If the computer was playing, $whoPlays becomes Player, and pauseRequested goes to Puzzle Rules, so a running sort stops where it is. Last, whoPlaysChanged tells the Outlines.
If you’re already playing, its If says no, and nothing happens. Its If reads $whoPlays == "Computer". Type the whole condition, quote marks and all.
The player takes over from the computer: $whoPlays becomes Player, a running sort pauses where it is, and the Outlines are told (whoPlaysChanged). When the player is already playing, nothing changes.
$whoPlays == "Computer"- Variable
$whoPlays- Value
'Player'
- Applies to
puzzleRules- Custom Event
pauseRequested
- Custom Event
whoPlaysChanged
5.5.2 Let Computer Play
Let Computer Play is its mirror. It hands the board to the computer, and it ends a half-done selection on the way. It can’t switch Player Exchange’s Mode, so it asks: Trigger Custom Event on Object sends clearSelectionRequested to Puzzle Rules, where Player Exchange answers.
The computer takes over from the player: $whoPlays becomes Computer, a half-done selection ends, and the Outlines are told (whoPlaysChanged). When the computer is already playing, nothing changes.
$whoPlays == "Player"- Variable
$whoPlays- Value
'Computer'
- Applies to
puzzleRules- Custom Event
clearSelectionRequested
- Custom Event
whoPlaysChanged
5.5.3 Who Plays
Who Plays is the switch, and it lives on Puzzle Rules. H hands the board to you, and so does a press on a piece. C hands it to the computer. So does every comparison, which means a Step takes over without asking.
Hands the game to the player or to the computer ($whoPlays): H and a press on a piece let the player play, and C and a comparison of the computer let the computer play. Keys that choose a piece let the player play through Choose Slot, and Sort through Sort Timer. The board never changes when who plays changes.
Any Object- puzzleRules
@self.puzzleRules
- puzzleRules
@self.puzzleRules
- puzzleRules
@self.puzzleRules
- puzzleRules
@self.puzzleRules
Here is Puzzle Rules as it is at the end of this chapter. Who Plays is the first of the five Logic Components it gains in this chapter, and the rest come one part at a time. Attach Who Plays now, using Puzzle Rules’ puzzleRules Shared Variable, and each of the others when its part makes it.
Make BoardMake Board DataComputer SortComputer Sort DataPuzzle RulesPiece OutlinePiecePuzzle Rules5.5.4 Choose Slot
The keys 1 to 9 and Enter come through Choose Slot. A key hands the board to you at once, even while pieces slide. Then Choose Slot waits for the slide, the same way Piece Press does, before it chooses anything.
Tells Puzzle Rules that the player chose a slot, as a tap on a piece does. Keys 1 to 9 and Enter use it. A key also lets the player play, even while pieces slide.
- Variable
$chosenSlot- Value
slot
- Applies to
puzzleRules- Custom Event
pieceChosen
- puzzleRules
puzzleRules
- Action Name
slideDone- Applies to
puzzleRules- Cooldown Key
"pieceSlide"
slideDone.value == true- Variable
$chosenSlot- Value
slot
- Applies to
puzzleRules- Custom Event
pieceChosen
5.5.5 Color Outline
Before Color Outline paints green or amber, it asks whether the computer is playing. Each of those Ifs gains $whoPlays == "Computer", joined to its other tests with &&. Type the whole new condition from the Changes card. Every test must be true.
Colors one Outline from what is shown on the board now: a settled slot is green, the keyboard focus and a pressed piece are blue, the selected piece is gold, the pair the computer compared last is amber, and every other Outline keeps the normal color. Green and amber are the computer's colors: they show only while the computer plays ($whoPlays).
slotNumberData StructureSlot Number- Name
outlineSlot- Value
0
- Variable
outlineSlot- Value
outline.slotNumber.slot
- Applies to
outline- Value
data('Outline Colors', 'normal', 'color')
$comparedSlot >= 0 && outlineSlot < $rangeStart$whoPlays == "Computer" && $comparedSlot >= 0 && outlineSlot < $rangeStart- Applies to
outline- Value
data('Outline Colors', 'settled', 'color')
$comparedSlot >= 0 && outlineSlot > $rangeEnd$whoPlays == "Computer" && $comparedSlot >= 0 && outlineSlot > $rangeEnd- Applies to
outline- Value
data('Outline Colors', 'settled', 'color')
outlineSlot == $focusSlot || outlineSlot == $pressedSlot- Applies to
outline- Value
data('Outline Colors', 'focus', 'color')
outlineSlot == $selectedSlot- Applies to
outline- Value
data('Outline Colors', 'selected', 'color')
$comparedSlot >= 0 && outlineSlot >= $comparedSlot && outlineSlot <= ($comparedSlot + 1)$whoPlays == "Computer" && $comparedSlot >= 0 && outlineSlot >= $comparedSlot && outlineSlot <= ($comparedSlot + 1)- Applies to
outline- Value
data('Outline Colors', 'compared', 'color')
5.5.6 Show Outline
Show Outline hears one more message, whoPlaysChanged, so every edge repaints the moment the board changes hands.
Colors this Outline whenever what it shows may have changed: the player's selection, focus or press, or the computer's compared pair and unsorted range, or who plays.
Any Objectself.slotNumber- outline
self
- outline
self
- outline
self
- outline
self
- outline
self
Run the game. Press C, then Step a few times. The amber walks along as before. Press H. The amber is gone, and the edges keep their plain color. Press Step again, and it’s back, because a comparison hands the board to the computer.
5.6 Sort, by Itself
Now the timer. This is the part the whole chapter is for.
Before Sort can run, it needs words for its button, numbers for its speeds, and a way to hear that the sort has ended.
Messages gains seven rows. Two are the button’s own words, Sort and Pause. Paused is what the bottom line says when you stop the sort. The other four wait for later parts.
Reset.Choose another piece.Picture complete.Swapped.Kept.This puzzle needs each home position exactly once.Paused.SortPauseForward pass.Backward pass.Picture loaded.Could not open that image. Try a PNG, JPEG or WebP.Sort Speeds is a new table, one row for each speed. Its three columns are the whole feel of a speed. How often the timer rings is intervalSeconds. How many Steps it may ask for on one ring is comparisonsPerTick. And how long a swap’s slide takes is slideSeconds.
Slow rings every 0.4 seconds and asks for 1 Step, so you can follow every pair with your eyes. Steady rings every 0.06 seconds. Fast rings every 0.0167 seconds, and asks for up to 16 Steps each time. Fast’s slides take 0.07 seconds, Steady’s 0.18 and Slow’s 0.35.
The table comes with its own Data Structure, named after it. Make that form’s fields first.
One row of the "Sort Speeds" Data Table.
0.410.350.0610.180.0167160.075.6.1 Compare Next Pair
Compare Next Pair is where the computer’s swaps learn to glide. After it counts a swap, it calls Slide Pieces for the same two slots. The seconds come from Sort Speeds, in the row for $speed, so a Slow swap glides longer than a Fast one. It gains a puzzleRules Parameter to hand on.
One comparison of the computer: it reads the pieces of a slot and the slot to its right, and swaps them when the left piece's ID is larger. It counts the comparison and any swap, and tells the board.
- Variable
$comparisons- Operator
+=- Value
1
data('Board Slots', leftSlot, 'piece') > data('Board Slots', leftSlot + 1, 'piece')- firstSlot
leftSlot- secondSlot
leftSlot + 1
- Variable
$swaps- Operator
+=- Value
1
- puzzleRules
puzzleRules- firstSlot
leftSlot- secondSlot
leftSlot + 1- seconds
data('Sort Speeds', $speed, 'slideSeconds')
- Variable
$message- Value
data('Messages', 'swapped', 'words')
- Variable
$message- Value
data('Messages', 'kept', 'words')
- Variable
$comparedSlot- Value
leftSlot
- Custom Event
pairCompared
5.6.2 Request Step
Request Step changes in two ways. First, it sends pauseRequested. A Step you ask for takes the sort out of the timer’s hands, so a running sort stops, and you decide each Step from there. Then it waits for any slide to land before it sends stepRequested.
Asks Puzzle Rules to pause a running sort, then for one Step of the computer's sort once no piece is sliding. The Step Button and the Step Command (Space) both use it.
- Applies to
puzzleRules- Custom Event
pauseRequested- Custom Event
stepRequested
- Action Name
slideDone- Applies to
puzzleRules- Cooldown Key
"pieceSlide"
slideDone.value == true- Applies to
puzzleRules- Custom Event
stepRequested
5.6.3 Request Sort and Request Lesson
Two more Functions have Request Step’s old shape, one message each. Request Sort sends sortRequested. It’s for the Sort button and A. And for the How it works button and F, Request Lesson sends lessonRequested, a message the panel will answer. Nothing listens for lessonRequested yet. The last part will.
Asks Puzzle Rules to start the computer's sort, or to pause it while it runs. The Sort Button and the Run or Pause Command (A) both use it.
- Applies to
puzzleRules- Custom Event
sortRequested
Asks Puzzle Rules to open the How it works panel. The How it works Button and the How It Works Command (F) both use it.
- Applies to
puzzleRules- Custom Event
lessonRequested
Puzzle Commands learns the two new keys, A and F, and each one calls its own new Function.
The keys ask for the same things as the Buttons: R for Reset, N for a new arrangement. Escape cancels a selection. Space asks the computer for one Step. A starts or pauses the computer's sort, and F opens the How it works panel.
Any Object- puzzleRules
@self.puzzleRules
- puzzleRules
@self.puzzleRules
- Custom Event
selectionCanceled
- puzzleRules
@self.puzzleRules
- puzzleRules
@self.puzzleRules
- puzzleRules
@self.puzzleRules
5.6.4 Computer Sort
Computer Sort learns to speak up about two things it already does. Each call to Compare Next Pair passes puzzleRules now.
Every time a pass begins, Computer Sort says which way, with forwardPassStarted or backwardPassStarted. The How it works panel will listen. And when the sort can’t go on, it says sortEnded. That happens on a board it refuses, in Fresh’s Otherwise. It happens when a pass ends the sort, right after the small If switches to Finished, in both passes. And it happens when every piece comes home.
The computer's cocktail shaker sort, one comparison per Step. The first Step on a board checks it and begins a forward pass from the first slot. Passes then go back and forth over the unsorted range, which shrinks by one slot at the end of each pass, until every piece is home or a pass makes no swaps. When the sort is finished, or the board cannot be sorted, it sends sortEnded.
Any Objectself.computerSortData- Action Name
boardCheck
boardCheck.value == true- Variable
$rangeStart- Value
0
- Variable
$rangeEnd- Value
$gridSize * $gridSize - 1
- Component Value
self.computerSortData.swapsBeforePass- Value
$swaps
- leftSlot
$rangeStart- puzzleRules
@self.puzzleRules
- Event
On Step Requested- Mode
Forward Pass
- Custom Event
forwardPassStarted
- Variable
$message- Value
data('Messages', 'invalid', 'words')
- Custom Event
sortEnded
- leftSlot
$comparedSlot + 1- puzzleRules
@self.puzzleRules
($comparedSlot + 1) == $rangeEnd- Variable
$rangeEnd- Operator
-=- Value
1
- Action Name
forwardPassEnd- swapsBeforePass
self.computerSortData.swapsBeforePass
forwardPassEnd.value == false- Event
On Step Requested- Mode
Finished
- Custom Event
sortEnded
- Custom Event
passFinished
forwardPassEnd.value == true- Event
On Step Requested- Mode
Backward Pass
- Custom Event
backwardPassStarted
- Component Value
self.computerSortData.swapsBeforePass- Value
$swaps
- leftSlot
$comparedSlot - 1- puzzleRules
@self.puzzleRules
$comparedSlot == $rangeStart- Variable
$rangeStart- Operator
+=- Value
1
- Action Name
backwardPassEnd- swapsBeforePass
self.computerSortData.swapsBeforePass
backwardPassEnd.value == false- Event
On Step Requested- Mode
Finished
- Custom Event
sortEnded
- Custom Event
passFinished
backwardPassEnd.value == true- Event
On Step Requested- Mode
Forward Pass
- Custom Event
forwardPassStarted
- Component Value
self.computerSortData.swapsBeforePass- Value
$swaps
- Event
On Step Requested- Mode
Fresh
- Event
On Step Requested- Mode
Fresh
$piecesHome == ($gridSize * $gridSize)- Event
On Step Requested- Mode
Finished
- Custom Event
sortEnded
5.6.5 Sort Timer
Sort Timer runs the sort by itself, from Puzzle Rules. Take it beat by beat.
Its sortRequested Event has two Modes, Stopped and Running. Stopped is where it starts. A press of Sort there asks one question: is some piece still away from home? If so, it lets the computer play, clears the bottom line, and starts the timer. A press of Sort in Running pauses. It stops the timer and says Paused.
Its speedChosen Event has the same two Modes, Stopped and Running, with a different job in each. Stopped does nothing, because a sort that isn’t running only needs $speed for later. Running starts the timer again, so the new speed takes hold at once.
Two Functions start and stop the timer. They can’t switch Modes, so Sort Timer switches both of those Events itself, with two Switch Modes just before each call. Those pick their Modes from lists, and they work on Sort Timer itself, so their Applies To stays Self. So make the sortRequested and speedChosen Events first, each with its two Modes and no Actions yet. Make its puzzleRules Shared Variable from its card first. Then attach Sort Timer to Puzzle Rules, using Puzzle Rules’ puzzleRules Shared Variable.
5.6.6 Start Sort Timer
Start Sort Timer starts the pictureSort timer on Puzzle Rules. Start Recurring Timer reads how often it rings from Sort Speeds, and starting it again gives it the new beat. Then the button’s word becomes Pause. Sort Timer has already switched both Events to Running before it calls this.
Starts the pictureSort timer at the chosen speed (or starts it again at a new speed) and makes the Sort Button read Pause.
- Applies to
puzzleRules- Timer Name
"pictureSort"- Repeat Every (s)
data('Sort Speeds', $speed, 'intervalSeconds')
- Variable
$sortButtonLabel- Value
data('Messages', 'pauseButton', 'words')
5.6.7 Stop Sort Timer
Stop Sort Timer undoes both. The timer stops, and the button reads Sort. Before each call, Sort Timer switches both Events back to Stopped. The board, the pass and the counters stay as they are, waiting for the next Sort or Step. That’s what makes Pause a pause.
Stops the pictureSort timer and makes the Sort Button read Sort. The board, the pass and the counters stay as they are.
- Applies to
puzzleRules- Timer Name
"pictureSort"
- Variable
$sortButtonLabel- Value
data('Messages', 'sortButton', 'words')
Now fill in Sort Timer. Here are its first three Events: when the game starts, Sort, and a new speed. The last two each show twice on the card, once for each Mode.
When the game starts, Sort Timer switches both Events to Stopped and calls Stop Sort Timer. Nothing is running yet. But $sortButtonLabel starts empty, and this is what first writes Sort on the button.
Runs the computer's sort by itself: Sort lets the computer play and starts the pictureSort timer, and every ring of the timer asks Computer Sort for Steps at the chosen speed. Sort again, a Step, the player taking over, a player exchange, Reset, Shuffle, Escape or opening the How it works panel pauses it, and it stops when the sort has ended. The board, the pass and the counters are kept.
Any Object- Event
On Sort Requested- Mode
Stopped
- Event
On Speed Chosen- Mode
Stopped
- puzzleRules
@self.puzzleRules
$piecesHome < ($gridSize * $gridSize)- puzzleRules
@self.puzzleRules
- Variable
$message- Value
""
- Event
On Sort Requested- Mode
Running
- Event
On Speed Chosen- Mode
Running
- puzzleRules
@self.puzzleRules
- Event
On Sort Requested- Mode
Stopped
- Event
On Speed Chosen- Mode
Stopped
- puzzleRules
@self.puzzleRules
- Variable
$message- Value
data('Messages', 'paused', 'words')
- Event
On Sort Requested- Mode
Running
- Event
On Speed Chosen- Mode
Running
- puzzleRules
@self.puzzleRules
Then the ring itself. Every time pictureSort rings, a Repeat asks for as many Steps as the speed’s comparisonsPerTick. Before each one, it checks two things. Is some piece still away from home, with the picture not yet whole? And has every slide landed? When both answers are yes, it sends stepRequested to Computer Sort.
That’s why a ring at Fast stops early. Sixteen Steps in a row would rush past the pieces before any of them could glide. But the first swap starts a slide, and the rest of that ring’s Steps find the cooldown running. The next ring tries again.
You might wonder why the ring doesn’t call Request Step. It would pause the sort, the very sort that’s asking for a Step.
After the ring come five more Events. Each has the same three Actions: two Switch Modes back to Stopped, then Stop Sort Timer. A pause, the end of the sort, a new arrangement, your own exchange or Escape stops the timer.
data('Sort Speeds', $speed, 'comparisonsPerTick')times- Action Name
slideDone- Cooldown Key
"pieceSlide"
$piecesHome < ($gridSize * $gridSize) && slideDone.value == true- Custom Event
stepRequested
- Event
On Sort Requested- Mode
Stopped
- Event
On Speed Chosen- Mode
Stopped
- puzzleRules
@self.puzzleRules
- Event
On Sort Requested- Mode
Stopped
- Event
On Speed Chosen- Mode
Stopped
- puzzleRules
@self.puzzleRules
- Event
On Sort Requested- Mode
Stopped
- Event
On Speed Chosen- Mode
Stopped
- puzzleRules
@self.puzzleRules
- Event
On Sort Requested- Mode
Stopped
- Event
On Speed Chosen- Mode
Stopped
- puzzleRules
@self.puzzleRules
- Event
On Sort Requested- Mode
Stopped
- Event
On Speed Chosen- Mode
Stopped
- puzzleRules
@self.puzzleRules
5.6.9 Slow, Steady and Fast
Some Object cards name Logic you’ll make later in this part. Make the Object first, then attach that Logic when its card comes. Later parts follow that order too.
Three Speed Buttons sit in a row under the word Speed, with a short blue line under the chosen one. The line’s picture is Gold Face, the same blue as the Sort button. That’s three new Objects: the Speed Caption, the Speed Button and the Speed Underline.
Window / UIUISpeed13Semibold#526478VectorWindow / UIUIX 92, Y 36Speed16Semibold#263D54CenterVector-1Button FaceX 92, Y 36Window / UIUIX 88, Y 3-1Gold FaceX 88, Y 3Choose Speed is the button’s Logic. It asks the Puzzle Controls the same question as Button Action. Then it writes its own speed, a Text Per Instance Variable, into $speed, and sends speedChosen.
Clicking or tapping a Speed Button makes its speed the chosen one. Each placement sets its speed (a row of Sort Speeds) and its text. While the How it works panel is open, the Button does nothing.
Any Object- Action Name
puzzleControlsOn- Input Context
Puzzle Controls
puzzleControlsOn.value == true- Variable
$speed- Value
self.speed
- Custom Event
speedChosen
Underline Chosen Speed shows one underline when its speed is the chosen one, and hides it otherwise. Show Speed Underline calls it when the underline is made. It calls it again at every speedChosen.
Shows one speed underline when its speed is the chosen one, and hides it otherwise.
speed == $speed- Applies to
underline- Visible
true
- Applies to
underline- Visible
false
Shows this underline under the chosen speed's Button only. Each placement sets the speed it stands for.
Any Object- underline
self- speed
self.speed
- underline
self- speed
self.speed
Place the Speed Caption, then the three Speed Buttons and their three Underlines, from PLACE THESE. Each button and the underline under it share one word, Slow, Steady or Fast: in the button’s Text, and in both Speed Variable fields.
Run the game, and press Sort. The button reads Pause, and the board comes alive. Pairs glide past each other, the amber flickers along the rows, and green creeps in from both ends.
5.7 Nine, Twenty-Five or Sixty-Four
Next, the board learns three sizes.
The board is made once, when the game starts, for the largest size: 64 slots. A smaller board uses its first slots and hides the rest. Each slot it keeps grows.
Piece Counts is a new table, one row for each size. Its gridSize is how many slots fill a row, such as the 3 of a board of 9 pieces, three rows of three. Its piecesColumn names the column of Pictures that holds the picture cut for that size.
The table comes with its own Data Structure, named after it. Make that form’s fields first.
One row of the "Piece Counts" Data Table.
3pieces95pieces258pieces64Pictures is a table of Sprites, one row for each picture. Each row holds the picture whole, for the Preview, and cut three ways. Pick each cell’s Sprite from its list.
The table comes with its own Data Structure, named after it. Make that form’s fields first.
One row of the "Pictures" Data Table.
Village PictureVillage Pieces 9Village Pieces 25Village Pieces 64Forest PictureForest Pieces 9Forest Pieces 25Forest Pieces 64Harbor PictureHarbor Pieces 9Harbor Pieces 25Harbor Pieces 64Uploaded PictureUploaded Pieces 9Uploaded Pieces 25Uploaded Pieces 645.7.1 Choose Piece Sprite
Choose Piece Sprite gives a Piece the right cut of the right picture. It looks in Piece Counts for the row whose gridSize is the board’s, with dataFind. That formula answers a row’s number, or -1 when no row matches. The row names the column, and $picture names the row of Pictures. Set Sprite does the rest.
Its piece input names no Object, so it stays on Structural, with nothing under it.
Gives a Piece the Sprite of the chosen picture cut for the chosen piece count: Piece Counts names the column of Pictures for the board's gridSize, and $picture names the row.
- Name
countRow- Value
0
- Type
Text- Name
piecesColumn
- Variable
countRow- Value
dataFind('Piece Counts', 'gridSize', $gridSize)
countRow >= 0- Variable
piecesColumn- Value
data('Piece Counts', countRow, 'piecesColumn')
- Applies to
piece- Sprite
data('Pictures', $picture, piecesColumn)
5.7.2 Show Piece
Show Piece calls Choose Piece Sprite before it shows its frame, when it’s placed and after every new arrangement.
Shows the picture frame of the piece that Board Slots puts in this Piece's slot, cut for the chosen piece count. Make Board gives each Piece its slot in its Slot Number (0 is the top-left slot, counting right, then down).
Any Objectself.slotNumber- piece
self
- Frame
data('Board Slots', self.slotNumber.slot, 'piece')
- piece
self
- Frame
data('Board Slots', self.slotNumber.slot, 'piece')
- Frame
data('Board Slots', self.slotNumber.slot, 'piece')
- Frame
data('Board Slots', self.slotNumber.slot, 'piece')
5.7.3 Lay Out One Slot
Lay Out One Slot puts one Piece or Outline where the board’s size wants it. Is its slot on the board? Then it’s shown, set on its slot’s middle, and scaled. A slot is $boardSide / $gridSize pixels across, so on 9 pieces it’s a third of the board. The Object was drawn to fit a slot of drawnSlotSide, 70 pixels, so its scale is slotSide, the slot’s side, divided by drawnSlotSide. A slot past the end of the board is hidden, and a hidden Piece answers no press.
Lays out one Piece or Outline for the board's piece count: a slot on the board is shown at its center and sized to the slot; a slot beyond the piece count is hidden, so it shows nothing and answers no input. drawnSlotSide is the slot side, in screen pixels, that the Object fits at scale 1.
slotNumberData StructureSlot Number- Name
slotSide- Value
0
slotObject.slotNumber.slot < ($gridSize * $gridSize)- Applies to
slotObject- Visible
true
- Action Name
center- slot
slotObject.slotNumber.slot
- Applies to
slotObject- Position Relative To
Screen- X
center.x- Y
center.y
- Variable
slotSide- Value
$boardSide / $gridSize
- Applies to
slotObject- Horizontal Scale
slotSide / drawnSlotSide- Vertical Scale
slotSide / drawnSlotSide
- Applies to
slotObject- Visible
false
5.7.4 Lay Out Slot
Lay Out Slot hands both its jobs to Lay Out One Slot now. Its old Slot Center and Set Position come out, and it gains a Shared Variable, drawnSlotSide, and an Event, boardArranged, for every new size.
The Piece Outline keeps drawnSlotSide at 70. Its square already fills the whole slot, and that same measure sets every new scale.
Places this Piece or Outline for the board's piece count: on its slot's center and sized to the slot when the slot is on the board, hidden when it is not. drawnSlotSide is the slot side, in screen pixels, that the Object fits at scale 1 (70, a slot of the 64-piece board).
Any Objectself.slotNumber- Action Name
center- slot
self.slotNumber.slot
- Position Relative To
Screen- X
center.x- Y
center.y
- slotObject
self- drawnSlotSide
@self.drawnSlotSide
- slotObject
self- drawnSlotSide
@self.drawnSlotSide
5.7.5 Make Board
Make Board finds the largest size in the last row of Piece Counts. dataCount answers how many rows a table has, so the last row is one less. It makes that size squared: 64 slots.
The rest of the board was ready already. One question changes, in the If at the end of When the Game Starts. Since Chapter 1, that If has sent a Shuffle when the count of slots is a multiple of 5, where every fifth piece wouldn’t deal each piece once. Now a game that starts at a smaller size gets a Shuffle too.
Keep the If and its request. Replace its condition with the card’s whole formula: the board starts smaller, or its slot count is a multiple of 5. The || joins those two tests. The struck If is the old condition; the green one is its replacement.
Makes the board when the game begins: a row of Board Slots for each slot, holding the starting arrangement, and on the screen an Outline with a Piece in front of it for each slot. The board is made once, for the largest piece count (the last row of Piece Counts); a smaller piece count uses its first slots and hides the rest (Lay Out Slot). The starting arrangement takes every fifth piece; a board where that would not hold each piece once (a piece count that is a multiple of 5, or a game that starts at a smaller count) starts with a Shuffle instead. slotCount is how many slots it makes; outline and piece are the Objects it makes.
Any Objectself.makeBoardData- Name
largestGridSize- Value
0
- Variable
largestGridSize- Value
data('Piece Counts', dataCount('Piece Counts') - 1, 'gridSize')
- Component Value
self.makeBoardData.slotCount- Value
largestGridSize * largestGridSize- Value
$gridSize * $gridSize
self.makeBoardData.slotCounttimes- Action Name
addedRow- Table
Board Slots- Row
text("Slot ", local.index + 1)
- Table
Board Slots- Row
local.index- Column
"piece"- Value
(5 * local.index + 3) % self.makeBoardData.slotCount
- Table
Board Slots- Row
local.index- Column
"startPiece"- Value
data('Board Slots', local.index, 'piece')
- Custom Event
boardMade
(self.makeBoardData.slotCount % 5) == 0$gridSize != largestGridSize || (self.makeBoardData.slotCount % 5) == 0- Custom Event
shuffleRequested
self.makeBoardData.slotCounttimes- Object to Create
@self.outline- X
0- Y
0- Created As
newOutline
- Variable
newOutline.slot- Value
local.index
- Applies to
newOutline- Custom Event
placedOnBoard
- Object to Create
@self.piece- X
0- Y
0- Created As
newPiece
- Variable
newPiece.slot- Value
local.index
- Applies to
newPiece- Custom Event
placedOnBoard
5.7.6 Arrange Board
Arrange Board learns that a new size or a new picture means a new deal. Both send a Shuffle. Reset and Shuffle also start the pieceSlide cooldown again at 0 seconds, so a slide under way ends at once.
Lays out a whole new arrangement when it is asked: Reset puts the starting arrangement back, Shuffle makes a new one, and so does a new piece count or a new picture. Then it tells every Piece that the board was arranged.
Any Object- Variable
$message- Value
data('Messages', 'reset', 'words')
- Cooldown Key
"pieceSlide"- Seconds
0
- Custom Event
boardArranged
- Variable
$message- Value
""
- Cooldown Key
"pieceSlide"- Seconds
0
- Custom Event
boardArranged
- Custom Event
shuffleRequested
- Custom Event
shuffleRequested
5.7.7 Hide Focus
Hide Focus takes the keyboard’s blue focus off the board. It’s the two steps Keyboard Focus did on a press, made into a Function, because a new size needs them too. The focus could be sitting on a slot the new board hides.
Hides the keyboard focus ($focusSlot -1), and tells the Outlines.
- Variable
$focusSlot- Value
-1
- Custom Event
selectionChanged
Keyboard Focus calls Hide Focus on a press, where those two steps were. It gains a pieceCountChosen Event that calls it too.
The keyboard plays like the pointer: keys 1 to 9 choose a slot, the arrow keys move a blue focus over the board, and Enter chooses the focused slot.
Any Object- puzzleRules
@self.puzzleRules- slot
0
- puzzleRules
@self.puzzleRules- slot
1
- puzzleRules
@self.puzzleRules- slot
2
- puzzleRules
@self.puzzleRules- slot
3
- puzzleRules
@self.puzzleRules- slot
4
- puzzleRules
@self.puzzleRules- slot
5
- puzzleRules
@self.puzzleRules- slot
6
- puzzleRules
@self.puzzleRules- slot
7
- puzzleRules
@self.puzzleRules- slot
8
- distance
-1
- distance
1
- distance
-$gridSize
- distance
$gridSize
$focusSlot >= 0- puzzleRules
@self.puzzleRules- slot
$focusSlot
- Variable
$focusSlot- Value
-1
- Custom Event
selectionChanged
5.8 Three Pictures and One of Your Own
Next, the Preview learns more pictures.
5.8.1 Use Picture
Use Picture makes a row of Pictures the one on the board. It writes the row’s name into $picture and sends pictureChosen. Arrange Board already listens for that message.
Makes a row of Pictures the picture the board shows: $picture becomes that row, and everyone who shows the picture is told (pictureChosen). Arrange Board then shuffles a new arrangement of it.
- Variable
$picture- Value
picture
- Custom Event
pictureChosen
5.8.2 Show Picture
Show Picture shows $picture whole, from the preview column of Pictures. It answers when the Preview is made and at every pictureChosen. The Preview uses it now. The Whole Picture will too.
Shows the chosen picture whole ($picture's preview in Pictures). The Picture Preview and the Whole Picture both use it.
Any Object- Sprite
data('Pictures', $picture, 'preview')
- Sprite
data('Pictures', $picture, 'preview')
Window / UIUIX 248, Y 248-1Village PictureX 248, Y 2485.8.4 Upload Picture
The Upload button lets you sort a picture of your own.
Myth has no block that opens your computer’s file chooser. So Upload Picture holds a short program in Run Code (JS), written in JavaScript, the language of web pages. Copy it from the card exactly as it is, line breaks and all.
Here’s what it does. It opens the chooser, for a PNG, JPEG, WebP or AVIF picture up to 25 MB. Pick one, and it cuts a square from the middle. It paints that square into the Uploaded row’s four Sprites, and sends pictureUploaded. A picture it can’t open sends uploadFailed instead. Canceling sends nothing at all.
The rest of Upload Picture is ordinary Logic, the kind you’ve built all along. A picture takes a moment to open. Press F in that moment, and the picture arrives with the panel open. Upload Picture closes the panel, so you see it. Then Use Picture chooses the Uploaded row, the way a Picture Button chooses the Village, and the bottom line says Picture loaded. The row’s name, Uploaded, goes into Use Picture’s box bare, as the card shows it.
Your picture lasts until the game closes. Choose the Village again, and the Village comes back.
Lets the player rebuild a picture of their own. Upload opens the file chooser; a PNG, JPEG, WebP or AVIF picture up to 25 MB is cut to a square from its middle and becomes the picture the board shows, for this session only, with a new arrangement. A picture that cannot be opened changes nothing but the message; canceling changes nothing.
Any Object- Java Script
const host=window.__mythBabylon,scene=host&&host.controller;
- Action Name
lessonOpenAtUpload- Input Context
Lesson Panel Controls
lessonOpenAtUpload.value == true- Custom Event
lessonCloseRequested
- picture
"Uploaded"
- Variable
$message- Value
data('Messages', 'uploaded', 'words')
- Variable
$message- Value
data('Messages', 'uploadFailed', 'words')
Request Upload asks for it.
Asks Puzzle Rules to let the player choose a picture of their own. The Upload Button uses it.
- Applies to
puzzleRules- Custom Event
uploadRequested
Now finish Button Action’s Upload branch with Request Upload. Place the Upload button with Command set to Upload. It’s the Puzzle Button once more, with its own size, white words, and Gold Face, the Sort button’s blue.
Run the game. Press Forest, and a waterfall in a green forest takes the board, shuffled. Press Harbor, and boats.
5.9 The Whole Picture
Next, the picture’s last moment.
A finished board still shows thin lines between the pieces. Each piece is a little smaller than its slot. When every piece is home, the game lays the picture whole over the board, and the lines disappear.
5.9.1 The Whole Picture
The Whole Picture is the picture again, the size of the whole board. Its Scene Depth Draw Order of 5 draws it over the pieces.
Window / UIUIX 560, Y 5605-1Village PictureX 560, Y 560Puzzle Rules5.9.2 Update Whole Picture
Update Whole Picture asks two things. Is the Game State Solved? And has every slide landed, so that each piece stands on its own slot? When both answers are yes, the Whole Picture shows, and otherwise it hides.
The slide matters. The last swap finishes the board the moment it’s made, but the two pieces still have to glide home. The picture waits for them.
Shows the whole picture over the board when the picture is complete (Game State Solved) and no piece is sliding, and hides it otherwise.
- Action Name
isSolved- Game State
Solved
- Action Name
slideDone- Applies to
puzzleRules- Cooldown Key
"pieceSlide"
isSolved.value == true && slideDone.value == true- Applies to
picture- Visible
true
- Applies to
picture- Visible
false
5.9.3 Show Whole Picture
Show Whole Picture asks that question whenever the answer might change: when it’s made, when the Game State changes, when a slide ends, and after a new arrangement.
Shows the whole picture, without the gaps between the pieces, once every piece is home and no piece is sliding.
Any Object- picture
self- puzzleRules
@self.puzzleRules
- picture
self- puzzleRules
@self.puzzleRules
- picture
self- puzzleRules
@self.puzzleRules
- picture
self- puzzleRules
@self.puzzleRules
Place the Whole Picture at 340 and -500, over the board. It’s hidden until the picture is complete.
5.10 How It Works
Last comes the panel that explains it all, while the sort runs.
Press How it works, or F, and a white panel covers the game. It says how the sort works in a few short lines, the ones you’ve been learning. Two lines follow the sort itself: the unsorted range and which pass it’s in, and the last pair with what happened to it. While the panel is open, the puzzle waits.
The waiting is the Input Contexts’ work. Opening the panel turns the Puzzle Controls off and the Lesson Panel Controls on. From then on, only Close Panel’s keys answer.
But a context only switches keys. A press on a piece or a button isn’t a key. That’s why the buttons ask Check Input Context Active before they act. They’ve been asking since the Sort button. Until now, the answer was always yes, and now it can be no.
5.10.1 The Panel’s Objects
The panel is made of six new Objects, most of them words. Lesson Panel is the white face. Lesson Title says How it works, in big dark letters. Lesson Line is one line of words, placed nine times. Lesson State and Lesson Result are the two lines that follow the sort, and the Close Button closes it.
Window / UIUIX 920, Y 760-1Panel FaceX 920, Y 760Window / UIUIHow it works27Extra Bold#263D54VectorWindow / UIUIEach piece has a home position.22Medium#526478VectorThe two sort lines count slots from 1, the way you would, so each of their live values adds 1 to the slot it shows.
Window / UIUIUnsorted: {$rangeStart + 1} to {$rangeEnd + 1}. {$lessonPass}19Medium#526478VectorWindow / UIUILast pair: slots {$comparedSlot + 1} and {$comparedSlot + 2}. {$lessonOutcome}18Medium#526478VectorWindow / UIUIX 110, Y 40Close16Semibold#263D54CenterVector-1Button FaceX 110, Y 40Puzzle Rules5.10.2 Show If Lesson Open
Show If Lesson Open shows one part of the panel while the Lesson Panel Controls are on, and hides it otherwise. Its part input names no Object, so it stays on Structural.
Shows one part of the How it works panel while the panel is open (the Lesson Panel Controls are on), and hides it otherwise.
- Action Name
lessonOpen- Input Context
Lesson Panel Controls
lessonOpen.value == true- Applies to
part- Visible
true
- Applies to
part- Visible
false
5.10.3 Show With Lesson Panel
Show With Lesson Panel is on the panel, its title, its lines and its button. When each is made, it moves it to the front with Set Z Order and asks the question. It asks again at every lessonToggled.
Shows this part of the How it works panel only while the panel is open, in front of the game. The panel, its title, its lines and its Close Button use it.
Any Object- Depth Amount
200
- part
self
- part
self
5.10.4 Show If Sort Under Way
The two sort lines have one more condition. Before the first comparison on a board, they’d have nothing true to say. So they show only while the panel is open and $comparedSlot is 0 or more.
Shows one line about the computer's sort while the How it works panel is open and the sort is under way, and hides it otherwise. Before the first comparison on a board ($comparedSlot is -1) the line has nothing to tell yet.
- Action Name
lessonOpen- Input Context
Lesson Panel Controls
lessonOpen.value == true && $comparedSlot >= 0- Applies to
line- Visible
true
- Applies to
line- Visible
false
5.10.5 Show Sort Lines
Show Sort Lines asks at the same moments as Show With Lesson Panel, and also after every comparison and every fresh start.
Shows this line about the computer's sort while the How it works panel is open and the sort is under way, in front of the game. The Lesson State and the Lesson Result use it.
Any Object- Depth Amount
200
- line
self
- line
self
- line
self
- line
self
5.10.6 Lesson Lines
Lesson Lines keeps the two lines’ words. After every comparison, it copies the bottom line’s Swapped or Kept into $lessonOutcome. When a pass begins, it writes Forward pass or Backward pass into $lessonPass. Remember forwardPassStarted and backwardPassStarted, from Computer Sort? This is who they were for.
Keeps the words of the How it works panel's two lines about the computer's sort up to date: the pass it is in ($lessonPass) and what its last comparison did ($lessonOutcome).
Any Object- Variable
$lessonOutcome- Value
$message
- Variable
$lessonPass- Value
data('Messages', 'forwardPass', 'words')
- Variable
$lessonPass- Value
data('Messages', 'backwardPass', 'words')
5.10.7 Close Lesson Panel
Close Lesson Panel turns the Lesson Panel Controls off and the Puzzle Controls back on, then sends lessonToggled. It’s the first card with Set Input Context Active, the Action that turns a set of keys on or off.
The first Set Input Context Active turns the lesson keys off, with Active false. The second turns the puzzle keys on. Active starts true, so that second card line is left out. Opening uses those same values.
Closes the How it works panel: the Lesson Panel Controls go off and the Puzzle Controls on again, and the panel's parts are told (lessonToggled).
- Input Context
Lesson Panel Controls- Active
false
- Input Context
Puzzle Controls
- Custom Event
lessonToggled
5.10.8 Lesson Panel Switch
Lesson Panel Switch opens and closes the panel, from Puzzle Rules. Opening does what Escape does first, with selectionCanceled. That ends a press or a choice, and Sort Timer hears it and pauses the sort. Then the contexts switch, and lessonToggled goes out.
Closing comes from F or Escape, through Close Panel, or from the Close Button’s message.
Opens the How it works panel when it is asked, and closes it on Close, F or Escape. While the panel is open the computer is stopped and only the Lesson Panel Controls are on, so the puzzle answers no key, Button or piece.
Any Object- Custom Event
selectionCanceled
- Input Context
Puzzle Controls- Active
No
- Input Context
Lesson Panel Controls
- Custom Event
lessonToggled
5.10.9 Close Lesson
Close Lesson lets a press on the Close Button end the lesson. Its request reaches Puzzle Rules, so clicking and pressing a closing key use the same panel switch.
Clicking or tapping the Close Button asks Puzzle Rules to close the How it works panel.
Any Object- Applies to
@self.puzzleRules- Custom Event
lessonCloseRequested
5.10.10 Piece Pointer
Piece Pointer asks the Puzzle Controls too, on a press and on a release. With the panel open, a piece under it tells Puzzle Rules nothing.
Tells Puzzle Rules when the pointer is pressed on this Piece and when it is released on it. Puzzle Rules decides what the press and the release mean. While the How it works panel is open, the Piece tells nothing.
Any Objectself.slotNumber- Variable
$chosenSlot- Value
self.slotNumber.slot
- Applies to
@self.puzzleRules- Custom Event
piecePressed
- Action Name
controlsOnAtPress- Input Context
Puzzle Controls
controlsOnAtPress.value == true- Variable
$chosenSlot- Value
self.slotNumber.slot
- Applies to
@self.puzzleRules- Custom Event
piecePressed
- Variable
$chosenSlot- Value
self.slotNumber.slot
- Applies to
@self.puzzleRules- Custom Event
pieceReleased
- Action Name
controlsOnAtRelease- Input Context
Puzzle Controls
controlsOnAtRelease.value == true- Variable
$chosenSlot- Value
self.slotNumber.slot
- Applies to
@self.puzzleRules- Custom Event
pieceReleased
Now place the panel from PLACE THESE: the Lesson Panel, the Title, the nine Lesson Lines with their own words and sizes, the two sort lines, and the Close Button. Last, place the How it works button, the Puzzle Button one more time, with Command set to Lesson.
Run the game, press Sort, and then press F to open the panel. The sort stops, and the panel tells you where it was.
Watch for each of these.
- Under the Preview, 64 and Fast are underlined. The board starts at 0 / 64, with the button beside Step reading Sort.
- Press Sort. It reads Pause, and pairs glide past each other along the rows. The amber pair flickers ahead, and green closes in from both ends.
- Press F while it runs. The panel opens, and the sort stops. A line reads Unsorted, then two slot numbers and Forward pass or Backward pass. The line under it names the last pair, by its two slots, and says Swapped or Kept.
- Press F again, then Sort. The sort goes on from the same pair.
- Then let it run all the way to the end, without touching anything. The caption reads 64 / 64, and the counter says Comparisons 1478 and Swaps 819, the same as all those Steps in Chapter 4. The bottom line says Picture complete, and the thin lines between the pieces disappear. The button reads Sort again.
- Press Sort on the finished picture. Nothing happens.
- Press 9. Nine large pieces fill the board, shuffled, and the underline moves to 9.
- Press Slow, then Sort. One pair every 0.4 seconds, and each swap glides for 0.35 seconds. You can follow every comparison.
- Press H. The sort pauses, and the green and amber leave the edges. Press C, and they’re back.
- Press Forest, then Harbor. Each one shuffles a new board of its picture.
- Press 64, Village, then Upload, and pick a photo of your own. It fills the board, cut into 64 pieces. The bottom line says Picture loaded.
- Tap two pieces. They glide into each other’s slots in 0.22 seconds, and Moves counts one.
Slide Pieces starts every glide, and the pieceSlide cooldown holds new moves until it lands. Who Plays decides whose colors show. Sort Timer presses Step for you, ring after ring, at the speed Sort Speeds gives. Piece Counts and Pictures choose the size and the picture, and every Piece lays itself out. How it works switches which keys listen. The buttons ask before they act.
Underneath all of it, the sort hasn’t changed since Chapter 4. Sort is a hand on Step that never tires. The board changes in an instant, and the slide only shows it later. The game you see is always a moment behind the numbers, and the cooldown keeps the two in step.
5.11 If It Didn’t Work
This chapter has more pieces than any other, so expect a slip or two. That’s normal. Run the game, try the one thing that misbehaves, and watch what it does.
Pieces jump instead of gliding? Look for Slide Piece on the Piece, and at its first If, which compares the Piece’s slot with $slideFrom and $slideTo. If a piece glides from the wrong place, look at otherSlot’s second step, inside the small If.
A piece glides and then stands a little off its slot? Look at the two Tween Actions. One is position.x, the other position.y, and each Target reads home.
Pieces stop answering after the first exchange, and never wake up? Perhaps the cooldown never ends. Look at Slide Pieces’ Start Cooldown, whose Seconds is seconds. Then look at the name pieceSlide on every card that asks for it. It should be spelled the same each time, with the same quote marks the card shows.
Sort does nothing? Look at the Sort button’s Command Variable, Sort, and Button Action’s Request Sort call. Next, look at Sort Timer’s sortRequested Event, and check that its Stopped Mode is the one it starts with.
Sort runs a few Steps and stops? Perhaps the ring calls Request Step, which pauses the sort. The ring sends stepRequested itself.
The button never reads Pause? Look at Start Sort Timer’s last step, and at the Sort button’s Text, {$sortButtonLabel}.
The sort finishes, but the button still says Pause? Look for each sortEnded in Computer Sort, two of them in the passes’ small Ifs, and for Sort Timer’s sortEnded Event.
Pressing 9 leaves 64 small pieces on the board? Look at Lay Out Slot’s boardArranged Event, and at Lay Out One Slot’s If. If nine pieces show the wrong pictures, look at Choose Piece Sprite.
Nothing on the board answers, ever? Perhaps the Puzzle Controls are off. Look at the INPUT CONTEXTS: Puzzle Controls is active at start, and Lesson Panel Controls isn’t. And look at the spelling of Puzzle Controls in each Check Input Context Active.
The panel never closes? Look for Close Panel in the Lesson Panel Controls, not in Puzzle Controls.
Upload opens no chooser at all? Perhaps a mark went missing in the program. Open the catch-up download, and go down its Run Code (JS) box beside yours, line by line.
Each of these is one small fix. Make it, run the game, and you’re back with the chapter. The catch-up download in the Goal is the finished game, if you’d like to compare.
The game is yours now, so make it say something of yours. Make a fourth speed, slower than Slow, so a friend can watch every pair and guess before it’s swapped. It’s a new row in Sort Speeds, a fourth Speed Button and a fourth Underline. Or give How it works a line in your own words, one more Lesson Line on the panel. What would you want someone to see, watching a sort for the first time?
In Chapter 1, the pieces lay where they’d been dealt, and nothing on the board could move them. Now they glide home by themselves, a pair at a time, and every piece, color, word and count on that screen is one you put there.
