[C++] How to increase maximum level on server

Gesior.pl

Mega Noob&LOL 2012
Joined
Sep 18, 2007
Messages
1,988
Reaction score
898
Location
PLand
This is not 'code release' (only)! There is full description of problem with maximum number value in C++.

Let's fix max. level problem (for high exp servers)!
THIS FIX YOU CAN ONLY INSTALL BEFORE SERVER START. THIS FIX REQUIRES ALL CHARACTERS RESET (level and exp).

Example with formulat with max. level over 250.000.000:
1. First thing to do is to reduce exp ratio/exp from monsters [.xml / .lua files]. When experience reaches '18.446.744.073.709.551.615' it stops leveling.

2. Change getExpForLevel function in player.h (sources)
There is something like:
Code:
static uint64_t getExpForLevel(int32_t lv) {
... (no matter what is here, we replace it!) ...
}
Replace it with (this is just example function, you should make some better, as it's growing flat lvl 1 = X exp, lvl 2 = 2*X exp, .. lvl N = N * X exp):
Code:
static uint64_t getExpForLevel(int32_t lv) {
lv--;
return ((150ULL * lv * lv) - (50ULL * lv * lv) + (1200ULL)) / 3ULL;
}
3. Rebuild sources (this change requires 'rebuild', not just 'compile'!)
[How to rebuild 0.3.6/0.4 on linux? Remove all .o files from compilation folder: rm *.o ]

Compare exp required for level:
Normal formula 'lvl 29' exp is equal to new formula 'lvl 100' exp - players gain levels much faster with same exp ratio!

-------------------------------------------------------------
Why? What? Where? Short explanation:

Exp-level formula is: ((50ULL * lv * lv * lv) - (150ULL * lv * lv) + (400ULL * lv)) / 3ULL
Now change it into math parts that computer must calculate (in computer-calculation order - different then school/human calculation):
$x1 = 400ULL * lv
$x2 = 150ULL * lv * lv
$x3 = 50ULL * lv * lv * lv
$x4 = $x3 + ($x1 - $x2)
$x5 = 3ULL
$x6 = $x4 / $x5

Now use some level in these calculations, hmm... 5.000.000 level? OK!
$lv = 5.000.000
$x1 = 2.000.000.000
$x2 = 3.750.000.000.000.000
$x3 = 6.249.999.999.999.999.475.712
$x4 = 6.249.996.250.001.999.659.008
$x5 = 3
$x6 = 2.083.332.083.333.999.886.336

18.446.744.073.709.551.615 - this is max. allowed value for math calculation [high precision] in C++ [and many other languanges]
(first 18 digits of numbers are bold to let you see which numbers are too high)


As you can see value of $x3 [50ULL * lv * lv * lv] for level 5.000.000 is much higher then maximum allowed value for number (and because of it $x4 and $x6 are also too high). So problem is with too high 'exp' value, not too high 'level' value.
Can you change maximum value in C++? No (there is possibility, but it's not easy.. it's super hard! - you must change it everywhere is sources).
Only thing you can do is to give more levels for X 'exp points'. Then when player reaches exp 'max', his level will be 5.000.000 not 717.206.


--------------------------------------------
Extra info + calculator:

ULL - unsigned long long (integer) - max. value: 18.446.744.073.709.551.615 , you must add it to every number in math formula to tell computer to calculate with highest precision (highest maximum value)

Awesome formula level calculator. Find too high number easy.
http://writecodeonline.com/php/
Paste in this *magic* formula (compare your exp-level calculation part values with maximum possible 'unsigned 64 bit integer value'):
Code:
$lv = 5000000;
$x1 = 400 * $lv;
$x2 = 150 * $lv * $lv;
$x3 = 50 * $lv * $lv * $lv;
$x4 = $x3 + ($x1 - $x2);
$x5 = 3;
$x6 = $x4 / $x5;

echo number_format($x1, 0, '', '.') . "\n" . number_format($x2, 0, '', '.') . "\n" . number_format($x3, 0, '', '.') . "\n" . number_format($x4, 0, '', '.') . "\n" . number_format($x5, 0, '', '.') . "\n" . number_format($x6, 0, '', '.') . "\n18.446.744.073.709.551.615 - this is max. allowed value";
You can modify values $x1 to $x5 and check why some changes in formula does not help.
 
Last edited:

Niioxce

Otland lurker
Premium User
Joined
Jun 22, 2012
Messages
322
Reaction score
3
Location
Sweden
This is amazing, i'll check this out later, AKA now... :D
 

Niioxce

Otland lurker
Premium User
Joined
Jun 22, 2012
Messages
322
Reaction score
3
Location
Sweden
By the way is this:
Code:
static uint64_t getExpForLevel(uint32_t lv)
{
static std::map<uint32_t, uint64_t> cache;
lv--;

std::map<uint32_t, uint64_t>::iterator it = cache.find(lv);
if(it != cache.end())
return it->second;

uint64_t exp = ((50ULL * (lv+1ULL) / 3ULL - 100ULL) * (lv+1ULL) + 850ULL / 3ULL) * (lv+1ULL) - 200ULL;
cache[lv] = exp;
return exp;
}
Better than this

Code:
static uint64_t getExpForLevel(int32_t lv) {
lv--;
return ((150ULL * lv * lv) - (50ULL * lv * lv) + (1200ULL)) / 3ULL;
}
?

Also what exp ratio do you suggest?

Thanks again!

Edit: I tried this and i reached level:
Code:
13:32 You are level : ----> 429496730 <----
haha
 
Last edited:

EvilSkillz

Back
Joined
Jul 12, 2012
Messages
1,716
Reaction score
297
Location
Egypt - Cairo
This is not 'code release' (only)! There is full description of problem with maximum number value in C++.

Let's fix max. level problem (for high exp servers)!
THIS FIX YOU CAN ONLY INSTALL BEFORE SERVER START. THIS FIX REQUIRES ALL CHARACTERS RESET (level and exp).

Example with formulat with max. level over 250.000.000:
1. First thing to do is to reduce exp ratio/exp from monsters [.xml / .lua files]. When experience reaches '18.446.744.073.709.551.615' it stops leveling.

2. Change getExpForLevel function in player.h (sources)
There is something like:
Code:
static uint64_t getExpForLevel(int32_t lv) {
... (no matter what is here, we replace it!) ...
}
Replace it with (this is just example function, you should make some better, as it's growing flat lvl 1 = X exp, lvl 2 = 2*X exp, .. lvl N = N * X exp):
Code:
static uint64_t getExpForLevel(int32_t lv) {
lv--;
return ((150ULL * lv * lv) - (50ULL * lv * lv) + (1200ULL)) / 3ULL;
}
3. Rebuild sources (this change requires 'rebuild', not just 'compile'!)
[How to rebuild 0.3.6/0.4 on linux? Remove all .o files from compilation folder: rm *.o ]

Compare exp required for level:
Normal formula 'lvl 29' exp is equal to new formula 'lvl 100' exp - players gain levels much faster with same exp ratio!

-------------------------------------------------------------
Why? What? Where? Short explanation:

Exp-level formula is: ((50ULL * lv * lv * lv) - (150ULL * lv * lv) + (400ULL * lv)) / 3ULL
Now change it into math parts that computer must calculate (in computer-calculation order - different then school/human calculation):
$x1 = 400ULL * lv
$x2 = 150ULL * lv * lv
$x3 = 50ULL * lv * lv * lv
$x4 = $x3 + ($x1 - $x2)
$x5 = 3ULL
$x6 = $x4 / $x5

Now use some level in these calculations, hmm... 5.000.000 level? OK!
$lv = 5.000.000
$x1 = 2.000.000.000
$x2 = 3.750.000.000.000.000
$x3 = 6.249.999.999.999.999.475.712
$x4 = 6.249.996.250.001.999.659.008
$x5 = 3
$x6 = 2.083.332.083.333.999.886.336

18.446.744.073.709.551.615 - this is max. allowed value for math calculation [high precision] in C++ [and many other languanges]
(first 18 digits of numbers are bold to let you see which numbers are too high)


As you can see value of $x3 [50ULL * lv * lv * lv] for level 5.000.000 is much higher then maximum allowed value for number (and because of it $x4 and $x6 are also too high). So problem is with too high 'exp' value, not too high 'level' value.
Can you change maximum value in C++? No (there is possibility, but it's not easy.. it's super hard! - you must change it everywhere is sources).
Only thing you can do is to give more levels for X 'exp points'. Then when player reaches exp 'max', his level will be 5.000.000 not 717.206.


--------------------------------------------
Extra info + calculator:

ULL - unsigned long long (integer) - max. value: 18.446.744.073.709.551.615 , you must add it to every number in math formula to tell computer to calculate with highest precision (highest maximum value)

Awesome formula level calculator. Find too high number easy.
http://writecodeonline.com/php/
Paste in this *magic* formula (compare your exp-level calculation part values with maximum possible 'unsigned 64 bit integer value'):
Code:
$lv = 5000000;
$x1 = 400 * $lv;
$x2 = 150 * $lv * $lv;
$x3 = 50 * $lv * $lv * $lv;
$x4 = $x3 + ($x1 - $x2);
$x5 = 3;
$x6 = $x4 / $x5;

echo number_format($x1, 0, '', '.') . "\n" . number_format($x2, 0, '', '.') . "\n" . number_format($x3, 0, '', '.') . "\n" . number_format($x4, 0, '', '.') . "\n" . number_format($x5, 0, '', '.') . "\n" . number_format($x6, 0, '', '.') . "\n18.446.744.073.709.551.615 - this is max. allowed value";
You can modify values $x1 to $x5 and check why some changes in formula does not help.
the secret has been revealed :D
 

Sir Islam

Never Give Up
Joined
Jun 6, 2008
Messages
504
Reaction score
118
Location
Suez , Egypt
You can change that in stages if you want.
by stages i got max Level: 94869
Code:
    <world id="0" multiplier="1">
        <stage minlevel="1" maxlevel="8" multiplier="100"/>
        <stage minlevel="9" maxlevel="20" multiplier="100"/>
        <stage minlevel="21" maxlevel="50" multiplier="100"/>
        <stage minlevel="51" maxlevel="100" multiplier="100"/>
        <stage minlevel="100" maxlevel="120" multiplier="100"/>
        <stage minlevel="130" maxlevel="150" multiplier="100"/>
        <stage minlevel="300" maxlevel="400" multiplier="100"/>
        <stage minlevel="717217" maxlevel="1000000" multiplier="100"/>
        <stage minlevel="2000000" maxlevel="3000000" multiplier="100"/>
        <stage minlevel="4000000" maxlevel="5000000" multiplier="0"/>
 
Last edited:

Niioxce

Otland lurker
Premium User
Joined
Jun 22, 2012
Messages
322
Reaction score
3
Location
Sweden
by stages i got max Level: 94869
Code:
    <world id="0" multiplier="1">
        <stage minlevel="1" maxlevel="8" multiplier="100"/>
        <stage minlevel="9" maxlevel="20" multiplier="100"/>
        <stage minlevel="21" maxlevel="50" multiplier="100"/>
        <stage minlevel="51" maxlevel="100" multiplier="100"/>
        <stage minlevel="100" maxlevel="120" multiplier="100"/>
        <stage minlevel="130" maxlevel="150" multiplier="100"/>
        <stage minlevel="300" maxlevel="400" multiplier="100"/>
        <stage minlevel="717217" maxlevel="1000000" multiplier="100"/>
        <stage minlevel="2000000" maxlevel="3000000" multiplier="100"/>
        <stage minlevel="4000000" maxlevel="5000000" multiplier="0"/>
Try this

Code:
<?xml version="1.0" encoding="UTF-8"?>
<stages>
     <stage minlevel="1" maxlevel="5000000" multiplier="100"/>
</stages>
Also have you done as @Gesior.pl told you, or similar atleast?
Btw have you edited your config so Experiencestages = true?
Code:
experienceStages = true
 
Last edited:

Sir Islam

Never Give Up
Joined
Jun 6, 2008
Messages
504
Reaction score
118
Location
Suez , Egypt
Try this

Code:
<?xml version="1.0" encoding="UTF-8"?>
<stages>
     <stage minlevel="1" maxlevel="5000000" multiplier="100"/>
</stages>
Also have you done as @Gesior.pl told you, or similar atleast?
Btw have you edited your config so Experiencestages = true?
Code:
experienceStages = true
16:48 You advanced from Level 4879037 to Level 5320245.

i want 5 000 000 no more
 

Niioxce

Otland lurker
Premium User
Joined
Jun 22, 2012
Messages
322
Reaction score
3
Location
Sweden
16:48 You advanced from Level 4879037 to Level 5320245.

i want 5 000 000 no more
I think you have to change the formula a bit, not quite sure. You can also try to lower the exp ratio on the mobs or the multiplier in stages..

Good luck :p
 
OP
Gesior.pl

Gesior.pl

Mega Noob&LOL 2012
Joined
Sep 18, 2007
Messages
1,988
Reaction score
898
Location
PLand
16:48 You advanced from Level 4879037 to Level 5320245.

i want 5 000 000 no more
1. Edit formula to make it lower (but it won't block at lvl 5000000, you got 1% chance to make it stop at lvl 5000000 exactly).
but let's try:
... wolfram alpha failed :( ...
You cannot make nice formula for 5.000.000 lvl, but you can check what I found with super-math computer http://www.wolframalpha.com/
This is formula for max level 5.000.003 (im not 100% sure that it will work):
Code:
static uint64_t getExpForLevel(int32_t lv) {
return 400ULL + 737869ULL * lv * lv - 737869ULL * lv;
}
Problem can be on low level, it will lvl up very slowly.

Of course best lvl 5.000.000 limit is stages.xml multiplier ZERO on lvl 5.000.000
 
OP
Gesior.pl

Gesior.pl

Mega Noob&LOL 2012
Joined
Sep 18, 2007
Messages
1,988
Reaction score
898
Location
PLand
By the way is this:
Code:
static uint64_t getExpForLevel(uint32_t lv)
{
static std::map<uint32_t, uint64_t> cache;
lv--;

std::map<uint32_t, uint64_t>::iterator it = cache.find(lv);
if(it != cache.end())
return it->second;

uint64_t exp = ((50ULL * (lv+1ULL) / 3ULL - 100ULL) * (lv+1ULL) + 850ULL / 3ULL) * (lv+1ULL) - 200ULL;
cache[lv] = exp;
return exp;
}
Better than this

Code:
static uint64_t getExpForLevel(int32_t lv) {
lv--;
return ((150ULL * lv * lv) - (50ULL * lv * lv) + (1200ULL)) / 3ULL;
}
?

Also what exp ratio do you suggest?

Thanks again!

Edit: I tried this and i reached level:
Code:
13:32 You are level : ----> 429496730 <----
haha
Version with cache is 10-20 times slower (I did tests with 200.000 reading same level with cache and without). I think that why it's not cached in TFS 1.0.
Cache is good when you make some very advanced calculations, not 10 x simple +,-,*. Allocating RAM, store data, read data, search something in 'map' - it all takes much more time then simple math.

ty alot @Gesior
I Want To Break Monsters' Hp Limit, have any idea
Solution: do not break limits of INTs, it's not a good plan. First you change something in one place, then you must change it everywhere in sources.. and then you figure out that there is no chance to show it in client, because you cannot modify tibia client variables.
Like OTS did with experience, you can get 18.000.000.000.000.000.000.000 exp, but in client it shows only 2.147.000.000 and Hp/mana: you can get 2.147.000.000 HP/MANA, but in client it shows only 65515 (at least in this case HP % bar works fine).
 

Niioxce

Otland lurker
Premium User
Joined
Jun 22, 2012
Messages
322
Reaction score
3
Location
Sweden
Version with cache is 10-20 times slower (I did tests with 200.000 reading same level with cache and without). I think that why it's not cached in TFS 1.0.
Cache is good when you make some very advanced calculations, not 10 x simple +,-,*. Allocating RAM, store data, read data, search something in 'map' - it all takes much more time then simple math.
Yea, i noticed that because when i raised the exp ratio to like 12000000000 it collected around 2GB of ram lol and then crashed :D

By the way @Gesior.pl i also noticed that my damage has increased significantly, just check this out
Code:
23:26 You deal 1316134911 damage to a Trainer.
I literally one shotted a trainer, Evil hero said to me that i had to edit the source ALOT.
Any other way to fix this? :)

Btw thanks for the tutorial, much love from sweden!
 

cuba

Member
Joined
Feb 24, 2015
Messages
136
Reaction score
2
This is not 'code release' (only)! There is full description of problem with maximum number value in C++.

Let's fix max. level problem (for high exp servers)!
THIS FIX YOU CAN ONLY INSTALL BEFORE SERVER START. THIS FIX REQUIRES ALL CHARACTERS RESET (level and exp).

Example with formulat with max. level over 250.000.000:
1. First thing to do is to reduce exp ratio/exp from monsters [.xml / .lua files]. When experience reaches '18.446.744.073.709.551.615' it stops leveling.

2. Change getExpForLevel function in player.h (sources)
There is something like:
Code:
static uint64_t getExpForLevel(int32_t lv) {
... (no matter what is here, we replace it!) ...
}
Replace it with (this is just example function, you should make some better, as it's growing flat lvl 1 = X exp, lvl 2 = 2*X exp, .. lvl N = N * X exp):
Code:
static uint64_t getExpForLevel(int32_t lv) {
lv--;
return ((150ULL * lv * lv) - (50ULL * lv * lv) + (1200ULL)) / 3ULL;
}
3. Rebuild sources (this change requires 'rebuild', not just 'compile'!)
[How to rebuild 0.3.6/0.4 on linux? Remove all .o files from compilation folder: rm *.o ]

Compare exp required for level:
Normal formula 'lvl 29' exp is equal to new formula 'lvl 100' exp - players gain levels much faster with same exp ratio!

-------------------------------------------------------------
Why? What? Where? Short explanation:

Exp-level formula is: ((50ULL * lv * lv * lv) - (150ULL * lv * lv) + (400ULL * lv)) / 3ULL
Now change it into math parts that computer must calculate (in computer-calculation order - different then school/human calculation):
$x1 = 400ULL * lv
$x2 = 150ULL * lv * lv
$x3 = 50ULL * lv * lv * lv
$x4 = $x3 + ($x1 - $x2)
$x5 = 3ULL
$x6 = $x4 / $x5

Now use some level in these calculations, hmm... 5.000.000 level? OK!
$lv = 5.000.000
$x1 = 2.000.000.000
$x2 = 3.750.000.000.000.000
$x3 = 6.249.999.999.999.999.475.712
$x4 = 6.249.996.250.001.999.659.008
$x5 = 3
$x6 = 2.083.332.083.333.999.886.336

18.446.744.073.709.551.615 - this is max. allowed value for math calculation [high precision] in C++ [and many other languanges]
(first 18 digits of numbers are bold to let you see which numbers are too high)


As you can see value of $x3 [50ULL * lv * lv * lv] for level 5.000.000 is much higher then maximum allowed value for number (and because of it $x4 and $x6 are also too high). So problem is with too high 'exp' value, not too high 'level' value.
Can you change maximum value in C++? No (there is possibility, but it's not easy.. it's super hard! - you must change it everywhere is sources).
Only thing you can do is to give more levels for X 'exp points'. Then when player reaches exp 'max', his level will be 5.000.000 not 717.206.


--------------------------------------------
Extra info + calculator:

ULL - unsigned long long (integer) - max. value: 18.446.744.073.709.551.615 , you must add it to every number in math formula to tell computer to calculate with highest precision (highest maximum value)

Awesome formula level calculator. Find too high number easy.
http://writecodeonline.com/php/
Paste in this *magic* formula (compare your exp-level calculation part values with maximum possible 'unsigned 64 bit integer value'):
Code:
$lv = 5000000;
$x1 = 400 * $lv;
$x2 = 150 * $lv * $lv;
$x3 = 50 * $lv * $lv * $lv;
$x4 = $x3 + ($x1 - $x2);
$x5 = 3;
$x6 = $x4 / $x5;

echo number_format($x1, 0, '', '.') . "\n" . number_format($x2, 0, '', '.') . "\n" . number_format($x3, 0, '', '.') . "\n" . number_format($x4, 0, '', '.') . "\n" . number_format($x5, 0, '', '.') . "\n" . number_format($x6, 0, '', '.') . "\n18.446.744.073.709.551.615 - this is max. allowed value";
You can modify values $x1 to $x5 and check why some changes in formula does not help.
how can i remove all .o files to rebuild source?
 
OP
Gesior.pl

Gesior.pl

Mega Noob&LOL 2012
Joined
Sep 18, 2007
Messages
1,988
Reaction score
898
Location
PLand
how can i remove all .o files to rebuild source?
I dont know in which folder are these files in TFS 1.0, but in 0.3.6 and 0.4 it was in folder in which you type 'make' to compile TFS. In this folder type:
rm *.o
to remove all files that ends with .o
 
Top