• Do not use Discord to host any images you post, these links expire quickly! You can learn how to add images to your posts here.
Resource icon

Resource Automatic Level Scaling 1.5.1

DeepBlue PacificWaves

Producer of Project Lunastone | Failed Dreamer
Member
Joined
Aug 22, 2020
Posts
133
I'm sorry if this was already asked before, but it's possible to cheese using this system in any shape or form? I mean, from a progression perspective, each new level the player's Pokémon's team gains will prevent this, but what if a player receive a an egg, which will hatch the Pokémon at the level 1.

In this, what would happen if the player's team consists only of a 1 level Pokémon and a 50 level Pokémon? If I'm not mistaken, the average would fall around the 24-26 benchmark, right?

If so, there's a way to prevent this?

I might be over thinking this, or I didn't still understood how the script works, but I found it fascinating and I want to use it for my project, but I have to think of the player's experience, and how players can potentially break the games logic (Mario Maker 2 taught me that)

Also, I really didn't understand how proportionalScaling works. Could you give me a practical example, pretty please?
 

grogro

Cooltrainer
Member
Joined
Mar 6, 2021
Posts
120
Every automatic system has its drawbacks. The way it works actually is that it takes the mean of your levels, with a small modificator. So yeah, you can cheese it with low level pokemons. You could say, yes, let's base it on the highest level in your team! But in this case, if the player only level up one pokémon in the early game, they can't catch up with the others so it's not perfect either. I'm personally going for a scaling depending on your badge number, but everything is up to you.

Proportional scaling makes it so your ace will be the highest level for example, even after the random modificator applied to its level.
 

Benitex

Trainer
Member
Joined
Nov 7, 2020
Posts
77
I'm sorry if this was already asked before, but it's possible to cheese using this system in any shape or form? I mean, from a progression perspective, each new level the player's Pokémon's team gains will prevent this, but what if a player receive a an egg, which will hatch the Pokémon at the level 1.

In this, what would happen if the player's team consists only of a 1 level Pokémon and a 50 level Pokémon? If I'm not mistaken, the average would fall around the 24-26 benchmark, right?

If so, there's a way to prevent this?

I might be over thinking this, or I didn't still understood how the script works, but I found it fascinating and I want to use it for my project, but I have to think of the player's experience, and how players can potentially break the games logic (Mario Maker 2 taught me that)

Also, I really didn't understand how proportionalScaling works. Could you give me a practical example, pretty please?
Hey, I love your gen V resources! I appreciate your interest in my plugin.

As @grogro said, there's only a modification that comes with pbBalancedLevel from Essentials by default, which should fix most problems related to this, but I didn't personally experiment too much with it, it seems to fix the problem at first glance. In my game, I prefer to always give the player a pokemon at the current party level using AutomaticLevelScaling.getScaledLevel to avoid this kind of issue, it wouldn't work with eggs though.

Another possible issue is if the player changes their party to lower-leveled pokemon at the "final boss", for example, which would make it much weaker and the battle will probably happen in a much different way than originally planned. In the near future, I think I'll probably add a setting to make it so the party level is stored after each battle and pokemon will not scale to levels lower than the level defined. The main drawback of this is that it would be much harder to change parties during a playthrough.

There probably are many other ways to cheese the system, and you can try to fix some of them, but many others will end up popping out. Because of this, I believe if players want to play the game in a cheesy way, I should just let them enjoy the game however they want. In my experience, most players will try to play the game "honestly" even after knowing about those options. If the project you're planning is very battle-focused, maybe you should try to experiment with level caps, or depending on the badge number like grogro said.

Good luck with your project! Please send any other questions you may have!
 

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
674
Well, you added the configuration option of "only scale if higher" and "only scale if lower". You can have the "only scale if higher" active and temporarily deactivate it on wild battles so you can't have an "easy battle" against the final boss or something like that while letting wild pokemon adjust to the actual player's team and allow them to train with wild pokemon.

I, for example, have this:
1698178498635.png

1698178520962.png

1698178564694.png

The pbNoPreEvo and pbSpecialWildEvolutions are extra code I made for the wild pokemon that evolve and devolve (is that how it's said?) to seem coherent (and for some regional pokemon or with ramified evolutions to actually evolve as they should).
 

DeepBlue PacificWaves

Producer of Project Lunastone | Failed Dreamer
Member
Joined
Aug 22, 2020
Posts
133
Hey, I love your gen V resources! I appreciate your interest in my plugin.

As @grogro said, there's only a modification that comes with pbBalancedLevel from Essentials by default, which should fix most problems related to this, but I didn't personally experiment too much with it, it seems to fix the problem at first glance. In my game, I prefer to always give the player a pokemon at the current party level using AutomaticLevelScaling.getScaledLevel to avoid this kind of issue, it wouldn't work with eggs though.

Another possible issue is if the player changes their party to lower-leveled pokemon at the "final boss", for example, which would make it much weaker and the battle will probably happen in a much different way than originally planned. In the near future, I think I'll probably add a setting to make it so the party level is stored after each battle and pokemon will not scale to levels lower than the level defined. The main drawback of this is that it would be much harder to change parties during a playthrough.

There probably are many other ways to cheese the system, and you can try to fix some of them, but many others will end up popping out. Because of this, I believe if players want to play the game in a cheesy way, I should just let them enjoy the game however they want. In my experience, most players will try to play the game "honestly" even after knowing about those options. If the project you're planning is very battle-focused, maybe you should try to experiment with level caps, or depending on the badge number like grogro said.

Good luck with your project! Please send any other questions you may have!
I think it's a far point. My project is all about giving players choices, why wouldn't I gave them the choice to cheese it? I mean, Zelda did it and look at it with did to the franchise. I gave us a wild breath of fresh air
Well, you added the configuration option of "only scale if higher" and "only scale if lower". You can have the "only scale if higher" active and temporarily deactivate it on wild battles so you can't have an "easy battle" against the final boss or something like that while letting wild pokemon adjust to the actual player's team and allow them to train with wild pokemon.

I, for example, have this:
View attachment 22213
View attachment 22214
View attachment 22215
The pbNoPreEvo and pbSpecialWildEvolutions are extra code I made for the wild pokemon that evolve and devolve (is that how it's said?) to seem coherent (and for some regional pokemon or with ramified evolutions to actually evolve as they should).
It honestly looks great. I gotta give a try when I come home. But right now, I'm more focused on making a demake Gen II style. Those hardcore mechanics can wait awhile
 

swampus

Rookie
Member
Joined
Oct 16, 2023
Posts
5
Not sure if this is a known issue or if I've made a mistake, but I set up an exclusion to scaling in a trainer event and it seems that only their first Pokemon abides by the rules. The other Pokemon on their team scale like normal.
 

Attachments

  • image_2023-10-28_145243175.png
    image_2023-10-28_145243175.png
    3 KB · Views: 64
  • image_2023-10-28_145839805.png
    image_2023-10-28_145839805.png
    23.9 KB · Views: 65
  • image_2023-10-28_145904440.png
    image_2023-10-28_145904440.png
    10.5 KB · Views: 64

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
674
Surskit, gible and mienfoo all evolve by levelling up, so the automatic evolution settings have no effect on them.
 

swampus

Rookie
Member
Joined
Oct 16, 2023
Posts
5
Surskit, gible and mienfoo all evolve by levelling up, so the automatic evolution settings have no effect on them.
Thanks for the response, I thought that just meant the script wouldn't evolve them. Is there an exception for the script to basically scale only the level of the Pokemon and not change their state of evolution or moveset? The movesets are still different from what is defined in the trainer pbs for every Pokemon except Growlithe. I tested this on another trainer as well and had the same result, only the first Pokemon was using the moveset I had set for it.
 

swampus

Rookie
Member
Joined
Oct 16, 2023
Posts
5
Thanks for the response, I thought that just meant the script wouldn't evolve them. Is there an exception for the script to basically scale only the level of the Pokemon and not change their state of evolution or moveset? The movesets are still different from what is defined in the trainer pbs for every Pokemon except Growlithe. I tested this on another trainer as well and had the same result, only the first Pokemon was using the moveset I had set for it.
Sorry for the double post but, I found the solution to my problem. For every Pokemon of a given party, it calls the setNewLevel method, but the setNewLevel method resets the temporary settings at the end of it, meaning only the first Pokemon of any given party is affected by the temporary settings. I did the following to fix it:
Cut lines 68-81
def self.resetSettings()# Settings reset
if @@settings[:temporary]@@settings = {
temporary: false,
automatic_evolutions: LevelScalingSettings::AUTOMATIC_EVOLUTIONS,
include_previous_stages: LevelScalingSettings::INCLUDE_PREVIOUS_STAGES,
first_evolution_level: LevelScalingSettings::DEFAULT_FIRST_EVOLUTION_LEVEL,
second_evolution_level: LevelScalingSettings::DEFAULT_SECOND_EVOLUTION_LEVEL,
first_evolution_level_other: LevelScalingSettings::DEFAULT_FIRST_EVOLUTION_LEVEL_OTHER,
proportional_scaling: LevelScalingSettings::PROPORTIONAL_SCALING,
only_scale_if_higher: LevelScalingSettings::ONLY_SCALE_IF_HIGHER,
only_scale_if_lower: LevelScalingSettings::ONLY_SCALE_IF_LOWER,
update_moves: true}
end
end

Then added AutomaticLevelScaling.resetSettings() to line 37 in EventHandlers. After those changes all Pokemon are effected by temporary settings and the temporary settings are reset after the battle. At least from my testing it didn't work properly before.
 

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
674
Or, you know, you could have defined the temporal settings in the loop for every pokemon on the trainer's party. Something like that:
Ruby:
Expand Collapse Copy
# Activates script when a trainer pokemon is created
EventHandlers.add(:on_trainer_load, :automatic_level_scaling,
  proc { |trainer|
    id = pbGet(LevelScalingSettings::TRAINER_VARIABLE)
    if trainer && id != 0
      AutomaticLevelScaling.setDifficulty(id)
      avarage_level = 0
      trainer.party.each { |pokemon| avarage_level += pokemon.level }
      avarage_level /= trainer.party.length

      for pokemon in trainer.party do
        if $game_switches[1]
          AutomaticLevelScaling.setTemporarySetting("updateMoves", false)
          AutomaticLevelScaling.setTemporarySetting("automaticEvolutions", false)
        end
        AutomaticLevelScaling.setNewLevel(pokemon, pokemon.level - avarage_level)
      end
    end
  }
)
Haven't tested but this should activate the temporary settings to not update moves and not evolve pokemon for any pokemon in the trainer's team for as long as the conditions are met (in this case, game switch 1 being on). And since I'm using the "setTemporarySetting" instead of "setSettings", they will only last until the "setNewLevel" happens.
 

Benitex

Trainer
Member
Joined
Nov 7, 2020
Posts
77
Sorry for the double post but, I found the solution to my problem. For every Pokemon of a given party, it calls the setNewLevel method, but the setNewLevel method resets the temporary settings at the end of it, meaning only the first Pokemon of any given party is affected by the temporary settings. I did the following to fix it:
Cut lines 68-81
def self.resetSettings()# Settings reset
if @@settings[:temporary]@@settings = {
temporary: false,
automatic_evolutions: LevelScalingSettings::AUTOMATIC_EVOLUTIONS,
include_previous_stages: LevelScalingSettings::INCLUDE_PREVIOUS_STAGES,
first_evolution_level: LevelScalingSettings::DEFAULT_FIRST_EVOLUTION_LEVEL,
second_evolution_level: LevelScalingSettings::DEFAULT_SECOND_EVOLUTION_LEVEL,
first_evolution_level_other: LevelScalingSettings::DEFAULT_FIRST_EVOLUTION_LEVEL_OTHER,
proportional_scaling: LevelScalingSettings::PROPORTIONAL_SCALING,
only_scale_if_higher: LevelScalingSettings::ONLY_SCALE_IF_HIGHER,
only_scale_if_lower: LevelScalingSettings::ONLY_SCALE_IF_LOWER,
update_moves: true}
end
end

Then added AutomaticLevelScaling.resetSettings() to line 37 in EventHandlers. After those changes all Pokemon are effected by temporary settings and the temporary settings are reset after the battle. At least from my testing it didn't work properly before.
Thank you for the bug report and the solution suggestion, I'll post an update with fixing it soon.
 

drdoom76

Cooltrainer
Member
Joined
Aug 1, 2023
Posts
212
To the cheese thing, I ended up modifying it to ignore pokemon >4 levels lower or higher than the balanced level. A few playthroughs and it seems to be handling well. Opponent is always within 1-2 levels around my pokemon.
I ran into this issue when adding random eggs as itemballs. Half the team was level 5 and the game was a joke.
You should also be able to balance the egg level, too, if you wish. I've got mine balanced and maxed at lvl 98 (to allow for evolutions).
 

OkunoShio

Cooltrainer
Member
Joined
Oct 22, 2022
Posts
129
Also adding to the "cheese" topic: a friend of mine was really pushing one of his Pokémon hard, resulting in enemy teams being waaay lower level than his highest level Pokémon (and of course, way higher than his remaining team, which could lead to him getting stuck once his "ace" gets hardcountered). However, to avoid this issue, my personal solution was to modify the following section in "003_Script" (see "#custom" block):

Ruby:
Expand Collapse Copy
  def self.getScaledLevel
    level = pbBalancedLevel($player.party) - 2 # pbBalancedLevel increses level by 2 to challenge the player

    # Difficulty modifiers
    level += @@selectedDifficulty.fixed_increase
    if @@selectedDifficulty.random_increase < 0
      level += rand(@@selectedDifficulty.random_increase..0)
    elsif @@selectedDifficulty.random_increase > 0
      level += rand(@@selectedDifficulty.random_increase)
    end

    #custom
    partymaxlevel = $player.party[0].level
    for i in 0...$player.party.length
        partymaxlevel = $player.party[i].level if partymaxlevel < $player.party[i].level
    end
    if @@selectedDifficulty.id == 1
        level = [level, partymaxlevel-5].max
    elsif @@selectedDifficulty.id == 2
        level = [level, partymaxlevel-3].max
    elsif @@selectedDifficulty.id == 3
        level = [level, partymaxlevel-1].max
    end
    #custom end
    level = level.clamp(1, GameData::GrowthRate.max_level)

    return level
  end

I have two difficulty settings in place (difficulty.id 1 is for wild encounters only), and based on the chosen difficulty, the scaled level will be modified to a minimum in reference to the highest level Pokémon in your party.
Of course - as it was stated before - with such a system, there are always tons of ways to cheese, and at the same time tons of opinions on if or how this needs to be caught by your system. I think in the end it comes down to preference, and - as Benitex was also stating - I also think it can be perfectly fine to allow the player to cheese the system if they are smart about it, Scarlet and Violet basically lets you do this, the new Zelda games let you do this, so I think there is basically nothing wrong about it.
 

DeepBlue PacificWaves

Producer of Project Lunastone | Failed Dreamer
Member
Joined
Aug 22, 2020
Posts
133
Also adding to the "cheese" topic: a friend of mine was really pushing one of his Pokémon hard, resulting in enemy teams being waaay lower level than his highest level Pokémon (and of course, way higher than his remaining team, which could lead to him getting stuck once his "ace" gets hardcountered). However, to avoid this issue, my personal solution was to modify the following section in "003_Script" (see "#custom" block):

Ruby:
Expand Collapse Copy
  def self.getScaledLevel
    level = pbBalancedLevel($player.party) - 2 # pbBalancedLevel increses level by 2 to challenge the player

    # Difficulty modifiers
    level += @@selectedDifficulty.fixed_increase
    if @@selectedDifficulty.random_increase < 0
      level += rand(@@selectedDifficulty.random_increase..0)
    elsif @@selectedDifficulty.random_increase > 0
      level += rand(@@selectedDifficulty.random_increase)
    end

    #custom
    partymaxlevel = $player.party[0].level
    for i in 0...$player.party.length
        partymaxlevel = $player.party[i].level if partymaxlevel < $player.party[i].level
    end
    if @@selectedDifficulty.id == 1
        level = [level, partymaxlevel-5].max
    elsif @@selectedDifficulty.id == 2
        level = [level, partymaxlevel-3].max
    elsif @@selectedDifficulty.id == 3
        level = [level, partymaxlevel-1].max
    end
    #custom end
    level = level.clamp(1, GameData::GrowthRate.max_level)

    return level
  end

I have two difficulty settings in place (difficulty.id 1 is for wild encounters only), and based on the chosen difficulty, the scaled level will be modified to a minimum in reference to the highest level Pokémon in your party.
Of course - as it was stated before - with such a system, there are always tons of ways to cheese, and at the same time tons of opinions on if or how this needs to be caught by your system. I think in the end it comes down to preference, and - as Benitex was also stating - I also think it can be perfectly fine to allow the player to cheese the system if they are smart about it, Scarlet and Violet basically lets you do this, the new Zelda games let you do this, so I think there is basically nothing wrong about it.
This is a neat workaround, though I agree, the "let the player play the way he intend" point is growing on me (it's a good argument after). My only concern is to make something so potentially open that the player might break the game. Sometimes, this can have good results, like the missigno, mew glitchs in generation 1 or the bomb surfing on Zelda BOTW (which was incorporated into TOTK). However, we can't deny it wouldn't be fun to have a chess which limits the players or even completely broke the game. Your friend, for example. He can easily become trapped in a cycle where his only usable Pokémon is his ace, since he would have to make a choice of using him, and only using him or not using him in his party at all.

I feel like this is a high reward, high risk choice which could very easil ly the playthrough not as enjoyable as intended, ya know?

I think having a celling and a floor level options would potentially prevent this. Imagine, some Pokémon can't get any higher than this level, nor lower than that one.

However, I'm totally illiterate when it comes to script, so I have no freaking idea how to even to start considering if this is a good solution or not, let alone if this is conviable.
 

SwoLe93

Rookie
Member
Joined
Nov 14, 2023
Posts
4
I need some help! I have 0% knowledge on how scripts work. I downloaded the script, and it shows up when booting the game, but idk how to set up the wild encounter scripts. When I look at my control switches, I don't have anything for variable 099 or 100. Any help is greatly appreciated! Also, are there any good tutorials out for 21.1?
 

Benitex

Trainer
Member
Joined
Nov 7, 2020
Posts
77
I need some help! I have 0% knowledge on how scripts work. I downloaded the script, and it shows up when booting the game, but idk how to set up the wild encounter scripts. When I look at my control switches, I don't have anything for variable 099 or 100. Any help is greatly appreciated! Also, are there any good tutorials out for 21.1?
Variables 099 and 100 are already set up from the get-go, they don't get named automatically, but you can change their values to one of the predefined difficulties IDs and it will activate the script. Also, maybe you are using the Control Switches instead of Control Variables event command, which might be causing the issue. You can set the value to 5 (which is the difficulty with settings from Essentials) and use it until you can understand enough to make your own difficulties (it's not that hard though).

As for tutorials for essentials, I recommend reading the pages of the official wiki, which are very detailed and always updated. There are some text tutorials on this page too, and you can also check out the video tutorials from Thundaga on YouTube, although they are a little bit outdated, I really like the way he explains the most essential stuff. Good luck in your journey, feel free to send me any other questions!
 

Quibbi

Rookie
Member
Joined
Dec 5, 2023
Posts
2
Benitex submitted a new resource:

Automatic Level Scaling - Scale and evolve wild and trainer pokemon levels according to multiple difficulty options.



Read more about this resource...
Hi, I don't know why but the plugin insn't working. It wont appear in the Debug Output window with the other installed plugins that appears when I run the game from the RPGmaker. I have extracted the rar file in the root folder and overwrite the plugin folder, but It doesen't seems to work. Any help?
 

Benitex

Trainer
Member
Joined
Nov 7, 2020
Posts
77
Hi, I don't know why but the plugin insn't working. It wont appear in the Debug Output window with the other installed plugins that appears when I run the game from the RPGmaker. I have extracted the rar file in the root folder and overwrite the plugin folder, but It doesen't seems to work. Any help?
Try holding ctrl after clicking the play button, to make the game compile all files.
 

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
674
The question is, why do you need such event handler? Maybe something can be done to make the little code this plugin has for partners fit your needs.
 
Back
Top