UI/RaceTimer.razor

UI panel Razor component that displays a race timer. It shows formatted elapsed time depending on game mode state and local player's lap state, and exposes BestTime and BestTimePlayer properties.

Networking
@using Machines.Components
@using Sandbox;
@using Sandbox.UI;
@using Machines.GameModes;
@using Machines.Player;

@namespace Machines.UI
@inherits Panel

<root class="race-timer">
    <div class="current-time">@FormatTime( GetElapsedTime() )</div>
</root>

@code
{
    /// <summary>
    /// Best lap time in seconds (0 = none recorded).
    /// </summary>
    [Property]
    public float BestTime { get; set; } = 0;

    /// <summary>
    /// Name of the player who set the best time.
    /// </summary>
    [Property]
    public string BestTimePlayer { get; set; } = "N/A";

    private float GetElapsedTime()
    {
        var mode = BaseGameMode.Current;
        if ( mode == null )
            return 0f;

        if ( mode.State == GameModeState.WaitingForPlayers )
            return mode.TimeRemaining;

        if ( mode.State != GameModeState.Playing )
            return 0f;

        // Show the local player's current lap time.
        if ( mode is RaceMode race )
        {
            var local = Car.Local;
            if ( local.IsValid() )
            {
                var state = race.GetPlayerState( local.Slot );
                if ( state.HasFinished )
                    return state.LastLapTime;

                if ( state.LapStartTime > 0f )
                    return Time.Now - state.LapStartTime;
            }
        }

        return BaseGameMode.CountdownDuration - mode.StateEndsAt;
    }

    private string FormatTime( float seconds )
    {
        var mins = (int)(seconds / 60f);
        var secs = seconds % 60f;
        return $"{mins:00}:{(int)secs:00}";
    }

    protected override int BuildHash()
    {
        return HashCode.Combine( Time.Now );
    }
}