Puzzles
A common mainstay of most role-playing games (RPGs), both new and old, is the puzzle. Defeating monsters and other assorted baddies to get through dungeons can be fun for quite a while, but puzzles break the monotony and make it so that the players have to flex their mental muscles as well as their alter egos’ physical muscles. During the course of this chapter, I will be covering three puzzles that I have devised in my time working with RPG Maker VX Ace (RMVXA). Without further ado, let us begin with the first one.
Perhaps the bane of any gamer who has played RPGs for even a short amount of time, slippery floors prevent you from controlling your character until it slams face-first into an obstacle. Making slippery floors is actually a very nuanced process in RMVXA eventing, as there are many things you have to take in consideration. For example:
The good news is that, once you understand what you need to do, you only require a single Parallel Process event to handle everything.
First, however, I’m going to unveil the tweaked version of Abandoned Mine FB1, which is where I’ll have the icy area that the player can slide on. Take a look at Figure 11-1 to see the area map. I segmented the large central area and separated the westernmost part of the floor into its own little section. Besides that, I added secret passages that connect the eastern sections. I placed a new staircase at the northern end of the western corridor. So, how does the top floor connect with this lower floor of the mines?
Figure 11-1. A screenshot of the first basement floor of the mines
That leaves the two staircases at the western corridor and a third near the northeastern corner of FB1 (at 49,10). We’ll set up those transfer events, once we work with the last level of this dungeon. For now, let’s work on our sliding puzzle!
We’ll begin by defining the icy floor as slippery, through the use of terrain tags. You could use Regions as well. The particular tile I’m using is Ground (Crystal), located within the A tab of the Dungeon tileset. Once that is done, we create a Parallel Process event to hold our slippery floor logic. I’ll break this down into parts.
@>Control Variables: [0002:X] = Player's Map X
@>Control Variables: [0003:Y] = Player's Map Y
@>Get Location Info: [0017], Terrain Tag, Variable [0002][0003]
@>Conditional Branch: Variable [0017:TerrainTag] == 1
@>Loop
@>Set Move Route: Player (Skip, Wait)
: : $>Walking Animation OFF
: : $>Change Speed: 5
: : $>Change Freq: 5
@>Label: Repeat
As is standard with most of our Parallel Process events, we have it write the player’s current location to a pair of variables and then fetch the location info for the tile that the player character is standing on at that precise moment. Next, we have a conditional branch that only triggers if the Terrain Tag is equal to 1. If it is, we use the Loop event command. As per its name, event commands within a Loop will repeat endlessly until you use a Jump To Label to escape the loop. In essence, an Autorun event is a loop (which is the reason why it is so easy to accidentally hang your game using one, if you forget to use a self-switch or some other method to break out of the event page).
The first order of action when the event enters its loop is to make it so that the player appears as if he/she is sliding on air. As mentioned near the start of the book, turning off a character’s walking animation will accomplish precisely that. We can increase the speed at which the player slips on ice by using Change Speed and increasing its value. I set it to 5. Change Frequency does nothing in this particular exercise, but I kept it there for testing purposes. You’ll see why it does nothing, as I reveal more of the event. The last thing I placed in that sample code was Label: Repeat. That was not a coincidence. Everything after that label will be repeated until a certain condition is met (more on that later). Here’s the second part of the event:
@>Control Switches: [0026:WalkMovement] = OFF
@>Set Move Route: Player (Skip, Wait)
: : $>1 Step Forward
@>Control Variables: [0019:X'] = Player's Map X
@>Control Variables: [0020:Y'] = Player's Map Y
@>Conditional Branch: Variable [0019:X'] == Variable [0002:X]
@>Conditional Branch: Variable [0020:Y'] == Variable [0003:Y]
@>Jump to Label: GoToNext
@>
: Else
@>Control Variables: [0002:X] = Player's Map X
@>Control Variables: [0003:Y] = Player's Map Y
@>Jump to Label: Repeat
@>
: Branch End
@>
: Else
@>Control Variables: [0002:X] = Player's Map X
@>Control Variables: [0003:Y] = Player's Map Y
@>Jump to Label: Repeat
@>
: Branch End
As of this time, the player character has no walking animation. We want to have a dedicated switch that is off when the player cannot move and is flipped on when he/she can. (You could invert the states so that the switch is on when the player cannot move. Just make sure you keep track of the fact.) WalkMovement will be that switch. We’ll have a conditional branch after this loop that checks to see if WalkMovement is off. If it is, we restore the player’s walking animation and normalize his/her speed. But, I’m getting ahead of myself.
When the player is found to be on slippery ground, he/she will slip uncontrollably in his/her current direction. It is extremely important that you make sure that you toggle both the “Skip if cannot move” and “Wait for completion” check boxes. If the former is untoggled, the game will hang as soon as the player reaches an obstacle. If the latter is untoggled, the event will not work. (Give it a try and note how the character moves on the icy terrain.) Next, I assign a new pair of variables to store the player’s current x and y coordinates after moving one space. Why? Well, recall the last bullet point in the summary list at the start of the chapter. We need to check to see if the player has been stopped by an obstacle.
We can figure that out by comparing the values of X’ and Y’ with the values of X and Y. The only time X’ and X (and Y’ and Y) will be identical is when the player is stationary. How can I guarantee this? It all comes down to the event flow. At the very top of the event, we write the player’s location to X and Y. After moving a single space (or failing to, if the character is already adjacent to an obstacle), we write his/her location to X’ and Y’.
We escape the loop if the values of X’ and Y’ are equal to the values of X and Y; otherwise, we loop back to the top of the sequence.
As it turns out, you may have already noticed that we don’t actually require that Loop command. That’s something really important to learn in programming in general and RMVXA specifically: Don’t do in ten lines what you can do in nine or fewer. In other words, make your events as efficient as possible. As you gain proficiency with RMVXA, you’ll probably find cases in which you created an event that has some fat that can be trimmed with no negative effects. In this case, the Loop command doesn’t take anything away from the slippery floor event, but you can use labels to achieve the same effect.
Eventing Our Sliding Puzzle (continued)
Here’s the last part of the slippery floor event:
@>
: Branch End
@>Label: GoToNext
@>Conditional Branch: Switch [0026:WalkMovement] == OFF
@>Set Move Route: Player (Skip, Wait)
: : $>Walking Animation ON
: : $>Change Speed: 4
: : $>Change Freq: 3
@>Control Switches: [0026:WalkMovement] = ON
@>
: Branch End
@>
This is where we go if the player is stationary from having bumped into an obstacle. We check to make sure that WalkMovement is off and restore the player character’s walking animation and set its speed back to 4. We set WalkMovement to ON and we’re all set. Of course, the event still isn’t as clean as it could be. Think hard on what the event is doing, and see if you can trim it down some more.
Of course, we’ve gone through all the trouble of creating this event. It wouldn’t be proper to just have it there doing nothing. Hence, let’s make a little ice maze. You can already see it in a zoomed-out state in the full-map screenshot, but Figure 11-2 shows a zoomed-in picture of the relevant area.
Figure 11-2. The ice area in the first basement floor
Note the secret passage on the right-hand side of the ice maze. We have a small section at the northwest corner of the room with three chests to reward exploration. You can add or remove obstacles, as wanted, to make it easier or harder to reach the chests or the entrance to the passage.
Speaking of chests, I scattered Mithril gear throughout the dungeon, to serve as the party’s possible upgrades. The first floor contains the Mithril Rod, which is actually a downgrade for Noah, but as good as any item to sell for gold. It also contains a Mithril Axe that will work wonderfully as an upgrade for Eric. The second floor has a Mithril Bow and a Mithril Shield. Finally, the third floor that I’m going to add in a few moments will contain Mithril Armour (RMVXA uses British English for item names, for some odd reason, considering that most of the rest of the engine uses American English) and a Mithril Circlet. Now then, let’s add the third and final floor to our dungeon, so I can talk about the second puzzle of this chapter. (See Figure 11-3.)
Figure 11-3. The bottom floor of the abandoned mines
For the final floor, I added a staircase in the left room, covered the hallway linking the two other rooms with debris, used a secret passage to connect them via an alternate route, and sealed off the entrance with a door.
The door is the protagonist of our next puzzle.
Riddles are one of my favorite ways of flexing my gray matter. Quite a few RPGs have one quest or another that involves having to solve a riddle. For this exercise, we’ll have that locked door pose a riddle to the player when he/she interacts with it. If the player can answer the riddle correctly, the door will open; otherwise, it will remain shut, patiently waiting.
Overview
How do we begin? We have two ways of handling a riddle.
I’ll be showing off the second method, as it is a little more involved eventing-wise.
Our Riddle of Choice
The first order of business is to figure out what riddle we want the player to solve. I’ll be using a classic riddle solved by Oedipus. Here it is (well, one translation of it, anyway): “What is that which has one voice and yet becomes four-footed and two-footed and three-footed?” (The traditional answer for that, by the way, is man. For the purposes of this exercise, we’ll make human the answer.) As the correct answer has five letters, we want the input box generated by the Name Input Processing command to have a limit of five characters. As you may have already noticed, we are using this event command in quite an unconventional way. It is intended as the means of changing a character’s name. For example, you could have a Name Input Processing event that allows the player to change Eric’s name to something else. Here, we want to use the command, to allow the player to answer a riddle.
Creating Our Riddle Event
To begin, you’ll want to make your way to the Actors tab of the Database and increase the maximum number of actors from ten to eleven. Once you do that, you’ll get a blank actor on the new slot. That’s exactly what we want. You could have a portrait for the riddle giver in this way, if you so desire. Because the player is talking to a door, we’ll skip that. Next, we have to write the player’s input into a variable. This is where we call upon scripting once again to come to our aid. Thankfully, the scripting required is not nearly as elaborate as that for the Smoke Bombs in Chapter 9. We need scripting for four small things.
You might wonder why at all we have to do this. After all, Conditional Branch also has an option on page 2 to check for a particular actor’s name. Well, let’s follow that thought process and work out a simple riddle event. In theory, your riddle event could look as simple as this.
@>Text: -, -, Normal, Bottom
: : What is that which has one voice and yet becomes
: : four-footed and two-footed and three-footed?
@>Name Input Processing: , 5 characters
@>Conditional Branch: [] is Name 'human' Applied
@>Text: -, -, Normal, Bottom
: : Correct.
@>
: Else
@>Text: -, -, Normal, Bottom
: : Wrong.
@>
: Branch End
@>
We have a single text box giving the riddle to be solved, and then a screen comes up, so that the player can write in his/her answer. The screen in question is displayed in Figure 11-4.
Figure 11-4. The Name Input Processing event command in action
However, as you’ll quickly find, if you do not write human exactly as I did in the relevant sentence, you will receive an error message. After all, the conditional branch is looking for “human,” not “hUmAn” or “HUMAN.” It also doesn’t solve the minor problem that the blank actor’s name will not be cleared if the player writes an incorrect answer. So, let us begin with our small snippets of Ruby script.
Finding How RMVXA Handles Actor Names Within Its Code
First, we have to find out how RMVXA handles actor names within the code. A good place to start our search is the code that governs the Conditional Branch command. After all, one of the possible conditionals involves inputted names. Running a search in the Script Editor for “conditional branch” returns a single result. Click it and scroll down until you find this part of the code.
when 4 # Actor
actor = $game_actors[@params[1]]
if actor
case @params[2]
when 0 # in party
result = ($game_party.members.include?(actor))
when 1 # name
result = (actor.name == @params[3])
From here, we learn that, whatever our end result looks like, it has to involve $game_actors in some capacity. As it turns out, that is correct. There is a Game_Actors class within the Script Editor, but checking it out is largely fruitless, save for one single tidbit: This is a wrapper for an actor array. An array in programming is a list of items. In this case, Game_Actors combines all of the relevant actor information into a single array. What we want is a specific actor’s name, so let’s head on over to Game_Actor, where we’re almost immediately greeted by the information following:
attr_accessor :name # Name
attr_accessor :nickname # Nickname
attr_reader :character_name # character graphic filename
attr_reader :character_index # character graphic index
attr_reader :face_name # face graphic filename
attr_reader :face_index # face graphic index
attr_reader :class_id # class ID
attr_reader :level # level
attr_reader :action_input_index # action number being input
attr_reader :last_skill # For cursor memorization: Skill
attr_accessor, attr_reader, and attr_writer (not present in Game_Actor) are a trio of Ruby modules that allows for instance variables to be used outside of the classes in which they normally exist. For the purposes of this exercise, all you have to know is that the listed attributes are contained within the array created by $game_actors. This is what you would need to write in the Script box of Control Variables to fetch an actor’s name: $game_actors[n].name (where n is equal to the actor’s ID in the Database).
Note You can also grab the other attributes in the same way. Just replace name with the attribute in question. Level, in particular, could be pretty useful in creating areas that can only be accessed if a player is of a certain level or higher.
How to Use the Script Option to Store and Modify Text in a Variable
To be precise, we’ll be storing an actor name within the Riddle1 variable, but this can be applied to any other type of text you can think of. While the most common use of variables in RMVXA is to store numbers, text can fit in there just fine. In any case, now that we know how to call for a specific actor’s name, we can write that value into a variable by using the Script option.
@>Control Variables: [0016:Riddle1] = $game_actors[11].name
That’s what the event command should look like, once you’re done (11 being the database ID of the new blank actor for this specific exercise). Next, we have to make sure that the player receives a positive response for a correct answer, no matter how it is written. There is a class within Ruby called String that contains various methods we can use to modify text. You can check the appropriate help page within RMVXA for additional details, but the two we’re interested in are upcase and downcase. Suppose the player writes “Human” in the name input screen. If we modified it with upcase, it would become “HUMAN.” On the other hand, downcase would turn it into “human.” For this exercise, I’ll be using downcase. What we want to do is modify the contents of the Riddle1 variable after the previously pictured event command has been processed. It’s as simple as doing the following:
Note Make sure that you don’t split a single expression in twain while scripting. In the following lines of script, the first example is correct; the second is incorrect.
@>Script: $game_variables[16] =
: : $game_variables[16].downcase
@>Script: $game_variables[16] = $game_variables
: : [16].downcase
It’s easier if you think of the preceding as three separate expressions. $game_variables[16] is the first one, the equal sign is the second, and applying the downcase method to $game_variables is the third. RMVXA reads the second example as four expressions, as you’re cutting the third into two halves.
Next, we need a conditional branch, to check if the value of our riddle variable is equal to human (if you used upcase instead of downcase, you’ll want to check for HUMAN instead). We use the script option and write out $game_variables[16] = "human" (make sure you include the quotation marks). In this particular case, you can either check “Set handling when conditions do not apply” or have another conditional branch for $game_variables[16] != "human" (!= is “not equal” in Ruby). In either case, the last thing that requires scripting is emptying out the actor name. To do this, we have another line of script: $game_actors[11].name = ""
The quotation marks are important here as well. If you leave the method assignment completely empty, the game will crash with an error. Here’s what the skeleton of the completed event looks like:
@>Text: -, -, Normal, Bottom
: : What is that which has one voice and yet becomes
: : four-footed and two-footed and three-footed?
@>Name Input Processing: , 5 characters
@>Control Variables: [0016:Riddle1] = $game_actors[11].name
@>Script: $game_variables[16] =
: : $game_variables[16].downcase
@>Conditional Branch: Script: $game_variables[16] == "human"
@>Text: -, -, Normal, Bottom
: : Correct.
@>
: Else
@>Text: -, -, Normal, Bottom
: : Wrong.
@>
: Branch End
@>Script: $game_actors[11].name = ""
@>
Because we want the door to open on a correct answer, you’ll want to flip a self-switch after the door announces “Correct.” Next, you display a message stating that the door opens and then switch to a second event page that is completely blank. There are areas of opportunity to tweak this event as well. Here are some tips if you choose to do so:
One of the beauties of programming (and working with RMVXA events) is that there can be multiple correct solutions to a problem. Some may even be equally efficient! I have one more puzzle to discuss in this chapter, so let’s get to it!
I left the most nuanced of the three puzzles for last. Manipulating objects from a distance has been a mechanic used in many video game genres throughout the years. For this exercise, the player will be sent to a distant snowy mountain to move two statues to their respective pedestals. Figure 11-5 is a screenshot of the area in question. The map is 27×23 and uses the Exterior tileset.
Figure 11-5. The map where the statue manipulation puzzle takes place
We have a pair of dragons that will be our statues for this exercise. The rock crosses on either side of the area are actually events that will disappear once the puzzle has been completed. The same goes for the three rocks blocking the staircase at the northern end of the area.
Overview
Here are the things that we need, in no particular order:
First, place the assorted rocks that will prevent the player from passing to the other side of the area until he/she completes the puzzle. Next, place a green dragon event at (12,10) and a red dragon event at (14,8). I specified color to differentiate the two statues. This will be important, as we want the green dragon to go on the left pedestal and the red dragon to go on the right pedestal. The pedestals are at (11,8) and (15,8) and are the golden cobblestone tiles present in tab A of the Exterior tileset.
Creating the Puzzle Trigger (Interaction) Event
The first event we’re going to fill out is the first one that the player will interact with, namely, the gravestone event. When the player interacts with the gravestone, we want a message to be displayed, then the game will ask if the player wants to touch the gravestone. If he/she does, we scroll the map up to center the player’s vision on the statues. We need to differentiate between when the puzzle is active and when it is not. For that, we can have a switch called StatuePuzzleStart. When it is off, the puzzle is inactive. When it is on, the puzzle is active. Check the following code to see the gravestone event in its entirety and note the extra things that it has. Some of it may not make sense currently, but it should by the end of this exercise.
@>Conditional Branch: Switch [0029:StatuePuzzleDone] == OFF
@>Conditional Branch: Switch [0030:StatuePuzzleStart] == OFF
@>Text: -, -, Normal, Bottom
: : The gravestone says: Place the statues
: : on their pedestals to open the way forward.
@>Text: -, -, Normal, Bottom
: : Will you touch the gravestone?
@>Show Choices: Yes, No
: When [Yes]
@>Scroll Map: Up, 5, 4
@>Set Move Route: Player (Wait)
: : $>Direction Fix ON
@>Text: -, -, Normal, Bottom
: : Press A to reset the statues.
: : Press a directional key to move the statues.
@>Control Switches: [0031:ButtonPressOFF] = ON
@>Jump to Label: PuzzleStart
@>
: When [No]
@>
: Branch End
@>
: Branch End
@>Label: PuzzleStart
@>Control Switches: [0030:StatuePuzzleStart] = ON
@>
: Branch End
@>Conditional Branch: Switch [0029:StatuePuzzleDone] == ON
@>Text: -, -, Normal, Bottom
: : This gravestone no longer serves any purpose.
@>
: Branch End
@>
So, the player has touched the gravestone and is now looking at the statues. We have to make it so that he/she can actually move them. That’s a job worthy of a Parallel Process event. First, however, two squares south of the gravestone, you’ll want to place a blank event that requires StatuePuzzleStart to be flipped on and has a Same As Characters priority. This ensures that the player is locked into one location for the duration of the puzzle. Given that we’re going to be using arrow key conditionals, we don’t want the player’s character to suddenly run off mid-puzzle.
Creating the Puzzle Logic Event
The Parallel Process event will have two pages. The first page will cover button presses, while the second page will check to see if the statues are at their desired destinations. Here’s the first part of page 1 of the Parallel Process event:
@>Conditional Branch: The Down Button is Being Pressed
@>Set Move Route: [LeftStatue] (Skip)
: : $>Move Down
@>Set Move Route: [RightStatue] (Skip, Wait)
: : $>Move Down
@>Jump to Label: SpotCheck
@>
: Branch End
@>Conditional Branch: The Left Button is Being Pressed
@>Set Move Route: [LeftStatue] (Skip)
: : $>Move Left
@>Set Move Route: [RightStatue] (Skip, Wait)
: : $>Move Right
@>Jump to Label: SpotCheck
@>
: Branch End
@>Conditional Branch: The Right Button is Being Pressed
@>Set Move Route: [LeftStatue] (Skip)
: : $>Move Right
@>Set Move Route: [RightStatue] (Skip, Wait)
: : $>Move Left
@>Jump to Label: SpotCheck
@>
: Branch End
@>Conditional Branch: The Up Button is Being Pressed
@>Set Move Route: [LeftStatue] (Skip)
: : $>Move Up
@>Set Move Route: [RightStatue] (Skip, Wait)
: : $>Move Up
@>Jump to Label: SpotCheck
@>
: Branch End
We have a conditional branch for each separate direction. Of course, it wouldn’t be much of a puzzle if both statues moved identically, so we make it so that the right statue (that would be the red one) moves on an inverted horizontal axis. In simpler terms, the red statue will move left when the player presses right and right when the player presses left. Notice how I only use the wait command once per branch. There’s nothing wrong with having a wait command on the left statue’s movement as well, but it just makes the puzzle take longer. When you set it up as I have, both of the statues will move in response to the key press, and the puzzle flows faster. Here’s the second half of page 1:
@>Conditional Branch: The X Button is Being Pressed
@>Text: -, -, Normal, Bottom
: : Reset the statues?
@>Show Choices: Yes, No
: When [Yes]
@>Set Event Location: [LeftStatue], (012,010)
@>Set Move Route: [LeftStatue]
: : $>Turn toward Player
@>Set Event Location: [RightStatue], (014,008)
@>Set Move Route: [RightStatue] (Wait)
: : $>Turn toward Player
@>Scroll Map: Down, 5, 4
@>Set Move Route: Player (Wait)
: : $>Direction Fix OFF
@>Control Switches: [0030:StatuePuzzleStart] = OFF
@>
: When [No]
@>
: Branch End
@>
: Branch End
@>Label: SpotCheck
@>Control Switches: [0031:ButtonPressOFF] = OFF
@>Control Switches: [0032:ButtonPress] = ON
@>
As mentioned before, we want the player to have a way to stop the puzzle if he or she would rather do something else. RMVXA has three otherwise functionless buttons named X, Y, and Z that tie into the A, S, and D keys of a keyboard, respectively. So, when the player presses A during the puzzle, the game will ask if he or she wishes to reset the statues. Saying no does nothing, but saying yes returns both statues to their initial positions. We scroll the map down the number of squares that we had moved it up previously and turn off the Direction Fix that we had imposed on the character.
At the very bottom of page 1, we have the SpotCheck label referenced in the quartet of directional conditional branches. The pair of button press switches is used for flow control. In essence, we want the following sequence:
It is functionally a two-page loop that can be broken by puzzle completion or the player pressing A and selecting Yes. With that said, page 1 requires that StatuePuzzleStart and ButtonPressOFF be on. Page 2, on the other hand, requires that StatuePuzzleStart and ButtonPress be on. Don’t let the minor switch name differences trip you up! If they do, feel free to differentiate them a little more. Check the following code for the first part of page 2 of the Parallel Process event.
@>Control Variables: [0023:LeftStatueX] = [LeftStatue]'s Map X
@>Control Variables: [0024:LeftStatueY] = [LeftStatue]'s Map Y
@>Control Variables: [0025:RightStatueX] = [RightStatue]'s Map X
@>Control Variables: [0026:RightStatueY] = [RightStatue]'s Map Y
@>Conditional Branch: Variable [0023:LeftStatueX] == 11
@>Conditional Branch: Variable [0024:LeftStatueY] == 8
@>Conditional Branch: Variable [0025:RightStatueX] == 15
@>Conditional Branch: Variable [0026:RightStatueY] == 8
@>Text: -, -, Normal, Bottom
: : About time!
@>Fadeout Screen
@>Play SE: 'Push', 80, 100
@>Set Event Location: [LeftStatue], (011,008)
@>Set Event Location: [RightStatue], (015,008)
@>Control Switches: [0029:StatuePuzzleDone] = ON
@>Scroll Map: Down, 5, 4
@>Fadein Screen
@>Control Switches: [0030:StatuePuzzleStart] = OFF
@>Set Move Route: Player (Wait)
: : $>Direction Fix OFF
@>
: Else
@>Jump to Label: DirectionCheck
@>
: Branch End
@>
: Else
@>Jump to Label: DirectionCheck
@>
: Branch End
@>
: Else
@>Jump to Label: DirectionCheck
Dissecting the Statue Manipulation Puzzle Logic
Now, don’t run off just yet. This might seem a bit overwhelming, but it’s actually very simple. Here’s a play-by-play of what the preceding event does:
@>
: Branch End
@>Label: DirectionCheck
@>Control Switches: [0032:ButtonPress] = OFF
@>Control Switches: [0031:ButtonPressOFF] = ON
@>
By swapping which of the button press switches is toggled, we can switch between the two pages of the Parallel Process event as needed. On that note, we have concluded our third and final puzzle for the chapter!
Creating the Second Town
All that remains is adding a relevant location that will lead us to the snowy statue puzzle mountain area. Use Load Sample Map to add Mountain Village to your project’s map list. We’re going to be tweaking the bottom part of the village to serve our needs. Take a peek at Figure 11-6, to see the changes.
Figure 11-6. The tweaked part of the Mountain Village. The rest of the terrain remains the same as normal
That cavern entrance connects with the one staircase in the Abandoned Mines we have not touched until now. For the sake of clarity, I’m talking about the stairs at (4,34) of FB1. The block impeding entry into the village is actually an event (the graphic is from !Door2) that transfers the player to our statue puzzle area. This block disappears once StatuePuzzleDone is turned on by completing the statue puzzle.
Additional Exercises
As is tradition, I’ll close out the chapter by giving you some exercises to work on.
Summary
This chapter covered three puzzles that I have devised in the time that I’ve used RMVXA. We made a door that could only be opened by correctly answering a riddle, a movement puzzle involving slippery ice, and a manipulation puzzle involving a pair of dragon statues. In the next chapter, we’ll be populating our newly added town.