Dev Blog / Script Follow Up – Breaking Victor’s Scripts

“Breaking” isn’t really the right word, because Victor’s script will still work as intended. Rather, what I’m doing here is hooking into it such that I don’t need to use a comment call.

As explained a few weeks ago, Victor’s scripts all use a “comment call” function to work – so you write a comment about lights to create lights. Great for people who know all of the information to make the light ahead of time. Awful for people who want to generate a light using variables instead of magic numbers. Fortunately, there’s an easy fix.

Torches and Lanterns in Vidar

Lanterns follow the same pattern as torches, no need to worry about the different terms!

Lanterns follow the same pattern as torches, no need to worry about the different terms!

After the Ice Cave (which I feel like I’ve been iterating to death), the player will enter the Dark Cave, filled with puzzles which are completely different in kind. You’ll find torches and lanterns which only stay lit for a short period of time.  Here, lights do a few things:

  • Actually light the map. The “Dark Cave” isn’t a misnomer, you can barely see the screen. So lighting a torch will let you see the puzzle better.
  • Reveal hidden puzzle elements. In the Dark Cave, switches are invisible until a torch within 2 tiles is lit – and will go dark again once the torch expires. Similarly, “light bridges” are only shown if a torch nearby is lit.
  • Open doors. Some puzzles rely on having all of the torches lit simultaneously for a door to open, Zelda-style.

The position of torches changes depending on which puzzle option has been loaded.

The torch pierces the shade even when the player isn't right next to it, allowing for better puzzle solving.

The torch pierces the shade even when the player isn’t right next to it, allowing for better puzzle solving.

Hooking Into Victor

Torches are a Class in Vidar. For our purposes, they have attributes lightindex and id. Remember that each light created using Victor’s script needs a unique number. It doesn’t have to be sequential, it just has to be unique. Once I figure that out, I’ll store it in the correct instance of torch as lightindex. And id is the event’s id when the object is first spawned.

My code to create a light in Victor’s script looks like this:

lightid= $game_map.screen.lights.keys.sort.last + 1
text = "<event light> id: #{lightid} index: #{self.id} name: 'light' zoom: #{zoom} var: 5 speed: 5 </event light>"
$game_map.setup_map_lights(:event, text)
self.lightindex = lightid

So the first line, I get all of the light ids on the map, sort them, and then add one to the highest. This will always be unique. And that’s the lightid I’ll use.

The second line is my comment call! Funny, huh? In Ruby, you can use #{}, and anything in the curly brackets will be evaluated as text. So lightid will be replaced with our unique number, and self.id will be replaced with our event id. Finally, zoom will be passed in when we create the light (we might want to make it bigger or smaller in certain circumstances. In actuality, this is what the text might look like:

<event light>
id: 50
index: 3
name: 'light'
zoom: 100
var: 5
speed: 4
</event light>

Look familiar? It’s exactly what you’d place in a comment call, except in a comment call, #{} won’t evaluate properly.

The third line of code calls Victor’s script, telling it’s an event light with :event, and passing in our comment call as text.

Finally, we store the lightid in the torch so that it can remember which light to turn off when it expires.

And that’s it – this will automatically create the light we need without using a comment call! How fancy!

Deleting Lights

With all that, it’s superbly easy to turn the torch off. The torch already knows which light it created, so all we do is call:

$game_map.screen.remove_light.push(self.lightindex)

And we’re done. This step is far less exciting, sorry.

We can talk about how all these light bridges show up some other time!

We can talk about how all these light bridges show up some other time!

 

 

Music Puzzle Round 2

Last week we discussed how to create a set-up where a player can load “notes” into torches, such that each torch remembers its note and can play it back accordingly. Now we want to test the solution. Tale of Two Arrays To do this, we need to create two arrays.

  1. sound_array, which is the names of our sound effects in order. So, for me, it’s [“A-bell”, “B-bell”, “C-bell” … etc.]
  2. correct_array, which is the index into that array of all the correct answers. Something like [3,6,8,2,1…]. Basically, converting your solution into numbers which index to sound_array

Stop and Go When the player checks the solution, we want them to hear the notes, and if one is wrong, stop playing immediately. I use a while loop. Just as before, I set variable 93 – our “play this note variable” – equal to whatever is stored in the first torch. I’ll set the self switch of that torch on just to change the animation. I’ll use that torch’s note as an index into sound_array to play the sound effect. And if it doesn’t equal the right number in correct_array, I’ll play a buzzer and break. Then we’ll wait 90 frames, and do all of that again with torch 2. If we finally make it to the end, we’ve won!

if $game_variables[torch_id] > 0
 RPG::SE.new(sound_array[$game_variables[torch_id]-1], 100, 100).play
 if $game_variables[torch_id] != correct_array[torch-1]
      wait(30)
      RPG::SE.new("Buzzer1", 50, 100).play
      break
 end
end

This is just a snippit of the code, but it gives you the core idea. You see a few “-1″s in there. There’s an off-by-one-errors in all of this, and that’s because we need to be able to represent no-note. If a torch has note A, you’ll recall from last week’s post that we store the integer “1” into its assigned variable. Except if I try to find A-bell in the sound_array, it’s at position 0. We just need to be careful of that as we go through our logic. The end result? Well check it out in the video below!

Dev Blog / Challenge Solution – Using Hime’s Script to Rotate Direction Arrows

A long long time ago, we talked about Hime’s tile swap script and how it’s great for changing the tile at a specific location. I issued a challenge that’s actually implemented in Vidar – using the script to rotate an arrow tile clockwise. Let’s dig into the solution.

Direction Arrow Gif

Making the Arrows

The first thing to do is actually make the arrows. These live in – you guessed it – a Puzzle Option. I call it the direction_hash, and each arrow is represented by the following

[x coordinate, y coordinate] => ["facing", unique ID]

I do that for every arrow, using “N” “S” “E” or “W” for facing,
and using just 1, 2, 3, etc. for each arrow’s unique ID.

Once we get that, we call a function called rotate_tile, where we give the function the unique ID (here called tile_id) and a rotation direction (90 degrees clockwise, 90 degrees counterclockwise, or flip, meaning 180-degrees). The function in all its glory looks like this:

def rotate_tile(tile_id, dir = "")
 rotating_hash = {1660 => "A246", 1653 => "A254", 1661 => "A245", 1652 => "A253"}
 flip_hash = {1660 => "A254", 1653 => "A245", 1661 => "A253", 1652 => "A246"}
 revrotating_hash = {1660 => "A245", 1653 => "A253", 1661 => "A246", 1652 => "A254"}
 my_hash = {}
 case dir
      when "Clock"
           my_hash = rotating_hash
      when "Flip"
           my_hash = flip_hash
      when "Cntrclock"
           my_hash = revrotating_hash
      end
 direction_hash = self.puzzle.choice.direction_hash 
 #figure out the coordinates
 direction_hash.each { |key, value|
      if value[1] != nil && value[1] == tile_id
           coord = key
           #figure out what the tile is currently
           current_id = $game_map.tile_id(coord[0] + self.puzzle.x, coord[1] + self.puzzle.y, 0)
           #swap the tile
           $gi.pos_swap(coord[0] + self.puzzle.x, coord[1] + self.puzzle.y, my_hash[current_id], 0, self.puzzle.map)
           break
      end
 }
end

Let’s talk about how we build this. First, we need to know two things about our direction arrows:

  1. What their RPG Maker Tile ID is. This is different than any other number you’ve come across. It’s a number assigned by the engine to each tile in the tileset. Why do we want this? We can get the ID of any tile by coordinate by calling $game_map.tile_id(x,y,layer). For more information about layers, check out the original post about Hime’s script.[[link]] The ID looks like 1660. To get it requires trial and error. Make a map with all of your arrows, and then puts $game_map.tile_id(x,y,layer) for each of them to get the correct numbers.
  2. What their Hime’s Tile ID is. It looks like “A246,” and I talked about how to get it in the original post.

Now I have a way to figure out which arrow is at a given position, and I have a way to place any arrow tile we want at a current position! This is the meat. The rest is gravy.

Replace With What?

The next step we need to figure out is what to replace an arrow with. At the top of my function, I have three hashes – rotating, flip, and revrotating. Each keys a RPG Maker Tile ID to a different tile’s Hime Tile ID. Specifically:

  • For rotating_hash, if the RPG Maker Tile ID is the tile for North, the Hime Tile ID is east. This is the case for all four, going clockwise.
  • For flip_hash, if the RPG Maker Tile ID is the tile for North, the Hime Tile ID is south. This is the case for all four, going 180 degrees.
  • You guess it, for revrotating_hash, we go from North to West, counterclockwise.

I ask what direction I’m supposed to go in our case statement, and then I have “my_hash” – the correct key to how to flip an arrow.

Putting it All Together

The second half of the function runs through the direction hash and finds the correct tile, by its unique id. It gets the current id using our $game_map.tile_id function. And then it calls Hime’s pos_swap based on that key. We throw the break in there to stop from looping through everything needlessly.

This function actually lives in the Switch class in Vidar, just because it’s the only time I’ll ever rotate an arrow.

 

 

Healing Variety

Reddit user kuroiryu146 is extremely thoughtful; he’s created a common event that heals all party members after every battle. He also wants to restore some amount of MP to each character, based on their class. We can put this right in our event using a script call. We’ll use a loop, and a case-statement in that loop.

Building The Loop

RPG Maker already provides you with an array of all of the people in your party. It’s called $game_party.members, and it will return a list of all actors in your party. Unless you’re in battle, then it will return a list of all actors currently in battle.

So to make a loop in Ruby, all we do is use the following syntax:

$game_party.members.each{|actor| }

In between the curly braces, after |actor|, we tell the loop what to do for every member.

Building the Case Statement

Each actor has an attribute called class_id. This is an index into your list of classes. Make sure you know the number for each class, you can find it easily in your database:

The number you need is next to the class name. In the default, 1 is soldier, 2 is monk, etc.

The number you need is next to the class name. In the default, 1 is soldier, 2 is monk, etc.

A case statement is a bit of logic that does different things depending on what a particular item equals. Here, we want to do different things depending on what the actor’s class_id is. If it’s 1 (Soldier), we don’t want to give them any MP. If it’s 2 (Monk), we want to give them a flat 50 MP. If it’s 3 (Paladin), maybe we only give them 25 MP. The case statement would look something like this:

case actor.class_id
     when 1
          actor.mp += 0
     when 2
          actor.mp += 50
     when 3
          actor.mp += 25
end

So putting it all together, our script looks like this:

$game_party.members.each{|actor|
     case actor.class_id
          when 1
               actor.mp += 0
          when 2
               actor.mp += 50
          when 3
               actor.mp += 25
     end
}

One Last Addition

Class 4 is our spell-blade. Suppose we wanted to always give him 50% of his maximum MP back. This is also easy! Just add the following to your case statement, before the “end”:

when 4
     actor.mp += actor.mmp * .5

Have fun!

Camping Out

Posting a day early to help a buddy out! Reddit user again_faster has created a really neat save system for his RPG Maker game. The “Save” function has been replaced with “Camp,” and it brings the player to a camp where they can, among other things, heal at a well and sleep in a tent. It’s a nice touch reminiscent of Dragon Age’s system which gives a pause in frenetic game play, and I think it might have lots of great story-telling implications. Check it out here:

Again_faster would loveit so that, when you load the game, you start off where you entered camp, on the overworld,  not in your camp. He’s already storing the Map ID, X, and Y in variables. He has to, to handle the return transfer event. This will be a nice quality of life change for the player, and can be done with two lines of code.

1) Go to the DataManager module and find the area called “Extract Save Contents”. It looks something like this:

Camp

This function gets called only on load, and is responsible for taking what’s in your save file and assigning it back to variables. So it finds the player, puts it in $game_player, does the same with switches and timers and all that jazz. It’s called only once on load, so it’s the perfect place to put our script.

2) Setup the correct map. In that function, add

$game_map.setup($game_variables[m])

where M is the variable you’re storing the map ID. This will overwrite the engine’s inclination to load the map you saved on, instead loading a map by it’s ID. If you always wanted to default to a specific map, you could easily use $game_map.setup(3), to always load map 3, instead.

3) Move the player. We’ve set up the map, but our player is in the void now. We need to call .moveto, which is like a transfer event except automatic – none of that fading in and out nonsense. Specifically:

$game_player.moveto($game_variables[x], $game_variables[y])

Where X and Y are the variables you’re storing the respective return coordinates. This will automatically teleport the player to those coordinates on the currently loaded map – the one you’ve chosen.

All said, you’ll have something that looks like this. The numbers chosen for the variables are just made up – make sure to use the correct ones for you!

Camp

Hope you’ve got a s’mores item, again_faster!

 

Music Puzzle

A little bit ago I talked about a library puzzle, in which I set up a bookcase system where each case would remember what book was stored inside it. Turns out, this is useful for way more than books. Let’s talk about a music puzzle in Vidar.

The core concept is this: on activating the puzzle, 7 flames appear, one for each note in a minor scale. There are 10 torches placed around the room. The player will have to select one of the notes and “load” it into the torch. After all 10 torches are lit, we’ll play them in order. If at any time the notes aren’t correct, we’ll play a buzzer and led the player correct it.

We need some sound assets for this – each individual note, and the music we want the player to match. After that, we can do this pretty easily.

Making the Notes

Like with the bookcases, we need to have a single variable that we use to identify what note-flame we’re interacting with. So each flame’s logic looks like this:

Each music note will have a different SE depending on the note. They should also set variable 80 to a unique number. So B-Bell is 2, C-Bell is 3, etc.

Each music note will have a different SE depending on the note. They should also set variable 80 to a unique number. So B-Bell is 2, C-Bell is 3, etc.

The common event is equally easy, just asking the player if they want to carry that note with them. If they do, take the # of the note-flame we approached and put it in our lantern (our way of carrying this magical musical fire).

You could do this in each event's logic, but I like to abstract wherever I can.

You could do this in each event’s logic, but I like to abstract wherever I can.

Making the Torches

Each torch is going to have 3 pages – unlit, lit, and different colored. We’ll use the last one only as an animation when we’re checking to see if all of the torches are correct.

Like with the note-flames, like with the bookcases we need to see what torch we’re selecting. Here we can’t just do 1-10, because each torch needs its own variable. So torch 1’s variable here is 82. We’ll set our “selected torch” to 82.

While there are three pages, the logic is always the same. I just use this to change the graphic to show the torch burning.

While there are three pages, the logic is always the same. I just use this to change the graphic to show the torch burning. We’ll talk about switching them back and forth next week.

The common event is also a little more complicated. We need yet another variable – the content of the torch. So, just to distinguish what’s happening here:

  • Variables 82-91 are assigned permanently to a torch. Whatever note is in Music Torch 1, that is if Music Torch 1 is currently set to the note “B”, the value of variable 82 will be “2”
  • Variable 92 gets set dynamically as we interact with a torch. So, if we interact with Music Torch 1, it will automatically set Variable 92 to “82” – the variable which represents its contents.
  • Variable 93 gets set by the common event to the content of the variable represented in 92. So since Variable 92 is “82”, Variable 93 looks at Variable 92 and finds “2.” Variable 93 is then 2.
It's a lot of variables, but it's rapidly scale-able. Turning this from 10 torches to 50 takes a matter of *seconds.*

It’s a lot of variables, but it’s rapidly scale-able. Turning this from 10 torches to 50 takes a matter of *seconds.*

Why all these variables? It allows for abstraction. All each torch has to do is set Variable 92, and call the common event. That’s it. That’s bug free. Imagine if we didn’t do these things, and just had each torch responsible for itself. If there was a bug in our logic about storing and retrieving the notes, and we had copy/pasted that logic into each torch, we’d have to fix it 10 times. That’s a mess. Don’t do that.

You're not seeing double: $game_variables[$game_variables[92]] means the value assigned to Variable X, where X is itself the value of Variable 92.

You’re not seeing double: $game_variables[$game_variables[92]] means the value assigned to Variable X, where X is itself the value of Variable 92.

We’ll examine the common event “Play a Note” in a second. The conditional branch asks if there’s anything in your lantern. Skip to the else if there isn’t – we’ll ask you to choose a note first, otherwise there’s nothing for you to really do. If there is something in your lantern, ask if you want to put it in the torch (we’ll ask slightly different questions based on whether there’s something already in the torch, but that’s just flavor text).

If after all that, the player decides to put the note into the torch, we’ll backtrack from variable 92 to figure out what torch we’re talking about. That variable will get assigned whatever is in your torch. And we’ll call play a note, this time with the new note.

Got all that? Let’s play some music

Play The Notes

The play the note common event is actually really simple. Right before we call it any time, we set variable 93 to the note we want to play. Then it’s just a simple matter of conditional branches. A lot of conditional branches.

In strict Ruby, we'd handle this with something called a "case statement." Here, a series of conditional branches is just fine!

In strict Ruby, we’d handle this with something called a “case statement.” Here, a series of conditional branches is just fine!

In our torch common event we call this twice. Once when you interact with  a torch (to play you what note it is currently holding), and once when you place a new note in (to play you what you put in).

We’ve now got a system that allows us to grab music notes from flames and add them as we want to torches. They can be replaced at will. And the torches all remember what note they hold. Next week we’ll talk about how to play and check the solution!

New Content!

Time for another round of Vidar iteration, Ice Cave style!

Since the build submitted to Boston FIG, I’ve been making some fun changes:

  • The window graphic has changed, courtesy of Becca Bair.
  • Three new quests have been added to the Ice Cave. Two of them can only be triggered if a specific person dies. I’m trying to beef up the number of these types of quests because otherwise, the longer the game goes, the fewer quests become available. This is a counterbalance to that. It’s not perfect, you could of course end up with NPCs dying in the statistically worst possible order, but that’s the fun of randomness, right?
  • The third puzzle is another take on random exploration. Through the Ice Cave, you can find cracks in the snow. Lilja gives you a shovel so you can dig. Only one of them has some buried treasure – up to you how many you explore!
Caption

Dig sites represented by cracks right now. 

Caption

Window graphics for a more nostalgic feel.

  • What’s nice about this is that the location of the dig locations is random (and not even necessarily 1 per map, like the graves), and which one has the treasure is also random. So you can luck out on your first go, and never have to dig in any of the others, to complete the quest. Or you can be chasing down the last of 10 sites.
  • Dialogue trees for about 10 NPCs are in! It contributes so much to making Vidar a living, breathing world. With only 10 in, already every day someone has something different to say.
  • Little touches, like music equalization and of course a ton of bug-fixes, have been cleaned up

But iteration can’t just be about new content and bug fixes. It’s really a process of going back and killing your darlings. Without the willingness to do that, I’ll never have the game I really want. So on tap for after the FantasticFest submission:

  • Cutting 1/3 of the Ice Puzzles – I’ve a clever idea on how to do this, but I need to make sure it works first!
  • More cutscenes, would love to get to one a night
  • Notes to find in the cave that change nightly

Finally, there’s a concern about the time spent in the cave as you go forward. No matter how many attempts I make at giving you teleportation mechanics, these don’t seem to activate in time for it to be meaningful. So, a test change:

  • Increase the day’s length by 1 minute every day

Always be willing to make the change!

Friday Script / Dev Blog – Modifying Yanfly’s Save Script

If you want to get the most out of RPG Maker, learn Ruby. In the meantime, lots of talented scripters have done the work for you. Every Friday, The Iron Shoe features a fun script and goes into detail about how to use it. It also covers a little bit of Ruby each time so you can make even more out of the script.

Today I’m talking about Yanfly’s Save Engine! Rather than go into how to use the script this time (because Yanfly is notoriously a clean coder, strong commenter, and all-around genius when it comes to scripting), I want to talk about breaking it. A few weeks ago I posted my modified save menu, let’s dig into how I did that.

Designing the Save Screen

The first thing we need to do is figure out what, exactly, we want on our save screen. After really talking out what matters in Vidar, and what we like to see on save screens in general, a few notes came to mind:

  • Save Screens show us the progress we’ve made in a particular file. Often times we track that with different variables like gold, playtime, character levels, but the goal is to give a graphic way of saying “this is where you are in the game.”
  • Vidar‘s progression is charted by day, and we already have a variable that represents what day it is, so let’s draw that
  • The other thing which distinguishes each save file is which NPCs have died. The player, in fact, never changes. So while we normally draw the player and display his level, since none of that applies, let’s look at the NPCs instead.

Clearing Out Unnecessary Draws

Yanfly’s engine does way more than I need it to do. He creates a function called “draw_save_contents” that handles all of these. It looks something like this:

The numbers in the ( ) are the location to draw these various pieces. Once you get to the last step of adjusting, come back here and play with these to get the locations just right.

The numbers in the ( ) are the location to draw these various pieces. Once you get to the last step of adjusting, come back here and play with these to get the locations just right.

You can tell just from looking at these things what they do, and can comment out the ones you don’t want accordingly. I don’t want playtime, total saves, gold, or location, so I put a “#” in front of each of those lines. Save Columns 1 and 2 reflect the fact that Yanfly’s engine can display any variable you want it to. I only need one column with one variable – “day” – so I commented out column 2 as well.

# in front of a line makes it green. More importantly, that line is never actually run. "Commenting out" lines like this allows you to experiment without deleting.

# in front of a line makes it green. More importantly, that line is never actually run. “Commenting out” lines like this allows you to experiment without deleting.

Now we’ve cleared the screen of any information we don’t care to display.

Drawing The Actors

This one gets more tricky. Right now, the drawing characters asks who is in your “battle party” – typically, the first four members of your party – and draws them with a lot of information. Find the part that looks like this:

What Yanfly does is set positioning variables based on the actor's place in your party. We're gonna change most of this.

What Yanfly does is set positioning variables based on the actor’s place in your party. We’re gonna change most of this.

Again, there is a lot of unnecessary information here. Specifically, my NPCs don’t have levels. So let’s get rid of all that stuff.

I commented it out here, but once you know you don't need it, delete it. Otherwise you end up with a ton of nonsense.

I commented it out here, but once you know you don’t need it, delete it. Otherwise you end up with a ton of nonsense.

Now the big change. We aren’t drawing party members, we’re drawing a select number of NPCs – in my case, they’re all actors. Specifically, they’re actors 8 – 31. So instead of a for each loop, I can actually just call draw 24 times. Ruby has a great “.times” loops, so I’ll use that. The next thing is, we have to do a bit of math that Yanfly never ran into. Because he was only drawing, at max, four characters, he never had to worry about rows.

I have 24 NPCs. You bet your ass I have to do this in rows.

So, “dx” – the x spacing between each character – is multiplied by (i % 5). This is “modulo” and it’s a really handy way of doing columns or groups of things. It asks for the remainder of i divided by 5. So, for actor 0, it’s 0. For actor 1, it’s 1. For actor 2, it’s 2….for actor 5, it’s 0. For actor 6, it’s 1. You can see how this gets us a loop that goes 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, etc., we can multiply this number by our x-spacing to figure out exactly where the NPC should be, horizontally speaking.

For “dy,” we use another neat Ruby trick. When you divide a number by another number, you get an integer result, not a fraction. 1 divided by 5 is 0. 7 divided by 5 is 1. So dividing by 5, we’ll know exactly which row the NPC falls in, and we can multiply that by dy to get the height.

It then comes down to playing with some spacing, which you can do both in this function, and the original one which passes in certain arguments. All in all, it looks like this.

For 24 separate times, we'll run the code, incrementing "i" each time.

For 24 separate times, we’ll run the code, incrementing “i” each time.

Note that nothing in the save engine modification changes the actor’s graphic to black and white if they are dead. This is actually handled in the NPC death function, which, when it kills an NPC, actually replaces the actor’s graphic. Since the save engine is just drawing whatever sprite is assigned to that actor, you can dynamically change the graphic as you need to.

Adding the Day

The finishing touch is scrolling to the top and telling Column 1 to display my “day” variable.

Variable 21 is my "day" variable, so it's easy. Just make sure you like the name of your variable in the RPG Maker engine - that'll get drawn too!

Variable 21 is my “day” variable, so it’s easy. Just make sure you like the name of your variable in the RPG Maker engine – that’ll get drawn too!

And that’s it! The final product, once I tweaked all of the positions, looks like this:

24 NPCs plus a variable. All nicely ordered.

24 NPCs plus a variable. All nicely ordered.

One Map At A Time

Workshop

Art courtesy of Becca Bair.

This is my first attempt at parallax mapping! Undoubtedly, I’ll need to fill this space with more trinkets and variation, but it’s definitely getting there. I used Reddit user PieHardLol’s super awesome tutorial and accompanying video on parallax mapping. If you’re going to attempt something like this, watch that video about a dozen times before starting.

Transfer Lock

Double-post today! Reddit user tilfordkage wanted to block a player from advancing to a new area until the player reached a certain level. This is an easy solution!

Make Your Party Level Variable

In any event, create a event command of the type “Control Variable.” You’ll be greeted by this screen (it won’t be filled in).

Use this window to set variables as you need.

Use this window to set variables as you need.

To get your window filled in like this, click on the … on the top line to name your variable (here, I did Player Level but it doesn’t matter). Select the Game Data radio button below, click …, and fill in the screen that pops up like this:

You can set the variable to a whole host of things about a player character, including their ATK, their current HP, or here, their level.

You can set the variable to a whole host of things about a player character, including their ATK, their current HP, or here, their level.

Now, every time we trigger our event, we’ll first set Variable 1 to Eric’s level.

 

Make The Rest Your Event

The rest is easy! Transfer events are almost always below characters/player touch so make sure your priority and trigger options in the bottom left are set accordingly. Then in the logic, after we set our variable, put in a conditional branch. If variable 1 >= 10, transfer. Otherwise, move the player away from the event and tell them to get a few more levels already!

Here we say to move the player down if he can't transfer, but use your judgment to replace the player accordingly.

Here we say to move the player down if he can’t transfer, but use your judgment to replace the player accordingly.

 

Multiparty

Worried that the player’s just power-leveled one actor and not the others? Average out the levels! Just do the math on the variable before the conditional branch.

Use control variable over and over to modify the event. Make sure to use the operators on the variable, don't just reset it!

Use control variable over and over to modify the event. Make sure to use the operators on the variable, don’t just reset it!

Good luck, tilfordkage!