# Communicating with the Server

## Understanding FireEvent and GetTopic

***

Punkland supports communication between the server and client using the **FireEvent** and **GetTopic** methods. Internally, it works by using **GetTopic** to register a key and a corresponding function. When that key is called via **FireEvent**, the previously registered function is executed.

**GetTopic** is a function used to handle events related to a specific topic. By using this function, you can process events associated with a particular topic sent from the client. For example, if you send a **FireEvent** with the topic "Apple," you can register a function to handle events related to that "Apple" topic.

```lua
-- When the client sends a FireEvent with the topic "Apple" 
-- Display the message "Apple" to all clients.
Server.GetTopic("Apple").Add(function()
  Server.SendCenterLabel("Apple")
end)

Client.FireEvent("Apple")
```

{% hint style="info" %}
By using **GetTopic** and **FireEvent**, you can handle events related to a specific topic and send messages to the client. Conversely, the client can also handle events using the **GetTopic** method.
{% endhint %}

## Serialization Issues

***

When communicating via **GetTopic** and **FireEvent**, advanced object serialization is not supported. This is because Lua scripts don’t provide such functionality by default. Therefore, if you need to serialize and transmit more complex objects or data types, additional processing is required.

To address this, Funkland offers **Utility.JSONParse**, **Utility.JSONSerialize**, as well as the Moonscript-based JSON library functions **json.parse** and **json.serialize**. The JSON methods in the **Utility** class also use Moonscript’s JSON conversion library under the hood.

### 1. **Handling string and number types**

In Lua scripts, **string** and **number** types can be sent via **FireEvent** without any additional processing. Below is an example of sending **string** and **number** types to the server.

```lua
Client.FireEvent("PlainData", "Hello", 1, 2, "World")

Server.GetTopic("PlainData").Add(function(...)
  print(...) -- Print Hello 1 2 World 
end)
```

### 2. **Handling table types**

Tables are a versatile data structure in Lua, allowing you to store and organize various pieces of data. For example, you can store multiple values in a table, serialize it, and then use **FireEvent** to send it.

Below is an example of serializing a table and using it for communication.

```lua
-- Serialize a table on the client side and send it via FireEvent
local data = {name = "John", age = 25, score = 100}
local serializedData = Utility.JSONSerialize(data) -- Serialize the table into a string

Client.FireEvent("TableData", serializedData) -- Send the serialized data using FireEvent

-- On the server side, receive the serialized data, convert it back into a table, and handle it
Server.GetTopic("TableData").Add(function(serializedData)
  local data = Utility.JSONParse(serializedData) -- Convert the serialized data back into a table
  print(data.name) -- Prints "John"
  print(data.age) -- Prints 25
  print(data.score) -- Prints 100
end)
```

In the example above, the table is serialized and converted into a string before being sent via **FireEvent**. On the server side, the received serialized data can be converted back into a table for processing. By using this method—serializing tables for communication—you can effectively work around the serialization limitations for advanced objects.

{% hint style="warning" %}
This method only applies to basic Lua types, such as tables. It cannot serialize userdata types provided by Funkland in class form. If a table contains other advanced objects, you may need to extract their properties individually and serialize them in order to communicate.
{% endhint %}

### 3. **Handling UserData Types**

For **userdata** types, you must individually extract their properties and then serialize them. Once the extracted properties are organized into a table, you can serialize that table and send it via communication channels.

```lua
-- Get the unit object
local me = Client.myPlayerUnit() 

-- Put the required properties of the unit object into a table
local serializedData = {
  name = me.name,
  exp = me.exp
}

-- Serialize the table and convert it into a string
local serializedString = Utility.JSONSerialize(serializedData)

-- Send the serialized data with FireEvent
Client.FireEvent("UnitData", serializedString) 

-- On the server side, receive the serialized data, convert it into a unit object, and process it
Server.GetTopic("UnitData").Add(function(serializedString)

  -- Convert the serialized data back into a table
  local unitData = Utility.JSONParse(serializedString) 
  print(unitData.name)
  print(unitData.exp)
  
  --
  -- Process the unit data
  --
end)
```

In the example above, the `name` and `exp` properties of a unit object are extracted, organized into a table, serialized, and then transmitted. On the server side, after receiving the serialized data, it’s converted back into a table and the values are reassigned to the unit object’s properties. By using tables in this manner, you can implement the serialization and communication of advanced objects.
