Eventing a Push/Pull System
October 29, 2020
October 27, 2020

Eventing a Push/Pull System

Eventing a Push/Pull System



October 29, 2020

The in-engine tutorial gives us a brief guide to making pushable events with moving rocks, but sometimes we want our players to have more options when dealing with a puzzle. So why don’t we create a system that lets players grab those events to push and pull them out of the way?

Having a hard moving rock puzzle can challenge our players’ minds, but it’s not always fun if they need to keep resetting the puzzle due to accidentally pushing an event into a corner or blocking a hallway. A push/pull system can give us more options when it comes to puzzles while also giving our players a way to fix any mistakes they make while trying to figure out the right thing to do.

One important thing to keep in mind is that pulling an event won’t work if followers are visible! Events see followers as other events, so the event will act like it’s blocked and won’t move if we leave followers on. That is an easy fix though, if our game shows followers then we just need to make sure to use the event command Change Player Followers to turn them off at the start of the event and then turn them back on at the end of the event.

Setting up a basic version

Before we try any complicated eventing, let’s start with a simple version. We just want to give our players the option to push and pull an event without causing issues, and an easy way to do that is to use Show Choices to let our players pick what they want to happen. So let’s set up an event with a round rock as the image and pull up the Show Choices event command. For simplicity's sake, we’ll just name the two choices we need Push and Pull. We could also write out a Cancel option as a choice, but for this event we’ll choose Branch as the Cancel option from the list on the right of the command so that we can give the players an option to not move the event just by hitting the in-game cancel button.

With our Show Choices created, the next step is to create the move routes for the event and player. Both the event and player’s move routes will have Skip If Cannot Move checked so that if there’s a wall or other thing blocking their path the game will just proceed normally (if you’ve ever had your game lock up seemingly randomly while a move route is happening, there’s a good chance the move route didn’t have Skip If Cannot Move checked and the event moving walked into something it thinks is solid and that causes the game to freak out because it doesn’t know what to do if it can’t complete the move route).

Set Movement Route has some useful options when it comes to moving the player forwards and backwards, so we’ll be using 1 Step Forward when we’re pushing and 1 Step Backward when pulling. By default the player moves faster than events so to make sure that both are moving at the same speed, we want to slow down our player before they move and then set it back to normal once they’ve moved.

The event’s move route first needs to turn off direction fix so that it will look like it’s rolling in the right direction. Once that’s done, we’ll rely on Move Away from Player when we’re pushing and Move Toward Player when pulling to have the rock move properly. We do need to add a minor Wait to the pulling move route since the engine will think the player is still in the way if there isn’t a wait, but since one frame is 1/60th of a second players won’t even notice

Once we’ve added those Move Routes to the event, we end up with our event looking something like this:

I decided to add in a little message before the choice box pops up, just so the player knows exactly what they’ll be doing. 

One thing to keep in mind is that setting it up in the event itself works fine if we’re only having a few rolling rocks in the game, but if we’re going to have these type of events spread throughout our games we should consider making the event content a common event so that we can just call that common event instead of having to copy and paste the eventing into each rock’s event. This also gives us the bonus ability to change all of the rocks at the same time if we later decide that we want the Show Choices to say something different than just ‘push’ and ‘pull’.

Now, this type of event works, but what if we want to give the player the option to push or pull the event as far as they want without having to pick the choice over and over? Then we’ll need to come at the push/pull system from a different angle.

Making a grab-and-move event

First thing we want to figure out is what exactly we want this push/pull system to do, since the clearer idea we have the easier it will be to figure out how to event it. For this tutorial, we want our system to let the player hold onto the event and move it back and forth with the arrow keys until they want to let it go. It sounds simple, but we need to keep a few things in mind while eventing so that it will work how we want:

  • There needs to be a way for the event to know when the player is holding onto the event and when they let go
  • The event needs to tell if the player is pushing or pulling no matter which direction they approach it from
  • We want to make sure the event doesn’t keep trying to move if the player isn’t touching the arrow keys

Let’s start by solving that first bullet point. To keep things simple, let’s make the ‘ok’ button control if the player is holding onto the event, so when the player holds down the spacebar they’ll be able to move the event. A Loop will let the event repeat until we break it which is perfect for this situation, so we’ll add one to our Push/Pull common event. To know when to stop the looping, we’ll add a Conditional Branch to see if the player is still holding down the ‘ok’ button and if they let go then the Break Loop will activate.

The Wait in the loop is there just to slow everything down a bit, since we don’t really need the event to check 60 times a second. Let’s also add in a move route for the player before the loop starts so that we don’t need to change their speed or lock their direction repeatedly in the loop and a move route to get the player back to normal once the loop ends.

Next we need to figure out if the player is trying to push or pull the event. To do that, let’s come up with a way to check the direction the player is facing and if they’re hitting the arrow key that either matches that direction or is the opposite direction. If the arrow key matches the player’s direction they’ll be pushing the event and if it’s the opposite direction then the player will be pulling. We can do this in a few different ways, so let’s look at how we could do it with just event commands and with script calls.

First up is checking if the player is pushing with just event commands. We’ll start with a Conditional Branch checking if the player faces a certain way and nestle another Conditional Branch into that to see if the corresponding button is being pushed. If they match, then we’ll set a variable to 1, which we’ll check later down the event to see which move routes should be used.

We’ll need Conditional Branches like these for each direction (down, left, right, and up), so by the end of this section of the event we should have four nested branches to check if the player is pushing the event.

Next, we’ll see how we can check if the player is pulling with script calls. The results will be exactly the same as the event commands above, but if you’re comfortable with basic JavaScript coding you may prefer using this. The best way to check out available script calls is to look at both the MZ Script Call Reference sheet and the MV Script Call Reference sheet, so we’ll be pulling a few from both of those to make our script call. The script calls we’ll be using are:

  • Conditional Branch: if (code) { stuff that happens }
  • Control Variables: $gameVariables.setValue(variable#, value);
  • Check If Player is Facing a Certain Direction: $gamePlayer.direction() == #
  • Check Button Input: Input.isPressed("key")

The direction numbers match up with the spritesheet, like so:

The last few things we need to know is how to say ‘and’ and ‘or’ in the code, so that we can check two things at once. Luckily that info is easy to find online, so now we know that ‘and’ is && and ‘or’ is ||.

Now that we know the script calls, we can set up our code. We want to check if the player is hitting the opposite arrow key as they are facing, and if they are then we’re setting our variable to 2. With the script calls we can check all the possible directions at once, so we end up with this:

We could put all the code into one line, but by separating it out like this it’s easier to look at and understand what’s going on later (and also easier to see if we accidentally miswrote something, which could cause an error). With it all put together, our event is able to check if the player is trying to pull the event.

After getting those two things set up, our event can properly check if the player wants to push or pull, but doesn’t actually do anything about that. So we’ve got to add in move routes for the event and player, which we’ll put into Conditional Branches that check our variable we used earlier so that the right move routes play.

With the push/pull checks and move routes added, our event technically would work! But there’s a minor problem: if our player pushes a button and then lets go, right now the variable won’t change or reset so the event will think it’s supposed to keep moving things. That means our player and event will keep moving until they hit a wall. Which works if we wanted them to be sliding around on ice, but not great for normal puzzles. 

That’s an easy thing to solve though, so we’ll just want to add a Control Variable command that sets our variable back to 0 after the move routes. Now there will only be movement if the player is touching one of the arrow keys.

With all of that figured out, all that’s left is to put it into a common event:

With our common event all set up, we can create our events now. Instead of rolling rocks, let’s make the events all crystals that light up and sparkle when they’re being moved. Since we didn’t add in any changes to the events in the common event, we’ll want to use a move route that turns on the stepping animation and lights the crystal up (we’ll use one of the Turn options, and figure out which one is right for the crystal by looking at its spritesheet) before calling the common event, and another one that turns the crystal back to normal once the player lets go.

Now we can copy this crystal event a few times to make a simple puzzle for our player to navigate through!

And with that, we’ve finished our push/pull system. Moving crystals out of the way isn’t the only use for this system, so what other ways could you see using this system in your game? And once you’ve made this yourself, what changes would you make to make this fit perfectly into your own game?

Recommended Posts