Updated Flyen's EXP Tutorial (Fixed Errors)
Posted: Mon Sep 28, 2026 12:28 pm
Hey guys, I read through Flyen's thread about his old EXP tutorial, seen that a LOT of people were having trouble and not understanding why they were getting errors... WELL, I'll post a working tutorial.
First: Include Your Modules
Then Define your classes, simply like this
Now we have to create the EXP, Levels, and Class Variables.
This is where your Maxclasses comes in
Now we will make the Levels with the Exp you desire
Now we create the plugin_init
Now we create the Death event, so it will keep your levels and exp, remember we called it eDeath, Let's begin.
We set the Hud to show the EXP and all that fun stuff
Now we create the Change Class Menu
Now we create the Menu Handler for the Class Menu
Now we set the Exp to load on someone who joins and has saved EXP
Now we set the Exp To save on someone who disconnects from the server
Now we set the exp to save to the Clients steam id
Now we set it to Load the Clients Exp Based on his Steam ID
And we're Finished
This is what it looks like all together
To add HP every 5 levels or however you want it. simply do all these things
YOU WILL NEED TO CREATE THIS WITHIN THE .SMA THIS IS NOT IN THE ORIGINAL!
First: Include Your Modules
Code: Select all
#include <amxmodx>
#include <amxmisc>
#include <nvault>Code: Select all
#define MAXCLASSES 5Code: Select all
new PlayerXP,PlayerLevel,PlayerClass[33]
//These are for your special kills
new XP_Kill,XP_Knife,XP_Hs
//This is for the vault, so your EXP saves to the server
new g_vaultCode: Select all
new const CLASSES[MAXCLASSES][] {
"None",
"Rifle Specialist",
"Sniper Specialist",
"Pistol Specialist",
"Machine Gun Specialist"
} Code: Select all
new const LEVELS[10] = {
"100",
"200",
"400",
"800",
"1600",
"3200",
"6400",
"12800",
"25600",
"51200"
} Code: Select all
public plugin_init()
{
register_plugin("Simple EXP Mod", "1.0", "Thelius") // Registers the Plugin to the ModName, Version, and Creator
register_event("DeathMsg", "eDeath", "a") // This is the death event
SaveXP = register_cvar("SaveXP", "1") // This is to make sure that Saving XP is enabled
XP_Kill = register_cvar("XP_per_kill", "40") // This defines the amount of EXP you gain per kill
XP_Hs = register_cvar("XP_hs_bonus", "50") // This defines the amount of exp gained per headshot
XP_Knife = register_cvar("XP_knife_bonus", "20") // This defines the amount of Exp gained per Knife Kill
g_vault = nvault_open("XPMod") // This opens the nvault so it can save the exp
register_clcmd("say /class", "ChangeClass") // Saying /class will open the class menu
register_clcmd("say_team /class", "ChangeClass") // Team saying /class will open the class menu
register_clcmd("say /xp", "ShowHud") // Saying /xp will show your EXP
register_clcmd("say_team /xp", "ShowHud") // Team Saying /xp will show your EXP
} Code: Select all
public eDeath( )
{
new headshot,attacker = read_data( 1 )
new weapon = get_user_weapon(attacker,headshot,headshot)
headshot = read_data( 3 )
PlayerXP[attacker] += get_pcvar_num(XP_Kill)
if(PlayerClass[attacker] == 0)
if(headshot)
PlayerXP[attacker] += get_pcvar_num(XP_Hs)
if(weapon == CSW_KNIFE)
PlayerXP[attacker] += get_pcvar_num(XP_Knife)
while(PlayerXP[attacker] >= LEVELS[PlayerLevel[attacker]])
{
client_print(attacker, print_chat, "[XP Mod] Congratulations you are now level %i %s!");
PlayerLevel[attacker] += 1
}
ShowHud(attacker)
SaveData(attacker)
} Code: Select all
public ShowHud(id)
{
set_hudmessage(0, 255, 0, 0.28, 0.88, 0, 6.0, 12.0)
show_hudmessage(id, "Level: %i^nXP: %i^nClass: %s", PlayerLevel[id],PlayerXP[id],CLASSES[PlayerClass[id]])
} Code: Select all
public ChangeClass(id)
{
new menu = menu_create("Class Menu", "Class_Handle");
menu_additem(menu ,"Rifle Specialist", "1" , 0);
menu_additem(menu ,"Sniper Specialist", "2" , 0);
menu_additem(menu ,"Pistol Specialist", "3" , 0);
menu_additem(menu ,"Machine Gun Specialist", "4" , 0);
menu_setprop(menu , MPROP_EXIT , MEXIT_ALL);
menu_display(id , menu , 0);
return PLUGIN_CONTINUE;
} Code: Select all
public Class_Handle(id , menu , item)
{
if(item == MENU_EXIT)
{
menu_destroy(menu);
}
new szCommand[6], szName[64];
new access , callback;
menu_item_getinfo(menu , item , access , szCommand , 5 , szName , 63 , callback);
new i = str_to_num(szCommand)
if(PlayerClass[id] != i)
{
PlayerClass[id] = i
client_print(id,print_chat, "[XP Mod] You are now a %s", CLASSES[i])
}
else
{
client_print(id,print_chat, "[XP Mod] You are already a %s",CLASSES[i]
}
menu_destroy(menu);
return PLUGIN_CONTINUE
} Code: Select all
public client_connect(id)
{
if(get_pcvar_num(SaveXP) == 1)
{
LoadData(id)
}
} Code: Select all
public client_disconnect(id)
{
if(get_pcvar_num(SaveXP) == 1)
{
SaveData(id)
}
PlayerXP[id] = 0
PlayerLevel[id] = 0
PlayerClass[id] = 0
} Code: Select all
public SaveData(id)
{
new AuthID[35]
get_user_authid(id,AuthID,34)
new vaultkey[64],vaultdata[256]
format(vaultkey,63,"%s-Mod", AuthID)
format(vaultdata,255,"%i#%i#",PlayerXP[id],PlayerLevel[id])
nvault_set(g_vault,vaultkey,vaultdata)
return PLUGIN_CONTINUE
} Code: Select all
public LoadData(id)
{
new AuthID[35]
get_user_authid(id,AuthID,34)
new vaultkey[64],vaultdata[256]
format(vaultkey,63,"%s-Mod",AuthID)
format(vaultdata,255,"%i#%i#",PlayerXP[id],PlayerLevel[id])
nvault_get(g_vault,vaultkey,vaultdata,255)
replace_all(vaultdata, 255, "#", " ")
new playerxp[32], playerlevel[32]
parse(vaultdata, playerxp, 31, playerlevel, 31)
PlayerXP[id] = str_to_num(playerxp)
PlayerLevel[id] = str_to_num(playerlevel)
return PLUGIN_CONTINUE
} This is what it looks like all together
Code: Select all
#include <amxmodx>
#include <amxmisc>
#include <nvault>
new PlayerXP,PlayerLevel,PlayerClass[33]
//These are for your special kills
new XP_Kill,XP_Knife,XP_Hs
//This is for the vault, so your EXP saves to the server
new g_vault
new const CLASSES[MAXCLASSES][] {
"None",
"Rifle Specialist",
"Sniper Specialist",
"Pistol Specialist",
"Machine Gun Specialist"
}
new const LEVELS[10] = {
"100",
"200",
"400",
"800",
"1600",
"3200",
"6400",
"12800",
"25600",
"51200"
}
public plugin_init()
{
register_plugin("Simple EXP Mod", "1.0", "Thelius") // Registers the Plugin to the ModName, Version, and Creator
register_event("DeathMsg", "eDeath", "a") // This is the death event
SaveXP = register_cvar("SaveXP", "1") // This is to make sure that Saving XP is enabled
XP_Kill = register_cvar("XP_per_kill", "40") // This defines the amount of EXP you gain per kill
XP_Hs = register_cvar("XP_hs_bonus", "50") // This defines the amount of exp gained per headshot
XP_Knife = register_cvar("XP_knife_bonus", "20") // This defines the amount of Exp gained per Knife Kill
g_vault = nvault_open("XPMod") // This opens the nvault so it can save the exp
register_clcmd("say /class", "ChangeClass") // Saying /class will open the class menu
register_clcmd("say_team /class", "ChangeClass") // Team saying /class will open the class menu
register_clcmd("say /xp", "ShowHud") // Saying /xp will show your EXP
register_clcmd("say_team /xp", "ShowHud") // Team Saying /xp will show your EXP
}
public eDeath( )
{
new headshot,attacker = read_data( 1 )
new weapon = get_user_weapon(attacker,headshot,headshot)
headshot = read_data( 3 )
PlayerXP[attacker] += get_pcvar_num(XP_Kill)
if(PlayerClass[attacker] == 0)
if(headshot)
PlayerXP[attacker] += get_pcvar_num(XP_Hs)
if(weapon == CSW_KNIFE)
PlayerXP[attacker] += get_pcvar_num(XP_Knife)
while(PlayerXP[attacker] >= LEVELS[PlayerLevel[attacker]])
{
client_print(attacker, print_chat, "[XP Mod] Congratulations you are now level %i %s!");
PlayerLevel[attacker] += 1
}
ShowHud(attacker)
SaveData(attacker)
}
public ShowHud(id)
{
set_hudmessage(0, 255, 0, 0.28, 0.88, 0, 6.0, 12.0)
show_hudmessage(id, "Level: %i^nXP: %i^nClass: %s", PlayerLevel[id],PlayerXP[id],CLASSES[PlayerClass[id]])
}
public ChangeClass(id)
{
new menu = menu_create("Class Menu", "Class_Handle");
menu_additem(menu ,"Rifle Specialist", "1" , 0);
menu_additem(menu ,"Sniper Specialist", "2" , 0);
menu_additem(menu ,"Pistol Specialist", "3" , 0);
menu_additem(menu ,"Machine Gun Specialist", "4" , 0);
menu_setprop(menu , MPROP_EXIT , MEXIT_ALL);
menu_display(id , menu , 0);
return PLUGIN_CONTINUE;
}
public Class_Handle(id , menu , item)
{
if(item == MENU_EXIT)
{
menu_destroy(menu);
}
new szCommand[6], szName[64];
new access , callback;
menu_item_getinfo(menu , item , access , szCommand , 5 , szName , 63 , callback);
new i = str_to_num(szCommand)
if(PlayerClass[id] != i)
{
PlayerClass[id] = i
client_print(id,print_chat, "[XP Mod] You are now a %s", CLASSES[i])
}
else
{
client_print(id,print_chat, "[XP Mod] You are already a %s",CLASSES[i]
}
menu_destroy(menu);
return PLUGIN_CONTINUE
}
public client_connect(id)
{
if(get_pcvar_num(SaveXP) == 1)
{
LoadData(id)
}
}
public client_disconnect(id)
{
if(get_pcvar_num(SaveXP) == 1)
{
SaveData(id)
}
PlayerXP[id] = 0
PlayerLevel[id] = 0
PlayerClass[id] = 0
}
public SaveData(id)
{
new AuthID[35]
get_user_authid(id,AuthID,34)
new vaultkey[64],vaultdata[256]
format(vaultkey,63,"%s-Mod", AuthID)
format(vaultdata,255,"%i#%i#",PlayerXP[id],PlayerLevel[id])
nvault_set(g_vault,vaultkey,vaultdata)
return PLUGIN_CONTINUE
}
public LoadData(id)
{
new AuthID[35]
get_user_authid(id,AuthID,34)
new vaultkey[64],vaultdata[256]
format(vaultkey,63,"%s-Mod",AuthID)
format(vaultdata,255,"%i#%i#",PlayerXP[id],PlayerLevel[id])
nvault_get(g_vault,vaultkey,vaultdata,255)
replace_all(vaultdata, 255, "#", " ")
new playerxp[32], playerlevel[32]
parse(vaultdata, playerxp, 31, playerlevel, 31)
PlayerXP[id] = str_to_num(playerxp)
PlayerLevel[id] = str_to_num(playerlevel)
return PLUGIN_CONTINUE
} Code: Select all
#include <fun> // Not sure if this is needed or not, but couldn't get mine to work without.
#include <fakemeta> // Will use for a future update, already used, just trying to get someone to help me with testing.
public plugin_init()
//[....]
register_event("ResetHUD", "on_spawn", "be")
//[....]
} Code: Select all
public on_spawn(id)
{
if (PlayerLevel[id] <= 5) // The number 5 Decides which levels are included, and Hopefully you know simple math to know what the <= means..
{
set_user_health(id, 150);
}
}