terminalCode Example

s&box Hints GameObjectSystem: UI hint queue

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

Hints GameObjectSystem Example

Hints is a GameObjectSystem that manages the display of timed popup hints in the UI. It queues hints with delays and displays them sequentially through the Notices system.

Type Signature

CSHARP
public class Hints : GameObjectSystem<Hints>
{
    [ConVar("cl_showhints", ConVarFlags.Saved | ConVarFlags.GameSetting)]
    public static bool cl_showhints { get; set; } = true;

    public void Queue(string hintName, string hintIcon, float delay);
    public void Cancel(string hintName);
}

Usage Example

CSHARP
// Queue a hint to display after 5 seconds
Hints.Current.Queue("my_hint", "ℹ️", 5.0f);

// Cancel a queued hint
Hints.Current.Cancel("my_hint");

Implementation Details

CSHARP
public class Hints : GameObjectSystem<Hints>
{
    record class Hint(string Name, string Icon, RealTimeUntil Delay)
    {
        public bool Ready => Delay < 0;
    }

    List<Hint> _queue = new();

    public Hints(Scene scene) : base(scene)
    {
        // Queue default hints
        Queue("openspawnmenu", "ℹ️", 10);
        Queue("openinspectmenu", "ℹ️", 40);
        Queue("openpausemenu", "ℹ️", 70);

        Listen(Stage.StartUpdate, 0, Tick, "UpdateHints");
    }

    public void Queue(string hintName, string hintIcon, float delay)
    {
        _queue.Add(new Hint(hintName, hintIcon, delay));
    }

    void Tick()
    {
        if (timeSinceLast < 3) return;
        if (!cl_showhints) return;

        var next = _queue.Where(x => x.Ready).FirstOrDefault();
        if (next is null) return;

        _queue.Remove(next);
        timeSinceLast = 0;

        var phrase = Game.Language.GetPhrase($"hint.{next.Name}");
        phrase = ReplaceSpecialTokens(phrase);

        Notices.AddNotice(next.Icon, Color.White, phrase, 5);
    }

    public void Cancel(string hintName)
    {
        _queue.RemoveAll(x => x.Name.Equals(hintName, StringComparison.OrdinalIgnoreCase));
    }

    string ReplaceSpecialTokens(string input)
    {
        // Replace {input:<inputname>} with the key bound to that input
        input = Regex.Replace(input, @"{input:([^}]+)}", match =>
        {
            string key = match.Groups[1].Value.Trim();
            return $"<span class=\"key\"> {Input.GetButtonOrigin(key)} </span>";
        });
        return input;
    }
}

Notes

  • Hints display every 3 seconds minimum (timeSinceLast)
  • Supports {input:<key>} tokens to show bound keys
  • Uses Game.Language for localization (hint.<name> phrase)
  • Displays through Notices.AddNotice for 5 seconds
  • cl_showhints ConVar controls visibility (saved setting)
Was this helpful?