TutorialsDijkstra’s Algorithm

Appendix A — Logic Reference

Every Logic Component and Function in Weighted Maze, as it is in the finished game. Each entry stands on its own: read what it does, see what it needs, and build it from its card into your own game. A card’s Shared Variables and Per Instance Variables are the values you can change. A Shared Variable holds one value for the whole Object, under Variables in its Properties. A Per Instance Variable holds one for each placement in the Scene.

A.1 Cell Picture (Function)

Built in Chapter 1, The Map and the Sidebar.

FunctionCell Picture

Which Terrain Tiles picture one cell shows. A cell shows its terrain, found by its cost in Terrains; a cost that no terrain lists is drawn as Road. The Camp and the Tower show their own pictures (Maze Layout campFrame and towerFrame) unless they are painted as Wall.

PARAMETERS
NameTypeStarts at
cellNumber0
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
cost
Value
0
2Declare Variable
Name
terrainRow
Value
-1
3Declare Variable
Name
frame
Value
0
4Change Variable
Variable
cost
Value
data('Maze Cells', cell, 'cost')
5Change Variable
Variable
terrainRow
Value
dataFind('Terrains', 'cost', cost)
6IfterrainRow >= 0
Then
7Change Variable
Variable
frame
Value
data('Terrains', terrainRow, 'frame')
8Otherwise
9Change Variable
Variable
frame
Value
data('Terrains', 'Road', 'frame')
10Ifcell == data('Maze Settings', 'rules', 'startCell') && cost != data('Terrains', 'Wall', 'cost')
Then
11Change Variable
Variable
frame
Value
data('Maze Layout', 'board', 'campFrame')
12Ifcell == data('Maze Settings', 'rules', 'goalCell') && cost != data('Terrains', 'Wall', 'cost')
Then
13Change Variable
Variable
frame
Value
data('Maze Layout', 'board', 'towerFrame')
14Return
Value
frame

A.2 Cell Screen Position (Function)

Built in Chapter 1, The Map and the Sidebar.

FunctionCell Screen Position

Where one cell's center is on the screen, in screen pixels. Cells count in reading order: Cell 00 is the top-left cell, and the numbers grow to the right, then down (a row holds Maze Settings columns cells). Maze Layout says where Cell 00 is and how far apart the cells are. x is measured right from the left edge of the screen; y is measured up from the top edge, so a cell below the top has a negative y, as Set Position takes it for a Screen UI Object anchored at the top-left corner.

PARAMETERS
NameTypeStarts at
cellNumber0
RETURN TYPECell Screen Position Result (a Data Structure)
ACTIONS
1Declare Variable
Name
column
Value
0
2Declare Variable
Name
row
Value
0
3Declare Variable
Name
right
Value
0
4Declare Variable
Name
down
Value
0
5Change Variable
Variable
column
Value
cell % data('Maze Settings', 'rules', 'columns')
6Change Variable
Variable
row
Value
floor(cell / data('Maze Settings', 'rules', 'columns'))
7Change Variable
Variable
right
Value
column * data('Maze Layout', 'board', 'spacing')
8Change Variable
Variable
right
Operator
+=
Value
data('Maze Layout', 'board', 'originX')
9Change Variable
Variable
down
Value
row * data('Maze Layout', 'board', 'spacing')
10Change Variable
Variable
down
Operator
+=
Value
data('Maze Layout', 'board', 'originY')
11Return
x
right
y
-down

A.3 Lay Out Map

Built in Chapter 1, The Map and the Sidebar.

Logic ComponentLay Out MapAttach to: Map

Lays out the map when the Scene starts: for each row of Maze Cells it creates a Map Cell and a Search Outline, gives each the cell number (its Map Place cell) and tells it, with placedOnMap, that it is placed; the piece then stands on its cell and shows itself. mapCell and searchOutline are the Objects it makes.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
mapCellObjectConstantNone
searchOutlineObjectConstantNone
When the Scene Starts
WhenScene Start
1RepeatdataCount('Maze Cells')times
Each time
2Create Instance
Object to Create
@self.mapCell
X
0
Y
0
Created As
newCell
3Change Variable
Variable
newCell.cell
Value
local.index
4Trigger Custom Event on Object
Applies To
newCell
Custom Event
placedOnMap
5Create Instance
Object to Create
@self.searchOutline
X
0
Y
0
Created As
newOutline
6Change Variable
Variable
newOutline.cell
Value
local.index
7Trigger Custom Event on Object
Applies To
newOutline
Custom Event
placedOnMap

A.4 Reset Trial

Built in Chapter 1, The Map and the Sidebar.

Logic ComponentReset TrialAttach to: Maze Rules

Puts the trial in its Ready state, keeping the terrain, with the Function Clear Trial: when the Scene starts, when the learner presses Reset (the Reset Command, R in the Input Manager) or the Reset button (resetRequested), and whenever a cell's terrain changes (terrainChanged), so a search never mixes two maps.

Attach toMaze Rules
When the Scene Starts
WhenScene Start
1Clear TrialFunction
rules
self
When Reset Is Pressed
WhenCommand PressedCommand: Reset
1Clear TrialFunction
rules
self
On Reset Requested
WhenresetRequestedCustom Event
1Clear TrialFunction
rules
self
On Terrain Changed
WhenterrainChangedCustom Event
1Clear TrialFunction
rules
self

A.5 Show Selection

Built in Chapter 1, The Map and the Sidebar.

Logic ComponentShow SelectionAttach to: Selection

Keeps the Selection, the ring around the cell the keyboard will paint, on the selected cell (the Project Global selectedCell). The Selection starts on the Camp (Maze Settings startCell).

Attach toAny Object
When Created
WhenCreate
1Change Variable
Variable
$selectedCell
Value
data('Maze Settings', 'rules', 'startCell')
2Cell Screen PositionFunction
Action Name
campPosition
cell
$selectedCell
3Set Position
Position Relative To
Screen
X
campPosition.x
Y
campPosition.y
On Variable Changed · Selected Cell
WhenVariable ChangedGlobal Variable: selectedCell
1Cell Screen PositionFunction
Action Name
cellPosition
cell
$selectedCell
2Set Position
Position Relative To
Screen
X
cellPosition.x
Y
cellPosition.y

A.6 Change Terrain

Built in Chapter 2, Paint the Maze.

Logic ComponentChange TerrainAttach to: Maze Rules

Changes the terrain of the selected cell when the learner paints it: with a click or a touch on a cell (paintRequested, sent by the cell), or with the Paint Command (Enter in the Input Manager).

Attach toAny Object
When Paint Is Pressed
WhenCommand PressedCommand: Paint
1Paint Selected CellFunction
On Paint Requested
WhenpaintRequestedCustom Event
1Paint Selected CellFunction

A.7 Choose Brush (Function)

Built in Chapter 2, Paint the Maze.

FunctionChoose Brush

Makes one terrain the brush, the terrain the learner paints with. terrain must be a row of Terrains (Road, Forest, Mud or Wall); a name Terrains does not list leaves the brush as it is.

PARAMETERS
NameTypeStarts at
terrainTextRoad
ACTIONS
1Check Data Row Exists
Action Name
isKnownTerrain
Table
"Terrains"
Row
terrain
2IfisKnownTerrain.value == true
Then
3Change Variable
Variable
$brush
Value
terrain

A.8 Choose Terrain

Built in Chapter 2, Paint the Maze.

Logic ComponentChoose TerrainAttach to: Terrain Button

One terrain the learner can paint with. The button shows the terrain's name and, unless it is a Wall, what entering it costs (from Terrains); activating it makes that terrain the brush, and the button is highlighted while it is. Each Terrain Button placement sets terrain, a row of Terrains (Road, Forest, Mud or Wall). chosenTint and plainTint are the button colors with and without the highlight.

Attach toAny Object
DATA STRUCTURES
Choose Terrain Dataself.chooseTerrainData
COMPONENTS
self.textText / UI
self.spriteSprite
SHARED VARIABLES
NameTypeKindStarting Value
chosenTintColorConstant#dab674
plainTintColorConstant#ede2cd
PER INSTANCE VARIABLES
NameTypeStarting Value
terrainTextRoad
When Created
WhenCreate
1Check Data Row Exists
Action Name
isKnownTerrain
Table
"Terrains"
Row
self.terrain
2IfisKnownTerrain.value == true
Then
3Change Component Value
Component Value
self.chooseTerrainData.label
Value
self.terrain
4Ifdata('Terrains', self.terrain, 'cost') >= 0
Then
5Change Component Value
Component Value
self.chooseTerrainData.label
Value
self.terrain + " " + data('Terrains', self.terrain, 'cost')
6Change Component Value
Component Value
self.text.text
Value
self.chooseTerrainData.label
7Highlight Terrain ChoiceFunction
button
self
terrain
self.terrain
chosenTint
@self.chosenTint
plainTint
@self.plainTint
On Hud Activated
WhenUI Activated
1Choose BrushFunction
terrain
self.terrain
On Variable Changed · Brush
WhenVariable ChangedGlobal Variable: brush
1Highlight Terrain ChoiceFunction
button
self
terrain
self.terrain
chosenTint
@self.chosenTint
plainTint
@self.plainTint

A.9 Choose Terrain By Key

Built in Chapter 2, Paint the Maze.

Logic ComponentChoose Terrain By KeyAttach to: Selection

Lets the keyboard choose the brush: Choose Road, Choose Forest, Choose Mud and Choose Wall (keys 1, 2, 3 and 4 in the Input Manager) each make their terrain the brush.

Attach toAny Object
When Choose Road Is Pressed
WhenCommand PressedCommand: Choose Road
1Choose BrushFunction
terrain
Road
When Choose Forest Is Pressed
WhenCommand PressedCommand: Choose Forest
1Choose BrushFunction
terrain
Forest
When Choose Mud Is Pressed
WhenCommand PressedCommand: Choose Mud
1Choose BrushFunction
terrain
Mud
When Choose Wall Is Pressed
WhenCommand PressedCommand: Choose Wall
1Choose BrushFunction
terrain
Wall

A.10 Choose Terrain By Picture

Built in Chapter 2, Paint the Maze.

Logic ComponentChoose Terrain By PictureAttach to: Terrain Preview

Shows the Terrain Tiles picture of one terrain beside its button (Terrains frame); activating the picture makes that terrain the brush, as its button does. Each Terrain Preview placement sets terrain, a row of Terrains (Road, Forest, Mud or Wall).

Attach toAny Object
PER INSTANCE VARIABLES
NameTypeStarting Value
terrainTextRoad
When Created
WhenCreate
1Check Data Row Exists
Action Name
isKnownTerrain
Table
"Terrains"
Row
self.terrain
2IfisKnownTerrain.value == true
Then
3Set Frame
Frame
data('Terrains', self.terrain, 'frame')
On Hud Activated
WhenUI Activated
1Choose BrushFunction
terrain
self.terrain

A.11 Find Grid Neighbor (Function)

Built in Chapter 2, Paint the Maze.

FunctionFind Grid Neighbor

The cell next to one cell in one direction (a row of Directions: Up, Right, Down or Left), or -1 when that side of the cell is the edge of the map. Cells count as Cell Screen Position counts them: Cell 00 is the top-left cell, and a row holds Maze Settings columns cells.

PARAMETERS
NameTypeStarts at
cellNumber0
directionTextUp
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
column
Value
0
2Declare Variable
Name
row
Value
0
3Declare Variable
Name
neighbor
Value
-1
4Change Variable
Variable
column
Value
cell % data('Maze Settings', 'rules', 'columns')
5Change Variable
Variable
row
Value
floor(cell / data('Maze Settings', 'rules', 'columns'))
6Change Variable
Variable
column
Operator
+=
Value
data('Directions', direction, 'columnStep')
7Change Variable
Variable
row
Operator
+=
Value
data('Directions', direction, 'rowStep')
8Ifcolumn >= 0 && column < data('Maze Settings', 'rules', 'columns') && row >= 0 && row < data('Maze Settings', 'rules', 'rows')
Then
9Change Variable
Variable
neighbor
Value
row * data('Maze Settings', 'rules', 'columns')
10Change Variable
Variable
neighbor
Operator
+=
Value
column
11Otherwise
12Change Variable
Variable
neighbor
Value
-1
13Return
Value
neighbor

A.12 Highlight Terrain Choice (Function)

Built in Chapter 2, Paint the Maze.

FunctionHighlight Terrain Choice

Colors one Terrain Button: chosenTint while its terrain is the brush, plainTint otherwise.

PARAMETERS
NameTypeStarts at
buttonObjectStructural
Required Components
Slot Namesprite
Component TypeSprite
terrainTextRoad
chosenTintColor#dab674
plainTintColor#ede2cd
ACTIONS
1Ifterrain == $brush
Then
2Change Sprite Tint Property
Applies To
button
Value
chosenTint
3Otherwise
4Change Sprite Tint Property
Applies To
button
Value
plainTint

A.13 Move Selection

Built in Chapter 2, Paint the Maze.

Logic ComponentMove SelectionAttach to: Selection

Lets the arrow keys move the Selection: each direction of the Move Selection Command (the arrow keys in the Input Manager) moves it one cell up, right, down or left. At the edge of the map it stays.

Attach toAny Object
When Move Selection Up Is Pressed
When2D Direction PressedCommand: Move SelectionDirection: Up
1Select NeighborFunction
direction
Up
When Move Selection Right Is Pressed
When2D Direction PressedCommand: Move SelectionDirection: Right
1Select NeighborFunction
direction
Right
When Move Selection Down Is Pressed
When2D Direction PressedCommand: Move SelectionDirection: Down
1Select NeighborFunction
direction
Down
When Move Selection Left Is Pressed
When2D Direction PressedCommand: Move SelectionDirection: Left
1Select NeighborFunction
direction
Left

A.14 Paint Map Cell

Built in Chapter 2, Paint the Maze.

Logic ComponentPaint Map CellAttach to: Map Cell

One cell of the map the learner can paint. It shows the picture its cost calls for, and draws its picture again whenever the terrain changes. Activating it (a click or a touch) selects it and asks Maze Rules to paint it with the brush. Its cell number is its Map Place cell, which Lay Out Map gives it.

Attach toAny Object
DATA STRUCTURES
Map Placeself.mapPlace
On Placed on Map
WhenplacedOnMapCustom Event
1Cell Screen PositionFunction
Action Name
place
cell
self.mapPlace.cell
2Set Position
Position Relative To
Screen
X
place.x
Y
place.y
3Cell PictureFunction
Action Name
picture
cell
self.mapPlace.cell
4Set Frame
Frame
picture.value
On Hud Activated
WhenUI Activated
1Change Variable
Variable
$selectedCell
Value
self.mapPlace.cell
2Trigger Custom Event
Custom Event
paintRequested
On Terrain Changed
WhenterrainChangedCustom Event
1Cell PictureFunction
Action Name
newPicture
cell
self.mapPlace.cell
2Set Frame
Frame
newPicture.value

A.15 Paint Selected Cell (Function)

Built in Chapter 2, Paint the Maze.

FunctionPaint Selected Cell

Paints the selected cell (the Project Global selectedCell) with the brush: its cost in Maze Cells becomes the brush terrain's cost from Terrains, and terrainChanged tells every cell. The Camp and the Tower are never painted, and a cell that already has that cost is left alone, so nothing is told.

ACTIONS
1If$selectedCell != data('Maze Settings', 'rules', 'startCell') && $selectedCell != data('Maze Settings', 'rules', 'goalCell') && data('Maze Cells', $selectedCell, 'cost') != data('Terrains', $brush, 'cost')
Then
2Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', $selectedCell)
Column
"cost"
Value
data('Terrains', $brush, 'cost')
3Trigger Custom Event
Custom Event
terrainChanged

A.16 Restore Defaults

Built in Chapter 2, Paint the Maze.

Logic ComponentRestore DefaultsAttach to: Maze Rules

Puts the supplied map back when the learner presses the Restore Defaults Command (D in the Input Manager): every cell gets the cost written in Maze Cells in the editor, the Selection goes back to the Camp, and every cell draws its picture again.

Attach toAny Object
When Restore Defaults Is Pressed
WhenCommand PressedCommand: Restore Defaults
1Reset Data Table
Table
"Maze Cells"
2Change Variable
Variable
$selectedCell
Value
data('Maze Settings', 'rules', 'startCell')
3Trigger Custom Event
Custom Event
terrainChanged

A.17 Select Neighbor (Function)

Built in Chapter 2, Paint the Maze.

FunctionSelect Neighbor

Moves the selection (the Project Global selectedCell) one cell in one direction, a row of Directions. At the edge of the map the selection stays where it is.

PARAMETERS
NameTypeStarts at
directionTextUp
ACTIONS
1Find Grid NeighborFunction
Action Name
next
cell
$selectedCell
direction
direction
2Ifnext.value >= 0
Then
3Change Variable
Variable
$selectedCell
Value
next.value

A.18 Check Maze Input (Function)

Built in Chapter 3, Settle One Cheapest Cell.

FunctionCheck Maze Input

Checks the map and Maze Settings before a search begins. problem is the Messages row of the first rule that is broken, or empty when every rule holds: the map has columns times rows cells (wrongMapSize); maxCost is a whole number from 0 to maxCostLimit, and unreached is larger than any route can cost and at most unreachedLimit (wrongSettings); the Camp and the Tower are cells of the map (wrongEndpoints); every cost is a Wall or a whole number from 0 to maxCost (wrongCost); neither the Camp nor the Tower is a Wall (blockedEndpoint).

PARAMETERS
NameTypeStarts at
maxCostLimitNumber99
unreachedLimitNumber1000000000
RETURN TYPEText
ACTIONS
1Declare Variable
Type
Text
Name
problem
2Declare Variable
Name
camp
Value
0
3Declare Variable
Name
tower
Value
0
4Declare Variable
Name
mapCells
Value
0
5Change Variable
Variable
camp
Value
data('Maze Settings', 'rules', 'startCell')
6Change Variable
Variable
tower
Value
data('Maze Settings', 'rules', 'goalCell')
7Change Variable
Variable
mapCells
Value
data('Maze Settings', 'rules', 'columns')
8Change Variable
Variable
mapCells
Operator
*=
Value
data('Maze Settings', 'rules', 'rows')
9Change Variable
Variable
problem
Value
""
10Ifdata('Maze Cells', camp, 'cost') == data('Terrains', 'Wall', 'cost') || data('Maze Cells', tower, 'cost') == data('Terrains', 'Wall', 'cost')
Then
11Change Variable
Variable
problem
Value
'blockedEndpoint'
12RepeatdataCount('Maze Cells')times
Each time
13Ifdata('Maze Cells', local.index, 'cost') < data('Terrains', 'Wall', 'cost') || data('Maze Cells', local.index, 'cost') > data('Maze Settings', 'rules', 'maxCost') || data('Maze Cells', local.index, 'cost') != floor(data('Maze Cells', local.index, 'cost'))
Then
14Change Variable
Variable
problem
Value
'wrongCost'
15Check Data Row Exists
Action Name
isCampOnMap
Table
"Maze Cells"
Row
camp
16Check Data Row Exists
Action Name
isTowerOnMap
Table
"Maze Cells"
Row
tower
17IfisCampOnMap.value == false || camp != floor(camp) || isTowerOnMap.value == false || tower != floor(tower)
Then
18Change Variable
Variable
problem
Value
'wrongEndpoints'
19Ifdata('Maze Settings', 'rules', 'maxCost') < 0 || data('Maze Settings', 'rules', 'maxCost') > maxCostLimit || data('Maze Settings', 'rules', 'maxCost') != floor(data('Maze Settings', 'rules', 'maxCost')) || data('Maze Settings', 'rules', 'unreached') <= (dataCount('Maze Cells') * data('Maze Settings', 'rules', 'maxCost')) || data('Maze Settings', 'rules', 'unreached') > unreachedLimit
Then
20Change Variable
Variable
problem
Value
'wrongSettings'
21IfmapCells != dataCount('Maze Cells') || data('Maze Settings', 'rules', 'columns') < 1 || data('Maze Settings', 'rules', 'columns') != floor(data('Maze Settings', 'rules', 'columns')) || data('Maze Settings', 'rules', 'rows') != floor(data('Maze Settings', 'rules', 'rows'))
Then
22Change Variable
Variable
problem
Value
'wrongMapSize'
23Return
Value
problem

A.19 Choose Cheapest Cell (Function)

Built in Chapter 3, Settle One Cheapest Cell.

FunctionChoose Cheapest Cell

The frontier cell with the smallest distance, or -1 when the frontier is empty. The frontier is every cell that is not a Wall, not settled, and already reached (its distance is less than Maze Settings unreached). On equal distances the lowest cell number wins.

RETURN TYPENumber
ACTIONS
1Declare Variable
Name
cheapest
Value
-1
2Declare Variable
Name
cheapestDistance
Value
0
3Change Variable
Variable
cheapest
Value
-1
4Change Variable
Variable
cheapestDistance
Value
data('Maze Settings', 'rules', 'unreached')
5RepeatdataCount('Maze Cells')times
Each time
6Ifdata('Maze Cells', local.index, 'settled') == 0 && data('Maze Cells', local.index, 'cost') != data('Terrains', 'Wall', 'cost') && data('Maze Cells', local.index, 'distance') < cheapestDistance
Then
7Change Variable
Variable
cheapest
Value
local.index
8Change Variable
Variable
cheapestDistance
Value
data('Maze Cells', local.index, 'distance')
9Return
Value
cheapest

A.20 Clear Trial (Function)

Built in Chapter 3, Settle One Cheapest Cell.

FunctionClear Trial

Puts the trial back to Ready, keeping the terrain: every cell of Maze Cells gets distance unreached (Maze Settings), no parent (-1) and settled 0 and no place on the Route (routeOrder -1), Visited goes back to 0, no cell is current (currentCell -1), the Marker's cell is the Camp (markerCell), Status asks the learner to paint terrain (the Messages ready words), and searchChanged clears every Search Outline. Last, trialCleared tells Step Trial on rules (Maze Rules) that the trial was cleared, so the next Step starts from Ready, and Find Route, so Find route stops.

PARAMETERS
NameTypeStarts at
rulesObjectMaze Rules
ACTIONS
1RepeatdataCount('Maze Cells')times
Each time
2Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', local.index)
Column
"distance"
Value
data('Maze Settings', 'rules', 'unreached')
3Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', local.index)
Column
"parent"
Value
-1
4Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', local.index)
Column
"settled"
Value
0
5Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', local.index)
Column
"routeOrder"
Value
-1
6Change Variable
Variable
$visited
Value
0
7Change Variable
Variable
$currentCell
Value
-1
8Change Variable
Variable
$status
Value
data('Messages', 'ready', 'words')
9Change Variable
Variable
$markerCell
Value
data('Maze Settings', 'rules', 'startCell')
10Trigger Custom Event
Custom Event
searchChanged
11Trigger Custom Event on Object
Applies To
rules
Custom Event
trialCleared

A.21 Color Search Outline (Function)

Built in Chapter 3, Settle One Cheapest Cell.

FunctionColor Search Outline

Shows one cell's place in the search on its Search Outline: hidden while the search has not reached the cell, a thin ring in frontierTint once it is reached, a thick ring in settledTint once it is settled, and currentTint while it is the current cell (the one the last Step settled), and routeTint once it is on the Route (its routeOrder is 0 or more). A later rule wins: Route over current over settled over frontier. The thin and the thick ring are frames 0 and 1 of the Cell Outline picture, so a settled cell shows by its shape as well as by its color.

PARAMETERS
NameTypeStarts at
outlineObjectStructural
Required Components
Slot Namesprite
Component TypeSprite
cellNumber0
frontierTintColor#32e9ed
settledTintColor#64afff
currentTintColor#ffffff
routeTintColor#ffe043
ACTIONS
1Set Visible
Applies To
outline
Visible
false
2Ifdata('Maze Cells', cell, 'distance') < data('Maze Settings', 'rules', 'unreached')
Then
3Set Visible
Applies To
outline
Visible
true
4Set Frame
Applies To
outline
Frame
0
5Change Sprite Tint Property
Applies To
outline
Value
frontierTint
6Ifdata('Maze Cells', cell, 'settled') == 1
Then
7Set Visible
Applies To
outline
Visible
true
8Set Frame
Applies To
outline
Frame
1
9Change Sprite Tint Property
Applies To
outline
Value
settledTint
10Ifcell == $currentCell
Then
11Set Visible
Applies To
outline
Visible
true
12Change Sprite Tint Property
Applies To
outline
Value
currentTint
13Ifdata('Maze Cells', cell, 'routeOrder') >= 0
Then
14Set Visible
Applies To
outline
Visible
true
15Change Sprite Tint Property
Applies To
outline
Value
routeTint

A.22 Relax Neighbor (Function)

Built in Chapter 3, Settle One Cheapest Cell.

FunctionRelax Neighbor

Offers one neighbor of a settled cell a route through it. The neighbor is the cell next to cell in direction (a row of Directions). A neighbor on the map that is not a Wall and not settled gets distance (cell's distance plus the neighbor's cost) and cell as its parent, but only when that is strictly smaller than its distance so far, so an equal route keeps the parent it found first.

PARAMETERS
NameTypeStarts at
cellNumber0
directionTextUp
ACTIONS
1Declare Variable
Name
neighbor
Value
-1
2Declare Variable
Name
newDistance
Value
0
3Find Grid NeighborFunction
Action Name
next
cell
cell
direction
direction
4Change Variable
Variable
neighbor
Value
next.value
5Ifneighbor >= 0 && data('Maze Cells', neighbor, 'cost') != data('Terrains', 'Wall', 'cost') && data('Maze Cells', neighbor, 'settled') == 0
Then
6Change Variable
Variable
newDistance
Value
data('Maze Cells', cell, 'distance')
7Change Variable
Variable
newDistance
Operator
+=
Value
data('Maze Cells', neighbor, 'cost')
8IfnewDistance < data('Maze Cells', neighbor, 'distance')
Then
9Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', neighbor)
Column
"distance"
Value
newDistance
10Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', neighbor)
Column
"parent"
Value
cell

A.23 Relax Neighbors (Function)

Built in Chapter 3, Settle One Cheapest Cell.

FunctionRelax Neighbors

Offers every neighbor of one settled cell a route through it (Relax Neighbor), in the order of Directions: Up, Right, Down, Left.

PARAMETERS
NameTypeStarts at
cellNumber0
ACTIONS
1RepeatdataCount('Directions')times
Each time
2Relax NeighborFunction
cell
cell
direction
dataRow('Directions', local.index)

A.24 Request Reset

Built in Chapter 3, Settle One Cheapest Cell.

Logic ComponentRequest ResetAttach to: Reset Button

Lets the learner ask for a Reset with a click or a touch: activating the Reset button sends resetRequested, which Reset Trial on Maze Rules answers.

Attach toAny Object
On Hud Activated
WhenUI Activated
1Trigger Custom Event
Custom Event
resetRequested

A.25 Request Step

Built in Chapter 3, Settle One Cheapest Cell.

Logic ComponentRequest StepAttach to: Step Button

Lets the learner ask for one Step with a click or a touch on the Step button, or with the Step Command (Space in the Input Manager): each sends stepRequested, which Step Trial on Maze Rules answers. Each first sends pauseRequested, so a Step while Find route runs pauses it before the Step (the Function Ask For One Step).

Attach toAny Object
On Hud Activated
WhenUI Activated
1Ask For One StepFunction
When Step Is Pressed
WhenCommand PressedCommand: Step
1Ask For One StepFunction

A.26 Settle Cheapest Cell (Function)

Built in Chapter 3, Settle One Cheapest Cell.

FunctionSettle Cheapest Cell

Settles the cheapest frontier cell (Choose Cheapest Cell): marks it settled, adds 1 to Visited, and sends cellSettled, so the Status line can name it. The cell settled becomes the current cell (the Project Global currentCell), which is -1 when the frontier was empty and nothing was settled; cell gives the same number.

RETURN TYPENumber
ACTIONS
1Choose Cheapest CellFunction
Action Name
cheapest
2Change Variable
Variable
$currentCell
Value
cheapest.value
3If$currentCell >= 0
Then
4Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', $currentCell)
Column
"settled"
Value
1
5Change Variable
Variable
$visited
Operator
+=
Value
1
6Trigger Custom Event
Custom Event
cellSettled
7Return
Value
$currentCell

A.27 Show Search Outline

Built in Chapter 3, Settle One Cheapest Cell.

Logic ComponentShow Search OutlineAttach to: Search Outline

One cell's ring that shows where the search is: whenever the search changes, it is hidden, a thin cyan ring (frontier), a thick blue ring (settled) or a thick white ring (the current cell), with Color Search Outline. Its cell is its Map Place cell, which Lay Out Map gives it. frontierTint, settledTint, currentTint and routeTint are the four colors: a cell on the Route is yellow.

Attach toAny Object
DATA STRUCTURES
Map Placeself.mapPlace
COMPONENTS
self.spriteSprite
SHARED VARIABLES
NameTypeKindStarting Value
frontierTintColorConstant#32e9ed
settledTintColorConstant#64afff
currentTintColorConstant#ffffff
routeTintColorConstant#ffe043
On Placed on Map
WhenplacedOnMapCustom Event
1Cell Screen PositionFunction
Action Name
place
cell
self.mapPlace.cell
2Set Position
Position Relative To
Screen
X
place.x
Y
place.y
3Color Search OutlineFunction
outline
self
cell
self.mapPlace.cell
frontierTint
@self.frontierTint
settledTint
@self.settledTint
currentTint
@self.currentTint
routeTint
@self.routeTint
On Search Changed
WhensearchChangedCustom Event
1Color Search OutlineFunction
outline
self
cell
self.mapPlace.cell
frontierTint
@self.frontierTint
settledTint
@self.settledTint
currentTint
@self.currentTint
routeTint
@self.routeTint

A.28 Show Settled Cell

Built in Chapter 3, Settle One Cheapest Cell.

Logic ComponentShow Settled CellAttach to: Status

The Status line while the search settles cells: each time Settle Cheapest Cell settles a cell (cellSettled), Status names the cell by its Maze Cells row and gives its distance, as in "Cell 52: cost 8". When the cell settled is the Tower, Status says the Route is being built instead (the Messages buildingRoute words).

Attach toAny Object
On Cell Settled
WhencellSettledCustom Event
1If$currentCell == data('Maze Settings', 'rules', 'goalCell')
Then
2Change Variable
Variable
$status
Value
data('Messages', 'buildingRoute', 'words')
3Otherwise
4Change Variable
Variable
$status
Value
dataRow('Maze Cells', $currentCell)
5Change Variable
Variable
$status
Operator
+=
Value
data('Messages', 'cellSettled', 'words')
6Change Variable
Variable
$status
Operator
+=
Value
data('Maze Cells', $currentCell, 'distance')

A.29 Step Trial

Built in Chapter 3, Settle One Cheapest Cell.

Logic ComponentStep TrialAttach to: Maze Rules

Makes one Step of the trial each time stepRequested arrives (the Step button or the Step Command). What a Step does depends on the trial's phase, the Mode of stepRequested: Ready begins the search and settles the Camp, Searching settles the next cheapest cell, and Finished does nothing. Before the first settle, Ready checks the map and Maze Settings (Check Maze Input); maxCostLimit and unreachedLimit are the largest maxCost and unreached that check allows. Once the Tower is settled, Tracing marks one cell of the Route per Step, from the Tower back to the Camp, checking each link (Check Route Link); traceCell is the cell the next Step marks and routeLength how many cells are marked. Then Replaying moves the Marker one cell of the Route per Step, toward the Tower: it commits the next cell (markerCell) and waits (Waiting For Marker) until Slide Marker says it has landed (markerLanded). On the Tower the Route is complete. Every way the trial ends goes through End Trial, which also tells Find Route. markerOrder is the routeOrder of the Marker's cell. A cleared trial (trialCleared, from Clear Trial) starts again from Ready.

Attach toMaze Rules
SHARED VARIABLES
NameTypeKindStarting Value
maxCostLimitNumberConstant99
unreachedLimitNumberConstant1000000000
On Step Requested
WhenstepRequestedCustom Event
ModeReady (Starting Mode)
1Check Maze InputFunction
Action Name
inputCheck
maxCostLimit
@self.maxCostLimit
unreachedLimit
@self.unreachedLimit
2IfinputCheck.value == ""
Then
3Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', data('Maze Settings', 'rules', 'startCell'))
Column
distance
Value
0
4Change Component Value
Component Value
self.stepTrialData.traceCell
Value
data('Maze Settings', 'rules', 'goalCell')
5Change Component Value
Component Value
self.stepTrialData.routeLength
Value
0
6Settle Cheapest CellFunction
Action Name
firstSettle
7IffirstSettle.value == data('Maze Settings', 'rules', 'goalCell')
Then
8Switch Mode
Event
On Step Requested
Mode
Tracing
9Otherwise
10Relax NeighborsFunction
cell
firstSettle.value
11Switch Mode
Event
On Step Requested
Mode
Searching
12Trigger Custom Event
Custom Event
searchChanged
13Otherwise
14End TrialFunction
rules
self
ending
inputCheck.value
15Switch Mode
Event
On Step Requested
Mode
Finished
On Step Requested
WhenstepRequestedCustom Event
ModeSearching
1Settle Cheapest CellFunction
Action Name
settle
2Ifsettle.value >= 0
Then
3Ifsettle.value == data('Maze Settings', 'rules', 'goalCell')
Then
4Switch Mode
Event
On Step Requested
Mode
Tracing
5Otherwise
6Relax NeighborsFunction
cell
settle.value
7Otherwise
8End TrialFunction
rules
self
ending
noRoute
9Switch Mode
Event
On Step Requested
Mode
Finished
10Trigger Custom Event
Custom Event
searchChanged
On Step Requested
WhenstepRequestedCustom Event
ModeTracing
1Set Data Cell
Table
"Maze Cells"
Row
dataRow('Maze Cells', self.stepTrialData.traceCell)
Column
routeOrder
Value
self.stepTrialData.routeLength
2Change Component Value
Component Value
self.stepTrialData.routeLength
Operator
+=
Value
1
3Ifself.stepTrialData.traceCell == data('Maze Settings', 'rules', 'startCell')
Then
4Change Variable
Variable
$status
Value
data('Messages', 'followRoute', 'words')
5Switch Mode
Event
On Step Requested
Mode
Replaying
6Otherwise
7Check Route LinkFunction
Action Name
link
cell
self.stepTrialData.traceCell
8Iflink.value == 1 && self.stepTrialData.routeLength < dataCount('Maze Cells')
Then
9Change Component Value
Component Value
self.stepTrialData.traceCell
Value
data('Maze Cells', self.stepTrialData.traceCell, 'parent')
10Otherwise
11End TrialFunction
rules
self
ending
invalidRoute
12Switch Mode
Event
On Step Requested
Mode
Finished
13Trigger Custom Event
Custom Event
searchChanged
On Step Requested
WhenstepRequestedCustom Event
ModeReplaying
1Declare Variable
Name
markerOrder
Value
-1
2Change Variable
Variable
markerOrder
Value
data('Maze Cells', $markerCell, 'routeOrder')
3IfmarkerOrder > 0
Then
4Change Variable
Variable
$markerCell
Value
dataFind('Maze Cells', 'routeOrder', markerOrder - 1)
5Switch Mode
Event
On Step Requested
Mode
Waiting For Marker
6Trigger Custom Event
Custom Event
markerMoved
7Otherwise
8End TrialFunction
rules
self
ending
cheapestRoute
9Switch Mode
Event
On Step Requested
Mode
Finished
On Step Requested
WhenstepRequestedCustom Event
ModeWaiting For Marker
(no Actions)
On Step Requested
WhenstepRequestedCustom Event
ModeFinished
(no Actions)
On Marker Landed
WhenmarkerLandedCustom Event
1If$markerCell == data('Maze Settings', 'rules', 'goalCell')
Then
2End TrialFunction
rules
self
ending
cheapestRoute
3Switch Mode
Event
On Step Requested
Mode
Finished
4Otherwise
5Switch Mode
Event
On Step Requested
Mode
Replaying
On Trial Cleared
WhentrialClearedCustom Event
1Reset Modes
Event
On Step Requested

A.31 Draw Route Line (Function)

Built in Chapter 4, Finish a Route.

FunctionDraw Route Line

Shows one Route Line (or its backing) between two neighboring cells, cell and neighbor, only while both are on the Route (routeOrder 0 or more) and one comes right after the other (their routeOrder values differ by 1); otherwise hides it. So a line never joins two Route cells that do not follow each other.

PARAMETERS
NameTypeStarts at
lineObjectStructural
Required Components
Slot Namesprite
Component TypeSprite
cellNumber0
neighborNumber0
ACTIONS
1Declare Variable
Name
cellOrder
Value
-1
2Declare Variable
Name
neighborOrder
Value
-1
3Change Variable
Variable
cellOrder
Value
data('Maze Cells', cell, 'routeOrder')
4Change Variable
Variable
neighborOrder
Value
data('Maze Cells', neighbor, 'routeOrder')
5IfcellOrder >= 0 && neighborOrder >= 0 && abs(cellOrder - neighborOrder) == 1
Then
6Set Visible
Applies To
line
Visible
true
7Otherwise
8Set Visible
Applies To
line
Visible
false

A.32 Lay Out Route Lines

Built in Chapter 4, Finish a Route.

Logic ComponentLay Out Route LinesAttach to: Map

Lays out the Route Line when the Scene starts: it joins every two neighboring cells with a Route Line over a Route Line Backing, once, from the cell that comes first in reading order to its neighbor on the right or below. Each line gets its two cells (its Route Link) and is told, with placedOnMap, that it is placed; it then stands between its cells and shows itself. routeLineBacking and routeLine are the Objects it makes.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
routeLineBackingObjectConstantNone
routeLineObjectConstantNone
When the Scene Starts
WhenScene Start
1RepeatdataCount('Maze Cells')times
Each time
2Declare Variable
Name
thisCell
Value
local.index
3RepeatdataCount('Directions')times
Each time
4Find Grid NeighborFunction
Action Name
next
cell
thisCell
direction
dataRow('Directions', local.index)
5Ifnext.value > thisCell
Then
6Create Instance
Object to Create
@self.routeLineBacking
X
0
Y
0
Created As
newBacking
7Change Variable
Variable
newBacking.cell
Value
thisCell
8Change Variable
Variable
newBacking.neighbor
Value
next.value
9Trigger Custom Event on Object
Applies To
newBacking
Custom Event
placedOnMap
10Create Instance
Object to Create
@self.routeLine
X
0
Y
0
Created As
newLine
11Change Variable
Variable
newLine.cell
Value
thisCell
12Change Variable
Variable
newLine.neighbor
Value
next.value
13Trigger Custom Event on Object
Applies To
newLine
Custom Event
placedOnMap

A.33 Marker Screen Position (Function)

Built in Chapter 4, Finish a Route.

FunctionMarker Screen Position

Where the Marker stands on one cell, in screen pixels: on the cell's lower-right corner, Maze Layout markerOffset pixels right of and below the cell's center (Cell Screen Position).

PARAMETERS
NameTypeStarts at
cellNumber0
RETURN TYPEMarker Screen Position Result (a Data Structure)
ACTIONS
1Declare Variable
Name
x
Value
0
2Declare Variable
Name
y
Value
0
3Cell Screen PositionFunction
Action Name
place
cell
cell
4Change Variable
Variable
x
Value
place.x + data('Maze Layout', 'board', 'markerOffset')
5Change Variable
Variable
y
Value
place.y - data('Maze Layout', 'board', 'markerOffset')
6Return
x
x
y
y

A.34 Show Route Cost

Built in Chapter 4, Finish a Route.

Logic ComponentShow Route CostAttach to: Route Cost

The Cost readout: whenever the search changes, it shows the cost of the cheapest Route, which is the Tower's distance once the Tower is settled, or the Messages noCost words ("--") while it is not.

Attach toAny Object
COMPONENTS
self.textText / UI
On Search Changed
WhensearchChangedCustom Event
1Declare Variable
Name
tower
Value
0
2Change Variable
Variable
tower
Value
data('Maze Settings', 'rules', 'goalCell')
3Ifdata('Maze Cells', tower, 'settled') == 1
Then
4Change Component Value
Component Value
self.text.text
Value
data('Maze Cells', tower, 'distance')
5Otherwise
6Change Component Value
Component Value
self.text.text
Value
data('Messages', 'noCost', 'words')

A.35 Show Route Line

Built in Chapter 4, Finish a Route.

Logic ComponentShow Route LineAttach to: Route Line, Route Line Backing

One piece of the Route Line, the yellow line that joins the Route's cells: whenever the search changes it is shown only while its two cells follow each other on the Route (Draw Route Line). The Route Line and the Route Line Backing both use it. Its two cells are its Route Link cell and neighbor, which Lay Out Route Lines gives it; it stands halfway between them, upright when one is above the other. lineTint is its color: yellow on the Route Line, and dark on the Route Line Backing, each Object's own Shared Variable.

Attach toAny Object
DATA STRUCTURES
Route Linkself.routeLink
COMPONENTS
self.spriteSprite
SHARED VARIABLES
NameTypeKindStarting Value
lineTintColorConstant#ffeb55
On Placed on Map
WhenplacedOnMapCustom Event
1Cell Screen PositionFunction
Action Name
from
cell
self.routeLink.cell
2Cell Screen PositionFunction
Action Name
to
cell
self.routeLink.neighbor
3Set Position
Position Relative To
Screen
X
(from.x + to.x) / 2
Y
(from.y + to.y) / 2
4Iffrom.x == to.x
Then
5Set Rotation
Degrees
90
6Change Sprite Tint Property
Value
@self.lineTint
7Draw Route LineFunction
line
self
cell
self.routeLink.cell
neighbor
self.routeLink.neighbor
On Search Changed
WhensearchChangedCustom Event
1Draw Route LineFunction
line
self
cell
self.routeLink.cell
neighbor
self.routeLink.neighbor

A.36 Slide Marker

Built in Chapter 4, Finish a Route.

Logic ComponentSlide MarkerAttach to: Marker

Shows the Marker on the cell markerCell names. When Step Trial commits the Marker's next cell (markerMoved), the Marker slides there in Maze Layout slideSeconds and sends markerLanded when it is exactly on it. When the search changes or is cleared (searchChanged), the Marker stands on markerCell at once, ending any slide.

Attach toMarker
On Search Changed
WhensearchChangedCustom Event
1Stop Recurring Timer
Timer Name
markerSlide
2Stand MarkerFunction
marker
self
On Marker Moved
WhenmarkerMovedCustom Event
1Marker Screen PositionFunction
Action Name
spot
cell
$markerCell
2Tween
Value
self.transform.position.x
Target
spot.x
Duration
data('Maze Layout', 'board', 'slideSeconds')
3Tween
Value
self.transform.position.y
Target
spot.y
Duration
data('Maze Layout', 'board', 'slideSeconds')
4Start Recurring Timer
Timer Name
markerSlide
Repeat Every (s)
data('Maze Layout', 'board', 'slideSeconds')
Ring Once
Yes
On the Marker Slide Timer
WhenRecurring TimerTimer name: markerSlide
1Stand MarkerFunction
marker
self
2Trigger Custom Event
Custom Event
markerLanded

A.37 Stand Marker (Function)

Built in Chapter 4, Finish a Route.

FunctionStand Marker

Stops the Marker and puts it exactly on the cell markerCell names (Marker Screen Position).

PARAMETERS
NameTypeStarts at
markerObjectMarker
ACTIONS
1Control Tween
Applies To
marker
2Marker Screen PositionFunction
Action Name
spot
cell
$markerCell
3Set Position
Applies To
marker
Position Relative To
Screen
X
spot.x
Y
spot.y

A.38 Ask For One Step (Function)

Built in Chapter 5, Find and Pause.

FunctionAsk For One Step

Asks Maze Rules for one Step: first pauseRequested, so Find Route stops Find route if it is running, then stepRequested, which Step Trial answers with one transition. Both are heard at once, in the order they are sent, so the Step is the only transition the learner asked for.

ACTIONS
1Trigger Custom Event
Custom Event
pauseRequested
2Trigger Custom Event
Custom Event
stepRequested

A.39 End Trial (Function)

Built in Chapter 5, Find and Pause.

FunctionEnd Trial

Ends the trial on rules (Maze Rules). ending is the Messages row that says how it ended (cheapestRoute, noRoute, invalidRoute, or the row of a broken input rule): Status shows its words, and trialEnded tells Find Route on rules that the trial has ended. Step Trial, which calls it, then goes to Finished.

PARAMETERS
NameTypeStarts at
rulesObjectMaze Rules
endingTextcheapestRoute
ACTIONS
1Change Variable
Variable
$status
Value
data('Messages', ending, 'words')
2Trigger Custom Event on Object
Applies To
rules
Custom Event
trialEnded

A.40 Find Route

Built in Chapter 5, Find and Pause.

Logic ComponentFind RouteAttach to: Maze Rules

Runs the trial by itself: each findRequested (the Find route button or the Find Route Command) starts Find route or pauses it, by the Mode of findRequested. While it runs, the searchTick timer sends stepRequested every Maze Settings tickSeconds, the same Step the Step button asks for, and the button reads Pause (findStarted). A cleared trial (trialCleared) stops it (Stop Finding), and so does pauseRequested (Escape, or a Step). A trial that has ended (trialEnded) stops it too, and the next findRequested then starts over: Start Over clears the trial before Start runs Find route on the new one. Whenever it stops (findStopped), Pause is taken out and Start put in.

Attach toMaze Rules
On Find Requested
WhenfindRequestedCustom Event
ModeStart Over
1Clear TrialFunction
rules
self
On Find Requested
WhenfindRequestedCustom Event
ModeStart (Starting Mode)
1Change Variable
Variable
$status
Value
data('Messages', 'searching', 'words')
2Start Recurring Timer
Timer Name
searchTick
Repeat Every (s)
data('Maze Settings', 'rules', 'tickSeconds')
3Trigger Custom Event
Custom Event
findStarted
4Switch Mode
Event
On Find Requested
Mode
Pause
On Find Requested
WhenfindRequestedCustom Event
ModePause
1Stop FindingFunction
rules
self
2Change Variable
Variable
$status
Value
data('Messages', 'paused', 'words')
On the Search Tick Timer
WhenRecurring TimerTimer name: searchTick
1Trigger Custom Event on Object
Custom Event
stepRequested
On Trial Cleared
WhentrialClearedCustom Event
1Stop FindingFunction
rules
self
2Turn Off Mode
Event
On Find Requested
Mode
Start Over
On Pause Requested
WhenpauseRequestedCustom Event
1Stop FindingFunction
rules
self
On Trial Ended
WhentrialEndedCustom Event
1Stop FindingFunction
rules
self
2Turn On Mode
Event
On Find Requested
Mode
Start Over
On Find Stopped
WhenfindStoppedCustom Event
1Turn Off Mode
Event
On Find Requested
Mode
Pause
2Turn On Mode
Event
On Find Requested
Mode
Start

A.41 Request Find

Built in Chapter 5, Find and Pause.

Logic ComponentRequest FindAttach to: Find Route Button

Lets the learner start or pause Find route with a click or a touch on the Find route button, or with the Find Route Command (F in the Input Manager): each sends findRequested, which Find Route on Maze Rules answers. The Pause Command (Escape) only pauses: it sends pauseRequested.

Attach toAny Object
On Hud Activated
WhenUI Activated
1Trigger Custom Event
Custom Event
findRequested
When Find Route Is Pressed
WhenCommand PressedCommand: Find Route
1Trigger Custom Event
Custom Event
findRequested
When Pause Is Pressed
WhenCommand PressedCommand: Pause
1Trigger Custom Event
Custom Event
pauseRequested

A.42 Show Find Caption

Built in Chapter 5, Find and Pause.

Logic ComponentShow Find CaptionAttach to: Find Route Button

The words on the Find route button: the Messages pauseCaption words ("Pause") while Find route runs (findStarted), and the findCaption words ("Find route") when it stops (findStopped).

Attach toAny Object
COMPONENTS
self.textText / UI
On Find Started
WhenfindStartedCustom Event
1Change Component Value
Component Value
self.text.text
Value
data('Messages', 'pauseCaption', 'words')
On Find Stopped
WhenfindStoppedCustom Event
1Change Component Value
Component Value
self.text.text
Value
data('Messages', 'findCaption', 'words')

A.43 Stop Finding (Function)

Built in Chapter 5, Find and Pause.

FunctionStop Finding

Stops Find route on rules (Maze Rules): its searchTick timer stops, and findStopped tells the Find route button and Find Route, so the next findRequested starts Find route again. Stopping a Find route that is not running changes nothing. The trial is kept as it is.

PARAMETERS
NameTypeStarts at
rulesObjectMaze Rules
ACTIONS
1Stop Recurring Timer
Applies To
rules
Timer Name
"searchTick"
2Trigger Custom Event
Custom Event
findStopped