terminalCode Example

RPC-based chat system with avatars and Steam filtering

calendar_today May 12, 2026 schedule ~1 min read person patrickjr verified 50

RPC-Based Chat System with Avatar Support

This example shows a complete chat system using Razor, RPC broadcasting, Steam filtering, and avatar display.

CSHARP
@using Sandbox;
@using Sandbox.UI;
@using Sandbox.Utility
@namespace Sandbox
@inherits PanelComponent

<root>
    <div class="output">
        @foreach (var entry in Entries)
        {
            <div class="chat_entry">
                @if (entry.steamid > 0)
                {
                    <div class="avatar" style="background-image: url( avatar:@entry.steamid )"></div>
                }
                <div class="author">@entry.author</div>
                <div class="message">@entry.message</div>
            </div>
        }
    </div>
    <div class="input">
        <TextEntry @ref="InputBox" onsubmit="@ChatFinished"></TextEntry>
    </div>
</root>

@code
{
    TextEntry InputBox = default;

    public record Entry( ulong steamid, string author, string message, RealTimeSince timeSinceAdded );
    List<Entry> Entries = new();

    protected override void OnUpdate()
    {
        if (InputBox is null) return;

        Panel.AcceptsFocus = false;

        if (Input.Pressed("chat"))
        {
            InputBox.Focus();
        }

        // Remove entries older than 20 seconds
        if (Entries.RemoveAll(x => x.timeSinceAdded > 20.0f) > 0)
        {
            StateHasChanged();
        }

        SetClass("open", InputBox.HasFocus);
        SetClass("hide", Player.FindLocalPlayer()?.WantsHideHud ?? false);
    }

    void ChatFinished()
    {
        var text = InputBox.Text;
        InputBox.Text = "";

        if (string.IsNullOrWhiteSpace(text)) return;

        AddText(text);
    }

    [ConCmd("say")]
    private static void Say(string msg)
    {
        var chat = Game.ActiveScene.GetAll<Chat>().FirstOrDefault();

        if (Application.IsDedicatedServer)
        {
            chat.AddSystemText(msg);
        }
        else
        {
            chat.AddText(msg);
        }
    }

    [Rpc.Broadcast]
    public void AddText(string message)
    {
        message = message.Truncate(300);

        if (string.IsNullOrWhiteSpace(message)) return;

        var author = Rpc.Caller.DisplayName;
        var steamid = Rpc.Caller.SteamId;

        Log.Info($"{author}: {message}");

        // Filter name and message content
        var filteredName = Steam.FilterName(author, steamid);
        message = Steam.FilterChat(message, steamid);

        Entries.Add(new Entry(steamid, filteredName, message, 0.0f));
        StateHasChanged();
    }

    [Rpc.Broadcast(NetFlags.HostOnly)]
    public void AddSystemText(string message, string icon = "ℹ️")
    {
        message = message.Truncate(300);

        if (string.IsNullOrWhiteSpace(message)) return;

        Entries.Add(new Entry(0, icon, message, 0.0f));
        StateHasChanged();
    }
}

Key Features

Was this helpful?