Note: This PRState documentation is out-dated and is for an older (pre-GMS v2.3) version of PRState. For the most up-to-date docs on the latest version of PRState, please refer to this page as well as the documentation included in the PRState package.

Documentation Topics
Article

Implementing a State Script

Each of the scripts that you've designated as a state script needs to receive 1 argument. The PRState engine will call those scripts automatically at the appropriate times, passing them a “mode” argument. Therefore at the top of each of your state scripts you will need a line similar to the following:

var mode = argument0;

“mode” will be set to one of the following values each time your scripts are called:

In the body of your scripts, you will implement code to react to the given mode. Responding to each of the modes is optional, so implement only the ones you need. Each one is described below.

PRStateModeInit

This mode means that the state of your object has just changed and you are now given the opportunity to run some initialization code for the current state. Continuing with the previous example, you might write something similar to the following in the characterIdleState script, right below the var mode = argument0; line:

// In characterIdleState script.
if mode == PRStateModeInit {
   sprite_index = sprHeroStanding; // Set the object’s sprite to the hero’s awesome standing pose.
   audio_play_sound(audWhistleTune, 7, true); // Our hero will begin whistling a tune while standing around waiting.
   return;
}

The above code means that upon entering the object’s Idle state, we set the hero’s current sprite to the appropriate standing/idle sprite image. We also have the hero start a whistling ditty while he’s waiting for player input. We issue a return statement so that the rest of the script isn’t executed, since we only want to cover the PRStateModeInit here.

PRStateModeEnd

This mode means that the current state is about the end and a new state will begin shortly. In this mode, you now have the opportunity to perform some cleanup or de-initialization routines. Continuing with our previous example, you might write something like this:

// Still in characterIdleState script, after the previous code above.
if mode == PRStateModeEnd {
  audio_stop_sound(audWhistleTune);  // Hero will no longer be standing idle, so he stops whistling.
  return;
}

The above code will run the moment right before an object’s state switches to another state, so we make sure that the hero isn’t whistling his lovely waiting-around tune because he won’t be idle anymore.

PRStateModeUpdate

When the "mode" argument is equal to PRStateModeUpdate, this means that your object needs to respond to the current frame update (the Step event.) Your object’s current state script will be called with this mode once for each Step event, so you will likely code the bulk of your object’s state behaviour here. Continuing with our idle state example, you might code something like this:

// No need for an IF statement here since there is only 1 mode left not handled yet.
// Nothing to do while the hero is idling except to monitor the player’s input, and make the hero run if input detected.
if keyboard_check(vk_left) or keyboard_check(vk_right) {
  PRStateSet(self, “Run”);  // Left/right pressed! Switch to Run state which will handle the hero’s running action.
  return;
}
if keyboard_check(vk_space) {
  PRStateSet(self, “Jump”);  // Action pressed! Switch to Jump state which will handle the hero’s jumping action.
  return;
}

The above code will switch the object’s current state to either Run or Jump depending on which keys the player has pressed.

This was a simple example of implementing a state script. Your code that handles the PRStateModeUpdate mode will likely be much longer for the more complex states that your object might have. The point here is to show that using states will segregate your object’s behaviour into sensible blocks of code that are called by PRState and handled by your scripts. If you find that your Run state is still too complicated and long winded, for example, the you might consider breaking it down further by specifying “RunLeft” and “RunRight” states to split the code up ever further.