lobby/PlayerReadyState.cs

Component that tracks a single player's lobby ready state. It stores a networked IsReady boolean, computes a display name, shows or hides an overhead indicator model, and tints that indicator green or red when readiness changes.

Networking
/// <summary>
/// Per-player lobby ready state. Holds the networked <see cref="IsReady"/>
/// bool that <see cref="LobbyReadyUp"/> flips when the player enters/exits
/// the ready zone, and drives the player's overhead indicator color. 
/// Also exposed to the lobby board UI, which reads <see cref="DisplayName"/> 
/// and <see cref="IsReady"/> to render each connected player's ready state.
/// </summary>
public sealed class PlayerReadyState : Component
{
    [Property] public ModelRenderer Circle { get; set; }

    [Sync, Change( nameof( OnIsReadyChanged ) )]
    public bool IsReady { get; set; }

    public string DisplayName => Network.Owner?.DisplayName ?? "Unknown";

    protected override void OnStart()
    {
        // Only show the overhead indicator when there's a lobby in this scene.
        ShowIndicator( LobbyManager.Current != null );
        ApplyTint( IsReady );
    }

    /// <summary>Show or hide the overhead indicator. The lobby toggles this on while we're in the lobby scene.</summary>
    public void ShowIndicator( bool visible )
    {
        if ( Circle.IsValid() ) Circle.Enabled = visible;
    }

    private void OnIsReadyChanged( bool oldValue, bool newValue )
    {
        ApplyTint( newValue );
    }

    private void ApplyTint( bool ready )
    {
        if ( Circle is null ) return;
        Circle.Tint = ready ? Color.Green : Color.Red;
    }
}