LogoLogo
⚠️ Outdated documentationGo to latestHomeAPI
SDK 1.3
SDK 1.3
  • Welcome
  • Overview
    • Features
    • Roadmap
  • Getting started
    • Get the Unity SDK
    • Setup a project
      • Scene setup
      • Prefab setup
      • Sample connection UIs
      • Local development
        • Local testing using Builds
        • Local testing via Unity's Multiplayer Play Mode (MPPM)
        • Local testing via ParrelSync
      • Test in the cloud
        • Deploy a Replication Server
        • Share builds
    • Video tutorials
    • Samples and tutorials
      • Package samples
      • First Steps tutorial
        • 1. Basic syncing
          • 1.2. Animation parameters
          • 1.3. Sending commands
        • 2. Physics / Authority transfer
        • 3. Areas of interest
        • 4. Parenting entities
        • 5. Complex hierarchies
        • 6. Persistence
      • Campfire project
        • Game mechanics
        • Leveraging object pooling
        • Remote interactions: Chairs
        • Remote interactions: Trees
        • A unique object with complex state
        • Custom instantiation and destruction
        • Running a server-side NPC
        • Playing audio and particles
        • A simple text chat
      • Beginner's guide to networking
  • Manual
    • Unity Components
      • CoherenceSync
      • CoherenceBridge
      • CoherenceNode
      • CoherenceLiveQuery
      • CoherenceTagQuery
      • PrefabSyncGroup
      • CoherenceInput
      • Order of execution
    • Networking state changes
      • Supported types
      • Messaging with Commands
      • Syncing child GameObjects
      • Animation
      • CoherenceSync references
      • [Sync] and [Command] Attributes
      • [OnValueSynced] Attribute
      • Creating your own syncable member
      • Custom Component Actions
      • Rigid Bodies
      • Interpolation
    • Authority
      • Authority transfer
      • Server-authoritative setup
    • Lifetime
      • Persistence
      • Uniqueness
      • Example: A global counter
    • Parenting network entities
      • Direct children CoherenceSyncs
      • Deeply-nested CoherenceSyncs
      • Nesting Prefabs at Edit time
    • Asset management
      • Instantiate via
      • Load via
      • Instantiating from CoherenceSyncConfig
    • Scene management
    • Baking (code generation)
    • Replication Server
      • Rooms and Worlds
      • Replication Server API
    • Simulators (Servers)
      • Scripting: Client vs Simulator
      • Run local Simulators
      • World Simulators
      • Room Simulators
      • Simulator slugs
      • Multi-Room Simulators
      • Build and Deploy
      • Command-line arguments
    • Client Connections
    • Optimization
      • Areas of Interest
      • Level of Detail (LOD)
      • Profiling
      • Simulation Frequency
    • Project Settings
    • Advanced topics
      • Big worlds
        • World Origin Shifting
        • Load balancing
      • Competitive games
        • Simulation Frame
        • Determinism, Prediction and Rollback
      • Team workflows
        • Version Control integration
        • Continuous Integration
      • Schema explained
        • Specification
        • Field settings
        • Archetypes
      • Code Stripping
      • Command-line interface tools
      • Single-player gameplay
    • Scripting API
  • Hosting
    • Choosing where to host
    • coherence Cloud
      • Online Dashboard
      • Manage Worlds
      • Configure Rooms
      • Lobbies
      • Game Services
        • Account
        • Key-Value Store
      • coherence Cloud APIs
        • Worlds API
        • Rooms API
        • Lobbies API
        • Game Services
          • Authentication Service (Player Accounts)
          • Key-value store
    • Peer-to-peer
      • Implementing Client hosting
  • Support
    • Release notes
    • Glossary
    • Unreal Engine support
    • WebGL support
    • ECS / DOTS support
    • Known issues and troubleshooting
    • Upgrade guide
      • Upgrade 1.2 -> 1.3
      • Upgrade 1.1 -> 1.2
      • Upgrade 1.0 -> 1.1
      • Upgrade 0.10 -> 1.0
      • Upgrade 0.9 -> 0.10
    • Credit cost & pricing
    • Report a bug
Powered by GitBook
On this page
  • Our use case
  • Getting extra mileage with byte[]
  • Never miss a chat message
  • Long-form chats

Was this helpful?

Export as PDF
  1. Getting started
  2. Samples and tutorials
  3. Campfire project

A simple text chat

Was this helpful?

Topics covered

Chat | Lobbies

Communication is an inherent part of online games and a chat, however simple, is a great way to enhance the range of expression for the players.

Our use case

We wanted to implement a very simple chat system. By pressing Enter, a small screen-space UI opens up and allows the player to compose a message. When they press Enter again, a balloon on top of their character displays the message to them, and to all connected Clients.

This is done in three parts.

The Chat script on the player reads the input, requests ChatComposerUI to display the chat composer that is part of the screen-space scene UI.

When the player sends a chat message, Chat is informed by an event sent by ChatComposerUI, and sends a Network Command SendChatMessage to all other clients.

Finally, the received message is displayed in world-space over the player's head the script ChatVisualiserUI present in the Player Prefab.

Getting extra mileage with byte[]

By default, coherence's Network Commands have a limit in the length that can be sent in one command. This is limited by the length of a UDP packet. While this limitation might be removed in the future, for now it means that chat messages can't be longer than a certain amount.

This amount, however, is quite different depending if you use a parameter of type string or of type byte[] (byte array). If you send a string, you will be able to pass on around 50 characters. This is really not much for a chat system.

If you use byte[] though, the number of characters goes up to (around) 500. Now we're talking!

So what we do in this demo is that first we convert the string that the player has typed in the UI into a byte array, and we send that via Network Command:

private void SendText(InputAction.CallbackContext _)
{
    string message = _chatComposer.GetText();
    if (message != string.Empty)
    {
        byte[] encodedMessage = Encoding.UTF8.GetBytes(message);
        sync.SendCommand<Chat>(nameof(SendChatMessage), MessageTarget.Other, encodedMessage);
    }
    // ...
}

Then, on the receiving side, we reconvert it back into a string:

[Command(defaultRouting = MessageTarget.Other)]
public void SendChatMessage(byte[] encodedMessage)
{
    string decodedMessage = Encoding.UTF8.GetString(encodedMessage);
    chatVisualiser.ShowText(decodedMessage);
    // ...
}

This simple trick allows us to send longer messages, or to send the same message generating less traffic.

Never miss a chat message

Because we are sending the chat messages on the CoherenceSync that is on the Player Prefab, it means that if that particular player instance is not visible to a Client because it's outside of their LiveQuery, they won't receive the Network Command and thus the chat message. This is maybe desirable in this demo, where the chat is visualised on top of the player.

But if chat messages are shown in a UI panel and players should receive them all regardless, then it might make more sense to rely on a special type of CoherenceSync: Client Connections. By sending the Network Command on that, it would ensure that the Command is sent and received regardless of LiveQuery ranges.

Read the Client Connections page for more info.

Long-form chats

This page talked about a simple chat system to use during gameplay, but keep in mind that coherence also has a solution for long-form chats as part of Lobby rooms. Players can be in a lobby before but also during gameplay.

For more information about Lobbies, read the specific page.

The chat composer
A chat balloon