---
# System prepended metadata

title: Message
tags: [ctrl]

---

---
title: "Message"
disqus: hackmd
tags: 'ctrl'
---
## Chapter 3 Message Management

### 3-1 Scenes and Messages

When a group of players connect to the game’s in-time communication server, the players in the same scene can “see” one another’s behaviors. The “see” here means that due to the transparency of internet messages, when a player sends a message to the game scene he is in, every player in the scene receives it. However, the players in other scenes do not. In other words, “game scenes” can separate internet spaces. In the practice of game development, players may be on a scene in the game or in many of them at the same time, which is different from how people in the real world can only show up in one scene at a time. 
        
![](https://i.imgur.com/1MZhaXt.png)     
      
The above picture demonstrates the four types of game scenes with different functions, which are created according to the game’s needs.

For example, in the beginning, one can create a scene named the main hall. Every time the players enter the game, they enter the main hall. The main hall can help send and receive all-round messages, such as the server’s maintenance ten minutes later, the delay of siege today, when a player uses the broadcaster, and so on.
           
Then, create two static scenes named the field and the volcano. When Player A walks on the field, Player B, who is on the volcano, does not receive his messages. After Player A uses the broadcaster, Player B receives the data. Therefore, as explained above, a player can be in several “internet scenes.”
                
<mark>This is the “scene” in Online perspective, and it has the idea of separating spaces like the “scenes” of Unity 3D. Despite having the same name, developers do not need to consider them the same. They can make a more flexible organization according to the game’s mechanism and needs.</mark>     

          
### 3-2 Creating a Game Scene

Developers can define other individual scenes according to their needs. In the Cloud API, there are three constructors in CloudScene:

(1) CloudScene(CloudGame game, string sguid)       
       
If the sguid represents a static scene, enter the scene with `Launch()`.

The below program appears after CloudGame calls `Launch()`. After triggering the OnCompletion event, if Launch succeeds, that static scene is intensified, and the system gives the instance scene a scene identification code (sid) and stores it in the `sid` attribute of the CloudScene item:

```csharp
void OnCompletion(int code, CloudGame game)
{
	if (code == 0)
	{
		string sguid = "....."; // static scene’s sguid
		CloudScene ars = new CloudScene(game,sguid);
		ars.onCompletion += SceneLaunchCompletion;
		ars.onMessageIn += SceneMessageIn;
		ars.Launch();
	}
}
void SceneLaunchCompletion(int code, CloudScene scene)
{
	if (code == 0)
	{
		Debug.Log(scene.sid); // scene instance’s sid
	}
}
void SceneMessageIn(string m, int d, CloudScene scene)
{
	// receive broadcast messages from the scene
}
```

If the sguid represents an active scene, there are three ways to create a scene instance:       
              
- Please be aware that every scene copy created by calling the `Launch()` function is unique. If one wants other players to interact in the scene together, the other players online have to know the sid identification code of the scene. Therefore, developers have to send the sid to other players with the main hall or a private scene.
          
```csharp
CloudScene ars = new CloudScene(game,sguid);
ars.onCompletion += SceneLaunchCompletion;
ars.onMessageIn += SceneMessageIn;
ars.Launch();
```
     
- Call `Match()` and enter a created scene copy with the Cloud server’s pairing, and scene copies that are created earlier are prioritized when ranking the pairing order.  

```csharp
CloudScene ars = new CloudScene(game,sguid);
ars.onCompletion += SceneLaunchCompletion;
ars.onMessageIn += SceneMessageIn;
ars.Match();
```
		 
<mark>Please be aware that if there is no limit on the number of players in the scene, the Cloud server automatically changes the way of pairing to using `FairMatch()`. </mark>        
		 
- Call `FairMatch()` and pair players to the created scene copies one by one. This function makes players paired equally in every scene copy.     
     
```csharp
CloudScene ars = new CloudScene(game,sguid);
ars.onCompletion += SceneLaunchCompletion;
ars.onMessageIn += SceneMessageIn;
ars.FairMatch();
```

(2) CloudScene(CloudGame game, string sguid, bool isLocked)          
            
Is used in an active scene, and one can only call `Launch()` to create a scene copy. When parameter `isLocked` is true, this scene copy does not accept the server’s automatic pairing. When players execute the pairing with `Match()` or `FairMatch()`, this scene copy will be excluded and not paired.

If parameter IsLocked is false, the function is the same as the first constructor. 
           
(3) CloudScene(CloudGame game, string sguid, uint sid)        
          
This construction function is used in active scenes. When a scene copy is already created, one only needs an additional parameter `sid` to enter the same scene. Of course, sid is usually not of the scene copy created by oneself. When a remote player creates it and sends the sid, local player programs enter the same scene with the sid.
         
```csharp
CloudScene ars = new CloudScene(game,sguid,sid);
ars.onCompletion += SceneLaunchCompletion;
ars.onMessageIn += SceneMessageIn;
ars.FairMatch();
```
          
### 3-3 Message System

The message system is for controlling the game, and there are three types of messages:
        
(1) Private Messages    
             
Cloud provides every user connecting a dedicated private scene. Messages that are designated to be sent in this private scene are only received by the private scene’s owner. When a message is sent to a private scene, the system triggers the OnPrivteMessageIn event of the CloudGame item, and here is the event function’s definition:
	     
`void OnPrivteMessageIn(string Msg, int delayMilliSecond, CloudGame game)`       

The parameter’s definition is the same as the main hall’s OnMessageIn event function.

The `PrivacySend()` function in the CloudGame item is responsible for sending private messages, and receiver’s poid has to be designated when calling. Here is the definition of `PrivacySend()`:

`void PrivacySend(string data, uint poid)`             

Because an online player is the only one who knows his poid, it is not public information. To let other players online send private messages to an online player, developers can make the program send the poid with the main hall right after the player logs in, which is broadcasting the information of the one who logs in.
          
(2) Specific Scene Messages           
           
Developers can add new scenes in the game management backstage according to the game’s needs, and Cloud will designate a set of SGUID to the added scene. Then, program designers can create CloudScene items with this SGUID.

There are three constructors in the CloudScene item, and we will explain when and how to use them in the later chapter in detail. 
           
Call functions such as `Launch()` ,  `Match()` , or `FairMatch()` after the CloudScene item is created. When entering the scene successfully after triggering the `OnCompletion()` event, the CloudScene item can start sending and receiving messages.
             
The Send() function of the CloudScene item is responsible for sending messages, and here is its definition:	
       
`void Send(string Msg)`    
         
Besides, the OnMessageIn event is responsible for receiving messages, and here is its definition:

`void OnMessageIn(string Msg, int delayMilliSecond, CloudScene scene)`    
          
Parameter `Msg` is the messages one wants to send or receive. If both the sender and the recipient turn on the “packet delay detection radar,” parameter `delayMilliSecond` suggests how many milliseconds ago the message is sent.
             
However, pay extra attention to the third parameter in the OnMessageIn event, whose type is CloudScene. This parameter is tremendously important. If the program does not additionally define the self-defined CloudScene type with succession and many scenes need to be created in the app, this parameter distinguishes which scene the messages come from when the event is triggered to make these scene items share the `OnMessageIn()` function program code. Then corresponding actions can be taken.
             
(4) Offline Broadcast Messages  
                 
The `SendOnClose()` function of the CloudGame item sends “offline broadcast messages,” and here is its definition:
                 
`void SendOnClose(string msg, CloudScene scene)`     
        
When the message is sent, it is stored in the Cloud server. When the connection ends, the server sends the message to specific scenes and makes every player online receive it. 
            
The message’s format is defined by the program designers themselves, and it will work as long as it lets every player know who is offline and makes necessary management.
               
Every player can only send one “offline broadcast message,” and if one calls `SendOnClose()` several times, the latter messages override the previous ones. In other words, only the message sent from the last call is sent when the player is offline.
         
If the player does not want to broadcast his offline messages, he can use another overloaded function:	
        
`void SendOnClose(string msg, uint poid)`    
       
The poid here is the poid of a specific online user, such as DP’s poid.
       
### 3-4 Sending Game Control Messages
          
`Send()`, `SendPrivacySend()`, `SendOnClose()`, and more that send messages are non-blocking functions, which come back right after calling them, and the messages are sent to the server with the background program.
              
The Cloud message’s purpose is to control the procession of multi-player interactive games. Messages’ formats are defined by the developers themselves, and program designers can design them as string formats that include “control orders” and “order parameters,” according to the game’s needs. For example:
`"newuser:userid,poid"` and "`newuser`" represent “control orders,” and "`userid,poid`" represents “order parameters.” “Control orders” and “order parameters” are separated with the ' : ' character. 

There are many parameters in “order parameters,” and they are separated by the ' , ' character. There are two parameters in this example. 
               
Due to the limit on the Cloud message packets, please do not send message strings that have more than 650 characters to avoid cutting the messages. Also, the longer the message is, the more time it takes to send it, and the recipient needs more time to process it as well. This will eventually lead to affecting the control smoothness of the multi-player game. Thus, developers should keep the message format as short as possible when designing it.

### 3-5 Receiving and Processing Messages
         
The OnMessageIn and OnPrivateMessageIn events of the CloudGame item and the OnMessageIn event of CloudScene are event functions for receiving messages. If the message format is made up of “control orders” and “order parameters” like in the previous session and separated with the ' : ' character, we can write the first-level message procession program like this:	
         
```csharp
public void OnMessageIn(string msg, int delayMilliSecond, CloudScene Scene)
{
    string[] s = msg.Split(':');
    try
    {
        string cmd = s[0];
        string param = s[1];
        switch (cmd)
        {
            case "cmd1":
                // here is the program code that deals with cmd1 
                break;
            case "cmd2":
                // here is the program code that deals with cmd2
                break;
            case "cmd3":
                // here is the program code that deals with cmd3
                break;
        }
    }
    catch (Exception)
    {}
}
```
     
Because the Cloud API guarantees to trigger message receiving event in the main thread, developers have to make sure the message procession program is not time-consuming when designing it, or the game program’s pictures and the operations will be frozen.

Time-consuming works such as blocking I/O actions have to be dealt with with the thread. However, to avoid a great amount of creation and destruction of threads, one can use a thread pool instead.
      
### 3-6 Leaving a Specific Scene

After creating a specific scene for a time, if the game does not need to let local players receive any messages from this specific scene anymore, we can call `CloudScne.Leave()`, and here is its function:
void Leave(OnCallCompletion cb,Object token);      
          
Parameter `cb` is the callback function, which developers have to write by themselves, and here is its definition: 
       
`cb(int code,Object token)`    

When the `code` is zero, it means that the scene leaving is successful. If it is not zero, the leaving fails and program designers can decide what to do next according to the `code` parameter that is sent in.
       
Parameter `token` is for `Leave()` and the callback function, and the systems will send the `token` parameter that is sent in when calling `Leave()` to the callback function without making any changes.
            
<mark>Because the specific scene’s Send() function is processed in the system’s background, calling Leave() right after calling Send() may make the messages deleted before sending them out. The best way is to use Leave() after the last Send() message is received by oneself.</mark>           
           
Once `CloudScene.Leave()` is called, the system will set `CloudScene.sid` as 0. If developers need this attribute, please store it in another variable in advance as well.

After leaving a specific scene, if there is a need to create a new one, please use `new CloudScene()` again. In other words, the `CloudScene` item that already executes `Leave()` cannot be used repeatedly again.
