-
Notifications
You must be signed in to change notification settings - Fork 6
Global Functions
Complete reference for all server functions exposed to Lua scripting system.
Function Call Methods:
-
Namespace:
Player.GetObjByIndex(index)✅ PREFERRED (organized, clear) Both methods have identical performance (zero overhead). Namespaces are implemented via dual-binding in C++.
- Server
- Object
- Player
- Combat
- Stats
- Inventory
- Item
- Monster
- ItemBag
- Buff
- Skill
- Viewport
- Move
- Party
- DB
- Message
- Timer
- ActionTick
- Scheduler
- Utility
- Log
- Lang
- Script Loading
Server configuration and information functions.
Server.GetCode()Returns: int - Unique server code identifier
Description: Returns the unique server code identifier of current game server.
Usage:
local serverCode = Server.GetCode()
Log.Add(string.format("Server Code: %d", serverCode))Server.GetName()Returns: string - Server display name
Description: Returns the display name of current game server.
Usage:
local serverName = Server.GetName()
Log.Add("Server: " .. serverName)
Message.Send(0, -1, 1, string.format("Welcome to %s!", serverName))Server.GetVIPLevel()Returns: int - VIP level setting (-1 if not set)
Description: Returns VIP level setting of current game server.
Usage:
local vipLevel = Server.GetVIPLevel()
if vipLevel > 0 then
Log.Add(string.format("VIP Level: %d", vipLevel))
endServer.IsNonPvP()Returns: bool - true if PvP disabled, false otherwise
Description: Returns whether server has PvP disabled globally.
Usage:
if Server.IsNonPvP() then
Log.Add("PvP is disabled on this server")
Message.Send(0, iPlayerIndex, 0, "This is a non-PvP server")
endServer.Is28Option()Returns: bool - true if +28 enabled, false otherwise
Description: Returns whether server has item option +28 enabled globally.
Usage:
if Server.Is28Option() then
-- Allow creation of +28 items
itemInfo.Option3 = 7 -- +28
endServer.GetClassPointsPerLevel(iPlayerClassType)Parameters:
-
iPlayerClassType(int): Character class type
Returns: int - Stat points gained per level for specified class
Description: Returns stat points gained per level for specified character class. This is a game rule setting.
Usage:
local pointsPerLevel = Server.GetClassPointsPerLevel(Enums.CharacterClassType.WIZARD)
Log.Add(string.format("Wizard gets %d points per level", pointsPerLevel))Object management and limits.
Object.GetMax()Returns: int - Maximum total object count
Description: Returns maximum total object count (monsters + players + summons).
Usage:
local maxObjects = Object.GetMax()
Log.Add(string.format("Max objects: %d", maxObjects))Object.GetMaxMonster()Returns: int - Maximum monster count
Description: Returns maximum monster object count.
Usage:
local maxMonsters = Object.GetMaxMonster()Object.GetMaxUser()Returns: int - Maximum user count
Description: Returns maximum player object count (online + queue).
Usage:
local maxUsers = Object.GetMaxUser()Object.GetMaxOnlineUser()
⚠️ Not available in s6 - This function does not exist in the s6 build.
Returns: int - Maximum online player capacity
Description: Returns maximum online player capacity.
Usage:
local maxOnline = Object.GetMaxOnlineUser()
Log.Add(string.format("Max online players: %d", maxOnline))Object.GetMaxQueueUser()
⚠️ Not available in s6 - This function does not exist in the s6 build.
Returns: int - Maximum queue player capacity
Description: Returns maximum queue player capacity.
Usage:
local maxQueue = Object.GetMaxQueueUser()Object.GetMaxItem()Returns: int - Maximum item on ground count
Description: Returns maximum item on ground count.
Usage:
local maxItems = Object.GetMaxItem()Object.GetMaxSummonMonster()Returns: int - Maximum summoned monster count
Description: Returns maximum summoned monster count.
Usage:
local maxSummons = Object.GetMaxSummonMonster()Object.GetStartUserIndex()Returns: int - Starting index of player object range
Description: Returns starting index of player object range. Use for iterating through players.
Usage:
local startIndex = Object.GetStartUserIndex()
local Player.IsConnected = Player.IsConnected
for i = startIndex, Object.GetMaxUser() - 1 do
if Player.IsConnected(i) then
local oPlayer = Player.GetObjByIndex(i)
-- Process player
end
endObject.ForEach(callback)Parameters:
-
callback(function): Callback function called for each object. ReceivesoObject(object). Returnfalseto break iteration.
Returns: None
Description: Iterates through ALL objects including players, monsters, summons, and items. Skips empty slots (OBJ_EMPTY). Use when you need to process all object types.
Usage:
-- Count players and monsters separately using dedicated iterators
local playerCount = 0
local monsterCount = 0
Object.ForEachPlayer(function(oPlayer)
playerCount = playerCount + 1
return true
end)
Object.ForEachMonster(function(oMonster)
monsterCount = monsterCount + 1
return true
end)
Log.Add(string.format("Objects: %d players, %d monsters", playerCount, monsterCount))
-- Find players at specific coordinates
local targetX, targetY = 100, 100
Object.ForEachPlayer(function(oPlayer)
if oPlayer.X == targetX and oPlayer.Y == targetY then
Log.Add(string.format("Found player %s at (%d, %d)",
oPlayer.AccountId, targetX, targetY))
return false -- break
end
return true
end)Object.ForEachPlayer(callback)Parameters:
-
callback(function): Callback function called for each player. ReceivesoPlayer(object). Returnfalseto break iteration.
Returns: None
Description: Iterates through all connected players (PLAYER_PLAYING state). High-performance C++ iteration - 10-20x faster than Lua loops.
Usage:
-- Count online players
local playerCount = 0
Object.ForEachPlayer(function(oPlayer)
playerCount = playerCount + 1
return true -- continue
end)
Log.Add(string.format("Players online: %d", playerCount))
-- Find specific player (break early)
Object.ForEachPlayer(function(oPlayer)
if oPlayer.Name == "TargetPlayer" then
Log.Add("Found player!")
return false -- break
end
return true -- continue
end)
-- Send message to all high-level players
Object.ForEachPlayer(function(oPlayer)
if oPlayer.Level >= 400 then
Message.Send(0, oPlayer.Index, 1, "Elite player bonus!")
end
return true
end)Object.ForEachPlayerOnMap(mapNumber, callback)Parameters:
-
mapNumber(int): Map number to filter by -
callback(function): Callback function called for each player on map. ReceivesoPlayer(object). Returnfalseto break iteration.
Returns: None
Description: Iterates through players on specific map only. More efficient than filtering manually.
Usage:
-- Count players in Lorencia
local lorenciaPlayers = 0
Object.ForEachPlayerOnMap(0, function(oPlayer)
lorenciaPlayers = lorenciaPlayers + 1
return true
end)
Log.Add(string.format("Lorencia players: %d", lorenciaPlayers))
-- Award bonus to all players in Devias
Object.ForEachPlayerOnMap(2, function(oPlayer)
Player.SetMoney(oPlayer.Index, 1000000, false)
Message.Send(0, oPlayer.Index, 0, "Devias bonus: 1kk zen!")
return true
end)
-- Teleport all players from specific map
Object.ForEachPlayerOnMap(10, function(oPlayer)
Move.ToMap(oPlayer.Index, 0, 130, 130) -- To Lorencia
return true
end)Object.ForEachMonster(callback)Parameters:
-
callback(function): Callback function called for each monster. ReceivesoMonster(object). Returnfalseto break iteration.
Returns: None
Description: Iterates through all alive monsters on server.
Usage:
-- Count all monsters
local monsterCount = 0
Object.ForEachMonster(function(oMonster)
monsterCount = monsterCount + 1
return true
end)
Log.Add(string.format("Total monsters: %d", monsterCount))
-- Heal all monsters
Object.ForEachMonster(function(oMonster)
oMonster.Life = oMonster.MaxLife
return true
end)
-- Find specific monster class
Object.ForEachMonster(function(oMonster)
if oMonster.Class == 275 then -- Golden Goblin
Log.Add(string.format("Golden Goblin at map %d", oMonster.MapNumber))
end
return true
end)Object.ForEachMonsterOnMap(mapNumber, callback)Parameters:
-
mapNumber(int): Map number to filter by -
callback(function): Callback function called for each monster on map. ReceivesoMonster(object). Returnfalseto break iteration.
Returns: None
Description: Iterates through monsters on specific map only.
Usage:
-- Kill all monsters in Devias
Object.ForEachMonsterOnMap(2, function(oMonster)
oMonster.Life = 0
oMonster.Live = false
return true
end)
-- Buff monsters in specific map
Object.ForEachMonsterOnMap(10, function(oMonster)
oMonster.AddLife = oMonster.AddLife + 5000
oMonster.Life = math.min(oMonster.Life + 5000, oMonster.MaxLife)
return true
end)
-- Count monsters by map
local counts = {}
for mapNum = 0, 10 do
local count = 0
Object.ForEachMonsterOnMap(mapNum, function(oMonster)
count = count + 1
return true
end)
if count > 0 then
Log.Add(string.format("Map %d: %d monsters", mapNum, count))
end
endObject.ForEachMonsterByClass(monsterClass, callback)Parameters:
-
monsterClass(int): Monster class ID to filter by -
callback(function): Callback function called for each monster of specified class. ReceivesoMonster(object). Returnfalseto break iteration.
Returns: None
Description: Iterates through monsters of specific class type only.
Usage:
-- Find all Golden Goblins
Object.ForEachMonsterByClass(275, function(oMonster)
Log.Add(string.format("Golden Goblin: Map %d at (%d, %d)",
oMonster.MapNumber, oMonster.X, oMonster.Y))
return true
end)
-- Kill all White Wizards
Object.ForEachMonsterByClass(230, function(oMonster)
oMonster.Life = 0
oMonster.Live = false
return true
end)
-- Count specific monster type
local bossCount = 0
Object.ForEachMonsterByClass(666, function(oMonster) -- Boss class
bossCount = bossCount + 1
return true
end)
Log.Add(string.format("Boss count: %d", bossCount))Object.ForEachPartyMember(partyNumber, callback)Parameters:
-
partyNumber(int): Party number (fromoPlayer.PartyNumber) -
callback(function): Callback function called for each party member. ReceivesoPlayer(object). Returnfalseto break iteration.
Returns: None
Description: Iterates through all members of specified party.
Usage:
-- Award bonus to entire party
function AwardPartyBonus(iPlayerIndex)
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil and oPlayer.PartyNumber >= 0 then
Object.ForEachPartyMember(oPlayer.PartyNumber, function(oMember)
Player.SetMoney(oMember.Index, 5000000, false)
Message.Send(0, oMember.Index, 1, "Party bonus: 5kk zen!")
return true
end)
end
end
-- Check if party is in same location
function IsPartyInMap(partyNumber, targetMap)
local allInMap = true
Object.ForEachPartyMember(partyNumber, function(oMember)
if oMember.MapNumber ~= targetMap then
allInMap = false
return false -- break early
end
return true
end)
return allInMap
end
-- Send party-wide message
function PartyBroadcast(partyNumber, message)
Object.ForEachPartyMember(partyNumber, function(oMember)
Message.Send(0, oMember.Index, 0, message)
return true
end)
endObject.ForEachGuildMember(guildName, callback)Parameters:
-
guildName(string): Guild name to filter by -
callback(function): Callback function called for each guild member. ReceivesoPlayer(object). Returnfalseto break iteration.
Returns: None
Description: Iterates through all online members of specified guild.
Usage:
-- Send guild-wide message
function GuildBroadcast(guildName, message)
Object.ForEachGuildMember(guildName, function(oMember)
Message.Send(0, oMember.Index, 2, message)
return true
end)
end
-- Count online guild members
function GetOnlineGuildCount(guildName)
local count = 0
Object.ForEachGuildMember(guildName, function(oMember)
count = count + 1
return true
end)
return count
end
-- Award guild achievement reward
Object.ForEachGuildMember("TopGuild", function(oMember)
Player.SetMoney(oMember.Index, 10000000, false)
Message.Send(0, oMember.Index, 1, "Guild achievement reward!")
return true
end)
-- Check if all guild members are in same map
function IsGuildInSameMap(guildName, targetMap)
local allInMap = true
Object.ForEachGuildMember(guildName, function(oMember)
if oMember.MapNumber ~= targetMap then
allInMap = false
return false -- break early
end
return true
end)
return allInMap
endObject.ForEachNearby(centerIndex, range, callback)Parameters:
-
centerIndex(int): Center object index -
range(int): Range in map units -
callback(function): Callback function called for each nearby object. ReceivesoObject(object) anddistance(int). Returnfalseto break iteration.
Returns: None
Description: Iterates through all objects within specified range of center object. Automatically calculates distance and filters by same map.
Usage:
-- AOE buff to nearby players
function ApplyAOEBuff(iPlayerIndex, range)
local oCenter = Player.GetObjByIndex(iPlayerIndex)
if not oCenter then return end
Object.ForEachPlayerOnMap(oCenter.MapNumber, function(oPlayer)
local dx = math.abs(oPlayer.X - oCenter.X)
local dy = math.abs(oPlayer.Y - oCenter.Y)
local distance = math.sqrt(dx * dx + dy * dy)
if distance <= range then
Buff.Add(oPlayer.Index, 50, 0, 100, 0, 0, 60, 0, iPlayerIndex)
Message.Send(0, oPlayer.Index, 0, "AOE buff applied!")
end
return true
end)
end
-- Find nearest monster to player
function FindNearestMonster(iPlayerIndex)
local nearestMonster = nil
local nearestDistance = 999999
local oCenter = Player.GetObjByIndex(iPlayerIndex)
if not oCenter then return nil, 0 end
Object.ForEachMonsterOnMap(oCenter.MapNumber, function(oMonster)
local dx = math.abs(oMonster.X - oCenter.X)
local dy = math.abs(oMonster.Y - oCenter.Y)
local distance = math.sqrt(dx * dx + dy * dy)
if distance < nearestDistance and distance <= 50 then
nearestMonster = oMonster
nearestDistance = distance
end
return true
end)
return nearestMonster, nearestDistance
end
-- Count players in area
function CountPlayersInArea(iCenterIndex, radius)
local count = 0
local oCenter = Player.GetObjByIndex(iCenterIndex)
if not oCenter then return 0 end
Object.ForEachPlayerOnMap(oCenter.MapNumber, function(oPlayer)
local dx = math.abs(oPlayer.X - oCenter.X)
local dy = math.abs(oPlayer.Y - oCenter.Y)
local distance = math.sqrt(dx * dx + dy * dy)
if distance <= radius then
count = count + 1
end
return true
end)
return count
endObject.CountPlayersOnMap(mapNumber)
Object.CountPlayersOnMap(mapNumber, filter)Parameters:
-
mapNumber(int): Map number -
filter(function, optional): Filter callback. ReceivesoPlayer, returnstrueto count,falseto skip
Returns: int - Number of players matching criteria
Description: Count players on specific map. Optional filter callback allows custom conditions for flexible counting without full iteration overhead.
Usage:
-- Simple count (all players)
local totalPlayers = Object.CountPlayersOnMap(0)
if totalPlayers > 50 then
Log.Add("Lorencia is crowded!")
end
-- Count high level players
local elitePlayers = Object.CountPlayersOnMap(0, function(oPlayer)
return oPlayer.Level >= 400
end)
-- Count VIP players (0 = basic VIP, -1 = no VIP)
local vipCount = Object.CountPlayersOnMap(0, function(oPlayer)
return oPlayer.userData.VIPType >= 0
end)
-- Count players with specific stats
local strongPlayers = Object.CountPlayersOnMap(0, function(oPlayer)
return oPlayer.userData.Strength >= 1000 and oPlayer.userData.Dexterity >= 1000
end)
-- Complex event validation
local readyPlayers = Object.CountPlayersOnMap(10, function(oPlayer)
return oPlayer.Level >= 400
and oPlayer.PartyNumber >= 0
and oPlayer.userData.Resets >= 5
and oPlayer.userData.Money >= 10000000
end)
-- Count players in area
local playersInArea = Object.CountPlayersOnMap(2, function(oPlayer)
return oPlayer.X >= 100 and oPlayer.X <= 150
and oPlayer.Y >= 100 and oPlayer.Y <= 150
end)
-- Check all maps for high level players
for mapNum = 0, 10 do
local count = Object.CountPlayersOnMap(mapNum, function(oPlayer)
return oPlayer.Level >= 400
end)
if count > 0 then
Log.Add(string.format("Map %d: %d elite players", mapNum, count))
end
endObject.CountMonstersOnMap(mapNumber)
Object.CountMonstersOnMap(mapNumber, filter)Parameters:
-
mapNumber(int): Map number -
filter(function, optional): Filter callback. ReceivesoMonster, returnstrueto count,falseto skip
Returns: int - Number of monsters matching criteria
Description: Count monsters on specific map. Optional filter callback allows custom conditions for flexible counting.
Usage:
-- Simple count (all monsters)
local totalMonsters = Object.CountMonstersOnMap(2)
if totalMonsters < 10 then
Log.Add("Devias needs respawn!")
end
-- Count boss monsters
local bossCount = Object.CountMonstersOnMap(2, function(oMonster)
return oMonster.Class >= 200 and oMonster.Class <= 250
end)
-- Count specific monster type
local goldenGoblins = Object.CountMonstersOnMap(0, function(oMonster)
return oMonster.Class == 275
end)
-- Count high HP monsters
local tankMonsters = Object.CountMonstersOnMap(2, function(oMonster)
return oMonster.Life > 50000
end)
-- Count monsters in area
local monstersInArea = Object.CountMonstersOnMap(3, function(oMonster)
return oMonster.X >= 50 and oMonster.X <= 100
and oMonster.Y >= 50 and oMonster.Y <= 100
end)
-- Count low HP monsters (for AOE finish)
local lowHpMonsters = Object.CountMonstersOnMap(2, function(oMonster)
local hpPercent = (oMonster.Life / oMonster.MaxLife) * 100
return hpPercent < 20
end)
-- Event validation
function CanStartBossEvent(mapNumber)
-- Check if any monsters remain
local monsterCount = Object.CountMonstersOnMap(mapNumber)
if monsterCount > 0 then
return false, "Map has monsters"
end
-- Check if enough players ready
local readyPlayers = Object.CountPlayersOnMap(mapNumber, function(oPlayer)
return oPlayer.Level >= 400 and oPlayer.PartyNumber >= 0
end)
if readyPlayers < 5 then
return false, "Not enough players"
end
return true, "Event can start"
endObject.GetObjByName(playerName)Parameters:
-
playerName(string): Player character name
Returns: object|nil - Player object if found, nil otherwise
Description: Optimized player search with early exit. More efficient than Player.GetObjByName() for single lookups.
Usage:
-- Find and teleport player
local oTarget = Object.GetObjByName("PlayerName")
if oTarget ~= nil then
Move.ToMap(oTarget.Index, 0, 130, 130)
Log.Add(string.format("Teleported %s", oTarget.Name))
else
Log.Add("Player not found or offline")
end
-- Check if player is online
function IsPlayerOnline(playerName)
return Object.GetObjByName(playerName) ~= nil
end
-- Send message to specific player
local oPlayer = Object.GetObjByName("Admin")
if oPlayer ~= nil then
Message.Send(0, oPlayer.Index, 1, "GM message")
endObject.AddMonster(iMonIndex, iMapNumber, iBeginX, iBeginY, iEndX, iEndY, iMonAttr)Parameters:
-
iMonIndex(int): Monster class ID (same asoMonster.Class) -
iMapNumber(int): Map to spawn the monster on -
iBeginX(int): Spawn area start X coordinate -
iBeginY(int): Spawn area start Y coordinate -
iEndX(int): Spawn area end X coordinate -
iEndY(int): Spawn area end Y coordinate -
iMonAttr(int): Elemental attribute - useEnums.ElementTypevalues,0for none
Returns: int - Object index of the spawned monster, or -1 on failure
Description: Spawns a monster of the given class on the specified map. The actual position is
chosen randomly within the defined bounding box. The monster is fully initialized and enters the
world immediately. If iMonAttr > 0 the monster's pentagram main attribute is overridden.
Notes:
- Returns
-1if the server object pool is full orgObjSetMonsterfails. -
iBeginX/iBeginYcan equaliEndX/iEndYto spawn at a fixed point.
Usage:
-- Spawn a Balrog at a fixed position on Devias (map 2)
local monIndex = Object.AddMonster(26, 2, 100, 100, 100, 100, 0)
if monIndex >= 0 then
Log.Add(string.format("Spawned Balrog at index %d", monIndex))
end
-- Spawn a Fire-element boss in a random area
local monIndex = Object.AddMonster(275, 7, 50, 50, 80, 80, Enums.ElementType.FIRE)
if monIndex < 0 then
Log.Add("[Error] Failed to spawn boss - object pool may be full")
end
-- Spawn wave of monsters for event
function SpawnEventWave(mapNumber, monClass, count, x1, y1, x2, y2)
local spawned = 0
for i = 1, count do
local idx = Object.AddMonster(monClass, mapNumber, x1, y1, x2, y2, 0)
if idx >= 0 then
spawned = spawned + 1
end
end
Log.Add(string.format("Spawned %d/%d monsters on map %d", spawned, count, mapNumber))
return spawned
endObject.DelMonster(aIndex)Parameters:
-
aIndex(int): Object index of the monster to remove
Returns: int - Result of internal gObjDel call
Description: Immediately removes the monster at the given object index from the world.
Use the index returned by Object.AddMonster or obtained from an iterator callback.
Usage:
-- Remove a specific monster by index
Object.DelMonster(monIndex)
-- Clear all monsters of a class from a map
Object.ForEachMonsterOnMap(mapNumber, function(oMonster)
if oMonster.Class == 275 then
Object.DelMonster(oMonster.Index)
end
return true
end)
-- Spawn and schedule removal after 60 seconds
local idx = Object.AddMonster(26, 2, 100, 100, 100, 100, 0)
if idx >= 0 then
Timer.Create(60000, "remove_monster_" .. idx, function()
Object.DelMonster(idx)
end)
endPlayer management and operations.
Player.IsConnected(iPlayerIndex)Parameters:
-
iPlayerIndex(int): Player object index
Returns: bool - true if connected and playing, false otherwise
Description: Checks if player at given index is connected and in PLAYER_PLAYING state.
Usage:
if Player.IsConnected(iPlayerIndex) then
Log.Add("Player is online and playing")
endPlayer.GetObjByIndex(iPlayerIndex)Parameters:
-
iPlayerIndex(int): Player object index
Returns: object - Player object (stObject), or nil if not found
Description: Returns player object at specified index.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
Log.Add(string.format("Player: %s, Level: %d", oPlayer.Name, oPlayer.Level))
endPlayer.GetObjByName(szPlayerName)Parameters:
-
szPlayerName(string): Player character name
Returns: object - Player object (stObject), or nil if not found
Description: Finds player by name and returns their object.
Usage:
local oPlayer = Player.GetObjByName("PlayerName")
if oPlayer ~= nil then
Log.Add(string.format("Found player at index: %d", oPlayer.Index))
endPlayer.GetIndexByName(szPlayerName)Parameters:
-
szPlayerName(string): Player character name
Returns: int - Player index, or -1 if not found
Description: Finds player by name and returns their index.
Usage:
local index = Player.GetIndexByName("PlayerName")
if index >= 0 then
Log.Add(string.format("Player found at index: %d", index))
Message.Send(0, index, 0, "Hello!")
endPlayer.SetMoney(iPlayerIndex, iAmount, bResetMoney)Parameters:
-
iPlayerIndex(int): Player object index -
iAmount(int): Zen amount (can be negative to subtract) -
bResetMoney(bool): Iftrue, resets to 0 first
Returns: None
Description: Sets or modifies player's zen currency.
Usage:
-- Add 1,000,000 zen
Player.SetMoney(iPlayerIndex, 1000000, false)
-- Reset and set to 5,000,000 zen
Player.SetMoney(iPlayerIndex, 5000000, true)
-- Subtract 500,000 zen
Player.SetMoney(iPlayerIndex, -500000, false)Save character data to database.
Player.SaveCharacter(playerIndex)Parameters:
-
oPlayer(object): Player object (stObject)
Example:
local oPlayer = Player.GetObjByIndex(100)
Player.SetMoney(oPlayer.Index, 100000, false)
Player.SaveCharacter(oPlayer)
Log.Add(string.format("Saved character: %s", oPlayer.Name))Send experience packet to player (required after modifying oPlayer.Experience).
Player.SetExp(playerIndex, targetIndex, exp, attackDamage, msbFlag, monsterType)Parameters:
-
playerIndex(number): Player index receiving experience -
targetIndex(number): Source index (monster/player that gave exp) -
exp(number): Experience amount -
attackDamage(number): Damage dealt (for display) -
msbFlag(boolean): Master Skill Book flag -
monsterType(number): Monster type ID
Example:
-- Give experience from custom event
local oPlayer = Player.GetObjByIndex(100)
oPlayer.Experience = oPlayer.Experience + 50000
Player.SetExp(oPlayer.Index, -1, 50000, 0, false, 0)
-- Give experience after killing custom boss
function OnBossKilled(oPlayer, bossIndex)
local expReward = 100000
oPlayer.Experience = oPlayer.Experience + expReward
Player.SetExp(oPlayer.Index, bossIndex, expReward, 0, false, 0)
Message.Send(oPlayer.Index, 0, string.format("Gained %d experience!", expReward))
end
-- Party experience distribution
function GivePartyExp(partyLeaderIndex, totalExp)
local partyCount = Party.GetCount(partyLeaderIndex)
local expPerMember = math.floor(totalExp / partyCount)
Object.ForEachPartyMember(partyLeaderIndex, function(oPlayer)
oPlayer.Experience = oPlayer.Experience + expPerMember
Player.SetExp(oPlayer.Index, -1, expPerMember, 0, false, 0)
end)
endNotes:
- Always call after modifying
oPlayer.Experience - Use
targetIndex = -1for non-combat experience -
msbFlagandmonsterTypecan befalseand0for custom exp
Player.SetRuud(iPlayerIndex, iRuud, iObtainedRuud, bIsObtainedRuud)
⚠️ Not available in s6 - This function does not exist in the s6 build.
Parameters:
-
iPlayerIndex(int): Player object index -
iRuud(int): Base Ruud value (used wheniObtainedRuud = 0) -
iObtainedRuud(int): Ruud to add (>0) or subtract (<0) -
bIsObtainedRuud(bool): Show notification iftrue
Returns: None
Description: Sets or modifies player's Ruud currency.
Usage:
-- Add 1000 Ruud with notification
Player.SetRuud(iPlayerIndex, 0, 1000, true)
-- Set to exactly 5000 Ruud
Player.SetRuud(iPlayerIndex, 5000, 0, false)
-- Subtract 500 Ruud
Player.SetRuud(iPlayerIndex, 0, -500, false)Player.Reset(iPlayerIndex)
⚠️ Not available in s6 - This function does not exist in the s6 build.
Parameters:
-
iPlayerIndex(int): Player object index
Returns: None
Description: Performs character reset operation for specified player.
Usage:
Player.Reset(iPlayerIndex)
Log.Add(string.format("Player %d performed reset", iPlayerIndex))Player.GetEvo(iPlayerIndex)Parameters:
-
iPlayerIndex(int): Player object index
Returns: int - Evolution level (1-5), or -1 if invalid
Description: Returns character evolution/class level.
Usage:
local evo = Player.GetEvo(iPlayerIndex)
if evo >= 3 then
Log.Add("Player is 3rd class or higher")
-- Allow 3rd class items
endPlayer.ReCalc(iPlayerIndex)Parameters:
-
iPlayerIndex(int): Player object index
Returns: None
Description: Recalculates all character stats, damage, defense, etc.
Usage:
-- After equipment change
Player.ReCalc(iPlayerIndex)
-- After stat modification
Stats.Set(iPlayerIndex, Enums.StatType.STRENGTH, 100, 0, 0)
Player.ReCalc(iPlayerIndex)Player.SendLife(iPlayerIndex, iLife, flag, iShield)Parameters:
-
iPlayerIndex(int): Player object index -
iLife(int): Life value to send -
flag(int): Update flag - useEnums.HPManaUpdateFlagvalues -
iShield(int): Shield value to send
Returns: None
Description: Sends a life/shield update packet to the player's client. Must be called
after directly modifying oPlayer.Life, oPlayer.MaxLife, oPlayer.Shield, or
oPlayer.MaxShield so the client reflects the change.
Notes:
- Use
Enums.HPManaUpdateFlag.CURRENT_HP_MANA(255) to send the current life/shield values. - Use
Enums.HPManaUpdateFlag.MAX_HP_MANA(254) after a max HP change (level up, stat change, buff). - Use
Enums.HPManaUpdateFlag.INVENTORY_STATE_RESET(253) to restore inventory interaction after a failed item operation.
Usage:
-- Restore player to full HP and sync client
oPlayer.Life = oPlayer.MaxLife
oPlayer.Shield = oPlayer.MaxShield
Player.SendLife(oPlayer.Index, oPlayer.Life, Enums.HPManaUpdateFlag.CURRENT_HP_MANA, oPlayer.Shield)
-- After a stat change that increases MaxLife, send new max values
Stats.Set(oPlayer.Index, Enums.StatType.VITALITY, oPlayer.userData.Vitality + 10, 0, 0)
Player.ReCalc(oPlayer.Index)
Player.SendLife(oPlayer.Index, (oPlayer.MaxLife + oPlayer.AddLife), Enums.HPManaUpdateFlag.MAX_HP_MANA, (oPlayer.MaxShield + oPlayer.AddShield))Player.SendMana(iPlayerIndex, iMana, flag, iBP)Parameters:
-
iPlayerIndex(int): Player object index -
iMana(int): Mana value to send -
flag(int): Update flag - useEnums.HPManaUpdateFlagvalues -
iBP(int): AG/stamina value to send
Returns: None
Description: Sends a mana/AG update packet to the player's client. Must be called
after directly modifying oPlayer.Mana, oPlayer.MaxMana, oPlayer.BP, or
oPlayer.MaxBP so the client reflects the change.
Usage:
-- Restore mana and AG, then sync client
oPlayer.Mana = oPlayer.MaxMana
oPlayer.BP = oPlayer.MaxBP
Player.SendMana(oPlayer.Index, oPlayer.Mana, Enums.HPManaUpdateFlag.CURRENT_HP_MANA, oPlayer.BP)
-- After a stat change that affects MaxMana
Player.ReCalc(oPlayer.Index)
Player.SendMana(oPlayer.Index, (oPlayer.MaxMana + oPlayer.AddMana), Enums.HPManaUpdateFlag.MAX_HP_MANA, oPlayer.MaxBP)Combat-related functions.
Combat.GetTopDamageDealer(aTargetMonsterIndex)Parameters:
-
aTargetMonsterIndex(int): Monster object index
Returns: int - Player index who dealt most damage, or -1 if none
Description: Returns player index who dealt most damage to specified monster.
Usage:
function onMonsterDie(oPlayer, oMonster)
if oMonster ~= nil then
local topPlayerIndex = Combat.GetTopDamageDealer(oMonster.Index)
if topPlayerIndex >= 0 then
-- Reward top damager
Player.SetMoney(topPlayerIndex, 1000000, false)
Message.Send(0, topPlayerIndex, 1, "Top damage bonus: 1kk zen!")
end
end
endCharacter stats and leveling.
Stats.Set(iPlayerIndex, iStatType, iStatValue, iStatAddType, iLevelUpPoint)Parameters:
-
iPlayerIndex(int): Player object index -
iStatType(int): Stat type (0=STR, 1=DEX, 2=VIT, 3=ENE, 4=CMD) -
iStatValue(int): Stat value to add -
iStatAddType(int): Add type (0=base stat, 1=additional stat) -
iLevelUpPoint(int): Level up points to use
Returns: None
Description: Adds to player's base or additional stats.
Usage:
-- Add 10 base STR
Stats.Set(iPlayerIndex, Enums.StatType.STRENGTH, 10, 0, 0)
-- Add 50 additional ENE (from items/buffs)
Stats.Set(iPlayerIndex, Enums.StatType.ENERGY, 50, 1, 0)Stats.SendUpdate(iPlayerIndex, iStatType, iStatValue, iLevelUpPoint)Parameters:
-
iPlayerIndex(int): Player object index -
iStatType(int): Stat type -
iStatValue(int): New stat value -
iLevelUpPoint(int): Remaining level up points
Returns: None
Description: Sends stat update packet to player client.
Usage:
Stats.SendUpdate(iPlayerIndex, Enums.StatType.STRENGTH, 100, 0)Stats.LevelUp(oPlayer, i64AddExp, iMonsterType, szEventType)Parameters:
-
oPlayer(object): Player object (stObject) -
i64AddExp(UINT64): Experience points to add -
iMonsterType(int): Monster type (0 if not from monster) -
szEventType(string): Event type name
Returns: bool - true if level up occurred, false otherwise
Description: Adds experience points to player, handles level up if threshold reached.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
Stats.LevelUp(oPlayer, 1000000, 0, "Quest")
endInventory management functions.
Inventory.SendUpdate(iPlayerIndex, iInventoryPos)Parameters:
-
iPlayerIndex(int): Player object index -
iInventoryPos(int): Inventory slot position
Returns: None
Description: Sends update packet for single inventory slot.
Usage:
-- Update weapon slot
Inventory.SendUpdate(iPlayerIndex, 0)Inventory.SendDelete(iPlayerIndex, iInventoryPos)Parameters:
-
iPlayerIndex(int): Player object index -
iInventoryPos(int): Inventory slot position
Returns: None
Description: Sends delete packet for inventory slot.
Usage:
Inventory.SendDelete(iPlayerIndex, 12)Inventory.SendList(iPlayerIndex)Parameters:
-
iPlayerIndex(int): Player object index
Returns: None
Description: Sends complete inventory list packet to player.
Usage:
Inventory.SendList(iPlayerIndex)Inventory.HasSpace(oPlayer, iItemHeight, iItemWidth)Parameters:
-
oPlayer(object): Player object (stObject) -
iItemHeight(int): Item height (1-4) -
iItemWidth(int): Item width (1-2)
Returns: bool - true if has space, false otherwise
Description: Checks if inventory has enough empty space for item of specified dimensions.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
if Inventory.HasSpace(oPlayer, 2, 1) then
-- Has space for 2x1 item
Log.Add("Inventory has space")
else
Message.Send(0, iPlayerIndex, 0, "Inventory is full")
end
endInventory.Insert(iPlayerIndex, oItem)Parameters:
-
iPlayerIndex(int): Player object index -
oItem(object): Item object (ItemInfo)
Returns: None
Description: Inserts item object into first available inventory slot.
Usage:
Inventory.Insert(iPlayerIndex, oItem)Inventory.InsertAt(iPlayerIndex, oItem, btInventoryPos)Parameters:
-
iPlayerIndex(int): Player object index -
oItem(object): Item object (ItemInfo) -
btInventoryPos(BYTE): Inventory position
Returns: BYTE - Result code
Description: Inserts item at specific inventory position.
Usage:
local result = Inventory.InsertAt(iPlayerIndex, oItem, 12)
if result == 1 then
Log.Add("Item inserted successfully")
endInventory.Delete(iPlayerIndex, iInventoryItemPos)Parameters:
-
iPlayerIndex(int): Player object index -
iInventoryItemPos(int): Inventory slot position
Returns: None
Description: Removes item from specified inventory position.
Usage:
Inventory.Delete(iPlayerIndex, 12)
Log.Add("Item deleted from slot 12")Inventory.SetSlot(iPlayerIndex, iInventoryItemStartPos, btItemType)Parameters:
-
iPlayerIndex(int): Player object index -
iInventoryItemStartPos(int): Starting position -
btItemType(BYTE): Item type (use0xFFto clear)
Returns: None
Description: Sets inventory slot state. Use 0xFF to clear slots occupied by item.
Usage:
-- Clear item slots starting at pos 12
Inventory.SetSlot(iPlayerIndex, 12, 0xFF)Inventory.ReduceDur(oPlayer, iInventoryItemPos, iDurabilityMinus)Parameters:
-
oPlayer(object): Player object (stObject) -
iInventoryItemPos(int): Inventory slot position -
iDurabilityMinus(int): Durability to subtract
Returns: int - Remaining durability
Description: Reduces item durability at specified inventory slot.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
local remainingDur = Inventory.ReduceDur(oPlayer, 0, 1)
Log.Add(string.format("Remaining durability: %d", remainingDur))
endItem information and creation functions.
Item.IsValid(iItemId)Parameters:
-
iItemId(int): Item ID
Returns: int - 1 if valid, 0 otherwise
Description: Returns whether item ID is valid.
Usage:
local itemId = Helpers.MakeItemId(0, 0)
if Item.IsValid(itemId) == 1 then
Log.Add("Valid item")
endItem.GetKindA(iItemId)Parameters:
-
iItemId(int): Item ID
Returns: int - KindA category type
Description: Returns KindA attribute of specified item (primary category).
Usage:
local kindA = Item.GetKindA(Helpers.MakeItemId(0, 0))
if kindA == Enums.ItemKindA.WEAPON then
Log.Add("This is a weapon")
endItem.GetKindB(iItemId)Parameters:
-
iItemId(int): Item ID
Returns: int - KindB subcategory type
Description: Returns KindB attribute of specified item (secondary category/subtype).
Usage:
local kindB = Item.GetKindB(Helpers.MakeItemId(0, 0))
if kindB == Enums.ItemKindB.SWORD_KNIGHT then
Log.Add("Knight sword")
endItem.GetAttr(iItemId)Parameters:
-
iItemId(int): Item ID
Returns: object - Item attributes struct (ItemAttr)
Description: Returns structure containing all item attributes (width, height, durability, requirements, etc.).
Usage:
local itemId = Helpers.MakeItemId(0, 0)
local attr = Item.GetAttr(itemId)
if attr ~= nil then
local itemName = attr:GetName()
Log.Add(string.format("Item: %s", itemName))
Log.Add(string.format("Size: %dx%d", attr.Width, attr.Height))
Log.Add(string.format("Damage: %d-%d", attr.DamageMin, attr.DamageMax))
endItem.IsSocket(iItemId)Parameters:
-
iItemId(int): Item ID
Returns: bool - true if socket item, false otherwise
Description: Returns whether item can have socket options.
Usage:
if Item.IsSocket(Helpers.MakeItemId(0, 0)) then
Log.Add("Item supports sockets")
endItem.IsExcSocketAccessory(iItemId)
⚠️ Not available in s6 - This function does not exist in the s6 build. UseItem.GetExcellentOption()in s6 instead.
Parameters:
-
iItemId(int): Item ID
Returns: bool - true if excellent socket accessory, false otherwise
Description: Returns whether item is excellent socket accessory.
Usage:
if Item.IsExcSocketAccessory(itemId) then
-- Handle excellent accessory
endItem.IsElemental(iItemId)
⚠️ Not available in s6 - This function does not exist in the s6 build.
Parameters:
-
iItemId(int): Item ID
Returns: bool - true if elemental item, false otherwise
Description: Returns whether item is elemental type.
Usage:
if Item.IsElemental(itemId) then
-- Handle elemental item
endItem.IsPentagram(iItemId)
⚠️ Not available in s6 - This function does not exist in the s6 build.
Parameters:
-
iItemId(int): Item ID
Returns: bool - true if pentagram, false otherwise
Description: Returns whether item is pentagram type.
Usage:
if Item.IsPentagram(itemId) then
-- Handle pentagram
endItem.IsMasterPentagram(iItemId)
⚠️ Not available in s6 - This function does not exist in the s6 build.
Parameters:
-
iItemId(int): Item ID
Returns: bool - true if master pentagram item, false otherwise
Description: Returns whether item is a master pentagram type.
Usage:
if Item.IsMasterPentagram(itemId) then
-- Handle master pentagram
endItem.IsPentagramJewel(iItemId)
⚠️ Not available in s6 - This function does not exist in the s6 build.
Parameters:
-
iItemId(int): Item ID
Returns: bool - true if pentagram jewel, false otherwise
Description: Returns whether item is a pentagram jewel.
Usage:
if Item.IsPentagramJewel(itemId) then
-- Handle pentagram jewel
endItem.IsMasterPentagramJewel(iItemId)
⚠️ Not available in s6 - This function does not exist in the s6 build.
Parameters:
-
iItemId(int): Item ID
Returns: bool - true if master pentagram jewel, false otherwise
Description: Returns whether item is a master pentagram jewel.
Usage:
if Item.IsMasterPentagramJewel(itemId) then
-- Handle master pentagram jewel
endItem.GetExcellentOption(iItemId)🔵 s6 only - This function exists only in the s6 build.
Parameters:
-
iItemId(int): Item ID
Returns: int - Excellent option flags
Description: Returns excellent option bitmask for the given item. In s7+ this functionality is split into dedicated type-check functions.
Usage:
local excOptions = Item.GetExcellentOption(itemId)
if excOptions > 0 then
Log.Add(string.format("Item has excellent options: %d", excOptions))
endItem.GetSetOption(iItemId)Parameters:
-
iItemId(int): Item ID
Returns: int - Set option index
Description: Generates ancient/set options and returns set index.
Usage:
local setIndex = Item.GetSetOption(itemId)
Log.Add(string.format("Set option: %d", setIndex))Item.GetRandomLevel(iMinLevel, iMaxLevel)Parameters:
-
iMinLevel(int): Minimum level -
iMaxLevel(int): Maximum level
Returns: int - Random item level
Description: Returns random item level between min and max range.
Usage:
local itemLevel = Item.GetRandomLevel(0, 9) -- Random 0-9
Log.Add(string.format("Random level: %d", itemLevel))Item.Create(iPlayerIndex, stItemCreate)Parameters:
-
iPlayerIndex(int): Player object index -
stItemCreate(object): Item creation info (CreateItemInfo struct)
Returns: None
Description: Creates item based on CreateItemInfo structure. The behaviour depends on the MapNumber field of CreateItemInfo:
-
MapNumber0–199 - normal map number. The item drops on the ground at coordinates (X,Y) on that map. Works in both s6 and s7+. -
MapNumber200+ (s7+ only) - special creation mode. The map coordinates are ignored and the value selects a specific system insertion path (inventory insert, mix system, event inventory, etc.). UseEnums.ItemSerialCreateMapTypeconstants for these values.
Usage:
-- Drop item on the ground at player's position (s6 and s7+)
local itemInfo = CreateItemInfo.new()
itemInfo.MapNumber = oPlayer.MapNumber
itemInfo.X = oPlayer.X
itemInfo.Y = oPlayer.Y
itemInfo.ItemId = Helpers.MakeItemId(14, 13) -- Jewel of Bless
itemInfo.ItemLevel = 0
itemInfo.Durability = 1
itemInfo.Option1 = 0
itemInfo.Option2 = 0
itemInfo.Option3 = 0
itemInfo.LootIndex = iPlayerIndex
Item.Create(iPlayerIndex, itemInfo)-- Insert item into a specific inventory slot (s7+ only)
local itemInfo = CreateItemInfo.new()
itemInfo.MapNumber = Enums.ItemSerialCreateMapType.INVENTORY_INSERT
itemInfo.ItemId = Helpers.MakeItemId(14, 13) -- Jewel of Bless
itemInfo.ItemLevel = 0
itemInfo.Durability = 1
itemInfo.Option1 = 0
itemInfo.Option2 = 0
itemInfo.Option3 = 0
itemInfo.LootIndex = iPlayerIndex
Item.Create(iPlayerIndex, itemInfo)Item.MakeRandomSet(iPlayerIndex, bGremoryCase, bDropMasterySet)Parameters:
-
iPlayerIndex(int): Player object index -
bGremoryCase(int): Gremory case flag -
bDropMasterySet(bool): Drop mastery set flag
Returns: None
Description: Generates random set item for player, drops under player or adds to Gremory case.
Usage:
-- Drop random set item on ground
Item.MakeRandomSet(iPlayerIndex, 0, false)
-- Add to Gremory case
Item.MakeRandomSet(iPlayerIndex, 1, false)Monster management functions for reading monster data.
Monster.GetAttr(iClass)Parameters:
-
iClass(int): Monster class ID
Returns: MonsterAttr - Monster attribute object, or nil if not found
Description: Returns the attribute table for a monster class. Provides access to stats, combat values, resistances and other configuration data for the given monster class ID.
📖 See Monster Structure for full
MonsterAttrfield reference.
Usage:
local attr = Monster.GetAttr(275) -- Kundun
if attr ~= nil then
Log.Add(string.format("Kundun HP: %d, Defense: %d", attr.HP, attr.Defense))
Log.Add(string.format("Name: %s", attr:GetName()))
endItem bag system functions.
ItemBag.Add(iBagType, iParam1, iParam2, strFileName)Parameters:
-
iBagType(int): Bag type (0=DROP, 1=INVENTORY, 2=MONSTER, 3=EVENT) -
iParam1(int): Parameter 1 (depends on bag type) -
iParam2(int): Parameter 2 (depends on bag type) -
strFileName(string): Bag file name (without .txt extension)
Returns: None
Description: Loads item bag configuration file.
Bag Types:
-
0 (DROP): Drop from ground item
-
iParam1: Item ID -
iParam2: Item level
-
-
1 (INVENTORY): Open from inventory item
-
iParam1: Item ID -
iParam2: Item level
-
-
2 (MONSTER): Drop from monster
-
iParam1: Monster class -
iParam2: Map number (0 = all maps)
-
-
3 (EVENT): Event reward
-
iParam1: Event ID -
iParam2: Event level
-
Usage:
-- Drop bag for Luck Box item
ItemBag.Add(0, Helpers.MakeItemId(14, 11), 0, 'Item_(14,11,0)_Luck_Box')
-- Inventory bag for Red Ribbon Box
ItemBag.Add(1, Helpers.MakeItemId(12, 32), 0, 'Item_(12,32,0)_Red_Ribbon_Box')
-- Monster bag for Dark Elf (class 340)
ItemBag.Add(2, 340, 0, 'Monster_(340)_Dark_Elf')
-- Event bag for Chaos Castle level 1 reward
ItemBag.Add(3, 14, 1, 'Event_ChaosCastle(1)_Reward')ItemBag.CreateItem(iPlayerIndex, stBagItem)Parameters:
-
iPlayerIndex(int): Player object index -
stBagItem(object): Bag item struct (BagItem)
Returns: None
Description: Creates and drops item from item bag structure.
Usage:
ItemBag.CreateItem(iPlayerIndex, bagItemStruct)ItemBag.Use(playerIndex, bagType, param1, param2)Parameters:
-
playerIndex(int): Player object index -
bagType(int): Type of item bag (use Enums.ItemBagType) -
param1(int): Depends on bag type (see below) -
param2(int): Depends on bag type (see below)
Returns: None
Description: Use item bags to give items to player. The item must be registered as a bag in ItemBagScript.lua.
ItemBag.Use(oPlayer.Index, Enums.ItemBagType.DROP, itemId, itemLevel)Uses an item that is registered as a bag. Contents drop at player's position.
Example:
-- Use item 14/13 (registered as bag) - drops contents on ground
ItemBag.Use(oPlayer.Index, Enums.ItemBagType.DROP, 14, 13)ItemBag.Use(oPlayer.Index, Enums.ItemBagType.INVENTORY, itemId, itemLevel)Uses an item that is registered as a bag. Contents go to player's inventory.
Example:
-- Use item 14/13 (registered as bag) - gives contents to inventory
ItemBag.Use(oPlayer.Index, Enums.ItemBagType.INVENTORY, 14, 13)ItemBag.Use(oPlayer.Index, Enums.ItemBagType.MONSTER, monsterClass, oPlayer.Index)Drops loot from specific monster type.
Example:
-- Drop Golden Goblin loot
ItemBag.Use(oPlayer.Index, Enums.ItemBagType.MONSTER, 53, oPlayer.Index)ItemBag.Use(oPlayer.Index, Enums.ItemBagType.EVENT, eventBagId, oPlayer.Index)Uses event-specific bag from ItemBagScript.lua.
Example:
ItemBag.Use(oPlayer.Index, Enums.ItemBagType.EVENT, 300, oPlayer.Index)Use reward box item (drop contents):
function UseRewardBox(oPlayer)
local boxItemId = 14
local boxLevel = 13
ItemBag.Use(oPlayer.Index, Enums.ItemBagType.DROP, boxItemId, boxLevel)
Message.Send(0, oPlayer.Index, 0, "Reward box opened!")
endUse reward box item (to inventory):
function UseRewardBox(oPlayer)
local boxItemId = 14
local boxLevel = 13
ItemBag.Use(oPlayer.Index, Enums.ItemBagType.INVENTORY, boxItemId, boxLevel)
Message.Send(0, oPlayer.Index, 0, "Rewards received!")
endEvent reward:
function GiveEventReward(oPlayer)
ItemBag.Use(oPlayer.Index, Enums.ItemBagType.EVENT, 500, oPlayer.Index)
Message.Send(0, oPlayer.Index, 0, "Event reward received!")
endDrop boss loot:
function DropBossLoot(oPlayer, bossClass)
ItemBag.Use(oPlayer.Index, Enums.ItemBagType.MONSTER, bossClass, oPlayer.Index)
endNote: For DROP and INVENTORY types, the item (itemId + itemLevel) must be registered as a bag in ItemBagScript.lua.
Buff management functions.
Buff.Add(oPlayer, iBuffIndex, EffectType1, EffectValue1, EffectType2, EffectValue2, iBuffDuration, BuffSendValue, nAttackerIndex)Parameters:
-
oPlayer(object): Player object (stObject) -
iBuffIndex(int): Buff index -
EffectType1(BYTE): Effect type 1 -
EffectValue1(int): Effect value 1 -
EffectType2(BYTE): Effect type 2 -
EffectValue2(int): Effect value 2 -
iBuffDuration(int): Duration in seconds -
BuffSendValue(WORD): Send value -
nAttackerIndex(int): Attacker index
Returns: None
Description: Adds buff effect to player with specified parameters.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
Buff.Add(oPlayer, buffIndex, 0, 100, 0, 0, 60, 0, -1)
endBuff.AddCashShop(oPlayer, wItemID, iBuffDuration)Parameters:
-
oPlayer(object): Player object (stObject) -
wItemID(WORD): Cash shop item ID -
iBuffDuration(int): Duration in seconds
Returns: None
Description: Adds buff effect from cash shop item usage.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
Buff.AddCashShop(oPlayer, itemID, 3600) -- 1 hour buff
endBuff.AddItem(oPlayer, iBuffIndex)Parameters:
-
oPlayer(object): Player object (stObject) -
iBuffIndex(int): Buff index
Returns: None
Description: Adds item-based buff to player.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
Buff.AddItem(oPlayer, buffIndex)
endBuff.Remove(oPlayer, iBuffIndex)Parameters:
-
oPlayer(object): Player object (stObject) -
iBuffIndex(int): Buff index
Returns: None
Description: Removes specified buff from player if active.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
Buff.Remove(oPlayer, buffIndex)
endBuff.CheckUsed(oPlayer, iBuffIndex)Parameters:
-
oPlayer(object): Player object (stObject) -
iBuffIndex(int): Buff index
Returns: bool - true if buff is active, false otherwise
Description: Returns whether player has specified buff active.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
if Buff.CheckUsed(oPlayer, buffIndex) then
Log.Add("Buff is active")
end
endSkill usage functions.
Skill.UseDuration(oPlayer, oTarget, TargetXPos, TargetYPos, iPlayerDirection, iMagicNumber)Parameters:
-
oPlayer(object): Player object (stObject) using skill -
oTarget(object): Target object (stObject) -
TargetXPos(int): Target X position -
TargetYPos(int): Target Y position -
iPlayerDirection(int): Player direction -
iMagicNumber(int): Magic/skill number
Returns: None
Description: Uses duration-based skill on target.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
local oTarget = Player.GetObjByIndex(targetIndex)
if oPlayer ~= nil and oTarget ~= nil then
Skill.UseDuration(oPlayer, oTarget, oTarget.X, oTarget.Y, oPlayer.Dir, magicNumber)
endSkill.UseNormal(oPlayer, oTarget, iMagicNumber)Parameters:
-
oPlayer(object): Player object (stObject) using skill -
oTarget(object): Target object (stObject) -
iMagicNumber(int): Magic/skill number
Returns: None
Description: Uses instant skill on target.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
local oTarget = Player.GetObjByIndex(targetIndex)
if oPlayer ~= nil and oTarget ~= nil then
Skill.UseNormal(oPlayer, oTarget, magicNumber)
endViewport management functions.
Viewport.Create(oPlayer)Parameters:
-
oPlayer(object): Player object (stObject)
Returns: None
Description: Creates viewport for player, shows surrounding objects.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
Viewport.Create(oPlayer)
endViewport.Destroy(oPlayer)Parameters:
-
oPlayer(object): Player object (stObject)
Returns: None
Description: Destroys viewport for player, hides surrounding objects.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil then
Viewport.Destroy(oPlayer)
endMovement and teleportation functions.
Move.Gate(iPlayerIndex, iGateIndex)Parameters:
-
iPlayerIndex(int): Player object index -
iGateIndex(int): Gate index from gate configuration
Returns: bool - true if successful, false otherwise
Description: Teleports player through specified gate index.
Usage:
if Move.Gate(iPlayerIndex, 17) then
Log.Add("Player moved through gate")
else
Message.Send(0, iPlayerIndex, 0, "Cannot use gate")
endMove.ToMap(iTargetObjectIndex, iMapNumber, PosX, PosY)Parameters:
-
iTargetObjectIndex(int): Target object index (player or monster) -
iMapNumber(int): Target map number -
PosX(BYTE): Target X coordinate -
PosY(BYTE): Target Y coordinate
Returns: None
Description: Teleports player or monster to specified map and coordinates.
Usage:
-- Teleport to Lorencia
Move.ToMap(iPlayerIndex, 0, 130, 130)
-- Teleport to Devias
Move.ToMap(iPlayerIndex, 2, 220, 70)Move.Warp(iTargetObjectIndex, PosX, PosY)Parameters:
-
iTargetObjectIndex(int): Target object index (player or monster) -
PosX(BYTE): Target X coordinate -
PosY(BYTE): Target Y coordinate
Returns: None
Description: Teleports player or monster within current map.
Usage:
-- Warp within current map
Move.Warp(iPlayerIndex, 150, 150)Party system functions.
Party.GetCount(iPartyNumber)Parameters:
-
iPartyNumber(int): Party number
Returns: int - Number of members in party
Description: Returns number of members in specified party.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil and oPlayer.PartyNumber >= 0 then
local memberCount = Party.GetCount(oPlayer.PartyNumber)
Log.Add(string.format("Party has %d members", memberCount))
endParty.GetMember(iPartyNumber, iArrayIndex)Parameters:
-
iPartyNumber(int): Party number -
iArrayIndex(int): Array index (1=leader, 2-5=members)
Returns: int - Player index
Description: Returns player index from party at specified position. Index 1 is always the party leader.
Usage:
local oPlayer = Player.GetObjByIndex(iPlayerIndex)
if oPlayer ~= nil and oPlayer.PartyNumber >= 0 then
-- Get party leader
local leaderIndex = Party.GetMember(oPlayer.PartyNumber, 1)
local oLeader = Player.GetObjByIndex(leaderIndex)
if oLeader ~= nil then
Log.Add(string.format("Party leader: %s", oLeader.Name))
end
-- Get all party members
local memberCount = Party.GetCount(oPlayer.PartyNumber)
for i = 1, memberCount do
local memberIndex = Party.GetMember(oPlayer.PartyNumber, i)
local oMember = Player.GetObjByIndex(memberIndex)
if oMember ~= nil then
Log.Add(string.format("Member %d: %s", i, oMember.Name))
end
end
endDatabase query functions.
DB.QueryDS(iPlayerIndex, iQueryNumber, szQuery, ...)Parameters:
-
iPlayerIndex(int): Player object index -
iQueryNumber(int): Query identifier (use to match responses) -
szQuery(string): SQL query string (supports format strings) -
...(variadic): Optional format string arguments
Returns: None
Description: Executes SQL query on DataServer database. Results received in DSDBQueryReceive callback.
Usage:
-- Simple query
DB.QueryDS(iPlayerIndex, 1, "SELECT * FROM Character WHERE Name = 'Player1'")
-- Query with parameters
local playerName = "TestPlayer"
DB.QueryDS(iPlayerIndex, 1001, string.format("SELECT Name, cLevel FROM Character WHERE Name = '%s'", playerName))
-- Handle results in callback
function DSDBQueryReceive(iUserIndex, iQueryNumber, btIsLastPacket, iCurrentRow, btColumnCount, btCurrentPacket, oRow)
if iQueryNumber == 1001 and oRow ~= nil then
local columnName = oRow:GetColumnName()
local value = oRow:GetValue()
Log.Add(string.format("%s = %s", columnName, value))
end
endDB.QueryJS(iPlayerIndex, iQueryNumber, szQuery, ...)Parameters:
-
iPlayerIndex(int): Player object index -
iQueryNumber(int): Query identifier (use to match responses) -
szQuery(string): SQL query string (supports format strings) -
...(variadic): Optional format string arguments
Returns: None
Description: Executes SQL query on JoinServer database. Results received in JSDBQueryReceive callback.
Usage:
-- Query account info
local accountId = "admin"
DB.QueryJS(iPlayerIndex, 2001, string.format("SELECT memb_guid FROM MEMB_INFO WHERE memb___id = '%s'", accountId))
-- Handle results in callback
function JSDBQueryReceive(iUserIndex, iQueryNumber, btIsLastPacket, iCurrentRow, btColumnCount, btCurrentPacket, oRow)
if iQueryNumber == 2001 and oRow ~= nil then
local columnName = oRow:GetColumnName()
local value = oRow:GetValue()
Log.Add(string.format("%s = %s", columnName, value))
end
endSee: Database-Structures for detailed query examples
Message and notification functions.
Message.Send(iPlayerIndex, aTargetIndex, btType, szMessage)Parameters:
-
iPlayerIndex(int): Player index (use 0 for system messages) -
aTargetIndex(int): Target index (-1for all players, specific index for single player) -
btType(BYTE): Message type:-
0= Golden text center screen -
1= Blue text left side -
2= Green text, guild notice -
3= Red text left side
-
-
szMessage(string): Message text
Returns: None
Description: Sends notice message to player(s).
Usage:
-- Send to single player (normal)
Message.Send(0, iPlayerIndex, 0, "Hello player!")
-- Send to all players (golden)
Message.Send(0, -1, 1, "Server restart in 5 minutes!")
-- Send to single player (blue)
Message.Send(0, iPlayerIndex, 2, "Quest completed!")Timer and tick functions.
Timer.GetTick()Returns: ULONGLONG - Milliseconds since system boot
Description: Returns milliseconds since system boot. Used for cooldown calculations.
Usage:
local currentTick = Timer.GetTick()
-- Check if 30 seconds passed
if (currentTick - lastActionTick) >= 30000 then
Log.Add("30 seconds passed")
endPlayer action timer/cooldown management.
ActionTick.Get(iPlayerIndex, iTimerIndex)Parameters:
-
iPlayerIndex(int): Player object index -
iTimerIndex(int): Timer index (0-2)
Returns: ULONGLONG - Tick count value, or 0 if invalid
Description: Gets tick count value from player's action timer by index.
Usage:
local lastTeleportTick = ActionTick.Get(iPlayerIndex, 0)
if (Timer.GetTick() - lastTeleportTick) >= 30000 then
Log.Add("Ready to teleport")
endActionTick.Set(iPlayerIndex, iTimerIndex, tickValue, [timerName])Parameters:
-
iPlayerIndex(int): Player object index -
iTimerIndex(int): Timer index (0-2) -
tickValue(ULONGLONG): Tick count value to set -
timerName(string, optional): Timer name for debugging
Returns: bool - true if successful, false otherwise
Description: Sets tick count value for player's action timer by index.
Usage:
-- Without name
ActionTick.Set(iPlayerIndex, 0, Timer.GetTick())
-- With name (for debugging)
ActionTick.Set(iPlayerIndex, 0, Timer.GetTick(), "Teleport")
ActionTick.Set(iPlayerIndex, 1, Timer.GetTick(), "Potion")
ActionTick.Set(iPlayerIndex, 2, Timer.GetTick(), "Buff")ActionTick.GetName(iPlayerIndex, iTimerIndex)Parameters:
-
iPlayerIndex(int): Player object index -
iTimerIndex(int): Timer index (0-2)
Returns: string - Timer name, or empty string if not set
Description: Gets name of player's action timer by index for debugging.
Usage:
local tickName = ActionTick.GetName(iPlayerIndex, 0)
Log.Add(string.format("Timer 0: %s", tickName))ActionTick.Clear(iPlayerIndex, iTimerIndex)Parameters:
-
iPlayerIndex(int): Player object index -
iTimerIndex(int): Timer index (0-2)
Returns: bool - true if successful, false otherwise
Description: Clears player's action timer, resets name and tick value to 0.
Usage:
-- Clear all timers on player disconnect
for i = 0, 2 do
ActionTick.Clear(iPlayerIndex, i)
endEvent scheduler system functions.
Scheduler.LoadFromXML(szXmlEventFileName)Parameters:
-
szXmlEventFileName(string): XML event file name (without path/extension)
Returns: bool - true if successful, false otherwise
Description: Loads event configuration from XML file.
Usage:
Scheduler.LoadFromXML("Events")Scheduler.GetEventCount()Returns: int - Number of loaded events
Description: Returns number of loaded events in scheduler.
Usage:
local eventCount = Scheduler.GetEventCount()
Log.Add(string.format("Loaded %d events", eventCount))Scheduler.CheckEventNotices(currentTick)Parameters:
-
currentTick(ULONGLONG): Current tick count
Returns: None
Description: Checks and triggers event notices based on current time.
Usage:
Scheduler.CheckEventNotices(Timer.GetTick())Scheduler.CheckEventStarts(currentTick)Parameters:
-
currentTick(ULONGLONG): Current tick count
Returns: None
Description: Checks and triggers event starts based on current time.
Usage:
Scheduler.CheckEventStarts(Timer.GetTick())Scheduler.CheckEventEnds(currentTick)Parameters:
-
currentTick(ULONGLONG): Current tick count
Returns: None
Description: Checks and triggers event ends based on current time.
Usage:
Scheduler.CheckEventEnds(Timer.GetTick())Scheduler.GetEventName(iEventId)Parameters:
-
iEventId(int): Event ID
Returns: string - Event name
Description: Returns event name by event ID.
Usage:
local eventName = Scheduler.GetEventName(1)
Log.Add(string.format("Event: %s", eventName))Scheduler.HasSecondPrecisionEvents()Returns: bool - true if any events use second precision, false otherwise
Description: Returns whether any loaded events use second-precision timing.
Usage:
if Scheduler.HasSecondPrecisionEvents() then
Log.Add("Scheduler requires second-precision checks")
endUtility and helper functions.
Utility.GetRandomRangedInt(min, max)Parameters:
-
min(int): Minimum value (inclusive) -
max(int): Maximum value (inclusive)
Returns: int - Random value between min and max (inclusive)
Description: Returns random integer value between min and max (inclusive).
Usage:
local randomNum = Utility.GetRandomRangedInt(0, 100) -- 0-100
Log.Add(string.format("Random: %d", randomNum))
-- Random item level
local itemLevel = Utility.GetRandomRangedInt(0, 15) -- 0-15Utility.GetLargeRand()Returns: int - Large random number
Description: Returns large random number.
Usage:
local largeRand = Utility.GetLargeRand()Utility.FireCracker(iPlayerIndex)Parameters:
-
iPlayerIndex(int): Player object index
Returns: None
Description: Generates firecracker visual effect for specified player.
Usage:
Utility.FireCracker(iPlayerIndex)Utility.SendEventTimer(playerIndex, milliseconds, countUp, displayType, deleteTimer)
⚠️ Not available in s6 - This function does not exist in the s6 build.
Parameters:
-
playerIndex(int): Player object index -
milliseconds(int): Timer duration in milliseconds (1000 = 1 second) -
countUp(int): Count direction -0= count down,1= count up -
displayType(int): Text label type (see table below) -
deleteTimer(int): Remove before expiry -0= show timer normally,1= remove immediately
Display Types:
| Value | Text Shown |
|---|---|
0 |
No text |
1 |
"Time limit" |
2 |
"Remaining time" |
3 |
"Hunting time" |
5 |
"Survival time" |
Returns: None
Description: Sends a visual countdown or countup timer directly to a specific player's screen. The timer automatically disappears when it reaches zero. Use deleteTimer = 1 only when you need to remove the timer before it naturally expires.
Usage:
-- Show 60-second countdown with "Remaining time" text
Utility.SendEventTimer(oPlayer.Index, 60000, 0, 2, 0)
-- Player sees: "Remaining time: 01:00" counting down
-- Automatically disappears after 60 seconds
-- Show 30-second countup with "Hunting time" text
Utility.SendEventTimer(oPlayer.Index, 30000, 1, 3, 0)
-- Player sees: "Hunting time: 00:00" counting up to 00:30
-- Automatically disappears after 30 seconds
-- Cancel/remove the timer before it expires
-- IMPORTANT: displayType must match the timer you're removing!
Utility.SendEventTimer(oPlayer.Index, 0, 0, 2, 1)
-- Must use same displayType (2) as when createdExamples:
-- Show buff duration (auto-removes when done)
function ShowBuffTimer(oPlayer, durationSeconds)
local ms = durationSeconds * 1000
Utility.SendEventTimer(oPlayer.Index, ms, 0, 2, 0)
-- Timer automatically disappears after durationSeconds
end
-- Cancel buff timer early
function CancelBuffTimer(oPlayer)
-- Must use same displayType (2) as in ShowBuffTimer!
Utility.SendEventTimer(oPlayer.Index, 0, 0, 2, 1)
-- Removes timer immediately before it expires
end
-- Event registration with cancel
local eventTimerType = 3 -- Store type for later removal
function ShowRegistrationTimer(oPlayer, durationSeconds)
local ms = durationSeconds * 1000
Utility.SendEventTimer(oPlayer.Index, ms, 1, eventTimerType, 0)
end
function CancelRegistration(oPlayer)
-- Use same type as ShowRegistrationTimer
Utility.SendEventTimer(oPlayer.Index, 0, 0, eventTimerType, 1)
endImportant Notes:
- This is a visual-only timer - no callback fires when it expires
- Timer automatically disappears when countdown/countup finishes
- The timer counts automatically on client side
-
CRITICAL: When removing early (
deleteTimer = 1), you must use the samedisplayTypeas when you created the timer - To update the timer, send a new one with same type (replaces previous one)
Common Mistake:
-- ❌ WRONG - displayType doesn't match!
Utility.SendEventTimer(oPlayer.Index, 60000, 0, 2, 0) -- Created with type 2
Utility.SendEventTimer(oPlayer.Index, 0, 0, 1, 1) -- Trying to remove with type 1 (won't work!)
-- ✅ CORRECT - displayType matches
Utility.SendEventTimer(oPlayer.Index, 60000, 0, 2, 0) -- Created with type 2
Utility.SendEventTimer(oPlayer.Index, 0, 0, 2, 1) -- Removing with type 2 (works!)Difference from Timer.Create:
| Feature | Timer.Create | Utility.SendEventTimer |
|---|---|---|
| Visual display | ✓ Yes | ✓ Yes |
| Callback when expires | ✓ Yes | ✗ No |
| Auto-cleanup on expiry | ✓ Yes | ✓ Yes |
| Named timers | ✓ Yes | ✗ No |
| Multiple players at once | ✓ Yes | ✗ One at a time |
| Control functions | ✓ Yes (Start/Stop/Remove) | ✗ Manual only |
| Removal | By name | By matching type |
When to use:
- Use Timer.Create when you need to execute code when time expires
- Use Utility.SendEventTimer for pure visual indicators where you handle logic separately
Server logging functions.
Log.Add(szLog)Parameters:
-
szLog(string): Log message
Returns: None
Description: Adds log message to game server console with default color (white).
Usage:
Log.Add("Server started successfully")
Log.Add(string.format("Player %s connected", playerName))Log.AddC(dwLogColor, szLog)Parameters:
-
dwLogColor(DWORD): Log color (useEnums.LogColororHelpers.RGB()) -
szLog(string): Log message
Returns: None
Description: Adds colored log message to game server console.
Usage:
-- Using predefined colors
Log.AddC(Enums.LogColor.Red, "Critical error!")
Log.AddC(Enums.LogColor.Green, "Event started")
Log.AddC(Enums.LogColor.Yellow, "Warning: Low memory")
-- Using custom RGB color
Log.AddC(Helpers.RGB(255, 0, 255), "Custom magenta message")Language text retrieval functions.
Lang.GetText(iLangID, iTextType, iTextID)Parameters:
-
iLangID(int): Language code (useoPlayer.LangCodeto get the player's language) -
iTextType(int): Text category (useEnums.eLANGUAGE_TEXT_TYPE) -
iTextID(int): Text entry ID within the category
Returns: string - Localised text string
Description: Returns a localised text string from the language database for the given language, category, and text ID.
Usage:
-- Send localised message to player
local text = Lang.GetText(oPlayer.LangCode, Enums.eLANGUAGE_TEXT_TYPE.COMMON, 1)
Message.Send(0, oPlayer.Index, 0, text)Global functions for loading Lua scripts into the server scripting engine. These are called without a namespace prefix, typically from Main.lua during initialization.
LoadScript(path)Parameters:
-
path(string): Relative path to the Lua script file (.lua)
Returns: None
Description: Loads and executes a Lua script file. The path is resolved automatically relative to the server's configured scripts directory.
Usage:
-- In Main.lua
LoadScript("Callbacks.lua")
LoadScript("EventHandler.lua")
LoadScript("Includes/EventScheduler.lua")LoadEncryptedScript(path)Parameters:
-
path(string): Relative path to the encrypted Lua script file (.lsc)
Returns: None
Description: Loads and executes an encrypted Lua script file (.lsc format). Can be used as a drop-in replacement for LoadScript when the script file has been encrypted with the IGC File Encrypt tool. The path is resolved automatically relative to the server's configured scripts directory.
Notes:
- Files must be encrypted with the IGC File Encrypt tool before use
- Use
.lscextension for encrypted files to distinguish them from plain.luafiles - Functionally identical to
LoadScript- only the file format differs
Usage:
-- Plain script
LoadScript("Callbacks.lua")
-- Encrypted equivalent (after encrypting Callbacks.lua → Callbacks.lsc)
LoadEncryptedScript("Callbacks.lsc")
-- Mix of plain and encrypted scripts
LoadScript("Includes/EventScheduler.lua")
LoadEncryptedScript("EventHandler.lsc")- CALLBACKS - Event callback reference
- Player-Structure - Player object structure
- Item-Structures - Item structures
- Database-Structures - Database query structures
-
Defines/GlobalFunctions.lua- Type hints for IDE
MuLua Scripting Plugin | Home
Version 1.5 | 2026-05-06 14:10 GMT+2