GS2-Chat

Text chat feature

GS2-Chat allows you to add text chat to your game. Text chat requires an always-on session to detect new messages and has complex server requirements.

Game Server Services frees you from the hassle of managing these always-on sessions.

Room

To start using GS2-Chat, you must first create a room. Rooms can be created freely by the player, or you can have a room created for you by the developer.

One thing to keep in mind is that GS2-Chat only guarantees a maximum of 3 messages per second per room. Posting more than this may cause errors. Therefore, it is not suitable for requirements such as social networking timelines where a large number of players are stored in a single room.

Passwords

Rooms can be assigned a password. The password must be specified when retrieving messages from a password-protected room or when posting a message.

Subscription

Players can subscribe to a room to receive notifications of new messages in the room. Messages can be categorized, and subscriptions can be made for each category in the room.

In a guild chat implementation, only messages from the guild master can be set to a special category, so that guild members can be sure to subscribe only to messages from the guild master.

Notification by subscription is handled by the GS2-Gateway’s notification functionality, but the GS2-Gateway does not have the ability to subscribe to messages when the player being notified is offline. The GS2-Gateway does provide a feature for out-of-game notifications, such as mobile push notifications.

There is no explicit limit on the number of people who can subscribe to a room, but GS2-Gateway API requests are required to send notifications, so the GS2-Gateway API usage fee is charged per notification. Also, the more notifications you have, the longer it will take for the notifications to reach you.

actor Player1
actor Player2
participant "GS2-Chat#Room"
participant "GS2-Gateway#Namespace"
participant "Firebase Cloud Messaging"
Player1 -> "GS2-Chat#Room" : Subscribe
Player2 -> "GS2-Chat#Room" : Post Message
"GS2-Chat#Room" -> "GS2-Gateway#Namespace" : Send Notification to Player1
"GS2-Gateway#Namespace" -> "Firebase Cloud Messaging" : Notification(if player is offline)
"GS2-Gateway#Namespace" -> Player1 : Notification
Player1 -> "GS2-Chat#Room" : Load New Message

Messages

You can send messages to a room. Messages will only be kept for the last 24 hours; earlier messages will be deleted.

NG Words

The message payload may contain inappropriate words. By working with GS2-Script, you can refuse to post messages that contain inappropriate words or rewrite the message payload.

Because GS2-Script can output HTTP communications, it can also forward them to its own NG word check server for processing.

actor Player
participant "GS2-Chat#Room"
participant "GS2-Script#Script"
Player -> "GS2-Chat#Room" : Post Message
"GS2-Chat#Room" -> "GS2-Script#Script" : Trigger post message
"GS2-Script#Script" -> "GS2-Chat#Room" : Continue? / Replaced Message

Category Model and Notification Settings

Message categories can be defined in master data. For each category, you can configure whether to reject posts using access tokens or forward them to mobile push notifications when offline.

The main master data models are as follows:

  • CategoryModel: Category settings and notification destination restrictions

Script Triggers

GS2-Script can be invoked before and after each of the following actions: room creation/deletion, message posting, and subscription/unsubscription. You can use synchronous execution for validation or tampering checks, or asynchronous execution to integrate external systems via Amazon EventBridge.

The main configurable event triggers and corresponding script names are as follows:

  • createRoomScript (Completion notification: createRoomDone): Before and after room creation
  • deleteRoomScript (Completion notification: deleteRoomDone): Before and after room deletion
  • postMessageScript (Completion notification: postMessageDone): Before and after message posting
  • subscribeRoomScript (completion notification: subscribeRoomDone): Before and after subscribing to a room
  • unsubscribeRoomScript (completion notification: unsubscribeRoomDone): Before and after unsubscribing from a room

Push Notifications

The main push notifications and their configuration names are as follows:

  • postNotification: Notify when a new post is made in a subscribed room

Notification categories can be controlled via notificationTypes, and mobile push forwarding to offline devices can also be configured.

Implementation Example

Creating a room

    var result = await gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).CreateRoomAsync();
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    );
    const auto Future = Domain->CreateRoom(
        "room-0001", // name
        nullptr, // metadata
        nullptr, // password
        nullptr // whiteListUserIds
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError()) return false;
    const auto Result = Future2->GetTask().Result();

Room Subscription

    var result = await gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Subscribe(
        roomName: "room-0001"
    ).SubscribeAsync(
        notificationTypes: new [] {
            new Gs2.Unity.Gs2Chat.Model.EzNotificationType {
                category = 0,
                enableTransferMobilePushNotification = false,
            },
        }
    );
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Subscribe(
        "room-0001" // roomName
    );
    const auto Future = Domain->Subscribe(
        []
        {
            const auto v = MakeShared<TArray<TSharedPtr<Gs2::Chat::Model::FNotificationType>>>();
            v->Add(MakeShared<Gs2::Chat::Model::FNotificationType>());
            return v;
        }() // notificationTypes
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError()) return false;
    const auto Result = Future2->GetTask().Result();

Room Unsubscribe

    var result = await gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Subscribe(
        roomName: "room-0001"
    ).UnsubscribeAsync(
    );
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Subscribe(
        "room-0001" // roomName
    );
    const auto Future = Domain->Unsubscribe(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

Posting a message

    var result = await gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    ).PostAsync(
        metadata: "MESSAGE_0001",
        category: 0
    );
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Subscribe(
        "room-0001" // roomName
    );
    const auto Future = Domain->Subscribe(
        []
        {
            const auto v = MakeShared<TArray<TSharedPtr<Gs2::Chat::Model::FNotificationType>>>();
            v->Add(MakeShared<Gs2::Chat::Model::FNotificationType>());
            return v;
        }() // notificationTypes
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError()) return false;
    const auto Result = Future2->GetTask().Result();

Get a list of messages

    var items = await gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    ).MessagesAsync(
    ).ToListAsync();
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    const auto It = Domain->Messages(
    );
    TArray<Gs2::UE5::Chat::Model::FEzMessagePtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

Message receipt notification handling

MessagesAsync responds to the cache if one exists, and the cache of data available in the message list is automatically updated by the SDK when it receives a message receipt notification. Therefore, there is usually no need to handle this event, and by calling MessagesAsync when necessary, the cache can usually be used to access the most recent message list.

    gs2.Chat.OnPostNotification += PostNotification =>
    {
        var namespaceName = PostNotification.NamespaceName;
        var roomName = PostNotification.RoomName;
    };
    Gs2->Chat->PostNotificationEvent.AddLambda([](const auto Notification)
    {

    });

Other Features

Categories that Cannot be Posted from Clients

By setting rejectAccessTokenPost to true in the CategoryModel master data, the corresponding category becomes inaccessible for posting using access tokens. This feature can be used to create categories that can only be posted through scripts, useful for storing system messages.

Player Room Creation Permission

The allowCreateRoom setting in the namespace controls whether players can freely create rooms.

allowCreateRoom=true: Players can create their own rooms allowCreateRoom=false: Only rooms prepared by administrators are available

Use this setting when you want to prevent excessive room creation or limit available rooms to specific ones.

Detailed Reference