# Server Script

* Server scripts must exist in the project folder or under the "Scripts" directory with file names like *Hello.lua* to be read properly.

| Script                                                                  | Description                                                             |
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| **Server.onJoinPlayer(unit)**                                           | A new player connects.                                                  |
| **Server.onLeavePlayer(unit)**                                          | A specific user leaves the game.                                        |
| **Server.SendCenterLabel(text)**                                        | Display a label on the screen.                                          |
| **Server.SendSay(text, color)**                                         | Display a message in the chat window.                                   |
| **ScriptEventPublisher Server.GetTopic(topic)**                         | Register a specific topic to send and receive messages with the client. |
| **Server.FireEvent(topic, args…)**                                      | Send a message to the client with a specific topic.                     |
| **Server.players**                                                      | Retrieve a list of players.                                             |
| **Server.fields**                                                       | Retrieve the entire map list.                                           |
| **Server.CreateEventUnit(name, imageID)**                               | Create an event user.                                                   |
| **Server.GetField(dataID)**                                             | Retrieve the map of a specific ID.                                      |
| **ScriptUnit**                                                          | Monsters are objects similar to players.                                |
| **Server.playerLeavePartyCallback(scriptRoomPlayer,scriptParty)**       | Triggered when a player leaves the party.                               |
| **Server.playerJoinPartyCallback(scriptRoomPlayer,scriptParty)**        | Triggered when a player joins the party.                                |
| **Server.onAddItem(scriptUnit,titem)**                                  | Triggered when a user acquires an item.                                 |
| **Server.onRemoveItem(scriptUnit,titem)**                               | Triggered when a user removes or uses an item.                          |
| [**ScriptClan**](/punkland-studio/script/server-script/scriptclan.md)   | Retrieve the class the user belongs to.                                 |
| [**ScriptColor**](/punkland-studio/script/server-script/scriptcolor.md) | Retrieve color information.                                             |

* unit.type = (0=player, 1=event, 2=monster)

Example: Server Script - Display a Message Upon Player Level-Up and Grant an Item at a Specific Level

{% code title="Scripts/Servers/Hello.lua" overflow="wrap" lineNumbers="true" %}

```lua
function onUnitLevelUp(target, level)
    if target.level == 50 then --When a target reaches level 50, a notification will be broadcast to the entire server, and Item 1 will be distributed to the target.
        Server.SendCenterLabel(target.name .. 'has ' .. level .. 'become!')
        target.AddItem(1) 
    elseif target.level == 55 then  --When the target reaches level 55, Skill 5 and 5,000 game money will be awarded. 
        target.AddSkill(5)
        target.AddGameMoney(5000)
    end
end
 
Server.onUnitLevelUp.Add(onUnitLevelUp)
```

{% endcode %}

Example: Server Script - Broadcast a Message to All Players and Grant Rewards for PVP Kills

{% code title="Scripts/Servers/Hello.lua" overflow="wrap" lineNumbers="true" %}

```lua
function onUnitDead(target, attacker) --Target: Deceased, Attacker: Aggressor
    if (target.type==0 and attacker.type==0) then --If it is a PlayerUnit
        Server.SendCenterLabel(target.name..'as \n'..attacker.name..'The attacker killed the target.')
        attacker.AddGameMoney(100) --100 gold is awarded to the attacker.
        if rand(1, 100) <= 50 then
            attacker.AddItem(100) --The attacker has a 50% chance to receive Item 1.
        end
    end
end
Server.onUnitDead.Add(onUnitDead) -- Add the onUnitDead function to Server.onUnitDead.
```

{% endcode %}

Example: Using `onJoinField` - Display Player Name Upon Entering a Specific Map and Send a Server-Wide Message

{% code overflow="wrap" lineNumbers="true" %}

```lua
function onJoinField()
    function onJoinField_1(Field,unit)
        unit.SendCenterLabel(Field.name) -- Temporarily displays field names to units.
        if #Field.playerUnits > 10 then -- # indicates the length of the table.
            Server.SendSay(Field.name.."More than 11 players gathered!")
        end
    end
        local map = Server.GetField(1)
        if map ~= nil then
                map.onJoinField.Add(onJoinField_1)--When entering field 1, the onJoinField_1 function is called.
        end
end
Server.RunLater(onJoinField,1) -- Executes the onJoinField function after 1 second.
-- The reason we run it after 1 second is to avoid referencing nil since the map may not have been created after the server runs.
```

{% endcode %}

onLeaveField - Handle actions when leaving a specific map

> map - ScriptField
>
> unit - ScriptUnit

**File: Script Example for a Specific Map**\
**Usage Example: Decreasing the Value of a World Variable by 1 When Leaving the Map**

{% code overflow="wrap" lineNumbers="true" %}

```lua
function onLeaveField(map,unit)
  print('Leaving: ' .. map.name .. ' ' ..unit.name)
  Server.SetWorldVar(10, Server.GetWorldVar(10)-1)
end

Server.GetField(5).onLeaveField.Add(onLeaveField)
```

{% endcode %}

**Examples of Events Triggered During Specific Actions:**

* **onUseItem**: Triggered when an item is used.
* **onBuyGameMoneyItem**: Triggered when an item is purchased with in-game currency.
* **onSellGameMoneyItem**: Triggered when an item is sold for in-game currency.

{% code overflow="wrap" lineNumbers="true" %}

```lua
Server.onUseItem.Add(
function(unit,item)
    print(unit.name)
    print(item.dataID)
  end)
  
Server.onBuyGameMoneyItem.Add(
  function(unit,itemID,count)
    print(string.format("%s ,%s ,%s",unit.name,itemID,count))
  end)
  
Server.onSellGameMoneyItem.Add(
  function(unit,itemID,count)
    print(string.format("%s,%s,%s",unit.name,itemID,count))
  end)
```

{% endcode %}

Examples: Adding, Removing, and Modifying Item Options (Refer to ScriptUtility)

* Please test the code by removing the applied comments (--). The script below was executed via a touch event - triggered through the script.

{% code overflow="wrap" lineNumbers="true" %}

```lua
-- Get information about the first item in your inventory.
local item = unit.player.GetItems()[1]
local option1 = item.options[1]
--Utility.SetItemOption(option1,option1.type,option1.statID,option1.value+1)
--Server.SendItemUpdated(item)
Utility.AddItemOption(unit.player.GetItems()[1],1,3,5)
--unit.player.RemoveItemOption(item,1)
unit.player.SendItemUpdated(item)
```

{% endcode %}

Example: Event Triggered Upon Joining a Party (playerJoinPartyCallback)

{% code overflow="wrap" lineNumbers="true" %}

```lua
Server.playerJoinPartyCallback =
function(scriptRoomPlayer,scriptParty) 
        print(scriptRoomPlayer.unit.name)
        print(scriptParty.maxPlayer)
        -- A party will be created if return is set to true. You can specify return true or false depending on the condition.
        return true
end
```

{% endcode %}

**Example: Event Triggered Upon Leaving a Party (playerLeavePartyCallback)**

```lua
Server.playerLeavePartyCallback = 
function(scriptRoomPlayer,scriptParty) 
        print(scriptRoomPlayer.unit.name)
        print(scriptParty.maxPlayer)
end
```

Example: Event Triggered Upon Item Acquisition (onAddItem)

{% code overflow="wrap" lineNumbers="true" %}

```lua
Server.onAddItem.Add(
function(scriptUnit,titem) 
        print(scriptUnit.name)
        print(titem.dataID)        
end)
```

{% endcode %}

**Example: Event Triggered Upon Item Removal (onRemoveItem)**

{% code overflow="wrap" lineNumbers="true" %}

```lua
Server.onRemoveItem.Add(
function(scriptUnit,titem) 
        print(scriptUnit.name)
        print(titem.id)
        print(titem.dataID)        
end)
```

{% endcode %}

**Example: Event Triggered When Damage is Applied (damageCallback)**

{% code overflow="wrap" lineNumbers="true" %}

```lua
-- If the damage amount is 0, no damage is output.
-- a,b ScriptUnit
Server.damageCallback = function(a, b, damage, skillDataID, critical, visible)
        damage = a.atk - b.def
        if damage <= 0  then
                visible = false
        end
        return damage, critical, visible;
end
```

{% endcode %}

Example: Event Triggered Upon Completion of a Trade (onTradeDone)

{% code overflow="wrap" lineNumbers="true" %}

```lua
function Trade(sender,receiver,senderItems,receiverItems)
print("sender: ")
print(sender.unit.name)
print("receiver: ")
print(receiver.unit.name)
print("senderItems: ")
print(senderItems)
for i=1 , #senderItems do
        print(i..": ")
        print(Server.GetItem(senderItems[i].dataID).name)
end
print("receiverItems: ")
print(receiverItems)
for j=1 , #receiverItems do
        print(j..": ")
        print(Server.GetItem(receiverItems[j].dataID).name)
end
end

Server.onTradeDone.Add(Trade)
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.punkland.io/punkland-studio/script/server-script.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
