TutorialsBinary Search

1  Safe Room

Goal

By the end of this chapter, the safe stands in its dark room, and the keypad answers your fingers. Type 4, then 2, and the display reads 42. Somewhere inside the safe, a secret code is waiting.

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.

Crack the Safe, Chapter 1 finishedMyth project · 1.4 MB

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

1.1 The Idea

A quiet room in deep navy. On the left stands the safe, blue steel with gold plates on its corners, a gold wheel on the door and a small green light. On the right is a dark panel. Above its keypad, a display says YOUR GUESS.

This chapter builds that room, and the first thing the game does in it is keep a secret. When the game starts, the safe draws its code, a whole number from 1 to 100, and keeps it to itself. The display starts at 50. Press 4 on the keyboard, and the 50 is gone, so the display reads 4. Press 2, and it reads 42.

That’s all the game does today, because you can’t ask the safe anything yet. SCAN comes in Chapter 2.

Here’s the real puzzle of this chapter. A keypad doesn’t hold a list of digits, it builds one number, so what should 4 do to the 50 already showing? Make 504? Make 54? In Crack the Safe, the first digit you type replaces what was there, and every digit after it goes on the right.

The number on the display is the entry. It works like a calculator’s display: each new digit pushes the others one place left and lands in the last place. On the cards it’s $entry, a value the whole game shares.

One more piece of this chapter stays hidden from start to finish, and that’s on purpose. The code lives on Safe Rules, an Object with no picture. Nothing here reads it. In Chapter 2, one small Function, Check Guess, holds it up against your guess. By Chapter 4, the computer cracks it, and it never once looks at the code to do it.

That’s where binary search starts: one answer out of 100, hidden. Nothing searches for it yet.

1.2 The Plan

Here’s how the pieces work together, one line for each thing that happens, read from left to right. The names are new now. Come back to these lines at the end of the chapter, and each one will be a piece you built.

  • The game starts -> New Safe draws the code into Safe State, and sets $entry to 50.
  • The display appears -> Show Entry asks Show Entry Or Dashes which to show.
  • You press a digit key -> Keypad Keys calls Type Digit -> $entry changes -> Show Entry hears the change and shows the new number.
  • You click a keypad key -> Type Its Digit calls the same Type Digit.
  • You press Backspace -> Keypad Keys calls Erase Digit.
  • You click Back -> Safe Button sends backClicked to Safe Rules -> Button Clicks calls the same Erase Digit.
  • You press Delete -> Keypad Keys calls Clear Entry, and the dashes come back.

1.3 Set Up

An empty project is a strange thing to look at: a blue Scene, a lot of buttons, and no game anywhere. It fills up faster than you’d think.

If you made a Blank 2D 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 Crack the Safe as its name, choose where it goes with Browse…, and press Create Project. Last, choose File > Install Myth Pack… and pick the kit’s file from the button below. Myth’s window starts on Add to This Project. Press Install.

Crack the Safe Starter KitMyth Pack · 959 KB · every picture

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

The Set up card comes after these paragraphs. Read them first, then work down the card from the top, one block at a time. The Set up card on Making what a card shows says where each block goes.

ART lists the four pictures this chapter uses, and the kit already brought them, so there’s nothing to make.

COMMANDS are the keys: Digit 0 to Digit 9, then Back on Backspace and Clear on Delete. Make all twelve now, in the Input Manager. They’re alike, so your hands will find a rhythm by the third. Nothing uses them until the keyboard part, near the end of the chapter.

Leave GLOBAL VARIABLES for later. A Global is made from inside a Logic Component, and your first Logic Component comes with the display.

Now the Game Settings. Enter the card’s lines top to bottom, in its order. Pixels per Meter comes first on purpose. When you type the Reference Height, Myth works out where the top of the screen sits in the world, and it uses the Pixels per Meter it has then. In the card’s order, that’s 19.5 meters up. It matters near the end of the chapter, when Safe Rules goes into the world. It stands right there, at the screen’s top-left corner.

Reference Width and Reference Height make the screen 1080 by 780 pixels. Every X and Y you’ll type for something on the screen counts in those pixels. The Page Background is the darker navy around it.

The card’s SCENE block makes a Scene called Safe Room. Your project already has one Scene, named Scene, so give it the new name instead of making a second. In the Resources panel, open Scenes, right-click Scene, choose Rename, and type Safe Room. Last, give it the card’s Background Color, the deep navy of the room.

Start Scene follows the new name by itself, and near the end of the card, it should already read Safe Room · 2D. Leave PLACE THESE for later, too. Each part of the chapter places its own Objects once they exist.

Set upWhat this chapter adds
ART (sprites, from the starter kit)
Locked Safe
Safe Panel
Safe Display
Safe Key
COMMANDS (Game Settings > Input Manager)
Digit 0Button
Keybindings0
Digit 1Button
Keybindings1
Digit 2Button
Keybindings2
Digit 3Button
Keybindings3
Digit 4Button
Keybindings4
Digit 5Button
Keybindings5
Digit 6Button
Keybindings6
Digit 7Button
Keybindings7
Digit 8Button
Keybindings8
Digit 9Button
Keybindings9
BackButton
KeybindingsBackspace
ClearButton
KeybindingsDelete
GLOBAL VARIABLES
$entryNumberstarts at 0
GAME SETTINGS > General > World Scale
Pixels per Meter40
GAME SETTINGS > Display > Window
TitleCrack the Safe
GAME SETTINGS > Display > Reference Resolution
Reference Width1080
Reference Height780
GAME SETTINGS > Display > Rendering
Texture FilteringSmooth Textures
Anti AliasingFXAA (Fast)
GAME SETTINGS > Display > Page Background (Outside the Game)
Color#09151E
SCENESafe Room (new)
Background Color#10212D
GAME SETTINGS > General > Startup
Start SceneSafe Room · 2D
SCENE Safe Room: PLACE THESE
ObjectXY
Safe Rules019.5
Control Console787-358
Game Title540-42
Safe270-347
Entry Display697-246
Entry Caption697-215
Entry Value697-252hidden
No Entry697-252
Digit Key619-326
with Text / UI > Text = 1 (Edit Object Locally)
with Per Instance Variables > Digit = 1
Digit Key700-326
with Text / UI > Text = 2 (Edit Object Locally)
with Per Instance Variables > Digit = 2
Digit Key781-326
with Text / UI > Text = 3 (Edit Object Locally)
with Per Instance Variables > Digit = 3
Digit Key619-388
with Text / UI > Text = 4 (Edit Object Locally)
with Per Instance Variables > Digit = 4
Digit Key700-388
with Text / UI > Text = 5 (Edit Object Locally)
with Per Instance Variables > Digit = 5
Digit Key781-388
with Text / UI > Text = 6 (Edit Object Locally)
with Per Instance Variables > Digit = 6
Digit Key619-450
with Text / UI > Text = 7 (Edit Object Locally)
with Per Instance Variables > Digit = 7
Digit Key700-450
with Text / UI > Text = 8 (Edit Object Locally)
with Per Instance Variables > Digit = 8
Digit Key781-450
with Text / UI > Text = 9 (Edit Object Locally)
with Per Instance Variables > Digit = 9
Digit Key700-512
with Per Instance Variables > Digit = 0
Back Key781-512

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

1.4 The Room

First come the title and the two big shapes.

The title stands at the top in cream letters: CRACK THE SAFE. It’s a Screen UI Object with a Text / UI on it, words that sit on the screen and never move. In the Create Object window, pick Screen UI Object as its Object Type. An Object card and its components on the Making page shows the rest. Keep it open beside this card: you’ll want its paragraphs on attaching a component, a Text / UI’s fields, the Rendering list, and UI Interaction. A new Screen UI Object comes with UI Interaction, and the title’s card doesn’t list it, so remove it.

ObjectGame Title
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextCRACK THE SAFE
Font Size34
EmphasisBold
Color#F5E9CA
RenderingVector

The safe and the panel are pictures. Each Object’s Bounding Box is the same size as its picture, 408 pixels square for the safe. A Z Index Within Object of -1 keeps each picture one step back, behind anything the Object shows on top. Like the title, neither keeps its UI Interaction.

ObjectControl Console
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 496, Y 400
Sprite
Z Index Within Object-1
SpriteSafe Panel
Transform > SizeX 496, Y 400
ObjectSafe
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 408, Y 408
Sprite
Z Index Within Object-1
SpriteLocked Safe
Transform > SizeX 408, Y 408

Now place them. Open Safe Room, 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), minus signs and all. Place the Control Console, the Game Title and the Safe, in that order.

PLACE THESE starts with Safe Rules, which you’ll make later on. That’s fine. In this chapter, the order you place things in changes nothing, because no list you pick from holds two of the same Object.

Run the game: press Play, the triangle at the top of the editor. The window is deep navy. The title stands at the top, the blue safe waits on the left with its green light, and a dark panel fills the right. Close the game’s window, and the editor is back.

That’s your room.

1.5 The Display

Next comes the display on the panel, where your guess will show.

It’s three Objects stacked in one spot. The Entry Display is the dark screen itself. On it sit two texts at the same place, the Entry Value and No Entry. Entry Value shows the number, and No Entry shows two dashes. Only one of them is ever visible.

Why two? An entry of 0 means nothing has been typed yet. A display reading 0 would look like a guess of 0, and 0 isn’t a code, so the game shows dashes instead.

The caption YOUR GUESS is a fourth Object, small and teal, above them.

ObjectEntry Caption
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextYOUR GUESS
Font Size12
EmphasisBold
Color#79C5C4
RenderingVector

Entry Value’s Text is the live part. {$entry} shows whatever $entry holds, and changes the moment it does. Type it as the card spells it, braces and all. The Global it names doesn’t exist yet. You’ll make it in a moment, in Show Entry, and the game finds it when it runs.

ObjectEntry Value
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
Text{$entry}
Font Size43
EmphasisBold
Color#F5CD73
RenderingVector
ObjectNo Entry
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
Text--
Font Size43
EmphasisBold
Color#F5CD73
RenderingVector

1.5.1 Show Entry

Show Entry keeps the display honest. It sits on the Entry Display and watches $entry. When the entry is above 0, it shows Entry Value and hides No Entry, and when it’s 0, it does the reverse.

It needs to know which two texts it’s swapping, so it has two Shared Variables, entryText and emptyText. Each holds an Object. The Logic reads them with @self in front, as @self.entryText, and there’s one of each for the whole Entry Display.

Make Show Entry first, with no Event yet, because the game’s one Global Variable is made inside a Logic Component. On the canvas’s Globals card, press + and choose New Global…. Give it the card’s three: a Number, named entry, that starts at 0. Leave out the $ in the window. Everywhere else, it goes in with one.

Now for the two Shared Variables that hold the texts. Press + on the Shared Variables card for each one, and give it the card’s four columns: Object, Constant, None. A Logic Component card on the Making page shows the window. None means it holds no Object yet. The Entry Display’s own card picks them, once it exists.

1.5.2 Show Entry Or Dashes

The swapping itself lives in a Function, a small piece of Logic that does one job whenever another piece asks. This one gets the two texts, and checks $entry.

Above 0, entryText is shown and emptyText hidden, and otherwise it’s the other way round. It’s an If with an Else, four Set Visible Actions in all. Each one’s Applies to box names one of the two texts it was handed, entryText or emptyText.

Its two Parameters go on its Start block. Each is an Object, and each card line names the Object that fits. So press the pencil on entryText’s row, choose Nominal, and pick Entry Value as its Object Type. emptyText is the same, with No Entry. A Function card shows the window, and If, Else and Repeat shows the If.

FunctionShow Entry Or Dashes

Shows the entry text while the entry has a number, and the dashes while it is empty (0).

PARAMETERS
NameTypeStarts at
entryTextObjectEntry Value
emptyTextObjectNo Entry
ACTIONS
1If$entry > 0
Then
2Set Visible
Applies to
entryText
Visible
true
3Set Visible
Applies to
emptyText
Visible
false
4Otherwise
5Set Visible
Applies to
entryText
Visible
false
6Set Visible
Applies to
emptyText
Visible
true

Now back to Show Entry, for its two Events. Each one calls Show Entry Or Dashes, from the Action List’s Functions group, and hands it the two texts. Type @self.entryText into its entryText box and @self.emptyText into emptyText. Those are Show Entry’s two Shared Variables, handed on.

Why two Events doing the same thing? A Variable Changed Event hears only a change, and the value the game starts with isn’t a change. So Create shows the entry the display starts with, and Variable Changed shows every change after it.

Logic ComponentShow EntryAttach to: Entry Display

Keeps the keypad display up to date: the number of the entry, or dashes while the entry is empty (0).

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
entryTextObjectConstantNone
emptyTextObjectConstantNone
When Created
WhenCreate
1Show Entry Or DashesFunction
entryText
@self.entryText
emptyText
@self.emptyText
On Variable Changed · Entry
WhenVariable ChangedGlobal Variable: entry
1Show Entry Or DashesFunction
entryText
@self.entryText
emptyText
@self.emptyText

Last comes the Entry Display, the dark screen behind the number. It’s the one that carries Show Entry, so this is where the two texts meet the Logic that swaps them. Its card ends with them. Attach Show Entry, then find entryText and emptyText under Variables, and pick Entry Value and No Entry.

ObjectEntry Display
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 277, Y 88
Sprite
Z Index Within Object-1
SpriteSafe Display
Transform > SizeX 277, Y 88
Logic
Show Entry
Shared Variables
entryTextEntry Value
emptyTextNo Entry

Place the four from PLACE THESE: the Entry Display, the Entry Caption, the Entry Value and No Entry. Entry Value is marked hidden. Its placement’s Properties have a switch, Visible at Game Start, a little under Screen Offset (px). Turn it off.

Run the game. The display reads YOUR GUESS, and under it, two gold dashes. That’s right for now, because $entry is still 0 and nothing has set it yet.

1.6 The Secret Code

Now the safe draws its code.

The code needs a home that only the rules can reach. That home is Safe Rules, an Empty Object with no picture and no words, only rules. It carries a Data Structure called Safe State, a small form with two fields.

The first field, code, is the secret. The second, startsNewEntry, answers one question: does the next digit start a new entry? It starts as true. That’s how the first digit you type will replace the 50. A Data Structure card on the Making page shows how to make it.

Data StructureSafe State

What the Safe Rules Object carries for its Logic to share. code: the secret code that opens the safe. startsNewEntry: true when the next digit typed starts a new entry instead of adding to the one shown.

codeNumberdefault 0
startsNewEntryBooleandefault true

The range of codes doesn’t live in the Logic. It lives in a table, Safe Settings, with one row, Standard Safe. Its lowestCode is 1, its highestCode is 100, and its startEntry, 50, is the number the display starts on. Change a number here, and the whole game follows it. No Logic needs editing. A Data Table card shows how to make one.

Data TableSafe SettingsData Structure: Safe Settings Entry
Row 0Standard Safe
lowestCode1
highestCode100
startEntry50

1.6.1 New Safe

When the game starts, New Safe deals the safe.

First, it asks Myth for a random whole number from lowestCode to highestCode, with 1 and 100 both possible. It calls the answer codeRoll. Then it writes codeRoll into the code field of its own Safe State. Last, $entry gets startEntry, and the display has its 50.

From New Safe’s point of view, nothing needs deciding. It doesn’t pick a code. It asks for one, and puts it away where nothing else can see it.

New Safe reads Safe State on the Object it’s attached to. So on its Data Structures card, press + and pick Safe State under Existing Data Structures. Myth names it self.safeState, as the card shows.

Generate Random Integer is the first Action you meet that hands back an answer. Its box after the word as is its Action Name, codeRoll. Change Component Value then reads the number as codeRoll.value, a name and a dot.

Logic ComponentNew SafeAttach to: Safe Rules

Starts a safe: draws its secret code with the engine's random block and shows the starting entry on the keypad display.

Attach toAny Object
DATA STRUCTURES
Safe Stateself.safeState
When the Game Starts
WhenGame Start
1Generate Random Integer
Action Name
codeRoll
Minimum
data('Safe Settings','Standard Safe','lowestCode')
Maximum
data('Safe Settings','Standard Safe','highestCode')
2Change Component Value
Component Value
self.safeState.code
Value
codeRoll.value
3Change Variable
Variable
$entry
Value
data('Safe Settings','Standard Safe','startEntry')

Make Safe Rules with Empty Object as its Object Type. Its Bounding Box is small. Nothing ever draws it. Attach the Data Structure first and pick Safe State, then switch to Logic and attach New Safe. The card names two more Logic Components, Keypad Keys and Button Clicks. You’ll make and attach them in the next two parts.

ObjectSafe Rules
Transform
Bounding Box > SizeX 0.8, Y 0.8
Data Structure
Data StructureSafe State
Logic
New Safe
Keypad Keys
Button Clicks

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

Run the game, and the dashes are gone. The display reads 50.

And somewhere in Safe Rules, a number from 1 to 100 is sitting in a field you can’t see. Run it again, and it’s very likely a different one. Nothing on the screen shows it. The only way to find it is to ask, and the asking comes next chapter.

1.7 The Keyboard

Now the keypad learns to type, starting with the keyboard.

1.7.1 Type Digit

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

Type Digit gets one digit, digit, and the Safe Rules that holds the entry, safeRules. It has two cases, and startsNewEntry picks between them.

When startsNewEntry is true, the number on the display is finished, so this digit starts a new one. $entry becomes the digit. After that, startsNewEntry turns false, because every digit after this one adds on.

When it’s false, the digit goes on the right. Multiply the entry by 10, which moves every digit one place left and leaves a 0 at the end. Then add the digit into that place. That’s the calculator.

Count the beats. The display shows 50, and startsNewEntry is true. Press 4. The 50 is replaced, and the entry is 4. Press 2. Four times 10 is 40, plus 2 is 42.

One guard stands in front of the adding. Digits go on only while the entry is still below highestCode, which is 100 here. So 10 still takes a third digit, and 100 can be typed. Once the entry is 100 or more, more digits are ignored.

Look closely, though. The guard looks at the entry before the digit, not after. Type 1, 0, then 5. Ten is still below 100, so the 5 goes on, and the display reads one hundred and five. That’s all right. In Chapter 2, the safe refuses a guess outside its range, and it costs you nothing.

On the card, the Otherwise holds nothing but another If. The canvas draws that pair as one block, Else If, and If, Else and Repeat says how to make it. Each condition is one box, typed as the card spells it. Type Digit’s safeRules is a Structural Parameter, with Safe State as its Required Component. A Function card walks through its window.

FunctionType Digit

Adds one typed digit to the entry. The first digit after a finished entry replaces it; later digits are added on the right while the entry is below the highest code.

PARAMETERS
NameTypeStarts at
safeRulesObjectStructural
Required Components
Slot NamesafeState
Component TypeData Structure
Required SchemaSafe State
digitNumber0
ACTIONS
1IfsafeRules.safeState.startsNewEntry == true
Then
2Change Variable
Variable
$entry
Value
digit
3Change Component Value
Component Value
safeRules.safeState.startsNewEntry
Value
false
4Otherwise
5If$entry < data('Safe Settings','Standard Safe','highestCode')
Then
6Change Variable
Variable
$entry
Operator
*=
Value
10
7Change Variable
Variable
$entry
Operator
+=
Value
digit

1.7.2 Erase Digit and Clear Entry

Back takes away the last digit. Erase Digit divides the entry by 10 and rounds down, which is what floor does. So 42 becomes 4, and the 2 falls off the end.

It also sets startsNewEntry to false. That line is small, and nobody playing will ever notice it. But watch what it does at the start, when the display shows 50 and the next digit would replace it. Press Backspace, and it shows 5. Now type 1. Because startsNewEntry is false, the 1 goes on the right, and the display reads 51. You took a digit off, and kept the rest.

FunctionErase Digit

Removes the last digit of the entry (Back). The next digit typed is added to what is left.

PARAMETERS
NameTypeStarts at
safeRulesObjectStructural
Required Components
Slot NamesafeState
Component TypeData Structure
Required SchemaSafe State
ACTIONS
1Change Variable
Variable
$entry
Value
floor($entry / 10)
2Change Component Value
Component Value
safeRules.safeState.startsNewEntry
Value
false

Clear Entry empties the entry, and $entry becomes 0, so the display shows its dashes. It sets startsNewEntry to false too. That sounds backwards, but follow the numbers. The entry is 0, and 0 times 10, plus the digit, is the digit. So the next digit you type becomes the whole entry anyway, as the first one should.

FunctionClear Entry

Empties the entry (Clear), so the next digit typed is its first digit.

PARAMETERS
NameTypeStarts at
safeRulesObjectStructural
Required Components
Slot NamesafeState
Component TypeData Structure
Required SchemaSafe State
ACTIONS
1Change Variable
Variable
$entry
Value
0
2Change Component Value
Component Value
safeRules.safeState.startsNewEntry
Value
false

1.7.3 Keypad Keys

Keypad Keys connects the keyboard to those three Functions. Like New Safe, it lists Safe State on its Data Structures card, because the Functions it calls read the entry’s flag there. It has twelve Events, one for each Command. Each one calls a Function and hands it self, Safe Rules, as safeRules, and the ten digit Events also hand over their digit.

Build the first Event, Digit 0. Command Pressed asks for its Command in a second window, so pick Digit 0 there. Add Type Digit from the Functions group. Type self into its safeRules box, and 0 into digit. The other nine digits are the same, with their own Command and digit. By the third, your hands know it.

Logic ComponentKeypad KeysAttach to: Safe Rules

Lets the keyboard work the keypad: the digit keys type a digit, Backspace erases the last digit, and Delete clears the entry. The keypad's buttons call the same Functions.

Attach toAny Object
DATA STRUCTURES
Safe Stateself.safeState
When Digit0 Is Pressed
WhenCommand PressedCommand: Digit 0
1Type DigitFunction
safeRules
self
digit
0
When Digit1 Is Pressed
WhenCommand PressedCommand: Digit 1
1Type DigitFunction
safeRules
self
digit
1
When Digit2 Is Pressed
WhenCommand PressedCommand: Digit 2
1Type DigitFunction
safeRules
self
digit
2
When Digit3 Is Pressed
WhenCommand PressedCommand: Digit 3
1Type DigitFunction
safeRules
self
digit
3
When Digit4 Is Pressed
WhenCommand PressedCommand: Digit 4
1Type DigitFunction
safeRules
self
digit
4
When Digit5 Is Pressed
WhenCommand PressedCommand: Digit 5
1Type DigitFunction
safeRules
self
digit
5
When Digit6 Is Pressed
WhenCommand PressedCommand: Digit 6
1Type DigitFunction
safeRules
self
digit
6
When Digit7 Is Pressed
WhenCommand PressedCommand: Digit 7
1Type DigitFunction
safeRules
self
digit
7
When Digit8 Is Pressed
WhenCommand PressedCommand: Digit 8
1Type DigitFunction
safeRules
self
digit
8
When Digit9 Is Pressed
WhenCommand PressedCommand: Digit 9
1Type DigitFunction
safeRules
self
digit
9
When Back Is Pressed
WhenCommand PressedCommand: Back
1Erase DigitFunction
safeRules
self
When Clear Is Pressed
WhenCommand PressedCommand: Clear
1Clear EntryFunction
safeRules
self

Attach Keypad Keys to Safe Rules, beside New Safe.

Run the game, and click it once so it hears the keyboard. The display shows 50. Type 4, then 2, and it reads 42. Press Backspace, and it reads 4, and Delete brings back the two dashes.

1.8 The Keypad

Last come the keys you click.

1.8.1 Type Its Digit

Ten keys, one Object. Every number key on the keypad is the Digit Key, placed ten times. Each placement has its own digit to type, and its own label.

Type Its Digit is short. When its key is clicked, it calls Type Digit, the same Function the keyboard calls. One Function, two ways in, so a click and a key press can never disagree.

It needs two Variables, and they’re two different kinds. The first, safeRules, is a Shared Variable, the same Safe Rules for every key. The second is a Per Instance Variable, digit. That’s one value for each placement, because each key types its own. Make both from their cards on the canvas. In the Type Digit block, type @self.safeRules into safeRules and self.digit into digit: this Logic’s own two Variables, handed on.

Logic ComponentType Its DigitAttach to: Digit Key

A keypad button that types its digit when the player clicks it, the same as pressing its digit key on the keyboard.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
safeRulesObjectConstantNone
PER INSTANCE VARIABLES
NameTypeStarting Value
digitNumber0
On Hud Activated
WhenUI Activated
1Type DigitFunction
safeRules
@self.safeRules
digit
self.digit

The Digit Key is words on a picture, its label centered on the Safe Key. It keeps its UI Interaction. That’s what lets a click reach it. Its card line says “as it is added”, so leave its fields the way they come. At the end of its card are its Shared Variables, and under Variables you pick Safe Rules for safeRules.

ObjectDigit Key
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 68, Y 51
Text / UI
Text0
Font Size18
EmphasisBold
Color#F5E9CA
AlignmentCenter
RenderingVector
Sprite
Z Index Within Object-1
SpriteSafe Key
Transform > SizeX 68, Y 51
UI Interaction(as it is added)
Logic
Type Its Digit
Shared Variables
safeRulesSafe Rules

Place it ten times from PLACE THESE, and look at the two “with” lines under each. The first, Text / UI > Text, gives the key its label with Edit Object Locally. The second, Per Instance Variables > Digit, goes into its Type Its Digit part, under Logic: the digit it types.

The 0 key, the last of the ten, has no Text line, so it keeps the Object’s own Text, 0. A placement’s own values walks through both kinds of line.

Ten placements is a lot of the same clicks. Take your time over the first one, and the other nine go quickly, because your hands learn the way.

1.8.2 Safe Button

Back is a key too, but it doesn’t type a digit. It erases one. And in Chapter 2, SCAN and New safe arrive, each doing something else again. Writing a Logic Component for each button would mean writing the same click over and over.

So Safe Button doesn’t know what a click means. It only rings a bell. When the button is clicked, Trigger Custom Event on Object sends the button’s message to Safe Rules. That message is a Custom Event, a name one piece of Logic sends and another listens for. Each button has its own, clickEvent, a Per Instance Variable. The Back Key’s is backClicked.

Make its two Variables first: safeRules, a Shared Variable, as in Type Its Digit, and clickEvent, a Per Instance Variable that’s Text and starts empty. Then add Trigger Custom Event on Object. Its box after the word on is its Applies to, @self.safeRules. Its Custom Event box takes self.clickEvent, the Variable instead of a fixed name.

Logic ComponentSafe ButtonAttach to: Back Key

A button that sends its Custom Event (clickEvent) to the Safe Rules Object when the player clicks it. Each button sets its own.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
safeRulesObjectConstantNone
PER INSTANCE VARIABLES
NameTypeStarting Value
clickEventText(empty)
On Hud Activated
WhenUI Activated
1Trigger Custom Event on Object
Applies to
@self.safeRules
Custom Event
self.clickEvent

The Back Key is made like the Digit Key, with the word Back, and with Safe Button in place of Type Its Digit. It keeps its UI Interaction too. Its card ends with two Variables. Under Variables, pick Safe Rules for safeRules, and type backClicked into clickEvent’s Value. That one word is the whole difference between Back and the buttons still to come.

ObjectBack Key
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 68, Y 51
Text / UI
TextBack
Font Size18
EmphasisBold
Color#F5E9CA
AlignmentCenter
RenderingVector
Sprite
Z Index Within Object-1
SpriteSafe Key
Transform > SizeX 68, Y 51
UI Interaction(as it is added)
Logic
Safe Button
Shared Variables
safeRulesSafe Rules
Per Instance Variables
clickEventbackClicked

1.8.3 Button Clicks

Somebody has to hear the bell. Button Clicks sits on Safe Rules and listens for backClicked. When it arrives, it calls Erase Digit, the same Function Backspace calls.

Its Event is a Custom Event. In the Add Event window, choose Custom Events > Project Events > Add Custom Event…, and type backClicked. It’s spelled the same as the Back Key’s word, letter for letter. Like Keypad Keys, it lists Safe State on its Data Structures card, and hands Erase Digit self.

Logic ComponentButton ClicksAttach to: Safe Rules

Does what each button on the screen asks. A button sends its Custom Event to Safe Rules when clicked, and each one here calls the Function its key calls.

Attach toAny Object
DATA STRUCTURES
Safe Stateself.safeState
On Back Clicked
WhenbackClickedCustom Event
1Erase DigitFunction
safeRules
self

Attach Button Clicks to Safe Rules, beside the other two. Then place the Back Key last. It needs nothing more, because its message is already on the Object, where every placement of it shares it.

Run the game, and click 6, then 8, and the display reads 68. Click Back, and it reads 6.

Play it!

Run it, and watch for each of these in turn.

  • The window is deep navy, and CRACK THE SAFE stands at the top in cream letters.
  • The blue safe sits on the left, shut, with its gold wheel and its green light.
  • On the right, the dark panel holds the display, YOUR GUESS, and under it the keypad: 1 to 9 in three rows, then 0 and Back.
  • The display starts at 50, in gold.
  • Type 4 on the keyboard, and the 50 is gone: the display reads 4.
  • Type 2, and it reads 42.
  • Press Backspace, and it reads 4, and then Delete puts two dashes in its place.
  • Click the keypad’s 6, then 8, and it reads 68.
  • Click Back, and it reads 6.
  • Press Delete, and type 1, 0, 0: the display reads 100, the highest code, and one more digit changes nothing.
  • Close the game and run it again: everything starts the same, at 50, though the secret code inside is new each time.
How it works

New Safe draws a code and sets the entry to 50. Type Digit builds the entry, one digit at a time, while Erase Digit and Clear Entry take it apart. Show Entry shows it, or the dashes. The keyboard and the keypad both call the same three Functions.

Underneath is one idea: the display holds nothing. It only shows $entry. Every key changes one number, and everything on the screen follows it. In Chapter 2, SCAN reads that same number as your guess.

1.9 If It Didn’t Work

It’s normal for something to be a little off the first time, 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.

The display shows dashes, never 50? Perhaps New Safe never ran. Look for Safe Rules in the Scene, and for New Safe on it. Open New Safe and look for a block standing apart, with no arrow into it, and join it with Connect to Sequence. Last, look at its Change Variable, $entry, with its $.

It shows 50, but the dashes show too? Then Entry Value and No Entry are both visible, one on top of the other. Look at the Entry Display’s Variables. Is entryText Entry Value, and emptyText No Entry? In Show Entry Or Dashes, each branch’s two Set Visible Actions should name different texts.

The display stays at 50 when you type? Perhaps the game window didn’t hear the keyboard, so click the game once, then type. Still 50? Look at Keypad Keys on Safe Rules, and at each Event’s Command.

Typing 4 gives 504, not 4? Then the first digit isn’t replacing the entry. Look at startsNewEntry in Safe State, whose Value should be on, true. Then look at Type Digit’s first If, whose condition ends startsNewEntry == true.

Typing 4, then 2, gives 2? The second digit replaced the first too, so look at step 3 of Type Digit, which sets startsNewEntry to false.

Typing 4, then 2, gives some other number than 42? Look at the two Operators in Type Digit: *= for the 10, then += for the digit. With = in place of either, the entry is replaced instead of added to.

Every keypad key types 0? Each placement needs its own Digit, typed into its Type Its Digit part, under Per Instance Variables. The label, set with Edit Object Locally, only changes what the key says.

Back does nothing? Perhaps the message is spelled two ways. Look at the Back Key’s clickEvent, backClicked, and at Button Clicks’ Custom Event. Then look for Button Clicks on Safe Rules, and for Safe Rules in the Back Key’s safeRules.

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 keypad has an empty corner, left of the 0. Clear lives on the Delete key, but nothing on the screen clears. Make a Clear button there. Place the Back Key again, at 619 and -512, and give it the word Clear with Edit Object Locally. In its Safe Button part, under Per Instance Variables, give it a message of its own: clearClicked. Then give Button Clicks one more Event. It’s a Custom Event for clearClicked, and it calls Clear Entry. Safe Button needs no change at all. Before you start Chapter 2, take the button and its Event out again. The cards that come next don’t have them, and a game that matches the cards is much easier to check.

The room is still. The safe is shut on its secret, and the keypad answers your fingers. In Chapter 2, you ask the safe your first question.