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.

New Method of Leveling [Solved]

JoshC

Member

Ok, I'm not going to try and name this cause I'm bad at naming things so whoever can do this make a really good name for it too. The idea is that you gain experience in battle like normal, but you don't level up there. Instead you take the experience and go to an npc, and trade that experience for levels or skills.

Reference: Anime - Beet the Vandel Buster, watch the first couple of episodes and you'll understand exactly what I'm talking about. Also I'd like this for RPG Maker XP.
 
sounds like you just need to prevent leveling when EXP goes up. The rest you can do in events.

Paste above Main
Code:
 

class Game_Actor

  #--------------------------------------------------------------------------

  # * Change EXP

  #     exp : new EXP

  #--------------------------------------------------------------------------

  def exp=(exp)

    @exp = [[exp, 9999999].min, 0].max

    # Correction if exceeding current max HP and max SP

    @hp = [@hp, self.maxhp].min

    @sp = [@sp, self.maxsp].min

  end

end

 
 

JoshC

Member

Ok, I have it setup up now, but how should I call it to check if it meets a certain exp amount and then level if it does? Don't suppose conditional branches could be used unless you could store the current amount of exp as a variable and then compare it to base amounts in the branch, but then you'd have to make a hell of a lot of conditional branches.... Wouldn't it be a lot simpler to create a function that can be called from the events menu, that just runs the basic exp vs exp table check and then levels based on that. Now I'm making this sound like a round-about leveling system, but I suppose thats basically what it is to begin with.
 

Tdata

Sponsor

It would be rather simple.

Depending on your Exp Curve all you need to know is each lvl's exp requirements.
Example:
Code:
 

$level_exp = Array.new

$level_exp = [0, 25, 66, 129, 220, 345, 513, 731, 1008, 1354, 1778, 2290, 2902, 3625, 4471, 5453, 

6584, 7877, 9347, 11008, 12875, 14846, 17291, 19873, 22727, 25870, 29320]

$exp = $game_party.actors[0].exp

 

for i in 0...$level_exp

if $exp > $level_exp[i]

next

else

$game_party.actors[0].level = (i+1)

end

end

 
I'm sure there is a way to access @exp_list for each actor, but I'm not going to try right now. In fact I don't know if my way is even close to the best way.
 
Are you saying you want to charge a variable amount for each level? i.e. using a curve or table?

You didn't specify any details in your request, so I assumed it was a simple static amount per level.

And instead of trying to keep track of what the exp was the last time the player visited the npc, why not just
keep track (in a game variable), the total amount that's been spent. then, each time you visit, a simple subtraction (Total EXP - Total Spent) will give you the amount you have to spend this time.
I'm also assuming that you can visit the NPC, and not spend all of your earned EXP.

If you detail the level system, we can make a better recommendation.

Be Well
 
Ok. This will work with the default DBS but any action battle system or anything that doesn't use the $game_temp.in_battle flag will probably cause a conflict.

When you are in battle, exp is transfered to a $game_variable for each actor (you set it up in the script). The rest is up to you to use the game variables with your event system to change the exp and skills.

Code:
 

class Game_Actor

  # Exp_To_Variables = {actor_id => variable_id, actor_id => variable_id, ...}

  Exp_To_Variables = {}

  alias_method :seph_exptovar_gmactr_exp=, :exp=

  def exp=(exp)

    if $game_temp.in_battle

      $game_variables[Exp_To_Variables[@actor_id]] += exp - @exp

    else

      self.seph_exptovar_gmactr_exp=(exp)

    end

  end

end

You just need to setup your Exp_To_Variables constant. If you want actor 1 to use variable 8 and actor 2 to use variable 9, your constant will look like:
Exp_To_Variables = {1=>8, 2=>9}


Let me know how that works.
 
Ugh. Yes it should be. Thanks for covering my tracks for me Brew, as always.


Because you could have @exp = to 500. When you use +=, you may only be adding 100 but it the exp in the method argument is = to @exp + 100. So you have to subtract the original @exp instance to get what you are only adding to the @exp (works with subtracting too).
 
No worries, I got yer '6' :scruff:

Ok, the fact that @exp wasn't getting updated in battle corn-fused me.

In order to level, Josh only needs to TRANSFER exp from the variable to @exp, and since he won't be in battle it will use the aliased method.
The variable will only hold 'unspent' exp.
So, if the player wants to buy a skill with his exp, you just subtract from the variable:

$game_variables[ACTOR_EXP_VARIABLE_ID] -= <cost of skill>

If he wants to apply exp to leveling:

$game_party.actors[0].exp += <amount to apply to leveling>

If he wants to get the amount needed for the next level:

$game_variables[TEMP_VARIABLE] = $game_party.actors[0].next_rest_exp_s.to_i

(or we whip up a next_rest_exp method that returns an integer)

Code:
 

class Game_Actor

  #--------------------------------------------------------------------------

  # * Get Until Next Level EXP as an integer

  #--------------------------------------------------------------------------

  def next_rest_exp

    return @exp_list[@level+1] > 0 ?

      (@exp_list[@level+1] - @exp) : 0

  end

end

 

then use:

$game_variables[TEMP_VARIABLE] = $game_party.actors[0].next_rest_exp
 

JoshC

Member

Sorry, I thought I had covered everything... I'm bad at explanations.... Let me try again:

The idea is you gain exp in battle like normal and it just builds up into a stock pile. Then after battle you go to an npc and the npc asks if you want to spend it on leveling up or on purchasing skills. If you want to level, it determines how many levels you can level up with the total amount exp you've earned, and gives you the option of how many levels you want to increase based on that. If you want to purchase skills it simply subtracts the amount of exp required to learn the skill from the total amount of exp you have. So yes it would still follow the basic exp curve table. Using events or script to track you stock pile of exp is fine either way, I just assumed it to be easier to simply track it with the script and then call a function from the npc to add/subtract from your exp stock pile. But I want it to still show in the menu what the current exp stock pile is, so is there a way to transfer the exp amount to an in-game variable but then transfer it back to exp or something?

And yes please make it compatible with other battle systems aside from the default, I prefer side-views.

There was that better?
 

JoshC

Member

Ok so it's
Code:
class Game_Actor

  #--------------------------------------------------------------------------

  # * Change EXP

  #     exp : new EXP

  #--------------------------------------------------------------------------

  def exp=(exp)

    @exp = [[exp, 9999999].min, 0].max

    # Correction if exceeding current max HP and max SP

    @hp = [@hp, self.maxhp].min

    @sp = [@sp, self.maxsp].min

  end

  

  #--------------------------------------------------------------------------

  # * Exp to Variables

  #     exp => exp variable

  #--------------------------------------------------------------------------

  # Exp_To_Variables = {actor_id => variable_id, actor_id => variable_id, ...}

  Exp_To_Variables = {1=>1,2=>2,3=>3,4=>4,5=>5,6=>6,7=>7,8=>8}

  alias_method :seph_exptovar_gmactr_exp=, :exp=

  def exp=(exp)

    if $game_temp.in_battle

      $game_variables[Exp_To_Variables[@actor_id]] += exp - @exp

    else

      self.seph_exptovar_gmactr_exp=(exp)

    end

  end

end 

 

That basically disables leveling up normally and tracks exp for each character in a default game. And from this I can easily make the npc, but it also disabled the exp update in the status menu. Any way we can make it so it still updates the current exp values to show in menu? Or would I just be better off making a custom menu to show the variable as exp? lol And then I just need a call to check the exp curve table and compare it to the total amount of exp you have to spend (Variable), thus telling you how many levels you can level. Then some way to ask how many levels they want to level up, thus leveling the amount they choose.

As for the skills shop, I guess I can just modify a skill shop demo to accept exp as payment, which I guess I'd have to do anyway if I'm going to ask for requirements to learn skills like a specific class, man I really need to study RGSS....
 

Jason

Awesome Bro

I guess you could just make an event with a character (The person who lets you spend EXP), and everytime you visit them, they say

"You have \v[variable id with exp in] EXP..."

Thats all I can think of anyways, lol.
 

JoshC

Member

Bump, Seph, Brew you still here? Ok, so I've setup the events and script, big problem now though, it wont let me call the level up event. When I have an event initiate a level up it only gives me the exp needed to level it doesn't level up.
 

Zeriab

Sponsor

[rgss]  #--------------------------------------------------------------------------
  # * Change Level
  #     level : new level
  #--------------------------------------------------------------------------
  def level=(level)
    # Check up and down limits
    level = [[level, $data_actors[@actor_id].final_level].min, 1].max
    # Change EXP
    self.exp = @exp_list[level]
  end
[/rgss]
Seems like when you change the level it changes the exp XD.
Just put this little snippet somewhere below your Game_Actor code:

[rgss]class Game_Actor < Game_Battler
  attr_writer   :level                    # level
end
[/rgss]

*hugs*
- Zeriab
 

JoshC

Member

Ok here's the finished product:

Code:
 

#----------------------------------------------------------------------------

#  Beet Style Leveling System

#

#  By: Kyomizero

#

#  Huge Credit to: Brewmeister, SephirothSpawn, & Zeriab from RMXP.ORG

#----------------------------------------------------------------------------

#

#     To apply exp to leveling use:

#   $game_party.actors[0].exp += <amount to apply to leveling>

#     To get the amount of exp needed for the next level use:

#   $game_variables[TEMP_VARIABLE] = $game_party.actors[0].next_rest_exp

#     To alter the amount of exp in the variable use:

#          Add

#   $game_variables[ACTOR_EXP_VARIABLE_ID] += <amount to change>

#          Subtract

#   $game_variables[ACTOR_EXP_VARIABLE_ID] -= <amount to change>

#

#----------------------------------------------------------------------------

 

class Game_Actor

  #--------------------------------------------------------------------------

  # * Change EXP

  #     exp : new EXP

  #--------------------------------------------------------------------------

  def exp=(exp)

    @exp = [[exp, 9999999].min, 0].max

    # Correction if exceeding current max HP and max SP

    @hp = [@hp, self.maxhp].min

    @sp = [@sp, self.maxsp].min

  end

  

  #--------------------------------------------------------------------------

  # * Exp to Variables

  #     exp => exp variable

  #--------------------------------------------------------------------------

  # Exp_To_Variables = {actor_id => variable_id, actor_id => variable_id, ...}

  Exp_To_Variables = {Actor_ID=>VARIABLE_ID, Actor_ID=>VARIABLE_ID, Etc...}

  #Place the id number of the actor => the id number of the variable to transfer exp to

  alias_method :seph_exptovar_gmactr_exp=, :exp=

  def exp=(exp)

    if $game_temp.in_battle

      $game_variables[Exp_To_Variables[@actor_id]] += exp - @exp

    else

      self.seph_exptovar_gmactr_exp=(exp)

    end

  end

 

  #--------------------------------------------------------------------------

  # * Get Until Next Level EXP as an integer

  #--------------------------------------------------------------------------

  def next_rest_exp

    return @exp_list[@level+1] > 0 ?

      (@exp_list[@level+1] - @exp) : 0

  end

 

  #--------------------------------------------------------------------------

  # * Change Level

  #     level : new level

  #--------------------------------------------------------------------------

  def level=(level)

    # Check up and down limits

    level = [[level, $data_actors[@actor_id].final_level].min, 1].max

    # Change EXP

    self.exp = @exp_list[level]

  end

 

  Game_Battler

  attr_writer   :level                    # level

end

 

 


P.S. Kyomizero is another of my nicknames
 

Zeriab

Sponsor

Note that it is
class Game_Actor < Game_Battler
and not just
class Game_Actor

The reason is that Game_Actor inherits from Game_Battler.
Saying that Game_Actor does not inherit from Game_Battler anymore can have some very bad consequences.

Also attr_writer :level is a synonym for this:
[rgss]def level=(level)
  @level = level
end
[/rgss]

Therefore there is no need to have both of the methods in the script.
I have altered your script with my suggestion:

[rgss] #----------------------------------------------------------------------------
#  Beet Style Leveling System
#
#  By: Kyomizero
#
#  Huge Credit to: Brewmeister, SephirothSpawn, & Zeriab from RMXP.ORG
#----------------------------------------------------------------------------
#
#     To apply exp to leveling use:
#   $game_party.actors[0].exp += <amount to apply to leveling>
#     To get the amount of exp needed for the next level use:
#   $game_variables[TEMP_VARIABLE] = $game_party.actors[0].next_rest_exp
#     To alter the amount of exp in the variable use:
#          Add
#   $game_variables[ACTOR_EXP_VARIABLE_ID] += <amount to change>
#          Subtract
#   $game_variables[ACTOR_EXP_VARIABLE_ID] -= <amount to change>
#
#----------------------------------------------------------------------------
 
class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # * Change EXP
  #     exp : new EXP
  #--------------------------------------------------------------------------
  def exp=(exp)
    @exp = [[exp, 9999999].min, 0].max
    # Correction if exceeding current max HP and max SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
 
  #--------------------------------------------------------------------------
  # * Exp to Variables
  #     exp => exp variable
  #--------------------------------------------------------------------------
  # Exp_To_Variables = {actor_id => variable_id, actor_id => variable_id, ...}
  Exp_To_Variables = {Actor_ID=>VARIABLE_ID, Actor_ID=>VARIABLE_ID, Etc...}
  #Place the id number of the actor => the id number of the variable to transfer exp to
  alias_method :seph_exptovar_gmactr_exp=, :exp=
  def exp=(exp)
    if $game_temp.in_battle
      $game_variables[Exp_To_Variables[@actor_id]] += exp - @exp
    else
      self.seph_exptovar_gmactr_exp=(exp)
    end
  end
 
  #--------------------------------------------------------------------------
  # * Get Until Next Level EXP as an integer
  #--------------------------------------------------------------------------
  def next_rest_exp
    return @exp_list[@level+1] > 0 ?
      (@exp_list[@level+1] - @exp) : 0
  end
 
  #--------------------------------------------------------------------------
  # * Change Level
  #     level : new level
  #--------------------------------------------------------------------------
  def level=(level)
    # Check up and down limits
    @level = [[level, $data_actors[@actor_id].final_level].min, 1].max
  end
end
[/rgss]

*hugs*
- Zeriab
 

Zeriab

Sponsor

After some testing it seems that if you have a class Game_Actor < Game_Battler and then have a class Game_Actor the super class of Game_Actor is implicitly assumed to be Game_Battler.
This means there is no difference between using class Game_Actor < Game_Battler or class Game_Actor when the script comes afterwards.
If however a class Game_Actor definition comes before the definition with the explicitly defined superclass its a different matter. In this case we will get that Game_Actor inherits from Object.
When class Game_Actor < Game_Battler comes we change the class which Game_Actor inherits from which practically means destroying the old class and making a new class as if the earlier class definition hadn't existed at all.

Even if it was not for that issue I would recommend making the inheritance explicit for structural purposes. There might of course be cases where this special behavior is beneficial, but it's very much the exception.

*hugs*
- Zeriab
 

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