ID:154670
 
I'm looking for a simple way to have a 'level up' procedure that will carry over any extra experience points that you have.

The following code is an example, it is not the actual code used in the game.
mob
var
experience
maxexperience
level
proc
Level_Up()
if(src.exp>=src.maxexp)
src.level+=1
src.maxexperience+=src.level*200
src.experience=0


Lets say your max experience is 100 and your experience is 95, and you gain 20 experience. This character will level up, but the extra fifteen experience points are lost.

I have a feeling that it will involve some kind of math, which, unfortunately, is not my strong subject.

Can somebody give or show me a good way to do this? Feel free to add on to the example code I have provided you. Or you can just explain how it would work.

Thanks very much,
-JaiZo
deleted
In response to FIREking
Great idea!

Thanks for the reply and assistance, FIREking.
Credit will be given in my project when released.
-JaiZo
In response to FIREking
FIREking wrote:
> mob
> var
> exp
> max_exp
> level
> proc
> addExp(n as num) //use this EVERY TIME you add experience, so instead of exp += ?? do src.addExp(20)
> if(checkLevelUp(n)) //was enough to level up
> var/extra_amount = (exp + n) - max_exp //find the amount left over from the level up
> LevelUp() // level up!
> exp = extra_amount //set our experience to the amount left over
> LevelUp()
> //set your max_exp and level here
> level += 1
> //max_exp = ???? (whatever your formula is)
> checkLevelUp(n as num)
> if(exp + n >= max_exp) //if the amount we want to add to current experience is larger or equal to maximum amount of experience required to level up
> return 1 // return true
> return 0 //no, this amount will not level us up
>


1. Your code only adds experience if you get enough to level up.

2. Proc arguments don't need types (ex: "as num").

3. You don't need the checkLevelUp() proc, you can do it all inside addExp()

4. You don't handle the case where the player gets enough experience to level up twice.

5. I'd also make the names consistent. Either call the vars and procs "max_exp" and "level_up" or call them "maxExp" and "levelUp".

mob
proc
add_exp(n)
exp += n

while(exp >= max_exp)
level_up()

// when you level up we do three things:
level_up()
// subtract the amount of experience it took to level up
exp -= max_exp

// increment your level
level += 1

// increase the amount of experience needed to level
max_exp += 200
In response to Forum_account
Forum_account wrote:
FIREking wrote:
> > mob
> > var
> > exp
> > max_exp
> > level
> > proc
> > addExp(n as num) //use this EVERY TIME you add experience, so instead of exp += ?? do src.addExp(20)
> > if(checkLevelUp(n)) //was enough to level up
> > var/extra_amount = (exp + n) - max_exp //find the amount left over from the level up
> > LevelUp() // level up!
> > exp = extra_amount //set our experience to the amount left over
> > LevelUp()
> > //set your max_exp and level here
> > level += 1
> > //max_exp = ???? (whatever your formula is)
> > checkLevelUp(n as num)
> > if(exp + n >= max_exp) //if the amount we want to add to current experience is larger or equal to maximum amount of experience required to level up
> > return 1 // return true
> > return 0 //no, this amount will not level us up
> >

1. Your code only adds experience if you get enough to level up.

2. Proc arguments don't need types (ex: "as num").

3. You don't need the checkLevelUp() proc, you can do it all inside addExp()

4. You don't handle the case where the player gets enough experience to level up twice.

5. I'd also make the names consistent. Either call the vars and procs "max_exp" and "level_up" or call them "maxExp" and "levelUp".

> mob
> proc
> add_exp(n)
> exp += n
>
> while(exp >= max_exp)
> level_up()
>
> // when you level up we do three things:
> level_up()
> // subtract the amount of experience it took to level up
> exp -= max_exp
>
> // increment your level
> level += 1
>
> // increase the amount of experience needed to level
> max_exp += 200
>


1. Good point, wasn't really paying that much attention
2. Doesn't matter
3. The proc can be useful somewhere else in the program.
4. True.
5. Naming conventions will be debatable forever.
In response to FIREking
FIREking wrote:
5. Naming conventions will be debatable forever.

The example you gave uses a mix of three different naming conventions. You're correct that there's no way to decide which convention is best, but we can say that using one convention consistently is better than mixing three different ones.
In conclusion of all of this (I know, it took me a while to implement; I was working on other things), this is what I came up with.
mob
var
exp
maxexp
level
proc
addExp(n) //as FIREking said, I'm using addExp(n) instead of src.exp+=n
src.exp+=n
if(src.exp>=src.maxexp) //I decided to use if() instead of while()
src.LvlUp()
LvlUp()
var/newmax=src.maxexp*3 //My formula, which just triples your maxexp.
src.level+=1 //Level increases..
src<<"You level up. You are now level [src.level]."
src.exp-=src.maxexp //Instead of resetting the experience, you just subtract the experience you
//have from the experience you needed to level up, leaving you with the
//difference. (A.K.A. "Extra Experience")
src.maxexp=newmax
//At this point, you have your new max and your leftover experience.
if(src.exp>=src.maxexp)src.LvlUp() //If you still have enough to level up again, repeat. (I know, it's the same
//as using while(), but I'm more fimilar with this.)


Thank you both for your assistance. FIREking & Forum_account you will both be credited in my project.

--JaiZo
In response to JaiZo
Using an if statement at the end of LvlUp isn't exactly the same as using a while loop in addExp(). Suppose you do this:

mob
verb
test()
addExp(100)

LvlUp()
..()
world << src.level

With the code you have there, this is the output you'll see:

You level up. You are now level 2.
You level up. You are now level 3.
3
3

The world << src.level line is called twice because you level up twice, but both times it outputs 3. This happens because of the if statement at the end of LvlUp(). If we remove that and make addExp use a while loop, this is the output we'll see:

You level up. You are now level 2.
2
You level up. You are now level 3.
3

This doesn't seem like a big deal, but we can override the LvlUp proc for other mob types to create type-specific benefits to leveling up. For example:

mob
soldier
LvlUp()
// call the LvlUp proc for /mob, which increments
// src.level and updates src.maxexp
..()

// do something extra that's specific for mobs of
// the /mob/soldier type
if(src.level == 2)
src.addAbility("power smash")

We want to add the ability when the soldier reaches level 2 but that won't always work with the way you have the LvlUp() proc. Using a while() loop in addExp() it will work.

Edit:
I tend to not use while loops because they're often confusing. There just aren't a lot of cases where they're necessary and they're less intuitive because they have fewer uses. When you look at a for loop it's almost always immediately clear what it's doing. This case, however, is one of the rare cases where a while loop does make good sense.

Also, I don't think it's been mentioned here so I'll stress that it's a good idea to use procs like addExp(), even for things that don't have side effects (ex: leveling up). Suppose you just add directly to a player's health var when they're healed, it would be hard to add a status ailment that halves the effectiveness of healing. If you use an addHealth() proc, this is very easy to add.
Confusing and unnessacary. The code I have works flawlessly in my project. Thanks anyway.

Edit: although I did read the last paragraph and yes you're right about that.
In response to JaiZo
JaiZo wrote:
Confusing and unnessacary. The code I have works flawlessly in my project. Thanks anyway.

That's not the point. You could write absolutely terrible code that works for your project. You could do something like this:

if(level == 1 && exp >= 10)
levelUp()
else if(level == 2 && exp >= 30)
levelUp()
else if(level == 3 && exp >= 90)
levelUp()
// etc.


That could work perfectly for what you need to do but I wouldn't recommend it.

Writing better code decreases the chances you'll run into a problem when you add something to the project. Just because your code works now, that doesn't mean it'll always work in the future. Also, getting into good habits makes you a good programmer and will benefit all of your projects.