Player Functions
Everything you need to work with players on the server side: getting data, modifying attributes, managing positions, and more.
Player Indices
Every connected player has a unique index (aIndex). This is how you reference them in functions.
-- Get min/max player indices
local minUser = GetMinUserIndex() -- Usually 0
local maxUser = GetMaxUserIndex() -- e.g., 1000
-- Iterate all online players
for aIndex = GetMinUserIndex(), GetMaxUserIndex() do
if GetObjectConnected(aIndex) == OBJECT_ONLINE then
local name = GetObjectName(aIndex)
LogPrint("Player online: " .. name)
end
end
Connection States
Players go through different connection states:
OBJECT_OFFLINE = 0 -- Disconnected
OBJECT_CONNECTED = 1 -- Connected but not logged in
OBJECT_LOGGED = 2 -- Logged in but character not loaded
OBJECT_ONLINE = 3 -- In game (use this one!)
Always check for OBJECT_ONLINE before doing anything with a player!
Basic Player Info
-- Check connection state
if GetObjectConnected(aIndex) == OBJECT_ONLINE then
-- Safe to proceed
end
-- Get character name
local name = GetObjectName(aIndex)
-- Get account ID
local accountId = GetObjectAccount(aIndex)
-- Get IP address
local ip = GetObjectIpAddress(aIndex)
-- Find player by name
local targetIndex = GetObjectIndexByName("PlayerName")
if targetIndex ~= -1 then
LogPrint("Player found!")
else
LogPrint("Player not online")
end
Class Constants
CLASS_DW = 0 -- Dark Wizard
CLASS_DK = 1 -- Dark Knight
CLASS_FE = 2 -- Fairy Elf
CLASS_MG = 3 -- Magic Gladiator
CLASS_DL = 4 -- Dark Lord
CLASS_SU = 5 -- Summoner
CLASS_RF = 6 -- Rage Fighter
CLASS_GL = 7 -- Grow Lancer
CLASS_RW = 8 -- Rune Wizard
CLASS_SL = 9 -- Slayer
CLASS_GC = 10 -- Gun Crusher
CLASS_KM = 11 -- Light Wizard
CLASS_LM = 12 -- Lemuria Mage
CLASS_IK = 13 -- Illusion Knight
CLASS_AL = 14 -- Abyss Lord
Level and Class
-- Get class
local class = GetObjectClass(aIndex)
if class == CLASS_DK then
LogPrint("Dark Knight!")
end
-- Get/Set level
local level = GetObjectLevel(aIndex)
SetObjectLevel(aIndex, 400)
-- Get/Set level points
local points = GetObjectLevelUpPoint(aIndex)
SetObjectLevelUpPoint(aIndex, 1000)
-- Experience
local exp = GetObjectExperience(aIndex)
local nextExp = GetObjectNextExperience(aIndex)
local progress = (exp / nextExp) * 100
Master Level
-- Get/Set master level
local mlevel = GetObjectMasterLevel(aIndex)
SetObjectMasterLevel(aIndex, 400)
-- Master points
local mpoints = GetObjectMasterPoint(aIndex)
SetObjectMasterPoint(aIndex, 100)
-- Master experience
local mexp = GetObjectMasterExperience(aIndex)
local nextMexp = GetObjectMasterNextExperience(aIndex)
Reset Counts
-- Get reset count
local resets = GetObjectReset(aIndex)
LogPrint("Resets: " .. resets)
-- Get master reset count
local mresets = GetObjectMasterReset(aIndex)
Attributes (Stats)
Getting Attributes
-- Total attributes (including bonuses from items)
local str = GetObjectStrength(aIndex)
local agi = GetObjectDexterity(aIndex)
local vit = GetObjectVitality(aIndex)
local ene = GetObjectEnergy(aIndex)
local cmd = GetObjectLeadership(aIndex)
-- Added attributes (points invested)
local addStr = GetObjectExtraStrength(aIndex)
local addAgi = GetObjectExtraDexterity(aIndex)
local addVit = GetObjectExtraVitality(aIndex)
local addEne = GetObjectExtraEnergy(aIndex)
local addCmd = GetObjectExtraLeadership(aIndex)
-- Base attributes (class default)
local baseStr = GetObjectDefaultStrength(aIndex)
Setting Attributes
SetObjectStrength(aIndex, 5000)
SetObjectDexterity(aIndex, 5000)
SetObjectVitality(aIndex, 5000)
SetObjectEnergy(aIndex, 5000)
SetObjectLeadership(aIndex, 5000)
-- IMPORTANT: Always recalculate after changing stats!
UserCalcAttribute(aIndex)
UserInfoSend(aIndex) -- Update client
Example - Reset Stats
function ResetStats(aIndex)
-- Get base values
local baseStr = GetObjectDefaultStrength(aIndex)
local baseAgi = GetObjectDefaultDexterity(aIndex)
local baseVit = GetObjectDefaultVitality(aIndex)
local baseEne = GetObjectDefaultEnergy(aIndex)
local baseCmd = GetObjectDefaultLeadership(aIndex)
-- Reset to base
SetObjectStrength(aIndex, baseStr)
SetObjectDexterity(aIndex, baseAgi)
SetObjectVitality(aIndex, baseVit)
SetObjectEnergy(aIndex, baseEne)
SetObjectLeadership(aIndex, baseCmd)
-- Calculate points to return
local level = GetObjectLevel(aIndex)
local mlevel = GetObjectMasterLevel(aIndex)
local pointsToReturn = (level * 5) + (mlevel * 7)
SetObjectLevelUpPoint(aIndex, pointsToReturn)
-- Recalculate everything
UserCalcAttribute(aIndex)
UserInfoSend(aIndex)
NoticeSend(aIndex, 1, "Stats reset!")
end
HP, MP, BP, and Shield
-- Get current/max values
local hp = GetObjectLife(aIndex)
local maxHp = GetObjectMaxLife(aIndex)
local mp = GetObjectMana(aIndex)
local maxMp = GetObjectMaxMana(aIndex)
local bp = GetObjectBP(aIndex)
local maxBp = GetObjectMaxBP(aIndex)
local sd = GetObjectShield(aIndex)
local maxSd = GetObjectMaxShield(aIndex)
-- Set values
SetObjectLife(aIndex, maxHp) -- Full HP
SetObjectMana(aIndex, maxMp)
SetObjectBP(aIndex, maxBp)
SetObjectShield(aIndex, maxSd)
-- Always update client after changes
UserInfoSend(aIndex)
Example - Full Heal
function FullHeal(aIndex)
SetObjectLife(aIndex, GetObjectMaxLife(aIndex))
SetObjectMana(aIndex, GetObjectMaxMana(aIndex))
SetObjectBP(aIndex, GetObjectMaxBP(aIndex))
SetObjectShield(aIndex, GetObjectMaxShield(aIndex))
UserInfoSend(aIndex)
NoticeSend(aIndex, 1, "Fully healed!")
end
Currency (Zen and Ruud)
-- Zen
local zen = GetObjectMoney(aIndex)
SetObjectMoney(aIndex, zen + 1000000)
MoneySend(aIndex, GetObjectMoney(aIndex)) -- Update client
-- Ruud
local ruud = GetObjectRuud(aIndex)
SetObjectRuud(aIndex, ruud + 10000)
RuudSend(aIndex, GetObjectRuud(aIndex))
Example - Give Reward
function GiveReward(aIndex, zenAmount, ruudAmount)
-- Add zen
local currentZen = GetObjectMoney(aIndex)
SetObjectMoney(aIndex, currentZen + zenAmount)
MoneySend(aIndex, GetObjectMoney(aIndex))
-- Add ruud
local currentRuud = GetObjectRuud(aIndex)
SetObjectRuud(aIndex, currentRuud + ruudAmount)
RuudSend(aIndex, GetObjectRuud(aIndex))
NoticeSend(aIndex, 1, string.format(
"Reward: %d Zen, %d Ruud", zenAmount, ruudAmount
))
end
Position and Maps
-- Get current position
local map = GetObjectMap(aIndex)
local x = GetObjectMapX(aIndex)
local y = GetObjectMapY(aIndex)
LogPrint(string.format("Position: %d, %d on map %d", x, y, map))
-- Set position (doesn't move immediately, use MoveUser)
SetObjectMap(aIndex, 0) -- Lorencia
SetObjectMapX(aIndex, 130)
SetObjectMapY(aIndex, 130)
-- Move to predefined gate
MoveUser(aIndex, 0) -- Gate 0
-- Move to specific coordinates
MoveUserEx(aIndex, 0, 130, 130) -- Map 0, coords 130,130
NoticeSend(aIndex, 1, "Teleported!")
PK System
-- Get PK count
local pkCount = GetObjectPKCount(aIndex)
-- Clear PK
SetObjectPKCount(aIndex, 0)
-- Get/Set PK level
local pkLevel = GetObjectPKLevel(aIndex)
SetObjectPKLevel(aIndex, 3)
PKLevelSend(aIndex, 3) -- Update client
-- PK timer
local pkTimer = GetObjectPKTimer(aIndex)
SetObjectPKTimer(aIndex, 0)
Chat Limits
-- Get chat limit time
local chatLimit = GetObjectChatLimitTime(aIndex)
-- Mute player for 10 minutes
SetObjectChatLimitTime(aIndex, 600)
NoticeSend(aIndex, 1, "You've been muted for 10 minutes!")
Authority (GM Level)
-- Get GM level (0=player, 1-3=GM)
local authority = GetObjectAuthority(aIndex)
if authority > 0 then
LogPrint("This player is GM level " .. authority)
end
-- Check GM permission
if CommandCheckGameMasterLevel(aIndex, 1) == 1 then
-- Has GM permission
else
NoticeSend(aIndex, 1, "No permission!")
return
end
Complete Example - Info Command
PlayerInfo = {}
PlayerInfo.Code = Toolkit:getUniqueIndex()
BridgeFunction:push("OnReadScript", function()
CommandAddInfo("/info", PlayerInfo.Code)
end)
BridgeFunction:push("OnCommandManager", function(aIndex, code, args)
if code == PlayerInfo.Code then
PlayerInfo:showInfo(aIndex)
return 1
end
return 0
end)
function PlayerInfo:showInfo(aIndex)
local name = GetObjectName(aIndex)
local class = GetObjectClass(aIndex)
local level = GetObjectLevel(aIndex)
local mlevel = GetObjectMasterLevel(aIndex)
local reset = GetObjectReset(aIndex)
local mreset = GetObjectMasterReset(aIndex)
local str = GetObjectStrength(aIndex)
local agi = GetObjectDexterity(aIndex)
local vit = GetObjectVitality(aIndex)
local ene = GetObjectEnergy(aIndex)
local hp = GetObjectLife(aIndex)
local maxHp = GetObjectMaxLife(aIndex)
local mp = GetObjectMana(aIndex)
local maxMp = GetObjectMaxMana(aIndex)
local zen = GetObjectMoney(aIndex)
local map = GetObjectMap(aIndex)
local x = GetObjectMapX(aIndex)
local y = GetObjectMapY(aIndex)
NoticeSend(aIndex, 0, "═══ PLAYER INFO ═══")
NoticeSend(aIndex, 0, string.format("Name: %s | Class: %d", name, class))
NoticeSend(aIndex, 0, string.format("Level: %d | MLvl: %d", level, mlevel))
NoticeSend(aIndex, 0, string.format("Reset: %d | MReset: %d", reset, mreset))
NoticeSend(aIndex, 0, string.format("STR: %d | AGI: %d | VIT: %d | ENE: %d",
str, agi, vit, ene))
NoticeSend(aIndex, 0, string.format("HP: %d/%d | MP: %d/%d",
hp, maxHp, mp, maxMp))
NoticeSend(aIndex, 0, string.format("Zen: %d", zen))
NoticeSend(aIndex, 0, string.format("Position: Map %d, X: %d, Y: %d",
map, x, y))
end
Best Practices
- Always check OBJECT_ONLINE before accessing player data
- Recalculate after changing stats - Use
UserCalcAttribute()andUserInfoSend() - Validate player indices - Check if GetObjectIndexByName() returns -1
- Update client - Use appropriate Send functions after changes (MoneySend, RuudSend, etc.)
- Use NoticeSend for feedback - Let players know what happened
Quick Reference
-- Connection
if GetObjectConnected(aIndex) == OBJECT_ONLINE then end
-- Basic info
local name = GetObjectName(aIndex)
local accountId = GetObjectAccount(aIndex)
-- Level
local level = GetObjectLevel(aIndex)
SetObjectLevel(aIndex, 400)
-- Stats
local str = GetObjectStrength(aIndex)
SetObjectStrength(aIndex, 5000)
UserCalcAttribute(aIndex)
UserInfoSend(aIndex)
-- HP/MP
SetObjectLife(aIndex, GetObjectMaxLife(aIndex))
UserInfoSend(aIndex)
-- Money
SetObjectMoney(aIndex, zen + amount)
MoneySend(aIndex, GetObjectMoney(aIndex))
-- Position
MoveUserEx(aIndex, map, x, y)
-- Authority
if CommandCheckGameMasterLevel(aIndex, 1) == 1 then end
That's player management covered! Next: working with items and monsters.