- Learn
- Tutorials
- Algorithms
- Dijkstra’s Algorithm
- 1 The Map and the Sidebar
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.
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.
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.
40Weighted Maze1200850Smooth TexturesFXAA (Fast)#152A31#152A31Map Table · 2DSave 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.
Window / UIUIWeighted maze (Dijkstra)30Semibold#F2E6C9CenterVectorThe Instruction is made the same way, a little smaller.
Window / UIUIPaint terrain. Find the cheapest route.16Semibold#DDCFADCenterVectorNow 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.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.
Paint terrain.One row of the "Messages" Data Table.
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.
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.
Any Object- Variable
$status- Value
data('Messages', 'ready', 'words')
Make Maze Rules from its card, and attach Reset Trial to it.
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.
Window / UIUIVisited {$visited}17Semibold#203F43CenterVectorWindow / UIUI{$status}16Semibold#203F43CenterVectorPlace 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.
103162-13One row of the "Terrains" Data Table.
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.
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.
Any Objectself.showTerrainChoiceDataText / UI- Action Name
isKnownTerrain- Table
"Terrains"- Row
self.terrain
isKnownTerrain.value == true- Component Value
self.showTerrainChoiceData.label- Value
self.terrain
data('Terrains', self.terrain, 'cost') >= 0- Component Value
self.showTerrainChoiceData.label- Value
self.terrain + " " + data('Terrains', self.terrain, 'cost')
- Component Value
self.text.text- Value
self.showTerrainChoiceData.label
self.terrain == $brush- Value
@self.chosenTint
- 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.
What one Terrain Button keeps: label, the words it shows (the terrain's name, and its cost unless it is a Wall).
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.
Window / UIUIX 216, Y 48Terrain17Bold#203F43CenterVector-1PanelX 216, Y 48#EEE3CCShow Terrain ChoiceShow Terrain Choice Data1.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.
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).
Any Object- Action Name
isKnownTerrain- Table
"Terrains"- Row
self.terrain
isKnownTerrain.value == true- Frame
data('Terrains', self.terrain, 'frame')
Window / UIUIX 54, Y 54-1Terrain TilesX 54, Y 54Now 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.
111One row of the "Maze Cells" Data Table.
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.
120119One row of the "Maze Settings" Data Table.
56154641645One row of the "Maze Layout" Data Table.
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.
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.
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.
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.
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.
- Name
column- Value
0
- Name
row- Value
0
- Name
right- Value
0
- Name
down- Value
0
- Variable
column- Value
cell % data('Maze Settings', 'rules', 'columns')
- Variable
row- Value
floor(cell / data('Maze Settings', 'rules', 'columns'))
- Variable
right- Value
column * data('Maze Layout', 'board', 'spacing')
- Variable
right- Operator
+=- Value
data('Maze Layout', 'board', 'originX')
- Variable
down- Value
row * data('Maze Layout', 'board', 'spacing')
- Variable
down- Operator
+=- Value
data('Maze Layout', 'board', 'originY')
- 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.
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.
- Name
cost- Value
0
- Name
terrainRow- Value
-1
- Name
frame- Value
0
- Variable
cost- Value
data('Maze Cells', cell, 'cost')
- Variable
terrainRow- Value
dataFind('Terrains', 'cost', cost)
terrainRow >= 0- Variable
frame- Value
data('Terrains', terrainRow, 'frame')
- Variable
frame- Value
data('Terrains', 'Road', 'frame')
cell == data('Maze Settings', 'rules', 'startCell') && cost != data('Terrains', 'Wall', 'cost')- Variable
frame- Value
data('Maze Layout', 'board', 'campFrame')
cell == data('Maze Settings', 'rules', 'goalCell') && cost != data('Terrains', 'Wall', 'cost')- Variable
frame- Value
data('Maze Layout', 'board', 'towerFrame')
- 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.
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.
Any Objectself.mapPlace- Action Name
place- cell
self.mapPlace.cell
- Position Relative To
Screen- X
place.x- Y
place.y
- Action Name
picture- cell
self.mapPlace.cell
- 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.
Window / UIUIX 64, Y 64-1Terrain TilesX 64, Y 64Show Map CellMap Place1.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.
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.
Any ObjectdataCount('Maze Cells')times- Object to Create
@self.mapCell- X
0- Y
0- Created As
newCell
- Variable
newCell.cell- Value
local.index
- 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.
Map CellPlace 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.
Puts the Selection, the ring around the cell the keyboard will paint, on its cell. The Selection starts on the Camp (Maze Settings startCell).
Any Object- Action Name
place- cell
data('Maze Settings', 'rules', 'startCell')
- 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.
Window / UIUIX 64, Y 6444Cell OutlineX 64, Y 64#FF9D361.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.
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).
Any Object- Action Name
place- cell
data('Maze Settings', 'rules', 'startCell')
- 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.
Window / UIUIX 24, Y 2455CompassX 24, Y 24Place 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.
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.
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.
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.
