This article discusses the targeting system in the default battle system in RPG Maker VX Ace. The purpose of this article is to understand how the target system works, and determine whether it is designed well. I provide a number of examples of different game mechanics that I use to put the target system to the test.
What is Targeting
In the context of battle actions (or actions in general), targeting refers to the object that an action will be used on. For example, you want to cast a Heal spell on your ally. We say that the ally is the target of your healing spell. Similarly, if you want to attack a Slime, we say the Slime is the target of your attack.
All items and skills have a scope. You can see the list of default scopes in the database editor. Check the help file for a description of each one, but they should be self-explanatory,
The scope determines who you may select as a target.
The Ally and the Enemy
The scope uses terms like “ally” and “enemy” to describe who the targets are. Recall that the default battle system consists of two units of battlers: the party and the troop. The party holds all of the actors, and the troop holds all of the enemies.
Every battler has their own idea of who an ally is, and who an opponent is. For actors, allies are members in the party, and opponents are members in the troop. You can verify this in the
def friends_unit $game_party end def opponents_unit $game_troop end
For enemies, the opposite is true. You can verify this in the
Overview of the Targeting Workflow
Now that the basics are out of the way, we look at how targeting is implemented. This is the general workflow in the default battle system, supposing that you want your actor to attack an enemy.
- Battler’s turn comes up
- Battler selects a skill (eg: Fire)
- The engine checks the scope of the skill and determines that it may target “one enemy”
- The engine brings up the target selection window asking you to select a target
- The battler chooses to cast fire on the first enemy
Game_Actionobject is created with the index of the target (zero, because Ruby) and the skill set as the action
- When the action is executed, the information is used to apply the skill to the correct enemy that you’ve selected
This sounds straightforward: you pick an enemy, and the skill is applied on the enemy. That is exactly the behaviour you expect. Let’s look at some of these steps in detail.
When you select an item that allows you to select your target, a target window will appear. There are two separate windows: an actor selection window, and an enemy selection window. Depending on whether the scope targets allies or enemies, the appropriate window will appear.
If an actor selects a skill that targets allies, then the actor selection window will appear showing all of your allies
If the skill targets enemies, then the enemy selection window will appear showing all of the enemies that can be targeted
Once you have selected your target, the engine determines the target’s index. In the default engine, every unit has an index. The index represents their position in the unit. If you think of your party’s formation, the leader is in the first position (index 0), the first follower is in the second position (index 1), and so on.
Your index is not necessarily related to where you appear on the screen. Indeed, enemy indices are based on the order that they are added to the troop (you can read more about troops in this tutorial), but you can place them wherever you want on the screen.
Action Target Adjustment
Recall that the target index is stored with the action when the action is created. In the default battle system, actions not executed immediately. Instead, they are queued up and will be executed when the battler’s “action phase” comes around.
When the action is executed, a separate set of methods are used to determine the actual battler which the action’s skill or item will be applied to. Furthermore, if the target is no longer available, the battler doesn’t simply cancel their action. Instead, the action will automatically be applied to the next available target. If no available target exists, then the action will be canceled.
So for example, you wanted to heal a wounded ally. However, before you could cast your spell, the enemy attacks and your ally dies. Now, when you try to cast your heal spell, the target is already dead…but the skill doesn’t apply to dead allies, so it will try to find the next available ally that is alive and automatically sets that as the target.
You can refer to the
make_targets method in
Game_Action to see how it is done.
Analysis of the Default Target System
If we assume that no one will ever have any need for a different battle system or battle mechanics, then our target system works well and does not need to consider anything else.
The requirements of a game engine is far more looser than the requirements of specific game, and building a game engine around a pre-defined set of game mechanics only serves to limit what you can do with the engine.
I will provide a review of the targeting system using examples of mechanics that are fairly common, but are made impossible to achieve because of the way it is designed.
Targeting both actors or enemies
Suppose you want to use a skill. Is it fairly unrealistic that you can ONLY attack enemies, or ONLY heal allies. It is much more realistic that you can use a heal spell on an enemy, or you can attack an ally, or even yourself. If you were fighting some undead monsters who are vulnerable to healing spells, you kind of want to be able to use your regular healing spells on the enemies as well.
Unfortunately, our scopes do not provide support for “one actor or enemy”, and neither does our selection window. There is no selection window that allows you to choose any actor or enemy.
Given the fact that the only piece of information that the engine has to determine which battler you wanted to target is an index, there’s no way for it to know whether you meant an ally or an enemy. This is where the scope comes in:
def make_targets if !forcing && subject.confusion? [confusion_target] elsif item.for_opponent? targets_for_opponents elsif item.for_friend? targets_for_friends else  end end
If the scope targets opponents, then it uses the index to look up an enemy. If the scope targets allies, then it uses the index to look up an ally. If you could manually override the scope of your action, then that would work. However, in the current state, you can only target an enemy or an ally, but not both at the same time.
Targeting Empty Positions
There is no concept of “empty positions” in the first place. You can only target valid indices, and valid indices are defined to be battlers that can be targeted. So you must pick a battler to target. Want to swing your sword in mid-air randomly? Tough.
Realistically, this means that you would not be able to create area of effect abilities that allow you to target a random opening in between two enemies and hit both enemies. Of course, some games might not want players to do this, but the solution is not to simply remove this option altogether.
There is no concept of “moving” in battle. If someone shoots an arrow, you will always be hit no matter how much you try to avoid it. of course, there is a calculation that allows you to “evade” an attack with some percent of success, but that’s a pretty limited option if you wanted to provide a more interactive experience where you actually step aside.
You could possibly implement formation changing functionality that allows you to swap positions between members, and that’s about as close as you can get to avoiding a hit. But it just means someone else will take the hit.
Suppose you have a skill that allows you to take control of an enemy and have it use its skills on their own allies. How dangerous. In fact, it’s so dangerous, RPG Maker doesn’t let you do it. You simply cannot control anyone that isn’t in the party.
Ok, so let’s put the enemy into the party. But the enemy is not an actor, so the party will reject it (by crashing the game).
Let’s just make it so that you can have an enemy attack it’s own allies! But you can’t either, because an enemy’s opponent is the party, and based on the scope rules, you simply cannot choose an enemy’s allies as a target for skills that target opponents.
On the upside, enemies cannot control you either, so you don’t have to worry about enemies mind controlling your party members.
Depending on how you see things, you may say that the target system is just fine, that it does what it was designed to do, and that anything else is outside the scope of the engine and is our own problem. However, there are plenty of ways to design a system that meets your own requirements and doesn’t limit flexibility. In that sense, it is not designed very well. Even something as simple as picking an actor or an enemy to attack is basically impossible because not enough data is provided to the relevant objects.
I would recommend building a more flexible targeting system and use it as a core script rather than trying to bend the default targeting system to fit your needs.
Spread the Word
If you liked the post and feel that others could benefit from it, consider tweeting it or sharing it on whichever social media channels that you use. You can also follow @HimeWorks on Twitter or like my Facebook page to get the latest updates or suggest topics that you would like to read about.