[Tutorial Series] Hime ATB #6: Initial ATB

Help spread the word!Share on FacebookShare on TumblrTweet about this on TwitterShare on Google+Share on LinkedInShare on RedditFlattr the author

This tutorial is part of a tutorial series on Active Time Battle (ATB) System development. In this series, you will learn how to build your own ATB system from scratch, and add new functionality to create a unique battle system based on ATB.

In this tutorial, we will be focused on “initial ATB”, which is how much ATB you begin with when you begin the battle.

Preparation

This is the sixth tutorial in the series. If you have not read the previous tutorials, I highly recommend doing so, starting from the first tutorial since the code base we will be using is built up from all of the previous tutorials.

We will base our code on the results of the fifth tutorial, which you can find here.

Re-Cap

Initial ATB determines how much ATB your battlers begin with at the start of battle.

In the first tutorial, we simply assumed that everyone begins with zero, and we haven’t changed it since then.

Battle Encounter Conditions

However, in RPG Maker, there are three types of battle encounters

  1. Normal Battles
  2. Pre-emptive Battles
  3. Surprise Battles

During normal battles, everyone starts at roughly the same amount.

During a pre-emptive battle, your actors will be able to perform their actions first. This means that they might have an initial boost in their ATB, or they might have full ATB immediately.

During a surprise battle, the enemies will be able to perform their actions first.

Now, you are not limited to these three rules when you set up initial ATB. You could have a special item that allows you to always start the battle with full ATB, regardless whether it’s a surprise battle or not.

Ideally, a versatile ATB system would allow the user to set up the initial ATB rules however they want. For now, we will just assume some things for demonstration purposes.

One of the biggest assumptions we will make is that there are only actors and enemies; there are no “neutral” battlers that are separate from these two.

Normal Battles

Let’s start by looking at how we chose to initialize ATB when a battle begins

var TH_GameBattler_onBattleStart = Game_Battler.prototype.onBattleStart
Game_Battler.prototype.onBattleStart = function() {
  TH_GameBattler_onBattleStart.call(this);
  this._atb = 0;
};

So we were setting it to 0.

What if you wanted to pick a random number between 0 and 24?

var TH_GameBattler_onBattleStart = Game_Battler.prototype.onBattleStart
Game_Battler.prototype.onBattleStart = function() {
  TH_GameBattler_onBattleStart.call(this);
  this._atb = Math.floor(Math.random() * 25);
};

Would work.

Personally I would go with a method like this

Game_Battler.prototype.initAtb = function() {
  this._atb = 0
};

var TH_GameBattler_onBattleStart = Game_Battler.prototype.onBattleStart
Game_Battler.prototype.onBattleStart = function() {
  TH_GameBattler_onBattleStart.call(this);
  this._atb = this.initAtb()
};

And then build on that. So for example, at the beginning of battle, I would initialize all ATB’s. Depending on the type of encounter, I would have to handle actors and enemies separately.

Game_Actor.prototype.initAtb = function() {
  Game_Battler.prototype.initAtb.call(this);
};

Game_Enemy.prototype.initAtb = function() {
  Game_Battler.prototype.initAtb.call(this);
};

Now we’re ready to set up ATB for each type of battler.

Pre-emptive Strike

Let’s assume that if the party gets the first attack, they will have full ATB at the beginning of battle, while enemies will have no ATB.

Game_Actor.prototype.initAtb = function() {
  Game_Battler.prototype.initAtb.call(this);
  if (BattleManager._preemptive) {
     this._atb = this.atbMax();
  }
};

Game_Enemy.prototype.initAtb = function() {
  Game_Battler.prototype.initAtb.call(this);
  if (BattleManager._preemptive) {
     this._atb = 0;
  }
};

For testing purposes, you can use this plugin which will allow you to force pre-emptive strikes or surprise battles.

What should happen is when it’s a pre-emptive strike, all of your battlers will have full ATB.

Surprise Battle

Surprise battles are the opposite of pre-emptive strikes. We can build on our methods from before to consider surprise battles.

Game_Actor.prototype.initAtb = function() {
  Game_Battler.prototype.initAtb.call(this);
  if (BattleManager._preemptive) {
    this._atb = this.atbMax();
  }
  else if (BattleManager._surprise) {
    this._atb = 0;
  }
};

Game_Enemy.prototype.initAtb = function() {
  Game_Battler.prototype.initAtb.call(this);
  if (BattleManager._preemptive) {
    this._atb = 0;
  }
  else if (BattleManager._surprise) {
    this._atb = this.atbMax();
  }
};

Alternative Design

What I showed above is just one way to do it.

I’m not too fond of this approach since we’re accessing variables that are meant to be private to the Battle Manager. It also increases coupling between the battlers and the battle manager, because now the battlers rely on the battle manager to provide certain info.

In terms of design, I don’t like it as much.

Let’s switch to an approach where the BattleManager is in charge of telling the battlers what ATB to use. For this approach, all battlers will provide a method called “setAtb”, which will set the ATB to a specific value.

Game_Battler.prototype.setAtb = function(atb) {
  this._atb = atb;
};

Now, depending on the settings, we’ll have the battle manager figure out what to assign for each battler.

var TH_BattleManager_startBattle = BattleManager.startBattle;
BattleManager.startBattle = function() {
  TH_BattleManager_startBattle.call(this);
  if (this._preemptive) {
    var actors = $gameParty.members();
    for (var i = 0; i < actors.length; i++) {
      actors[i].setAtb(actors[i].atbMax());
    }
    
    var enemies = $gameTroop.members();
    for (var i = 0; i < enemies.length; i++) {
      enemies[i].setAtb(0);
    }
  }
  else if (this._surprise) {
    var actors = $gameParty.members();
    for (var i = 0; i < actors.length; i++) {
      actors[i].setAtb(0);
    }
    
    var enemies = $gameTroop.members();
    for (var i = 0; i < enemies.length; i++) {
      enemies[i].setAtb(enemies[i].atbMax());
    }
  }
};

So instead of having each battler figure out what to do with it, we let the BattleManager figure out what to do with it.

The advantage to this approach is that battlers don’t need to know anything about the battle system rules for pre-emptive or surprise battles. It’s up to the battle manager.

However, if each battler had some special rules of their own…it might get a bit messy.

Perhaps a better solution would be to have the battle manager figure out whether there’s a pre-emptive or surprise battle, then tell each battler what the situation is and then let them determine how to go from there.

Summary

In this tutorial I showed you two ways to initialize ATB based on whether it’s a normal encounter, a surprise encounter, or a pre-emptive encounter.

There are a lot of ways that you could implement it; there is no “correct” solution, only better ones and not-so-good ones.

It will be up to you to figure out what works best for you, and which would be most flexible depending on your needs.

Feedback

Do you have any questions or comments? Perhaps there is something that is unclear, or could be implemented in a better way? Let me know in the comments!

Share the Tutorial

If you know anyone that is interested in writing battle systems for RPG Maker, share this with them!
You can also follow me on TwitterFacebook, or Youtube  for the latest posts and videos.

Support HimeWorks

If you would like to support me in writing these tutorials, you can put in a monthly pledge on Patreon! Every little bit helps, and becoming a supporter allows you to gain access to some exclusive content like development logs/rants, closed beta tests, and other things that I offer.

Help spread the word!Share on FacebookShare on TumblrTweet about this on TwitterShare on Google+Share on LinkedInShare on RedditFlattr the author

You may also like...

Leave a Reply

Your email address will not be published.

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax