Battle Action Exp

In RPG Maker, actors can receive exp by defeating enemies in battle. When all enemies are defeated, the victory processing will occur, and actors will receive exp from the battle.

However, this means that if you were to escape before the battle was over, your actors would not receive any exp even if they defeated some enemies.

This plugin changes the way exp is obtained. Instead of only on battle end, exp is received whenever you perform an action.

For example, if an actor attacks an enemy, exp calculation will occur and if the actor earns exp from that attack, the actor will receive that exp
immediately, and potentially level up on the spot.

Action exp can also be obtained outside of battle, depending on the rules you have set up for your exp calculations.

With this plugin, actors will be rewarded immediately for their actions, which provides you with some additional mechanics that you can use.

Download

Plugin: download here (right-click, save as)

Addons

  • Battle Exp Popup – example plugin showing how you can display exp gained in battle.

Patches

  • Patch for Yanfly Victory Aftermath. The exp gained screen will display how much exp was gained in battle. However, the victory aftermath plugin disables level up messages during battle.

Installation

Download the plugin and place it in the “plugins” folder in your project’s “js” folder. Then open your Plugin Manager (F10), double-click an empty row, and select the HIME_BattleActionExp plugin.

Once it is in your list of plugins, turn the plugin on.

Usage

Global Action Exp Formula

The global formula is used whenever action exp calculations are required and applies to all actions, regardless whether it’s an actor or an enemy. It is defined in the plugin parameters:

battleActionExp2

The following formula variables are available:

a - user of the action
b - target of the action
v - game variables
s - game switches

By default, you only receive EXP when you defeat the enemy. Here is the formula:

b.isEnemy() && b.isDead() ? b.exp() : 0

This means

IF the target of the action is an enemy, and the target is dead,
THEN the amount of EXP gained is equal to the enemy's EXP.
OTHERWISE, no EXP

It also means that if an actor targets another actor, no EXP is gained. It is important to check whether the target is an actor or enemy in certain situations, since certain properties may not exist for all battlers.

Examples

Let’s say that instead of only receiving exp when an enemy is defeated, you wanted to receive exp based on the amount of damage you deal, as a percentage of the enemy’s exp.

That is to say, if the enemy has 100 HP and gives a total of 100 exp, and you deal 20 damage, then you will receive 20% exp from the enemy, or 20 exp.

To accomplish this, you can retrieve the damage dealt from the action result object for the target:

b.result()

From there, you can ask for the HP Damage:

b.result().hpDamage

To get the ratio, you would take that and divide it by the target’s max HP

b.result().hpDamage / b.mhp

Which would give you the percentage of damage that you dealt relative to the target’s total HP.

Finally, you can multiply this percentage with the enemy’s total EXP, to determine the fraction of EXP that the attacker receives:

(b.result().hpDamage / b.mhp) * b.exp()

Again, because only enemy’s have EXP by default, you may need to check if the target is actually an enemy:

b.isEnemy() ? (b.result().hpDamage / b.mhp) * b.exp() : 0

Which means if you target an actor, you receive no exp.

Now, what happens if the amount of damage you deal is greater than the amount of HP the enemy has left? For example, if you deal 200 damage to an enemy with only 100 HP.

Unfortunately, with this plugin alone, you don’t have access to the enemy’s HP BEFORE the action was applied, but if you had such a plugin, and it stored this information in a property called `oldHp` in the action result, you could say this:

b.isEnemy() ? (Math.min(b.result().hpDamage, b.result().oldHp) / b.mhp) * b.exp() : 0

You may also like...

93 Responses

  1. Here is the most current code I am using.

    Math.round(b.isEnemy() ? (b.result().hpDamage / b.mhp) * b.exp() + ((b.level – a.level) * (b.exp() * 0.12)) : 0)

    It rounds exp to a whole number, and if enemy level is higher or lower than character, it adjusts amount of exp given by 20% per level difference.

  2. I made some code for my new in development game combining Himes original code, and some comment section code, its working so I thought I would share it.

    It gives exp per damage of max hp and changes exp amount based upon difference of level of the actor and the enemy (Note you will need to partner this plugin with himes enemy levels plugin for this code to work)

    b.isEnemy() ? (b.result().hpDamage / b.mhp) * b.exp() + ((b.level – a.level) * (b.exp() * 0.15)) : 0

  3. Hime, Is there a way to only display exp gained up to 0.00 im getting like 0.0000000 and its a bit much, can you help?

  4. Sweet says:

    If you use YEP_InstantCast and level during an ‘Instant Cast’ attack the game stalls at that point. You can’t take any further actions or anything. Any thoughts or recommendations?

    Thanks in advance

  5. Crackerwood says:

    Hello. First of all, it’s a great script. The problem is that it doesn’t work well in me. I have troops or when a monster dies another one. So the script doesn’t take into account party b.isdead or it works perfectly. I can’t send a version of my project because I’m not in France, so I’m limited by the Internet. I can just say that I use mostly yanfly scripts. If anybody had an idea. Thank you very much.

  6. Krystal says:

    Okay so the forum is poinltess to ask on at this point so I’m gonna ask on here and pray I get a reply:

    Is there a way to make it so that exp is distributed AFTER combat(at the end) still with this plugin?

    Since I’m not very code savy I’m unsure of how to do this if its even possible and the reason I ask is because there will be instances where I want the actor to gain exp AFTER battle instead of during.

  7. Wonder Spirit says:

    It sometimes gives a long decimal when receiving exp based on damage

  8. RHER says:

    Can it accumulate a ExpWeight (no Exp) during battle and it defines enemy Exp piece in the end?

    Example:

    .

    You & I

    VS

    Dungger

    .

    You attack –> +3 weight

    I heal –> +2 weight

    You attack –> +3 weight

    I attack –> +3 weight

    Dungger dead

    .

    Dungger Exp = 1000

    You: 6/11 –> Exp +545

    I: 5/11 –> Exp +455

  9. ktnh says:

    Hello. Loving the this plugin.

    I used this parameter,,

    b.isEnemy() && b.isDead() ? b.exp() : 0

    But, when you knock down with continuous attack, experience value is obtained many times.
    ex) 1000exp 1000exp 1000exp 1000exp..

    Is there a solution?

    • Hime says:

      Unfortunately, I am not sure how to check for whether a damage is part of the same action, or a different action.
      There may be a situation where someone wants each consecutive hit to count for exp as well.

      It may be necessary to change the exp formula.

  10. resi says:

    I have a huge issue with your plugin and Victory Aftermath.
    Everything is in order as it should, but more often than not there always seems to be a lockup that you really have to wait through before any exp is showed as being earned. It’s really hampering the game and I would really love to use your plugin plus Victory Aftermath but it just doesn’t want to cooperate.

    If you can help, it would be appreciated

  11. Iqus says:

    Hi Hime! This plugin is amazing!

    I was trying to make it a passive effect, so those who have a certain state ON will gain experience per hit but those who doesn’t are not getting experience at all, I tried this but when I access the Status Menu the game cannot process the exp that was gained by the non-affected battlers. Any suggestion as how to do this? This is the code I used:

    a.isStateAffected(8) ? b.isEnemy() ? Math.ceil((Math.min(b.result().hpDamage, b.hp) / b.mhp) * b.exp()) : 0 : b.exp

    • Iqus says:

      After a while I realized that that formula wouldn’t work, I’m trying this one now, but there will be no exp for those who do not have the state for some reason:

      a.isStateAffected(8) ? b.isEnemy() ? Math.ceil((Math.min(b.result().hpDamage, b.hp) / b.mhp) * b.exp()) : 0 : b.isEnemy() && b.isDead() ? b.exp() : 0

      • Hime says:

        Your logic as it is written means

        1. If state 8 is applied, then gain exp if target is an enemy, and 0 otherwise.
        2. If state 8 is not applied, and if target dies, then you gain all of the enemy’s exp

        So basically you want it so that if the state isn’t applied, the actor should gain exp normally when the enemy dies?

  12. Dynelf says:

    Would it be too hard to make an add-on that allows you to play an animation if a character levels up during battle?

  13. Hernan says:

    Hello I really love this and want to say thanks for your work. I have a question, when a pj “miss” the attack, he/she wins exp. ¿How can I turn off the exp for miss?

    • Hime says:

      What is the exp gain based on? You might want to check if damage was dealt. Something like including this condition in the formula:

      b.result().hpDamage > 0

  14. Lucas says:

    It doesn’t work with Yanfly’s Aftermath plugin. Even with the Fix provided. Instead, when I add the fix at the end of both plugins(yanfly’s and this one) it gives me a RangeError: Maximum stack call exceeded.
    Is there someway to fix this?

    • Hime says:

      I just tried it with aftermath and it works fine for me. If you have other plugins installed you’ll need to figure out which one is causing the problem.

      • Lucas says:

        Just to make sure I’m adding it right. I have to add the fix after all the code, right? Even after the closing braces, right?

        I’m using almost all Yanfly’s plugins and some of yours.

        • Hime says:

          The fix isn’t for the range error problem. You should create a new project to see if the two plugins work together.

          • Lucas says:

            Yeah, I know. However, the console says the error is in the Image of the error

            Am I doing anything wrong? The console says the error is in your code. I don’t know why. Even if I disable all my other plugins, it continues to give me this error. I tried to create a new project, I tried to disable everything. I let enabled the core plugins and yours, yet, it continues to give this error every single time.

            So… Either the fix is wrong, or I copy/pasted it wrong or I don’t know. I’m running MV 1.3.1. Everything works fine except when I put your “fix” in both Yanfly’s and yours. I don’t get it. 🙁

          • Hime says:

            Set up the plugin in this project and see if the same error occurs. If it doesn’t, upgrade it to 1.3.1 and then test it again.
            If the error occurs, send it to me and I will take a look.

          • Lucas says:

            I got it to work. I just didn’t add anything to Yanfly’s plugin whatsoever. No error and XP showing up mid-battle and also popping up.

            This was the mistake all along. I added the fix code under both plugins, as it is stated in this website, but it didn’t need to be that way. I only added the fix to your plugin and everything is great.

            Thanks for every help and everything. Really appreciate it.

            Also, one question. My EXP keep showing up like “20.333333333” or “8.6666667” or “0.67748347”.

            Is there a way to show only Integer numbers and not Float ones? It’s really annoying to see so many numbers at once, also the letter become so small due to this many numbers.

            Is there a fix for this?
            Thanks in advance.

          • Lucas says:

            Any advice on that exp float number issue?

          • Hime says:

            Use Math.round( YOUR_FORMULA ) to round the exp off to an integer.

  15. Jeysonmcfly says:

    Is it possible that you could use this plugin to where they gain the XP during the battle by like… killing pawn enemies and then level up and are able to now use a new skill because say… they reached level 20, which was the prerequisite for learning a new skill?

  16. kovak says:

    can’t i make the user get XP by simply perform an action?

  17. Gambitben says:

    If I have a plugin that adds levels to monsters, how could the formula be so if the monster is lvl 3 and the actor lvl 5, X ammount of xp would be substracted?

    Loving the plugin, with that tweak I would use it.

    • Hime says:

      You could for example say something like (assuming level is how you access the level property)
      b.isEnemy() && b.isDead() ? b.exp() + ((b.level - a.level) * (b.exp() * 0.1)) : 0

      Which is basically (EXP + BONUS). The bonus can be positive or negative.
      In our case, we add or subtract 10% depending on their level difference.

      So if enemy was level 3 and actor was level 5, then the difference between enemy and actor is -2. Multiplied by 10% of enemy’s EXP, that means the attacker will gain only 80% of the EXP they would have originally obtained if the level was the same.

      Depending on how complex the calculation is, you might introduce a plugin that will handle level difference calculations for you, and then plug that into the formula.

Leave a Reply to Hime Cancel reply

Your email address will not be published. Required fields are marked *