Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Enemy Leveling Script

This script is used to simulate the effect of enemy levels. It does not provide enemies with an actual level; it operates on a per stat basis and generates values using weighted averages of the current party's stats. Since this function will not always be desired as is, I have provided five different modes in which this script may operate on a given enemy, they, as well as usage details and other such, will be provided below.

Script

[rgss]<span style="color:#000080; font-style:italic;">=begin
<span style="color:#000080; font-style:italic;">==============================================================================
<span style="color:#000080; font-style:italic;">Title: Enemy Leveling Script
<span style="color:#000080; font-style:italic;">Author: Phoenixia
<span style="color:#000080; font-style:italic;">Date: 07172011
<span style="color:#000080; font-style:italic;">==============================================================================
<span style="color:#000080; font-style:italic;">This script simulates enemy levels by using a system of weighted averages based
<span style="color:#000080; font-style:italic;">off of the current party's stats. It adds to classes Game_Party, Game_Troop, and
<span style="color:#000080; font-style:italic;">Game_Enemy. In addition, it modifies how the database enemies tab functions by
<span style="color:#000080; font-style:italic;">using the stat values as indicators for weights (Please see the 'stat_adjust'
<span style="color:#000080; font-style:italic;">method in Game_Enemy. It also modifies the enemy abilities box's function
<span style="color:#000080; font-style:italic;">in a minor way by using the switch_condition in the first ability to control this
<span style="color:#000080; font-style:italic;">script's mode, you should not use these switches for anything else. Please see
<span style="color:#000080; font-style:italic;">the thread this script was posted in at Hbgames.org for more information if
<span style="color:#000080; font-style:italic;">you are using this from another source. Enjoy:)
<span style="color:#000080; font-style:italic;">==============================================================================
<span style="color:#000080; font-style:italic;">=end
class Game_Party
   
    #returns a high, middle, and low average of the party's values for the given stat
    def stat_averages(stat)
        values = Array.new(@actors.size) {|id| @actors[id].send(stat)}
        values.sort!
        counter, high, middle, low, divsor, total = 0, 0, 0, 0, 0, values.size
        values.each do |value|
            low += (total - counter) * value
            counter += 1
            divsor += counter
            high += counter * value
            middle += value
        end
        high = (3 * high) / 2
        low = (3 * low) / 4
        return low / divsor, middle / total, high / divsor
    end
end
 
class Game_Troop
   
    #Adjusts each enemies stats using the 'stat_adjust' method in Game_Enemy
    def apply_leveling
        ['maxhp', 'maxsp', 'str', 'dex', 'agi', 'int', 'atk', 'pdef', 'mdef'].each do |stat|
            averages = $game_party.stat_averages(stat)
            @enemies.each {|enemy| enemy.stat_adjust(averages, stat)}
        end
        @enemies.each {|enemy| enemy.reset_points}  #ensures that enemy hp/sp is set to its new max values
    end
 
    alias :eek:ldsetupdlo :setup
    def setup
        oldsetupdlo
        apply_leveling
    end
end
           
class Game_Enemy
   
    #Adjust enemy's stat using mode and values from the editor database
    def stat_adjust(averages, stat)
        case (mode = self.actions[0].condition_switch_id)
        when 86 #Bypass
            return
        when 87 #MixedBypass
            return if $data_enemies[1 + @enemy_id].name.include?(stat)
        when 88 #BlendBypass
            return if $data_enemies[1 + @enemy_id].name.include?(stat)
            mode = 89   #Blend
        end
       
        value = send(stat)
        high_weight = value % 10
        middle_weight = ((value % 100) - high_weight) / 10
        low_weight = value / 100
        total_weight = high_weight + middle_weight + low_weight
        new_value = averages[0] * low_weight + averages[1] * middle_weight + averages[2] * high_weight
        new_value /= total_weight
       
        if mode == 89    #Blend
            page2 = $data_enemies[1 + @enemy_id]
            new_value *= page2.gold
            new_value += page2.send(stat) * (100 - page2.gold)
            new_value /= 100
        end
       
        send(stat << '=', new_value)
    end
   
    def reset_points
        @hp, @sp = maxhp, maxsp
    end
 
    def atk=(val)
        @base_atk = val
    end
   
    def pdef=(val)
        @base_pdef = val
    end
   
    def mdef=(val)
        @base_mdef = val
    end
 
    alias :eek:ldbase_atkdlo :base_atk
    def base_atk
        return @base_atk if @base_atk
        return $data_enemies[@enemy_id].atk
    end
   
    alias :eek:ldbase_pdefdlo :base_pdef
    def base_pder
        return @base_pdef if @base_pdef
        return $data_enemies[@enemy_id].pdef
    end
   
    alias :eek:ldbase_mdefdlo :base_mdef
    def base_mdef
        return @base_mdef if @base_mdef
        return $data_enemies[@enemy_id].mdef
    end
end
[/rgss]

Basic Premise

The following explains the basic calculation, by the current formula, for a given enemy in the normal mode of the script; Each stat is handled individually and is assigned a set of weights (high, middle, and low) via the database.

1.) Three averages are calculated using the party's values in the given stat. These averages are named high, middle, and low. The high average is calculated by applying a weight equal to the number of party members to the highest ranking member in that given stat then moves downwards, decreasing the weight by 1 for each step. After this is calculated, the average is multiplied by 3 / 2. The low value is calculated using the same principle, except that the weights begin at 1 and count upwards by 1 at each step, and the end result is multiplied by 3 / 4. The middle average is the normal average with all weights being equal.

2.) The database for the enemy's stat is read and gives a three digit number: xyz, Each digit(0-9) is the value of a weight. The weights, again, are high, middle, and low with the x digit giving the low value, the y digit giving the middle value, and the z digit giving the high value.

3.) A second average is calculated using the new weights applied to the corresponding value from the party average; so the high weight from the z digit is used with the high value from the party average. The enemy's value in the given stat is then set to this final value.

Example of Normal Mode Calculation

Suppose we have a party with str values 30, 80, and 40 and that the enemy we are looking at has an str score of 114.

1.) We take 30 + 80 + 240 = 350, multiply by 3 / 2 to get 525. then divide by 6 to get a high value of 87.

2.) We take 30 + 40 + 80 = 150, then divide by 3 to get a middle value of 50.

3.) We take 90 + 80 + 80 = 250, multiply by 3 / 4 to get 187, then divide by 6 to get a low value of 36.

4.) The enemy's str stat is broken down into high, middle, and low weights of 4, 1, and 1.

5.) We get the predvided value of 4 * 87 + 50 + 36 = 434. Then, we divide by 6 to get the enemy's actual str value, which is 72.

Modes

For each enemy this script can be applied to them in 1 of 5 different modes. What each mode does is described below, how to set the enemies up in the database is explained in the next section.

Normal Mode: This will perform the calculation method that was just discussed without any alteration to every stat.

Bypass Mode: When applied in this mode, then enemy's stat values will act as they would if this script were not in use. In short, the script will not modify anything about the enemy.

Mixed Bypass Mode: Preselected stats will remain unmodified, while those not selected will be modified using the method described.

Blend Mode: When operating in this mode the user will have setup the enemy to have a base set of stat values and a blend rate. The actual, in game, stat values for the enemy will be given as an blending of these base values with the modified values computed by the script. For example: if we gave the enemy used in the above example section a blend rate of 20% and a base str of 100, then the in game stat for the enemy would be (20 * 72 + 80 * 100) / 100 = 94.

Blend Bypass Mode: Preselcted stats are skipped and remain unmodified by the script. Those stats not selected will be modified using the blend method and require the specification of additional data, as with the blend method above.

How to Setup Each Mode

If you are not going to process an enemy using the normal mode, then you must make the first action in that enemy's ability box set with a condition switch of 86 to 89, which mode will be used is indicated by the switch; this action shuold be considered empty and not used to contain an actual action the enemy might use in game. Here is how each of the modes is used:

Bypass: Set the switch condition to 86, the enemy will then be unmodified.

Mixed Bypass: Set the switch condition to 87. When processing, the name of the next enemy in the database will be checked for the stat name, if it is found, then that stat will be bypassed. You must sacrifice the next enemy slot in the database to use this. Example: if you want to bypass the maxhp stat, add maxhp to the name of the next enemy in the database.

Blend: Set the switch condition to 89. The next enemy in the database will have its stats used for the base values, this second slot's gold value will be used for the blend rate, this value should be between 0 and 100. The blend rate specifies the % of the modified version to be used not the base value to be used; so, higher blend rates give greater weights to the base stats.

Blend Bypass: Set the switch condition to 88. The base rates should be setup exactly as in the blend mode. The stats to be bypassed should be setup in the name as in the mixed bypass mode.

A Few Points On Each Mode's Purpose

Normal: Simulates enemy levels using the methods detailed above.

Bypass: This mode should be used for enemies, like bosses, that have a fixed set of stats and are in no way variant on the party's stats or level.

Mixed Bypass: This mode should be used for situations where certain stats need to be preset. For example, if you wanted an enemy that had a set ammount of sp so you could weigh ahead of time how many times it could use each ability. Or, if you wanted a boss who had a fixed number of hp, but would have its attack rates set off of the party's.

Blend: This mode can be used to ensure the player is still rewarded for leveling up since it can make enemies grow stronger with the party, but at a diminshing rate. For example, if you had a blend rate of 50, then 50% of the enemy's stats would be the base stats, which are fixed. Hence, as the party levels up and the base stats become less threatining, the enemy will still have 50% of its stats gotten from them, thus, the enemy will have gotten stronger, but not at a rate proportionate to the party. The reason this should be used over bypass for common enemies is because the bypass mode does not vary the enemies by party, however, when using blend, the stat portion calculated by averages will vary per party; hence, enemy's still have a statistical basis and the player is still rewarded for leveling.

Blend Bypass: This mode should be used for reasons given in both Blend and Mixed Bypass.

Notes

1.) A db entry with less than 3 digits will act as if you had added digits to the front. So 4 is really 004

2.) For maxhp and maxsp the database provides four digits, this script will not raise any type of error, however, it will greatly overbalance the low side of the average.

3.) When using the Bypasses for maxhp and maxsp, be sure to type the "max", "hp" alone will not do anything.

4.) The default values I used will probably not give stats that will work for your specific needs, they are more of an example.

5.) I considered raising errors when the next enemy in the db is not setup for the correct mode, if the blend rate was not in the correct range, or if you used 4 digits for weights in maxhp or maxsp; however, since these errors will not destroy the game, just make the battles poor, I did not do so. At any rate, be cautious of them. Please pm if you think this would be a good addition and I will add it.

License

If you want to use this, give me credit somewhere; or not if you don't want too, I don't care that much...just leave my intro on the script in full:) If you are using this, for some reason, in something commercial, that's fine too:)
 
Hmm, I've been looking for a good enemy leveling script for a while. I'll take a look at this in the morning and test it. :3
Does this include gold as well? Btw, would this work with CBS scripts? I'm using Atoa's Tankentai btw

Some things to ask for:

*Could you provide a feature to change an enemy's (using the ID of course) treasure and probability if their level is =, >, <, >=, or <= to value n, please? (and maybe, if you have steal script or if you could make one; do the same for stealing items/weapons/armor)
*A list, where if a certain enemy ID (useful for special enemies or bosses) is put into the list; they are given a level cap. The level of an enemy could be in theory figured out by dividing their stats together, taking the average number from their stats (weighted) or something else, I'm not very good with scripting.
*Add/remove skills from enemy ID n if their level (again, you could find a way to calculate an enemy's level in theory) is =, >, <, >=, or <= to value n
*Add a list where a map ID can be added, and if a map ID's value is in that list; the map's encounters (via evented encounters or in engine via random encounters) are exempt to auto-leveling, and can be set to: A specific level, or stay the same.
 
Thank you for your response:) Right now my script is in a fairly rudimentary phase, I was hoping to get some feedback to what people would want before I added a bunch of features in. I may make a stealing script, though I will include it in a different topic. I'm not sure abuot CBS's, I've never used any, but this script does nothing (at the moment) except generate enemy stats from database entries and party entries; so, if you are using enemies from the database and not using those entries for something else, it should work as intended (please let me know if there are any issues.)

For anyone looking at this topic, please give me some feedback on the below:

1.) Right now it just includes a basic method that modifies stats based off of the parties, the only cool thing is that everything can be done from the database and that it works on a per stat basis; and you don't have to set up enemies to have a curve governing how their stats level. Thus, it does not currently modify gold, experience, or treasure. However, I will add these to the next version (I will begin working on it this sunday)

2.) This version does not modify abilities, though I do plan on adding it. I have a few questions though:

  • a.) Would you want abilities to be linked in the sense of, say, Fire 1 -> Fire 2 and if an enemy has
    Fire 1 at low levels, it will have Fire 2 at higher ones?

    b.) Or would you like to set up individual ability sets per enemy?

    c.) Or would you like some middle ground; perhaps, abilities belong to classes of abilities and have a level in
    that class, then, the enemies could have individually governed levels in ability classes that would
    determine what abilities that have?

3.) How would you like to see treasure dealt with? Would individual items have a level? Or would you like to assign a set of treasures to an enemy, which the enemy has depending on level? Or, perhaps better, we could have classes of treasures, these classes have levels; the enemy is assigned treasure classes and, then, these plus the level will generate a random treasure?

4.) Back to skills: would you like to see the skills variable to some extent of fixed? Basically, should all level 42 Slimes have the same skills, or should there be some probability determining what they have?

5.) I will add the map id option to the next script.

6.) The current system does not use actual levels, though, you are right that a level can theoretically be calculated using the party's leveling curves, per stat. However, rather than using this, what do you think about enemies that have levels, then using the party at that level as a base to calculate stats in the above sense. For example, if you encountered a level 42 slime, it would use your stats at level 42 to get it's stats? Of course, my objection here is that the current script accomodates variance in the party's levels. In short, I will work out something that 'rates' an enemy per stat, though, I'm not sure the exact relation it will have to actor levels. Please share your thoughts.

7.) Should the ammount of experience/gold/treasure/etc. you recieve be dependent upon the threat the enemy poses on you? For example, if you fight an enemy that you easily outclass, should you recieve less for it? I think it is possible to come up with some sort of threat rating system; however, this rating may require using the default system; perhaps it can be optional. Or, perhaps, the computer can track the battle and determine the enemy's efficacy that way, then deliver rewards based upon the outcome (though, this may let the player cheat by selecting bad moves...) Thoughts?

8.) Right now you can give an enemy fixed stats using the bypass mode or, fairly fixed stats, using the blending mode. Supposing that you needed a level cap, specifically, would it suffice supply a maxlevel, then allocate levels around the party on which to base stats off of? For example, if the level cap is 20 and you have four party members at levels 4, 5, 6, 7, then it would use the party's stats as if they were level 4, 5, 6, 6? Or would you rather have a cap for what the max party member level could be? Say if we had the previous party with 4, 5, 6, 7 and the enemy had a cap of 5, it would, then, use 4, 5, 5, 5 for the levels to compute with? Finally, how should we factor in things like weapons and armour that effect atk and pdef, yet are not directly level based?
 
Thank you for your response! Anyhow:

1: It might be wise to include exp with a quick edit. It wouldn't make sense if enemies grew with the party and didn't give higher EXP as a result.
2: C sounds good to me, it's good for balancing between the two choice and would be good for people who like having organization.
3: I'm actually not very sure about three.
4: Not sure about four either. Having some probability in determining might be useful, however.
6. Yes, variance is problem in any aspect of dealing with numbers and calculations; especially if are multiple random factors to infleunce the outcome.

On a side-note, all of my suggestions came from FFVIII, which is the only game I can think of using this system.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top