Additional tutorial credits: @TheoAllen, for converting MV/Z formulas to Ace. The parallels are now included in the intro post.
If you're uncomfortable going much further than a.atk * 4 - b.def * 2 for your damage formulas, this is the guide for you. Damage formulas are extremely powerful tools that can let you create complex abilities. They are fairly similar to actual scripts in syntax (which is why they can be intimidating).
I placed this tutorial in Non-Maker Specific because it has worked with MV and VX Ace.
Basic Setup
[MV]
[VX Ace]
Type. There are six different damage types: HP damage, MP damage, HP recover, MP recover, HP drain, and MP drain. They each should be fairly self-explanatory. Drain restores health to the user equal to damage dealt (not half as in some games).
Element. Element allows you to select the damage element. Normal Attack is best for most physical moves (e.g., a skill like Wild Blow). Elements are important to set for most games because they can let you add in elemental weakness and effectiveness.
Variance. Variance is a percentage that lets you set how much the damage will vary from what the formula says. If the formula computes to 50, and if variance is 20%, it can do 80-120% of 50 damage, so 40-60 damage. I recommend setting it to 10%.
Critical. Critical allows you to select if the attack can have a critical. Most spells do not have this enabled, in most games. But do what you like!
Basic Formulas and Parameters
Onto the meat of the tutorial! Before we begin, note the importance of capitalization. Everything must be capitalized as directed in this thread. Do not randomly capitalize or un-capitalize as you desire. If you do, the formulas will not work. Let's break down the standard attack formula:
Code:
a.atk * 4 - b.def * 2
复制代码
"a" symbolizes the user, and "b" symbolizes the targets.
Think of the period as an apostrophe + s: 's.
In other words, "The damage dealt is a's attack multiplied by 4, minus b's defense multiplied by 2." Pretty simple.
Say the user's attack is 20, and the enemy's defense is 15. In that case the damage dealt is 20*4-15*2=80-30=50. With a variance of 20, the actual damage will be between 40-60 damage.
It would now be instructive to look at a standard spell: perhaps Water.
Code:
300 + a.mat * 2 - b.mdf * 2
复制代码
mat
复制代码
is "magic attack", and
mdf
复制代码
is "magic defense".
We can interpret the formula this way, "The damage dealt is 300 plus the user's magic attack multiplied by 2, minus the target's magic defense multiplied by 2."
Say the user's MAT is 20, and the enemy's MDF is 15. In that case the damage dealt is 300+(20*2-15*2)=300+(40-30)=300+10=310. With a variance of 20, the actual damage will be between 248-372 damage.
Aura Blade is up next. This skill is slightly more complex:
Code:
a.atk * 4 + a.mat * 3 - b.def - b.mdf
复制代码
The skill description tells us, "Damage is based off user's ATK and MAT."
Translating into English, "The damage dealt equals the user's physical attack multiplied by 4 plus the user's magic attack multiplied by 3, minus the target's physical defense and magic defense."
Say the user's ATK is 25, MAT is 20, and the enemy's DEF is 30, MDF is 15. In that case the damage dealt is (25*4)+(20*3)-(30)-(15)=100+60-30-15=115. With a variance of 20, the actual damage will be between 92-138 damage. That's not very much - this skill is not necessarily good on all enemies.
"Okay, but what are all the parameters for a and b, besides atk, def, mat, and mdf?" Turns out that there are quite a lot of them. You will see that some have an ID number listed. This is important for using buffs in a formula, which I will get to towards the end.
level
复制代码
- current level, for actor only
hp
复制代码
- current HP, NOT max HP
mp
复制代码
- current MP, NOT max MP
tp
复制代码
- current TP
mhp
复制代码
- max HP
ID: 0
mmp
复制代码
- max MP
ID: 1
atk
复制代码
- attack stat
ID: 2
def
复制代码
- defense stat
ID: 3
mat
复制代码
- magic attack stat
ID: 4
mdf
复制代码
- magic defense stat
ID: 5
agi
复制代码
- agility stat
ID: 6
luk
复制代码
- luck stat
ID: 7
All of the following are decimal numbers. 1.0 converts to 100%. 0.5 converts to 50%. Etc. These values are generally not useful in damage formulas, but are certainly available if you want to get more creative.
hit
复制代码
- hit rate
eva
复制代码
- evasion rate
cri
复制代码
- critical rate
cev
复制代码
- critical evasion rate
mev
复制代码
- magic evasion rate
mrf
复制代码
- magic reflection rate
cnt
复制代码
- counter attack rate
hrg
复制代码
- HP regeneration rate
mrg
复制代码
- MP regeneration rate
trg
复制代码
- TP regeneration rate
tgr
复制代码
- target rate
grd
复制代码
- guard effect rate
rec
复制代码
- recovery effect rate
pha
复制代码
- pharmacology
mcr
复制代码
- MP cost rate
tcr
复制代码
- TP charge rate
pdr
复制代码
- physical damage rate
mdr
复制代码
- magical damage rate
fdr
复制代码
- floor damage rate
exr
复制代码
- experience rate
Exercises
Of course, you don't "have" to do these exercises. However, I find that a good way to learn things like this is to actually try and make your own. If you're up to it, why not try creating...
...a defense-ignoring attack?
...a healing spell dependent on the user's magic attack?
...a resurrection spell that restores half the target's health? How about 5% of it? Or exactly 1 point?
...a sword attack that drains life based on the user's attack and magic attack?
...an attack based on the user's attack and defense? How about attack and agility?
Spoiler: Solutions
a.atk * 4
复制代码
a.mat * 10
复制代码
OR
250 + a.mat
复制代码
OR
b.mhp * 0.25 + a.mat
复制代码
, etc.
Under Effects, a separate section from the formula, have the effect Remove State [Death] 100%. As for the formula: HP recover, with
b.mhp / 2
复制代码
for 50%,
b.mhp / 20
复制代码
for 5%, and just
1
复制代码
for 1 health point.
See the end of the States section below for a different solution that utilizes only formulas and no effects.
Set damage type to HP drain. Formula might look like
a.atk * 4 + a.mat * 4 - b.def - b.mdf
复制代码
Something like
a.mat * 4 - b.mdf * 2
复制代码
a.atk * 4 + a.def * 2 - b.def * 2
复制代码
and
a.atk * 4 + a.agi * 2 - b.def * 2
复制代码
None of those exercises included any of the decimal parameters. You generally will not need them. Everything included in the default VX Ace skill list has been covered by everything before this point, and more besides. So at this point we are finished with the basics and can proceed to the more complex formula functions!
Frog Drop: Using Level, Variables, and "If-Else"
In Final Fantasy 9, a minigame exists whereby the player catches frogs. A character has a skill, called "Frog Drop", that increases in power directly dependent on the number of frogs caught and the level of the character, as follows:
Code:
Damage = Quina's level * Number of frogs caught
复制代码
(It is supposed to drop all frogs ever caught onto the target.) This is quite easy to replicate in RM and is instructive for the tutorial, as it will let us examine variables and "if-else". We already learned how to get the character's level:
Code:
a.level
复制代码
In RM, the best way to replicate the frogs caught is via a variable. Variables can actually be used in damage formulas, to great effect! Say Variable 1 is "Frogs caught". Then the damage formula would be:
Code:
a.level * v[1]
复制代码
Quite simple, really. Now, in FF9, if no frogs are caught, the skill deals 1 damage. But as our formula stands, it would deal 0 damage (if v[1] is 0, then we multiply by 0 and get 0). How can we correct this? With an "if-else" statement, we can check to see if frogs have been caught. If not, 1 damage is dealt. Behold the following:
Code:
v[1] > 0 ? a.level * v[1] : 1
复制代码
What does that mean? The syntax is as follows:
Code:
statement ? formula1 : formula2
复制代码
Formula1 is used if statement is true. Formula2 is used otherwise. So what we are doing is saying, "Is Variable 1 greater than (>) 0? If so, then we're using the ordinary frog drop formula. Otherwise, Variable 1 must be 0. If it's 0, we'll just do 1 damage."
>
复制代码
- greater than
<
复制代码
- less than
>=
复制代码
- greater than or equal to
<=
复制代码
- less than or equal to
===
复制代码
- equal to
&&
复制代码
- and
||
复制代码
- or
!==
复制代码
- not equal to
!
复制代码
- not
States and Multiple Lines
By far one of the most powerful and cool things you can do with damage formulas is state checks. Say you have a state, Poison. Maybe an attack deals extra damage if the target is poisoned. In Pokemon, the skill Venoshock does exactly this:
The user drenches the target in a special poisonous liquid. Its power is doubled if the target is poisoned. Click to expand...
We can replicate this in RPG Maker through an if-else statement, using the ternary operator, ?. MV/Z:
Code:
This formula assumes that Poison is state 2. Change 2 accordingly if necessary.
First, we just check to see if the target is poisoned (
b.isStateAffected(2)
复制代码
If the target is poisoned, it deals the normal damage formula, but doubled (
2 * (a.atk * 4 - b.def * 2)
复制代码
).
Otherwise, it just does the normal formula (
a.atk * 4 - b.def * 2
复制代码
).
Here are the rest of the state formulas. Make sure to place either a. or b. before each one.
MV/Z:
isDeathStateAffected()
复制代码
- is the target dead? Returns a boolean (true or false)
VX Ace:
death_state?()
复制代码
MV/Z:
resetStateCounts(ID)
复制代码
- refreshes how long a state will last for the battler. Does not return a value
If trying to replicate Venoshock, you could add this line so that the target not only takes extra damage, the poison is also renewed on them.
VX Ace:
reset_state_count
复制代码
MV/Z:
updateStateTurns()
复制代码
- shortens all states on battler by 1 turn. Does not return a value
VX Ace:
update_state_turns
复制代码
MV/Z:
addState(ID)
复制代码
- adds state. Does not return a value
VX Ace:
add_state(ID)
复制代码
MV/Z:
isStateAddable(ID)
复制代码
- can state be added? Returns a boolean
VX Ace:
state_addable?(ID)
复制代码
MV/Z:
removeState(ID)
复制代码
- remove state. Does not return a value
VX Ace:
remove_state(ID)
复制代码
states.length
复制代码
- checks how many states are on the battler. Returns an integer.
b.states.length * 500
复制代码
would deal 500 damage for each state on the target.
Semicolons are used to separate multiple lines of formula code. Let's revisit our Resurrection spell.
Code:
b.mhp / 2
复制代码
We can change this as follows: MV/Z:
Code:
b.removeState(1); b.mhp / 2
复制代码
VX Ace:
Code:
b.remove_state(1); b.mhp / 2
复制代码
Voila! The target's death state is removed and they are healed to 50% HP. Here, we can remove the death heal effect from the Effects section. This will let us combine everything in the damage formula, which I would argue is better.
Two Important Notes on Extra Lines
If you have multiple lines of formula, only the last line will actually do damage! So if you have the following:
Code:
a.atk * 4 - b.def * 2; a.mat * 4 - b.mdf * 2
复制代码
Only the
a.mat * 4 - b.mdf * 2
复制代码
will be computed as damage. So make sure that any prior lines you have are not damage dealing (in the example with the death state removal, that's fine, since no damage is dealt or healed). In addition, if you want to write something that does not deal damage in a formula, you must also write another line with a 0 in it. What I mean is, you cannot simply write something like
b.removeState(1)
复制代码
and be done. You must also include a 0, like so:
b.removeState(1); 0
复制代码
.
Other Things
HP and MP can be directly controlled with the following formulas, replacing x with the appropriate number or formula:
MV/Z:
gainHp(x)
复制代码
VX Ace:
hp += x
复制代码
MV/Z:
gainMp(x)
复制代码
VX Ace:
mp += x
复制代码
MV/Z:
gainTp(x)
复制代码
VX Ace:
tp += x
复制代码
MV/Z:
setHp(x)
复制代码
VX Ace:
change_hp(x)
复制代码
MV/Z:
setMp(x)
复制代码
VX Ace:
change_mp(x)
复制代码
MV/Z:
setTp(x)
复制代码
VX Ace:
change_tp(x)
复制代码
MV/Z:
clearTp()
复制代码
VX Ace:
clear_tp
复制代码
To obtain a random number, you can use three different functions:
MV/Z:
Math.random()
复制代码
- returns a random number between 0 and 1
VX Ace:
rand
复制代码
MV/Z:
Math.floor(Math.random()*max)+min
复制代码
- returns a random number between min and max
MV/Z:
Math.randomInt(max)+min
复制代码
- returns a random number between min and max
There may come a time when you want a skill to have different effects depending on whether the user/target is an actor or an enemy. In these cases you can use
isActor()
复制代码
and
isEnemy()
复制代码
(with an a. or b. before each). They return booleans (true-false) and can be used in if-else statements.
VX Ace:
is_actor()
复制代码
and
is_enemy()
复制代码
Buffs and debuffs can be controlled via formulas. Each stat has a specific parameter ID. I listed those earlier in this guide. Be sure to include a damage line at the end if you use these, even if it is just a 0!
addBuff(ID, turns)
复制代码
VX Ace:
add_buff(ID, turns)
复制代码
addDebuff(ID, turns)
复制代码
VX Ace:
add_debuff(ID, turns)
复制代码
removeBuff(ID)
复制代码
VX Ace:
remove_buff(ID, turns)
复制代码
removeDebuff(ID)
复制代码
VX Ace:
remove_buff(ID, turns)
复制代码
removeAllBuffs()
复制代码
VX Ace:
clear_buffs
复制代码
You can also use the function
consumeItem($dataItems[ID])
复制代码
to make a skill force the target to use an item. A skill might force the target to consume a potion, for example. Be sure to include a damage line.
VX Ace:
consume_item(ID)
复制代码
Conclusion
That's all the basics you need to know. For help with specific skills, feel free to ask in this thread. I'll respond when I have time, and other helpful community members probably can too . Also, if you see any errors in the the post, please call me out on them so I can correct them.