TutorialsDijkstra’s Algorithm

1  The Map and the Sidebar

Goal

By the end of this chapter, the map lies on the table: 120 cells of road, forest, mud and wall. The camp is in one corner and the tower in the other. The sidebar stands beside it. The compass waits at the camp.

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

Weighted Maze, Chapter 1 finishedMyth project · 1.7 MB

To open it, start Myth Engine, choose File › Open Project... and pick the downloaded file.

1.1 The Idea

The Welcome page showed you this screen, the map lying on the dark teal table. The camp’s tent is in one corner and the tower’s orange flag in the other. The compass waits at the camp.

This chapter builds all of it, and then it stops. Click a cell or a button at the end, and nothing answers yet. That starts in Chapter 2.

Here’s the first real question. The map you’re about to make has 120 cells. Do you place 120 Objects by hand, each in its exact spot, each with its exact picture? That would be a long afternoon, with 120 chances to slip.

You don’t. The game lays out its own map, every time it starts. A cell is one square of the map, and the cells are numbered the way you read a page. The top row is 0 to 11, the next row starts at 12, and the last cell, in the bottom-right corner, is 119. So the camp is cell 0, and the tower is cell 119.

Behind the map stands a Data Table, a spreadsheet the game reads while it plays. This one is called Maze Cells, and it has a row for each cell. Each row holds that cell’s cost. The pictures only follow the numbers, so a cost of 3 draws forest and a cost of -1 draws a wall.

So each cell draws itself. It knows one thing, its own number, and it asks two questions: where do I stand, and which picture do I show? A Function answers each one. A Function is a small piece of Logic that answers a question whenever other Logic asks it. Both answers come out of tables.

By the end of the chapter, the tables hold everything a search will need: what each cell costs, and which cells are the camp and the tower. Nothing searches yet. In Chapter 3, Dijkstra’s algorithm reads these same costs, and nothing else.

Most parts of this chapter show you something new each time you run the game. The map is the exception. It stays empty until the last piece of its part is in, and then all 120 cells appear at once.

1.2 The Plan

Here’s how the pieces work together as the game starts. Read each line from left to right. Almost every name here is new. So read the lines once for their shape, and come back after the map. By then you’ll have built every piece they name.

  • The Scene starts -> Lay Out Map makes one Map Cell for each row of Maze Cells, gives it its number and sends it placedOnMap.
  • A Map Cell hears placedOnMap -> Show Map Cell asks Cell Screen Position where it stands and Cell Picture what it shows, and goes there.
  • The Scene starts -> Reset Trial copies Paint terrain from Messages into $status -> the Status line shows it.
  • Each Terrain Button is made -> Show Terrain Choice writes its terrain’s name and cost on it, and colors it tan if it’s the terrain you’ll paint with, $brush.
  • Each Terrain Preview is made -> Show Terrain Picture shows its terrain’s picture.
  • The Selection and the Marker are made -> each asks Cell Screen Position where the camp is, and goes there.

Nothing waits for a key or a click yet. Everything here happens once, as the game opens.

1.3 Set Up

Every game starts as an empty project, and an empty project is a strange thing to look at. There’s a blue Scene, a lot of buttons, and no game anywhere. It fills up faster than you’d think.

If you made the project on the Welcome page and installed the Starter Kit into it, you’re ready. If not, do it now. Choose File > New Project… and pick Blank 2D. Type Weighted Maze as its name, choose where it goes with Browse…, and press Create Project. Install the Starter Kit with File > Install Myth Pack…, and pick its file from the button below.

Weighted Maze Starter KitMyth Pack · 1168 KB · every picture

To install it, open Myth Engine, choose File › Install Myth Pack... and pick the downloaded file.

Myth Engine asks before it installs. Its window has Add to This Project already chosen, and it says the kit adds 4 resources. Press Install.

The Set up card comes after these paragraphs, so read them first, then work down the card from the top.

ART lists the four pictures this chapter uses. The Starter Kit brought them, so there’s nothing to make.

Leave GLOBAL VARIABLES for later. They’re made on a Logic Component’s Globals card, and your first Logic Component comes in the third part, with the Status line.

The card’s SCENE block makes a Scene called Map Table. Your project already has one Scene, named Scene, so give it that name instead of making a second one. In the Resources panel, open Scenes, right-click Scene, choose Rename, and type Map Table. Start Scene, near the end of the card, follows the new name by itself.

Now the Game Settings. Open them with the Game Settings button above the Resources, and enter the card’s lines top to bottom. The Set up card on Making what a card shows says where each one lives.

Pixels per Meter comes first on purpose. Myth turns the Reference Height into meters at the Pixels per Meter it has at that moment. In the card’s order, the top of the screen comes out at 21.25 meters. The Main Camera, halfway up, is at 10.625. Typed the other way round, nothing on the screen would look different. The Main Camera’s Y would be off.

Reference Width and Reference Height make the screen 1200 by 850 pixels. Every X and Y you’ll type for something on the screen counts in those pixels. The Page Background is the dark teal around the game. Click its swatch, the small square of color, and type the code into the HEX box.

Now the Scene’s own settings. Its tab is already open. Pick the arrow tool, the first button above the preview, and click an empty spot. The Properties on the left show the Scene’s Background Color: give it the same dark teal.

Under Cameras and Views, press Add View. It makes the Main View and the Main Camera together, sized from the Game Settings you’ve typed. So they already match the card’s Camera and View lines. Check them, and type any number that differs.

Start Scene, near the end of the card, should already read Map Table · 2D. It moved with the name. Leave PLACE THESE for later. Each part of the chapter places its own Objects, once they exist.

Set upWhat this chapter adds
ART (sprites, from the starter kit)
Terrain Tiles
Cell Outline
Compass
Panel
GLOBAL VARIABLES
$visitedNumberstarts at 0
$statusTextstarts at
$brushTextstarts at Road
GAME SETTINGS > General > World Scale
Pixels per Meter40
GAME SETTINGS > Display > Window
TitleWeighted Maze
GAME SETTINGS > Display > Reference Resolution
Reference Width1200
Reference Height850
GAME SETTINGS > Display > Rendering
Texture FilteringSmooth Textures
Anti AliasingFXAA (Fast)
GAME SETTINGS > Display > Page Background (Outside the Game)
Color#152A31
SCENEMap Table (new)
Camera Main CameraX 15, Y 10.625, view 30 x 21.25 m
View Main View1200 x 850 pixels, camera Main Camera
Background Color#152A31
GAME SETTINGS > General > Startup
Start SceneMap Table · 2D
SCENE Map Table: PLACE THESE
ObjectXY
Maze Rules021.25
Sidebar Panel1000-442
Title408-55
Instruction408-88
Map021.25
Selection56-154
Marker72-170
Route Caption1000-151
Terrain Caption1000-187
Terrain Button1020-238
Terrain Preview887-238
Terrain Button1020-304
with Per Instance Variables > Terrain = Forest
Terrain Preview887-304
with Per Instance Variables > Terrain = Forest
Terrain Button1020-370
with Per Instance Variables > Terrain = Mud
Terrain Preview887-370
with Per Instance Variables > Terrain = Mud
Terrain Button1020-436
with Per Instance Variables > Terrain = Wall
Terrain Preview887-436
with Per Instance Variables > Terrain = Wall
Cost Caption977-515
Route Cost1040-515
Visited1000-554
Status1000-593
Step Button940-662
Find Route Button1077-662
Reset Button1000-728

Save your project now, with Ctrl+S, and again at the end of each part.

1.4 The Title Over the Map

First come the words over the map.

The title stands near the top in cream letters: Weighted maze (Dijkstra). Under it, smaller, is the line Paint terrain. Find the cheapest route. That’s the whole game, in six words.

Each one is a Screen UI Object with a Text / UI on it. Those are words that sit on the screen and never move. An Object card and its components on the Making page shows how to make one, and this is your first. For the Title, you need only its paragraphs on making an Object, attaching a component and a Text / UI’s fields. The others are for later cards. A new Screen UI Object comes with UI Interaction, and the Title’s card doesn’t list it, so remove it. Everything else comes from the card.

ObjectTitle
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextWeighted maze (Dijkstra)
Font Size30
EmphasisSemibold
Color#F2E6C9
AlignmentCenter
RenderingVector

The Instruction is made the same way, a little smaller.

ObjectInstruction
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextPaint terrain. Find the cheapest route.
Font Size16
EmphasisSemibold
Color#DDCFAD
AlignmentCenter
RenderingVector

Now place them. Open Map Table, find each one under Predefined Objects in the Place Scene Content panel, and drag it onto the Scene. Type its X and Y from PLACE THESE into its Screen Offset (px). The Title goes at 408 and -55, the Instruction at 408 and -88. Across, 408 pixels is the middle of the map that’s coming.

Run the game: press Play, the triangle at the top of the editor. The game opens in a window of its own. The title and its line stand near the top, cream on dark teal, over an empty space. Close the game’s window, and the editor is back.

That’s your game, running.

1.5 The Sidebar

Next comes the sidebar.

It’s the pale panel on the right, where the player will choose and step. From the top down, it reads Camp to tower, then Terrain, then a gap where the four terrains will go. Below the gap are Cost and two dashes. Three buttons sit at the bottom: Step, Find route and Reset.

The panel itself is one picture, the Panel, stretched to 336 by 640 pixels and tinted a warm off-white. Its Scene Depth Draw Order of -20 keeps it under everything else. Its Tint goes on its placement, as A placement’s own values shows.

Its card gives that size twice. That’s not a slip. Under Transform, the Bounding Box is the Object’s own box, which the editor lines things up by. It doesn’t change the picture. The Sprite has a Transform group of its own, and its Size is how big the picture is drawn. On every card with a picture, the two match.

ObjectSidebar Panel
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 336, Y 640
Sprite
Scene Depth Draw Order-20
Z Index Within Object-20
SpritePanel
Transform > SizeX 336, Y 640
Tint (on its placement)#ECE9DF

Four of the sidebar’s lines never change: Camp to tower, Terrain, Cost, and the two dashes beside Cost. Those dashes are an Object of their own, Route Cost. In Chapter 4 it shows what the cheapest route costs, once a search has found one. Make all four like the Title, in their cards’ darker color.

The four cards are alike except for two lines, the Text and the Font Size.

ObjectRoute Caption
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextCamp to tower
Font Size18
EmphasisSemibold
Color#203F43
AlignmentCenter
RenderingVector
ObjectTerrain Caption
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextTerrain
Font Size20
EmphasisSemibold
Color#203F43
AlignmentCenter
RenderingVector
ObjectCost Caption
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextCost
Font Size21
EmphasisSemibold
Color#203F43
AlignmentCenter
RenderingVector
ObjectRoute Cost
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
Text--
Font Size21
EmphasisSemibold
Color#203F43
AlignmentCenter
RenderingVector

The three buttons are words on a picture: the Panel again, with a Text / UI on top. A Z Index Within Object of -1 keeps the picture under the words. Each one keeps its UI Interaction. A later chapter makes it answer a click. Find route is gold on its placement, and Step and Reset are pale.

ObjectStep Button
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 108, Y 48
Text / UI
TextStep
Font Size18
EmphasisBold
Color#203F43
AlignmentCenter
RenderingVector
Sprite
Z Index Within Object-1
SpritePanel
Transform > SizeX 108, Y 48
Tint (on its placement)#EEE3CC
UI Interaction(as it is added)
ObjectFind Route Button
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 146, Y 48
Text / UI
TextFind route
Font Size18
EmphasisBold
Color#203F43
AlignmentCenter
RenderingVector
Sprite
Z Index Within Object-1
SpritePanel
Transform > SizeX 146, Y 48
Tint (on its placement)#D6B06B
UI Interaction(as it is added)
ObjectReset Button
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 254, Y 48
Text / UI
TextReset
Font Size18
EmphasisBold
Color#203F43
AlignmentCenter
RenderingVector
Sprite
Z Index Within Object-1
SpritePanel
Transform > SizeX 254, Y 48
Tint (on its placement)#EEE3CC
UI Interaction(as it is added)

Place all eight from PLACE THESE, at the foot of the Set up card. The link takes you up to the card, and your browser’s Back button brings you here again. Give each its Tint where its card has one. That’s the Sidebar Panel and the three buttons.

Run the game. The pale panel stands at the right, with its captions and its three buttons. Click a button. Nothing happens, and that’s right for now.

1.6 The Status Line

Then comes the line that talks.

Near the foot of the sidebar are two lines: Visited 0, and under it, Paint terrain. In Chapter 3, Visited counts the cells the search has finished with. Today there’s no search, so it reads 0. Status says what the game is doing, in the game’s own words.

Both lines show a Global Variable, a value the whole game shares. The words themselves live in a table, Messages, which today has one row: ready, holding Paint terrain. Later chapters add a row for each thing Status can say. A Data Table card on the Making page shows how to make one.

A table’s columns come on a second card. Myth makes a Data Structure with every table, and names it after the table: Messages Entry for Messages. Its one field, words, is the table’s one column.

Data TableMessagesData Structure: Messages Entry
Row 0ready
wordsPaint terrain.
Data StructureMessages Entry

One row of the "Messages" Data Table.

wordsTextdefault (empty)

Maze Rules comes next. It’s an Empty Object, with no picture and no words. The whole search will live on it from Chapter 3, but today it carries one small piece of Logic.

1.6.1 Reset Trial

When the Scene starts, Reset Trial copies the ready words from Messages into $status. That’s its whole job today. The Status line shows $status, so the words appear there.

Its name looks further ahead. From Chapter 3, a Reset puts the search back where it started, and this is the piece that does it. Its Description, at the top of its card, says so in the game’s own words. A trial is one run of the search, from Ready, with nothing searched yet, until it ends. The notes call the player the learner.

It’s your first Logic Component. A Logic Component card on the Making page shows how to make one. Reset Trial’s card has one line before its Event, Attach to Any Object, and a new Logic Component starts that way. So that passage’s first paragraphs are all it needs today. Then Events: the When bars and Actions, one at a time show what goes inside it: a When bar, and the Actions under it.

Make Reset Trial, but give it no Event yet. The game’s three Global Variables come first, from GLOBAL VARIABLES on your Set up card. On Reset Trial’s canvas, press + on the Globals card and choose New Global…, once for each.

Add the three rows as the card gives them. Two need care. Status starts empty, so clear its Default box. Brush starts at Road, the terrain you’ll paint with first, and Road goes in with no quote marks.

Now give Reset Trial its Event, a Scene Start, which runs once as the Scene begins. Then add its one Action. Every new Action lands a little to one side, apart from the line, with no arrow into it. There it does nothing. Right-click it and choose Connect to sequence. It joins the line, right above End, and an arrow runs into it.

Logic ComponentReset TrialAttach to: Maze Rules

Puts the trial in its Ready state: nothing searched yet, and Status asks the learner to paint terrain. The words come from the Messages table.

Attach toAny Object
When the Scene Starts
WhenScene Start
1Change Variable
Variable
$status
Value
data('Messages', 'ready', 'words')

Make Maze Rules from its card, and attach Reset Trial to it.

ObjectMaze Rules
Logic
Reset Trial

Place Maze Rules from PLACE THESE. It stands in the world, not on the screen, so its X and Y go into World Position: 0 and 21.25. That’s the screen’s top-left corner, in the world’s meters. With no picture, it never shows.

Visited and Status are words on the sidebar, made like the Title. Their Text is the live part. Type it as the card spells it, braces and all.

ObjectVisited
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextVisited {$visited}
Font Size17
EmphasisSemibold
Color#203F43
AlignmentCenter
RenderingVector
ObjectStatus
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
Text{$status}
Font Size16
EmphasisSemibold
Color#203F43
AlignmentCenter
RenderingVector

Place both from PLACE THESE: Visited at 1000 and -554, and Status under it, at 1000 and -593. Run the game. Near the foot of the sidebar, it says Visited 0, and under it, Paint terrain.

1.7 The Terrain Choices

The four terrains come next.

Down the middle of the sidebar stand four rows. Each has a small picture, and beside it a button with words: Road 1, Forest 3, Mud 6, and Wall, with no number, because nothing can enter it. Road is tan. It’s the terrain you’ll paint with first. The others are pale.

Every one of those words and numbers comes from one table, Terrains. It has a row for each terrain, with what it costs and which picture it shows. A wall’s cost is -1. No real price is below 0, so -1 marks the one thing nothing enters.

The pictures all come from Terrain Tiles, one image from the Starter Kit. It holds six pictures, its frames: road, forest, mud and wall, then the camp and the tower. They’re numbered from 0. The frame column of Terrains says which one each terrain shows.

Its columns, cost and frame, are the fields of Terrains Entry, on the card after it.

Data TableTerrainsData Structure: Terrains Entry
Row 0Road
cost1
frame0
Row 1Forest
cost3
frame1
Row 2Mud
cost6
frame2
Row 3Wall
cost-1
frame3
Data StructureTerrains Entry

One row of the "Terrains" Data Table.

costNumberdefault 1
frameNumberdefault 0

1.7.1 Show Terrain Choice

The four buttons are one Object, the Terrain Button, placed four times. Each placement says which terrain it stands for, with its own terrain: Road, Forest, Mud or Wall. That’s a Per Instance Variable, one value for each placement. One piece of Logic serves all four.

When a button is made, Show Terrain Choice first makes sure Terrains has a row by that name, and calls the answer isKnownTerrain. That check is there for a slip of the fingers. A misspelled terrain has no row. Its button keeps its own word, Terrain, instead of showing a made-up cost.

With a real row, it puts the button’s words together in label: the name, then two spaces and the cost. A wall’s -1 isn’t a price, so Wall gets its name alone. Then it writes label on the button. Last comes the color. Show Terrain Choice compares terrain with $brush, the terrain being painted with. The brush’s button gets chosenTint, tan, and the others get plainTint, pale.

This is the first card with blocks before its Event, and A Logic Component card on the Making page goes through each one. Here’s what they hold. label lives in this Logic’s own Data Structure, Show Terrain Choice Data. Its card comes after the Logic’s, with its one field, a Text that starts empty. The two tints are Shared Variables, the same for every button. terrain is the Per Instance Variable, and Road, its Starting Value, takes no quote marks. The Components card fills itself in: self.text turns up as soon as step 6 writes the button’s words.

Step 3 and step 5 write label with Change Component Value, through its path, self.showTerrainChoiceData.label. The two spaces of step 5 go inside quote marks.

Steps 4 and 5 are an If inside step 2’s True line. Step 6 comes back out of it, onto step 2’s line, as the card’s indent shows. So for steps 6 and 7, right-click step 2’s If, not step 4’s, and choose Add inside Then. The Else is step 7’s own.

Logic ComponentShow Terrain ChoiceAttach to: Terrain Button

Shows one terrain the learner can paint with: its name and, unless it is a Wall, what entering it costs (from Terrains). The button is highlighted while its terrain is the brush. 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
Show Terrain Choice Dataself.showTerrainChoiceData
COMPONENTS
self.textText / UI
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.showTerrainChoiceData.label
Value
self.terrain
4Ifdata('Terrains', self.terrain, 'cost') >= 0
Then
5Change Component Value
Component Value
self.showTerrainChoiceData.label
Value
self.terrain + " " + data('Terrains', self.terrain, 'cost')
6Change Component Value
Component Value
self.text.text
Value
self.showTerrainChoiceData.label
7Ifself.terrain == $brush
Then
8Change Sprite Tint Property
Value
@self.chosenTint
9Otherwise
10Change Sprite Tint Property
Value
@self.plainTint

Myth makes Show Terrain Choice Data when you choose New Data Structure on the Data Structures card, and opens it. Give it its field from this card.

Data StructureShow Terrain Choice Data

What one Terrain Button keeps: label, the words it shows (the terrain's name, and its cost unless it is a Wall).

labelTextdefault (empty)

The Terrain Button is words on the Panel, like the buttons at the foot of the sidebar. Its Text says Terrain. No player ever sees that word, because Show Terrain Choice writes over it as the game starts. In the same way, its Tint is the pale #EEE3CC in the Scene, and the Logic gives it its color in the game.

ObjectTerrain Button
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 216, Y 48
Text / UI
TextTerrain
Font Size17
EmphasisBold
Color#203F43
AlignmentCenter
RenderingVector
Sprite
Z Index Within Object-1
SpritePanel
Transform > SizeX 216, Y 48
Tint (on its placement)#EEE3CC
UI Interaction(as it is added)
Data Structure
From LogicShow Terrain Choice
Data StructureShow Terrain Choice Data
Logic
Show Terrain Choice

1.7.2 Show Terrain Picture

Beside each button sits a Terrain Preview, a small picture of the terrain, so the player can see what a painted cell will look like.

Show Terrain Picture works like Show Terrain Choice, only shorter. It has the same Per Instance Variable, terrain, and its first two steps are the same check for a row. Then one Set Frame shows that row’s frame of Terrain Tiles.

Logic ComponentShow Terrain PictureAttach to: Terrain Preview

Shows the Terrain Tiles picture of one terrain beside its button (Terrains frame). 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')
ObjectTerrain Preview
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 54, Y 54
Sprite
Z Index Within Object-1
SpriteTerrain Tiles
Transform > SizeX 54, Y 54
UI Interaction(as it is added)
Logic
Show Terrain Picture

Now the eight placements, a Terrain Button and a Terrain Preview for each terrain, from PLACE THESE. Under most of them is a line like with Per Instance Variables > Terrain = Forest. That’s the placement’s own value. A placement’s own values shows where it goes. Type Forest, Mud or Wall into its Terrain box, with no quote marks. The two Road placements have no such line, because terrain starts at Road. Give each button its Tint as well.

Run the game. Four terrains stand down the sidebar, each with its picture. Road is tan and reads Road 1, and Wall has no number.

1.8 The Map

Now the map itself.

It’s 120 cells in twelve columns and ten rows, each cell 64 pixels square, edge to edge with no gaps. This is the longest part of the chapter, and the map stays empty until its last piece is in. Keep going, because it’s worth the wait.

Three tables hold the map, and Maze Cells is the first: its 120 costs. Maze Settings says how many cells a row has, and which cells are the camp and the tower. Maze Layout says where the map sits on the screen. Cell 00’s center is 56 pixels in from the left and 154 down from the top, and each cell stands 64 pixels from the next.

You won’t type Maze Cells’ 120 rows. First, give Maze Cells Entry, the Data Structure that came with the table, its one field from its card: cost, a Number that starts at 1. The table’s card names it at the top, and its IMPORT CSV block names the file. Click its name, and it downloads. Then press Import CSV, under the grid beside Add Row, and pick that file. Myth Engine asks first, showing what it will add, and you press Import CSV again to let the rows in. Check the first ones against the card’s FIRST ROWS.

The column comes first for a reason. A column the file brings that the table doesn’t have yet comes in as Text, and the map needs numbers.

Data TableMaze CellsData Structure: Maze Cells Entry
IMPORT CSV120 rows, from a file
FIRST ROWS3 of 120, to compare
Row 0Cell 00
cost1
Row 1Cell 01
cost1
Row 2Cell 02
cost1
Data StructureMaze Cells Entry

One row of the "Maze Cells" Data Table.

costNumberdefault 1

Maze Settings and Maze Layout have one row each. You’ll type those. Give each one’s Entry its fields first, from its card. Then a new row starts at the card’s values already, and needs only its name: rules, and board.

Data TableMaze SettingsData Structure: Maze Settings Entry
Row 0rules
columns12
startCell0
goalCell119
Data StructureMaze Settings Entry

One row of the "Maze Settings" Data Table.

columnsNumberdefault 12
startCellNumberdefault 0
goalCellNumberdefault 119
Data TableMaze LayoutData Structure: Maze Layout Entry
Row 0board
originX56
originY154
spacing64
markerOffset16
campFrame4
towerFrame5
Data StructureMaze Layout Entry

One row of the "Maze Layout" Data Table.

originXNumberdefault 56
originYNumberdefault 154
spacingNumberdefault 64
markerOffsetNumberdefault 16
campFrameNumberdefault 4
towerFrameNumberdefault 5

Every Map Cell carries one number of its own: which cell it is. It keeps that number in a Data Structure, Map Place, a small form with one field, cell. The field starts at -1, no cell at all, until the cell is given its number. A Data Structure card on the Making page shows how to make it.

Data StructureMap Place

The cell a piece of the map stands on. cell is its number: 0 is the top-left cell, and the numbers grow to the right, then down (its row of Maze Cells). Lay Out Map gives each Map Cell its cell right after creating it.

cellNumberdefault -1

1.8.1 Cell Screen Position

This one has no picture. It answers a question: where on the screen does a cell stand? You give it a cell number, cell, and it hands back two numbers, x and y, together in one Data Structure, Cell Screen Position Result.

It works that out in two moves. First comes which column and which row. The column is what’s left over when cell is divided by 12. The row is how many whole rows of 12 come before it. Then it turns them into pixels: 64 for each column across or row down, plus where Cell 00 stands, 56 across and 154 down.

Here, row and column mean the map’s rows and columns, not a table’s. A row runs across the map, and a column runs down it. So when the card’s Description says a row holds Maze Settings columns cells, it means 12, the columns value in Maze Settings.

Its y comes back below zero. On the screen, y is 0 at the top edge, and it goes below zero as you go down. So the lower a cell stands, the smaller its y. The camp, cell 0, comes out at 56 and -154, which is 154 pixels down.

Nobody playing Weighted Maze will ever notice this Function, but the map would fall apart without it. Every cell asks it where to stand, and so do the ring and the compass.

It’s your first Function. A Function card on the Making page shows how to make one. Make Cell Screen Position Result first, from its card. Then the Function’s Return Type list offers it. The four numbers it works with, column, row, right and down, are its first four steps, Declare Variables. They last only while the Function runs. Its Return, the last step, hands back right as x and -down as y.

Data StructureCell Screen Position Result

Where a cell's center stands on the screen, as Cell Screen Position returns it, in screen pixels from the top-left corner: x to the right, and y up (so it is negative below the corner), as Set Position takes them for a Screen UI Object.

xNumberdefault 0
yNumberdefault 0
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

1.8.2 Cell Picture

The second question is which picture a cell shows, out of the six frames of Terrain Tiles.

Cell Picture reads the cell’s cost from Maze Cells. This time the row is a number. A table’s rows can be named by a word, as Terrains’ are, or by their number, counting from 0. So cell 0 reads the row Cell 00. Then it looks for the row of Terrains with that cost. That’s what dataFind does: it searches one column of a table and hands back the first row where it finds the value, or -1 when there’s none. The row goes in terrainRow.

Found, and the cell shows that terrain’s frame. Not found, and it shows Road, so a cost that no terrain lists still draws as road. Two checks come last. The camp and the tower show their own pictures, campFrame and towerFrame, unless they’ve been painted as walls. Each check is one If with two tests, joined by &&.

The answer is one plain number: the frame, which picture to show. So the Return Type is Number. The Return, step 14, hands back frame.

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

1.8.3 Show Map Cell

From one Map Cell’s point of view, there’s very little to decide. It knows its number, self.mapPlace.cell, and it waits for one message, placedOnMap. When the message comes, it asks Cell Screen Position where its cell stands, and goes there. Then it asks Cell Picture which frame it shows, and shows it.

The message is a Custom Event: one piece of Logic sends it, and others listen. Events: the When bars on the Making page shows how to listen for a new one. The two questions go in as Actions, as any Function call does, and their answers come back as place and picture. The answer named place has two fields, place.x and place.y, and the one named picture is a single number, picture.value.

Its DATA STRUCTURES line is the Map Place you made a moment ago. Press + on the Data Structures card and pick it, under Existing Data Structures. Myth names it self.mapPlace. That’s how the Logic reads its own number.

Its Set Position counts in screen pixels from the top-left corner, as a placement’s Screen Offset (px) does. So its Position Relative To list says Screen. Left at World, where the list starts, the numbers would count in the game world’s meters. The cell would land far off the screen.

Logic ComponentShow Map CellAttach to: Map Cell

Draws one cell of the map with the picture its cost calls for. 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

Now the Map Cell itself: a Screen UI Object showing Terrain Tiles at 64 by 64. Its Bounding Box matches its picture, as on the sidebar’s cards. It keeps its UI Interaction. In Chapter 2, a click paints a cell. Its Data Structure arrives From Logic when you attach Show Map Cell.

The Scene never places a Map Cell. The next piece makes all of them.

ObjectMap Cell
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 64, Y 64
Sprite
Z Index Within Object-1
SpriteTerrain Tiles
Transform > SizeX 64, Y 64
UI Interaction(as it is added)
Data Structure
From LogicShow Map Cell
Data StructureMap Place
Logic
Show Map Cell

1.8.4 Lay Out Map

Here is the chapter’s one hard idea, so take it slowly.

When the Scene starts, Lay Out Map runs a Repeat, once for each row of Maze Cells. That’s dataCount('Maze Cells'), 120 times. Inside, local.index counts the times round, starting at 0. It’s the cell number.

Each time round does three things. First, Create Instance makes a new Map Cell, from the Shared Variable mapCell, and calls it newCell. Then it gives newCell its number: newCell.cell is local.index. Last, it sends placedOnMap to newCell, and to newCell only.

Think of it as handing out tickets. Each new cell gets a ticket with its number on it, and finds its own seat.

Count the first few. The first time round, local.index is 0, and a Map Cell is made. It’s given 0, and told it’s placed, and it goes to the top-left corner and shows the camp. The second time round, local.index is 1: a cell one place to the right, showing road. The third, 2. The fourth, 3. On it goes, row after row, until the last time round, 119, makes the tower.

mapCell holds the kind of Object the Repeat makes. Press + on the Shared Variables card, and give it the card’s four columns: an Object that stays Constant, starting at None. It gets Map Cell later, on the Map itself. Create Instance reads it as @self.mapCell.

The new cells start at X 0 and Y 0, so type 0 into both. Each one moves itself a moment later. Actions, one at a time shows Create Instance and its Created As box, and If, Else and Repeat shows the Repeat.

You may wonder why step 3 says newCell.cell, when Show Map Cell reads self.mapPlace.cell. Both reach the same field, from two sides. Show Map Cell’s self can be any Object that carries a Map Place, so it goes in through the name Myth gave it, mapPlace. But newCell is a Map Cell, and a Map Cell’s own Variables are the fields of the Data Structure it carries. So cell is one of them. Type step 3’s Variable box exactly as the card has it, newCell.cell.

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, 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 is the Object it makes.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
mapCellObjectConstantNone
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

The Map holds Lay Out Map and nothing else, an Empty Object like Maze Rules. Attach Lay Out Map. Then, in the Map’s Properties under Variables, find mapCell, marked From Logic. Its Value is a list. Pick Map Cell.

ObjectMap
Logic
Lay Out Map
Shared Variables
mapCellMap Cell

Place the Map from PLACE THESE, at World Position 0 and 21.25, like Maze Rules.

Run the game. The map is there. All 120 cells appear at once, edge to edge: the road winding from the camp to the tower, the pines, the mud and the walls. You never placed a single cell.

1.9 The Ring and the Compass

Last come the ring and the compass, at the camp.

An orange ring sits around the camp. In Chapter 2 it marks the cell the arrow keys will paint. The teal compass sits small on the camp’s lower-right corner, so the tent still shows.

1.9.1 Show Selection

The ring is the Selection. When it’s made, Show Selection asks Cell Screen Position where the camp is, and moves the ring there. The camp’s number comes from Maze Settings, startCell. This works like Show Map Cell, Screen and all, with the camp’s number in place of its own.

You’ll place the ring on the camp in the Scene too, so you see it there while you build. But in the game, Show Selection has the last word. It puts the ring wherever startCell says, whatever its placement says. In Chapter 2, the ring learns to walk.

Logic ComponentShow SelectionAttach to: Selection

Puts the Selection, the ring around the cell the keyboard will paint, on its cell. The Selection starts on the Camp (Maze Settings startCell).

Attach toAny Object
When Created
WhenCreate
1Cell Screen PositionFunction
Action Name
place
cell
data('Maze Settings', 'rules', 'startCell')
2Set Position
Position Relative To
Screen
X
place.x
Y
place.y

The Selection shows the Cell Outline’s first frame, the thin ring, at 64 by 64. Its orange Tint goes on its placement. A Scene Depth Draw Order of 4 keeps it over the cells.

ObjectSelection
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 64, Y 64
Sprite
Scene Depth Draw Order4
Z Index Within Object4
SpriteCell Outline
Transform > SizeX 64, Y 64
Tint (on its placement)#FF9D36
Logic
Show Selection

1.9.2 Show Marker

The compass is the Marker. Show Marker asks the same question about the camp. Then it moves 16 pixels right and 16 pixels down, the markerOffset in Maze Layout, to the cell’s lower-right corner. Down is a smaller y on the screen, so it takes 16 away from y.

Logic ComponentShow MarkerAttach to: Marker

Puts the Marker on the lower-right corner of the cell it stands on, Maze Layout markerOffset pixels right of and below the cell's center. The Marker starts on the Camp (Maze Settings startCell).

Attach toAny Object
When Created
WhenCreate
1Cell Screen PositionFunction
Action Name
place
cell
data('Maze Settings', 'rules', 'startCell')
2Set Position
Position Relative To
Screen
X
place.x + data('Maze Layout', 'board', 'markerOffset')
Y
place.y - data('Maze Layout', 'board', 'markerOffset')

The Marker shows the Compass, 24 pixels across. A Scene Depth Draw Order of 5 puts it over the ring.

ObjectMarker
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 24, Y 24
Sprite
Scene Depth Draw Order5
Z Index Within Object5
SpriteCompass
Transform > SizeX 24, Y 24
Logic
Show Marker

Place the Selection and the Marker from PLACE THESE, the Selection at 56 and -154, the Marker at 72 and -170. Give the Selection its Tint, and run the game.

Play it!

Watch for each of these.

  • The window is dark teal. Weighted maze (Dijkstra) stands at the top, and the line under it asks you to paint terrain and find the cheapest route.
  • The map is twelve cells across and ten down, edge to edge, with no gaps between cells.
  • The camp’s tent is in the top-left corner, and the tower’s orange flag is in the bottom-right.
  • Pale stone road runs from the camp along the top, turns down, winds left and right through the pines, and reaches the tower.
  • Brown mud and gray rubble walls sit among the pines.
  • An orange ring stands around the camp, and the compass sits on the camp’s lower-right corner.
  • The sidebar reads Camp to tower, then Terrain, then four rows: Road 1, Forest 3, Mud 6, and Wall, each with its picture.
  • Road is tan, and the other three are pale.
  • Cost shows two dashes. Visited shows 0, and the Status line says Paint terrain.
  • Step, Find route and Reset sit at the bottom, and Find route is gold.
  • Click a cell or a button. Nothing happens yet.
How it works

Maze Cells holds the map as numbers. Lay Out Map makes a cell for each row and hands it its number. Each cell asks where it stands and which picture it shows. The sidebar reads Terrains, and Status reads Messages.

Underneath all of it is one idea: the tables are the map. The pictures only follow them. Change a cost in Maze Cells, and the next time the game starts, that cell shows another terrain. Every chapter from here works on those numbers: Chapter 2 lets you paint them, and Chapter 3 searches them.

1.10 If It Didn’t Work

Something may be a little off the first time. That’s normal, and it’s how everyone learns where things live in the editor. Run the game, watch what it does, and think it through one piece at a time.

No map at all, but the sidebar is there? Perhaps Lay Out Map never ran. Look in Map Table for the Map’s placement, and on the Map for Lay Out Map. Under the Map’s Variables, mapCell should say Map Cell. Does it say None? Pick Map Cell in its list. Open Lay Out Map, too, and look for a block standing apart, with no arrow into it. Join it with Connect to sequence. The Repeat runs once for each row of Maze Cells, so the table needs its 120 rows too.

The Map and Lay Out Map look right, and still no map? Perhaps the cells went into the game world, far off the screen. Look at step 2 of Show Map Cell. Its Position Relative To should say Screen.

Only one cell? The Actions belong inside the Repeat, in its Each time panel, because one left outside the panel runs once, not 120 times. Right-click the Repeat and choose Add inside Repeat for each one, so it lands there.

All the cells piled in the top-left corner? They were made, but never moved to their places. Perhaps they never heard placedOnMap. Look at the name in two places: the Trigger Custom Event on Object in Lay Out Map, and the When bar of Show Map Cell. They must match, with a capital O and a capital M. Or perhaps Cell Screen Position hands back 0s, so every cell goes to the same spot. Its Return, step 11, should say right and -down.

The cells stand in their places, but every one shows road, even the camp? Cell Picture may be handing back 0, which is the road’s frame. Its Return, step 14, should say frame. And in Show Map Cell, step 4’s Frame should say picture.value.

Only the camp or the tower shows road? Look at steps 10 and 12 of Cell Picture, and at campFrame and towerFrame in Maze Layout: 4 and 5.

All four terrain buttons are pale? Look at step 7 of Show Terrain Choice: self.terrain == $brush, with the $. Then at $brush on the Globals card, whose Default is Road, with no quote marks.

A terrain button still says Terrain? Perhaps its placement’s Terrain, under Per Instance Variables, doesn’t match a row of Terrains. Type the name exactly, Forest, Mud or Wall, with no quote marks. If all four still say it, open Show Terrain Choice and look for a block standing apart, with no arrow into it. Step 6 writes the words, and it sits on step 2’s line.

Every picture beside the buttons shows road? Look in Show Terrain Picture for a block standing apart, and at each preview’s Terrain, under Per Instance Variables. Road is the first frame of Terrain Tiles, so it’s what a preview shows until Set Frame runs.

No Paint terrain? Look for Reset Trial on Maze Rules, and Maze Rules in the Scene. Open Reset Trial, and look for its Change Variable standing apart, with no arrow into it. Join it with Connect to sequence. And look at Status’s Text: {$status}, braces and all.

The map is right, but the ring or the compass is off the camp? Look at its own Logic. Show Selection’s cell is the camp’s, data('Maze Settings', 'rules', 'startCell'). Show Marker adds markerOffset to X and takes it away from Y. Both Set Positions say Screen.

Each of these is one small fix. Make it, run the game again, and you’re back with the chapter. And if you’d like to compare, the catch-up download in the Goal is this chapter’s game, finished.

Challenge

The map is yours to change. Open Maze Cells, find a few cells, and give them new costs: -1 for a wall across the road, or 6 for mud where the pines are. Cells count from Cell 00 in the top-left, twelve to a row. Run the game, and your map is the one on the table. Chapter 2 is written for the map on the card, so import the file again before you start it. Import CSV finds each row by its name, Cell 00 to Cell 119. So this time its window says 0 new rows, and as many existing rows as you changed. Press Import CSV, and every cost goes back.

The map is on the table, and the compass waits at the camp. In Chapter 2, the land answers your hands.