Build a GameCreating Crystal Cascade

3  Clearing Lines

Goal

A full row breaks. Its crystals burst into shards of their own colors, the rows above drop down, and the LINES count climbs. Every crystal that locks gives a small pop.

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 4 from it.

Crystal Cascade, Chapter 3 finishedZip of a Myth project · 4.5 MB

To open it, right-click the downloaded file, choose Extract All... and then Extract. Start Myth Engine, choose File › Open Project... and pick the .mythproj file in the new folder. Nunito-OFL.txt beside it comes with the game.

3.1 The Idea

A full row reaches from wall to wall. Until now, it stays there like any other row, making the well shallower. This chapter lets the crystals break.

The row flashes white. Shards burst outward, the rows above drop into the gap, and LINES climbs. A piece that locks gives a small pop of light too. The well can empty as well as fill.

There’s a quiet problem inside that moment. If the row disappears at once, there’s nothing left to draw shattering. Instead, the game marks its cells first. The pictures show that mark while the numbers still remember each crystal’s color.

Only after the clear delay does the stack move. Mark, show, then move: those are separate jobs. The table keeps enough information for each to happen in its own time.

3.2 The Plan

  • Lock Piece writes the crystals, then sends pieceLocked to the well. Moving waits.
  • Clear Full Lines finds and marks full rows -> wellChanged makes their cells shatter -> linesCleared updates the count.
  • The clear-delay timer rings. Kept rows move downward, and unused rows at the top empty.
  • A short entry delay ends -> spawnPiece brings the next shape and restores its controls.

3.3 Set Up

Continue from Chapter 2 or its catch-up project. The Starter Kit already has the shard and sparkle pictures. Add the lines Global from this setup card through the + on the Logic canvas’s Globals block.

Leave the placements until the end. The well’s new work comes first; the words can wait until there is something to count.

Set upWhat this chapter adds
ART (sprites, from the starter kit)
FX Sparkle
FX Shard
GLOBAL VARIABLES
$linesNumberstarts at 0
SCENE Gameplay: PLACE THESE
ObjectXY
Game Rules033.75
LINES Label-522-97.5
with Z-Index = 120
LINES Value-432-97.5
with Z-Index = 120

3.4 The Well Remembers a Clear

Give a cell one more thing to remember.

Add isClearing to Well Entry, using the Changes card. The table’s rows follow their Entry Type, so this field becomes a column in Well. Its default leaves every cell unmarked.

Data StructureWell EntryAddDelete

One row of the "Well" Data Table. Its fields are the columns of the table. The stack, one row per cell: row index = row * columns + column (Well Layout), row 0 at the bottom; rows 20 and 21 are hidden above the top. kind: 0 empty, 1-7 a crystal of that kind (Piece Kinds). Its rows are made, all empty, by Empty The Well when a game begins. isClearing: the crystal is in a full line and is shattering (until the rows above drop).

kindNumberdefault 0
isClearingBooleandefault false

3.4.1 Empty The Well

A fresh game clears the marks as well as the crystals. Update its Control Data Row. The same loop that prepares its rows now prepares both fields together.

FunctionEmpty The WellAddDelete

Makes the Well table one empty row per cell of the well (Well Layout: columns x rows), or empties the rows it already has.

ACTIONS
1Repeatdata('Well Layout', 0, 'columns') * data('Well Layout', 0, 'rows')times
Each time
2Control Data Row
Action Name
addedRow
Table
Well
Row
blockLocal("index")
Values
{"kind":"0","isClearing":"false"}
Values
{"kind":"0"}

Well State keeps a different memory: how many full rows the last lock found. Other Objects need to read that answer. Give Clear Full Lines this structure through its Data Structures block, then attach the new Logic to Glass Well beside Build The Well.

Data StructureWell State

What the well did after the last lock: linesCleared, the number of full lines it found (0-4). Game Rules reads it when the well sends linesCleared.

linesClearedNumberdefault 0
ObjectGlass WellAddDelete
Transform
Physics > Physics ObjectOn
Sprite
Scene Depth Draw Order-10
SpriteGlass Well
Transform > SizeX 16.5, Y 31.5
Data Structure
Data StructureWell State
Logic
Build The Well
Clear Full Lines
Shared Variables
wellCellWell Cell

3.4.2 Row Is Full

Before breaking a row, the well asks whether every cell is taken. Row Is Full reads its cells from the Well table. An empty entry makes the answer false; only a row with no gap gets a true answer back.

This is the same separation you used for Piece Fits. A Function answers the question without drawing anything or changing the stack.

FunctionRow Is Full

Answers whether every cell of a well row holds a crystal (Well, Well Layout columns). Row 0 is the bottom row.

PARAMETERS
NameTypeStarts at
rowNumber0
RETURN TYPEBoolean
ACTIONS
1Declare Variable
Name
checkColumn
Value
0
2Declare Variable
Name
filledCount
Value
0
3Declare Variable
Type
Boolean
Name
isFull
Value
false
4Change Variable
Variable
filledCount
Value
0
5Change Variable
Variable
checkColumn
Value
0
6WhilecheckColumn < data('Well Layout', 0, 'columns')
Each time
7Well Cell IndexFunction
Action Name
countedCell
column
checkColumn
row
row
8Ifdata('Well', countedCell.value, 'kind') != 0
Then
9Change Variable
Variable
filledCount
Operator
+=
Value
1
10Change Variable
Variable
checkColumn
Operator
+=
Value
1
11Change Variable
Variable
isFull
Value
false
12IffilledCount == data('Well Layout', 0, 'columns')
Then
13Change Variable
Variable
isFull
Value
true
14Return
Value
isFull

3.4.3 Mark Full Line

Once a row is full, Mark Full Line walks across it and turns on isClearing for every cell. It keeps each kind unchanged. The pictures can still read which color should shatter.

FunctionMark Full Line

Marks every cell of a full well row as clearing (the Well table's isClearing), so its crystals shatter. Row 0 is the bottom row.

PARAMETERS
NameTypeStarts at
rowNumber0
ACTIONS
1Declare Variable
Name
cellIndex
Value
0
2Repeatdata('Well Layout', 0, 'columns')times
Each time
3Well Cell IndexFunction
Action Name
markedCell
column
local.index
row
row
4Change Variable
Variable
cellIndex
Value
markedCell.value
5Set Data Cell
Table
Well
Row
cellIndex
Column
"isClearing"
Value
"true"

3.4.4 Move Row Down

After the shards appear, a kept row needs a lower home. Move Row Down copies the kind from each old cell into the corresponding cell of its target row. The target cells lose their clearing marks.

The Function handles one row. Clear Full Lines will choose which row it reads and where that row belongs. That keeps the copying separate from the decision about gaps.

FunctionMove Row Down

Copies every crystal of one well row (fromRow) into a lower row (toRow); the copied cells are not clearing. Row 0 is the bottom row.

PARAMETERS
NameTypeStarts at
fromRowNumber0
toRowNumber0
ACTIONS
1Declare Variable
Name
cellIndex
Value
0
2Declare Variable
Name
movedKind
Value
0
3Repeatdata('Well Layout', 0, 'columns')times
Each time
4Well Cell IndexFunction
Action Name
movedFromCell
column
local.index
row
fromRow
5Well Cell IndexFunction
Action Name
movedToCell
column
local.index
row
toRow
6Change Variable
Variable
movedKind
Value
data('Well', movedFromCell.value, 'kind')
7Change Variable
Variable
cellIndex
Value
movedToCell.value
8Set Data Cell
Table
Well
Row
cellIndex
Column
"kind"
Value
movedKind
9Set Data Cell
Table
Well
Row
cellIndex
Column
"isClearing"
Value
"false"

3.4.5 Empty Row

Moving rows down leaves old numbers at the top. Empty Row clears them away. The well can call it for every row left over once the kept rows are home.

FunctionEmpty Row

Empties every cell of a well row: no crystal (kind 0), not clearing. Row 0 is the bottom row.

PARAMETERS
NameTypeStarts at
rowNumber0
ACTIONS
1Declare Variable
Name
cellIndex
Value
0
2Repeatdata('Well Layout', 0, 'columns')times
Each time
3Well Cell IndexFunction
Action Name
emptiedCell
column
local.index
row
row
4Change Variable
Variable
cellIndex
Value
emptiedCell.value
5Set Data Cell
Table
Well
Row
cellIndex
Column
"kind"
6Set Data Cell
Table
Well
Row
cellIndex
Column
"isClearing"
Value
"false"

3.4.6 Clear Full Lines

Now the well can put those jobs together.

Make Row Sparkle before this Logic’s Actions. It bursts along a full row, while the cells themselves will make the colored shards. The card’s shape spreads those sparkles across the line.

Particle EffectRow Sparkle
Emitter
Emission > Emit Every (ms)0
Emission > Burst Count26
Emitter Shape > Emit Shaperectangle
Emitter Shape > Shape Sizew 15, h 0.469
Motion
Lifecycle > Each Particle Lives (ms)min 300, max 700
Motion > Speed (m/s)min 0.469, max 3.281
Appearance
Appearance > Particle SpriteFX Sparkle
Appearance > Color#E8FCFF
(Color first: choosing Multiple Colors hides it)
Appearance > Color SourceMultiple Colors
Appearance > Multiple Colors#FFFFFF, #D8FBFF, #A8ECFF
Appearance > Glow1.5
Appearance Over Life > Scalestart 1.3, end 0
Appearance Over Life > Starting RotationRandom Spin On

Clear Full Lines is one Logic Component, shown in three pieces here. In On Piece Locked, it starts a fresh count and asks Row Is Full about every row. A full row gains a mark, a sparkle and a place in linesCleared.

After the search, a nonzero count sends wellChanged and linesCleared, then starts the clear delay. No clear means a shorter wait. Both paths eventually ask for the next piece.

Logic ComponentClear Full LinesAttach to: Glass Well

The line clear: after each lock it marks the full lines (they shatter); clearSeconds later every row that stays moves down into the lowest free row and the rows left at the top are emptied; entrySeconds after that (or after a lock with no full line) it asks for the next piece.

Attach toAny Object
DATA STRUCTURES
Well Stateself.wellState
SHARED VARIABLES
NameTypeKindStarting Value
clearSecondsNumberConstant0.42
entrySecondsNumberConstant0.06
shakePerLineNumberConstant0.003
shakeSecondsNumberConstant0.28
flashColorColorConstant#c9f6ff
flashSecondsNumberConstant0.25
On Piece Locked
WhenpieceLockedCustom Event
1Change Component Value
Component Value
self.wellState.linesCleared
Value
0
2Repeatdata('Well Layout', 0, 'rows')times
Each time
3Declare Variable
Name
checkRow
Value
local.index
4Row Is FullFunction
Action Name
checkedRow
row
checkRow
5IfcheckedRow.value == true
Then
6Change Component Value
Component Value
self.wellState.linesCleared
Value
self.wellState.linesCleared + 1
7Mark Full LineFunction
row
checkRow
8Cell MiddleFunction
Action Name
fullRowMiddle
column
(data('Well Layout', 0, 'columns') - 1) / 2
row
checkRow
9Burst Particles
Particles
Row Sparkle
Position Relative To
World
X
fullRowMiddle.x
Y
fullRowMiddle.y
Z Index Offset
6
10Ifself.wellState.linesCleared > 0
Then
11Trigger Custom Event
Custom Event
wellChanged
12Camera Shake
Intensity
@self.shakePerLine * self.wellState.linesCleared
Seconds
@self.shakeSeconds
13Ifself.wellState.linesCleared == 4
Then
14Camera Flash
Color
@self.flashColor
Seconds
@self.flashSeconds
15Trigger Custom Event
Custom Event
linesCleared
16Start Recurring Timer
Timer Name
"clearDelay"
Repeat Every (s)
@self.clearSeconds
Ring Once
Yes
17Otherwise
18Start Recurring Timer
Timer Name
"entryDelay"
Repeat Every (s)
@self.entrySeconds
Ring Once
Yes

When the clear delay ends, imagine two fingers climbing the well. One reads each old row; the other points to the next place a kept row can go. The reading finger always climbs. The target moves only when a row is kept.

A marked row is skipped, so the next kept row copies into the gap. With no gap below, a row copies into its own place. Once every old row has been considered, Empty Row clears whatever remains above the target.

The card calls those positions checkRow and targetRow. They start at the bottom. Moving upward keeps a copied row from replacing another row before that other row has been read.

Logic ComponentClear Full Linescontinued
On the Clear Delay Timer
WhenRecurring TimerTimer name: clearDelay
1Declare Variable
Name
targetRow
Value
0
2Change Variable
Variable
targetRow
Value
0
3Repeatdata('Well Layout', 0, 'rows')times
Each time
4Declare Variable
Name
checkRow
Value
local.index
5Well Cell IndexFunction
Action Name
rowStart
column
0
row
checkRow
6Ifdata('Well', rowStart.value, 'isClearing') == false
Then
7Move Row DownFunction
fromRow
checkRow
toRow
targetRow
8Change Variable
Variable
targetRow
Operator
+=
Value
1
9WhiletargetRow < data('Well Layout', 0, 'rows')
Each time
10Empty RowFunction
row
targetRow
11Change Variable
Variable
targetRow
Operator
+=
Value
1
12Trigger Custom Event
Custom Event
wellChanged
13Start Recurring Timer
Timer Name
"entryDelay"
Repeat Every (s)
@self.entrySeconds
Ring Once
Yes

The last Event has a smaller job. When entryDelay rings, it sends spawnPiece. A lock without a clear reaches it sooner; a clear reaches it after the rows have moved.

Logic ComponentClear Full Linescontinued
On the Entry Delay Timer
WhenRecurring TimerTimer name: entryDelay
1Trigger Custom Event
Custom Event
spawnPiece

Nothing sends pieceLocked yet. Run now, and your game still plays as it did in Chapter 2. The new well is waiting for the lock to hand over its turn.

3.5 Handing Over the Lock

The falling piece must wait while the well works.

3.5.1 Lock Piece

Lock Piece still writes its crystals into Well. After that, it turns off the Logics that could move, rotate or hard-drop that old shape. It asks the well to check the stack rather than spawning the next piece itself.

The messages have different listeners. pieceLocked starts the well’s clear; crystalsLocked tells the cell pictures that new crystals arrived. Read The Move Keys stays on, so it can still hear a released key while movement waits.

Logic ComponentLock PieceAttach to: Falling PieceAddDelete

Writes the falling piece's four crystals into the Well, takes the piece out of play, tells the well it locked and the Well Cells that crystals joined.

Attach toAny Object
DATA STRUCTURES
Pieceself.piece
On Lock Piece
WhenlockPieceCustom Event
1Declare Variable
Name
lockedKind
Value
0
2Stop Recurring Timer
Timer Name
"gravity"
3Stop Recurring Timer
Timer Name
"lockDelay"
4Change Variable
Variable
lockedKind
Value
self.piece.kind
5Repeat4times
Each time
6Crystal CellFunction
Action Name
lockedCrystal
kind
self.piece.kind
rotation
self.piece.rotation
crystal
local.index + 1
7Well Cell IndexFunction
Action Name
lockedCell
column
self.piece.column + lockedCrystal.column
row
self.piece.row + lockedCrystal.row
8Declare Variable
Name
cellIndex
Value
lockedCell.value
9Set Data Cell
Table
Well
Row
cellIndex
Column
"kind"
Value
lockedKind
10Control Sound
Sound
Lock Click
11Set Logic State
Logic Component
Piece Gravity
State
Disable
12Set Logic State
Logic Component
Move Piece
State
Disable
13Set Logic State
Logic Component
Rotate Piece
State
Disable
14Set Logic State
Logic Component
Hard Drop Piece
State
Disable
15Trigger Custom Event
Custom Event
pieceLocked
Custom Event
wellChanged
12Trigger Custom Event on Object
Custom Event
spawnPiece
16Trigger Custom Event
Custom Event
crystalsLocked

3.5.2 Spawn Piece

The next piece wakes the controls again. Spawn Piece enables the same Logics before preparing the new shape. With no State line shown on Set Logic State, its starting choice is Enable.

Logic ComponentSpawn PieceAttach to: Falling PieceAddDelete

Puts a new piece at the top of the well: a random kind, rotation up, its box in the hidden rows, then one row down into view if it fits.

Attach toAny Object
DATA STRUCTURES
Pieceself.piece
SHARED VARIABLES
NameTypeKindStarting Value
startColumnNumberConstant3
When Created
WhenCreate
1Trigger Custom Event on Object
Custom Event
spawnPiece
On Spawn Piece
WhenspawnPieceCustom Event
1Set Logic State
Logic Component
Piece Gravity
2Set Logic State
Logic Component
Move Piece
3Set Logic State
Logic Component
Rotate Piece
4Set Logic State
Logic Component
Hard Drop Piece
5Generate Random Integer
Action Name
randomKind
Minimum
1
Maximum
dataCount('Piece Kinds')
6Change Component Value
Component Value
self.piece.kind
Value
randomKind.value
7Change Component Value
Component Value
self.piece.rotation
Value
0
8Change Component Value
Component Value
self.piece.column
Value
@self.startColumn
9Change Component Value
Component Value
self.piece.row
Value
data('Well Layout', 0, 'rows') - 4
10Piece Fits HereFunction
Action Name
roomBelowNewPiece
piece
self
columnShift
0
rowShift
-1
11IfroomBelowNewPiece.value == true
Then
12Change Component Value
Component Value
self.piece.row
Value
self.piece.row - 1
13Find Landing RowFunction
piece
self
14Trigger Custom Event
Custom Event
pieceMoved

The wait now belongs to the well. Its cells need one last change before they can show the whole moment.

3.6 The Crystals Show It

The marks become visible here.

Add the new fields to Show Well Cell Data. shownKind remembers what a cell last drew, and isShowingShatter remembers whether it already burst. They keep a new message from making the same shard burst twice.

Data StructureShow Well Cell DataAddDelete

Object Data of Logic "Show Well Cell" (its state that lasts between Events). cellIndex: the row of the Well table this cell shows. shownKind: the crystal kind it shows now (0 empty, -1 before the first). isShowingShatter: its crystal is bursting in a full line.

cellIndexNumberdefault 0
shownKindNumberdefault -1
isShowingShatterBooleandefault false

Make Crystal Frames Entry, then Crystal Frames. Its shatter field picks the white picture from Crystal Blocks. The frame number lives in a table so the drawing Logic can ask for it by meaning.

Data StructureCrystal Frames Entry

One row of the "Crystal Frames" Data Table. Its fields are the columns of the table. Frames of the sprite "Crystal Blocks" that are not a kind of piece. One row. shatter: a crystal in a full line.

shatterNumberdefault 8
Data TableCrystal FramesData Structure: Crystal Frames Entry
Row 0Frames
shatter8

The two particle effects have different moments. Lock Glint accompanies a new crystal’s small pop. Crystal Shards bursts when a full line breaks, tinted with that crystal’s kind color. Make them before adding their Actions below.

Particle EffectLock Glint
Emitter
Emission > Emit Every (ms)0
Emission > Burst Count2
Emitter Shape > Emit Radius (m)0.469
Motion
Lifecycle > Each Particle Lives (ms)min 200, max 380
Motion > Speed (m/s)min 0.234, max 1.406
Appearance
Appearance > Particle SpriteFX Sparkle
Appearance > Color#FFFFFF
(Color first: choosing Multiple Colors hides it)
Appearance > Color SourceMultiple Colors
Appearance > Multiple Colors#FFFFFF, #E6FDFF
Appearance > Glow1.4
Appearance Over Life > Scalestart 0.5, end 0
Appearance Over Life > Alphastart 0.9, end 0
Particle EffectCrystal Shards
Emitter
Emission > Emit Every (ms)0
Emission > Burst Count7
Emitter Shape > Emit Radius (m)0.469
Motion
Lifecycle > Each Particle Lives (ms)min 450, max 950
Motion > Speed (m/s)min 4.219, max 15
Motion > Angle (Deg)min 20, max 160
Forces > Gravityx 0, y -51.563
Appearance
Appearance > Particle SpriteFX Shard
Appearance > Color#FFFFFF
(Color first: choosing Multiple Colors hides it)
Appearance > Color SourceMultiple Colors
Appearance > Multiple Colors#FFFFFF, #CCCCCC, #EEEEEE, #FFFFFF
Appearance > BlendNormal
Appearance Over Life > Scalestart 2.2, end 0.5
Appearance Over Life > Size Variation (0–1)0.4
Appearance Over Life > Rotatestart 0, end -540
(Rotate first: Random Spin hides it)
Appearance Over Life > Starting RotationRandom Spin On

3.6.1 Show Well Cell

A cell can now notice a change, rather than drawing every update the same way. If it was empty and a lock filled it, it grows a little and returns to its normal size. That’s the pop.

A clearing cell takes the other path. It bursts into colored shards and shows the white shatter frame. The kind stays in the table during that moment, so the shards can still find their color. When the rows move, the same picture Logic draws the new kind at that cell.

Watch the order of the messages as you build. The well handles pieceLocked before the pictures hear crystalsLocked. A crystal already shown as shattering therefore doesn’t also count as a fresh pop.

Logic ComponentShow Well CellAttach to: Well CellAddDelete

One cell of the well: it finds its cell from where it is placed, then shows the crystal stored there whenever the well changes; a crystal a lock just put there pops, and a crystal in a full line bursts into shards.

Attach toAny Object
DATA STRUCTURES
Show Well Cell Dataself.showWellCellData
SHARED VARIABLES
NameTypeKindStarting Value
popScaleNumberConstant1.22
popSecondsNumberConstant0.2
When Created
WhenCreate
1Cell AtFunction
Action Name
myCell
x
self.transform.position.x
y
self.transform.position.y
2Well Cell IndexFunction
Action Name
thisCellIndex
column
myCell.column
row
myCell.row
3Change Component Value
Component Value
self.showWellCellData.cellIndex
Value
thisCellIndex.value
4Set Frame
Frame
data('Well', self.showWellCellData.cellIndex, 'kind')
4Trigger Custom Event on Object
Custom Event
wellChanged
On Crystals Locked
WhencrystalsLockedCustom Event
1Ifself.showWellCellData.shownKind == 0 && data('Well', self.showWellCellData.cellIndex, 'kind') != 0
Then
2Set Scale
Horizontal Scale
@self.popScale
Vertical Scale
@self.popScale
3Tween
Value
self.transform.scale
Target
1
Duration
@self.popSeconds
Ease
Quad Out
4Burst Particles
Particles
Lock Glint
Z Index Offset
6
5Trigger Custom Event on Object
Custom Event
wellChanged
On Well Changed
WhenwellChangedCustom Event
1Set Frame
Frame
data('Well', self.showWellCellData.cellIndex, 'kind')
1Ifdata('Well', self.showWellCellData.cellIndex, 'isClearing') == true && self.showWellCellData.isShowingShatter == false
Then
2Burst Particles
Particles
Crystal Shards
Z Index Offset
6
Tint
data('Piece Kinds', data('Well', self.showWellCellData.cellIndex, 'kind') - 1, 'color')
3Change Component Value
Component Value
self.showWellCellData.isShowingShatter
Value
data('Well', self.showWellCellData.cellIndex, 'isClearing')
4Change Component Value
Component Value
self.showWellCellData.shownKind
Value
data('Well', self.showWellCellData.cellIndex, 'kind')
5Ifself.showWellCellData.isShowingShatter == true
Then
6Set Frame
Frame
data('Crystal Frames', 0, 'shatter')
7Otherwise
8Set Frame
Frame
self.showWellCellData.shownKind

Run again. Lock a piece, then fill a row. The stack can finally make room for more crystals.

3.7 Counting What Broke

The broken line leaves a number behind for the player to read, even after its crystals have vanished.

3.7.1 Count Lines

Count Lines hears linesCleared and reads the well’s linesCleared field. One is a message; the other is the answer kept in Well State. It adds the answer to lines.

Declare its well Shared Variable as an Object of the Glass Well kind. That kind makes Well State’s fields available to the Logic, because Glass Well carries the structure it needs to read. Make Game Rules, attach Count Lines, and set its well Variable to Glass Well.

Logic ComponentCount LinesAttach to: Game Rules

Adds the lines the well cleared to the lines count (the Project Global lines).

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
wellObjectConstantNone
OBJECT KINDS
wellGlass Well
On Lines Cleared
WhenlinesClearedCustom Event
1Change Variable
Variable
$lines
Operator
+=
Value
@self.well.wellState.linesCleared
ObjectGame Rules
Transform
Physics > Physics ObjectOn
Logic
Count Lines
Shared Variables
wellGlass Well

The two text Objects have different jobs. LINES Label keeps its word. LINES Value has a template reading the live lines Global, so it changes whenever the count does. Its Nunito font is already in the Starter Kit.

ObjectLINES Label
Transform
Presentation > SpaceWindow / UI
Presentation > Screen AnchorCenter
Presentation > Render LayerUI
Bounding Box > SizeX 128, Y 48
Text / UI
TextLINES
FontNunito
Font Size28.5
EmphasisBold
Color#BFEAFF
Letter Spacing1.5
Text BoundsWrap to Width
Transform > Size X210
ObjectLINES Value
Transform
Presentation > SpaceWindow / UI
Presentation > Screen AnchorCenter
Presentation > Render LayerUI
Bounding Box > SizeX 128, Y 48
Text / UI
Text{$lines}
FontNunito
Font Size39
EmphasisBold
Letter Spacing1.5
AlignmentRight
Text BoundsWrap to Width
Transform > Size X240

Place Game Rules and the text Objects using the setup list. Their Screen UI offsets count from their screen anchor, while Game Rules has no picture to place on screen. Clear a row and watch LINES climb.

3.8 Play It!

  • Lock a piece on an empty part of the floor and watch its new crystals pop briefly into place.
  • Fill a row from wall to wall. Watch its white flash and the burst of shards, each taking the color of the crystal that broke.
  • Watch the crystals above that row. After the clear delay, they move down into the gap.
  • Read LINES as a row breaks. Its count rises by the number of full rows found together.
  • Try pressing movement and rotation during a clear. The old piece stays out of play until the next one arrives.
  • Clear a row with gaps higher in the stack. Their gaps move down too.

3.9 How It Works

The table now holds marks beside the crystals it already held. A mark lets the picture show a change before the stored stack takes its new shape.

Finding full rows and moving kept rows are separate passes over the same well. The delay between them gives the shatter time to be seen.

3.10 If It Didn’t Work

The line flashes, but the stack never moves? Check the clearDelay timer Event and its name in Start Recurring Timer. The same spelling joins the wait to its listener. Restore the timer’s name or its listener, then fill another row to watch the delay finish its work.

A row gets copied into the wrong place? Watch targetRow in the clear-delay Event. It advances only for a kept row, while checkRow advances through every old row. Compare the If’s inside Actions with the card, then run the same clear again.

The count stays at its starting value? Check Count Lines is attached to Game Rules and its well Shared Variable names Glass Well. Then compare the Global lines name with the template on LINES Value. Those pieces can now share the same answer.

The next piece won’t move? Compare the Set Logic State Actions in Spawn Piece with the ones in Lock Piece. The first set wakes what the second set rested. Restore the missing Enable Action, start another piece, and check its controls before trying the next clear.

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

3.11 Challenge

How should a clear feel in your own game? Change the clear delay or try another sparkle color, keeping a working copy to compare. A longer pause can let a shatter hang in the air. A shorter one can make the next choice arrive sooner.

The well can make room now. Next, it shows what is coming.