Record struct holding tunable car stats and utilities. It defines speed, acceleration, braking, turning, drift and boost parameters, computes UI display ratings (1-5) and provides a Default instance.
namespace Machines.Resources;
/// <summary>
/// Stats container for a car resource
/// </summary>
public record struct CarStatValues
{
public CarStatValues() { }
/// <summary>
/// Maximum forward speed (units/s).
/// </summary>
[Property]
public float MaxSpeed { get; set; } = 800f;
/// <summary>
/// Maximum reverse speed (units/s).
/// </summary>
[Property]
public float ReverseSpeed { get; set; } = 300f;
/// <summary>
/// Acceleration rate (units/s²).
/// </summary>
[Property]
public float Acceleration { get; set; } = 1200f;
/// <summary>
/// Braking / reverse deceleration (units/s²).
/// </summary>
[Property]
public float BrakeForce { get; set; } = 1600f;
/// <summary>
/// Base turn rate in degrees per second.
/// </summary>
[Property]
public float TurnRate { get; set; } = 280f;
/// <summary>
/// Passive drag when no input (units/s²).
/// </summary>
[Property]
public float Drag { get; set; } = 600f;
/// <summary>
/// Turn rate multiplier while drifting (higher = more slide).
/// </summary>
[Property]
public float DriftTurnMultiplier { get; set; } = 1.8f;
/// <summary>
/// Minimum drift time needed to earn a boost on release.
/// </summary>
[Property]
public float MinDriftTimeForBoost { get; set; } = 0.5f;
/// <summary>
/// Instant velocity added on dash (units/s).
/// </summary>
[Property]
public float BoostImpulse { get; set; } = 400f;
/// <summary>
/// Sideways influence of steering on the dash direction (0 = forward, 1 = full side).
/// </summary>
[Property]
public float DashSideStrength { get; set; } = 0.7f;
/// <summary>
/// Hill acceleration compensation (1.0 roughly doubles accel on a 45 deg slope, 0 = off).
/// </summary>
[Property]
public float HillStrength { get; set; } = 1.0f;
/// <summary>
/// 1-5 display ratings for UI stat bars.
/// </summary>
public readonly record struct DisplayRatings( int TopSpeed, int Accel, int Handling, int Braking );
/// <summary>
/// Computes 1-5 display ratings using fixed reference ranges.
/// </summary>
public DisplayRatings GetDisplayRatings()
{
return new DisplayRatings(
Rate( MaxSpeed, 600f, 750 ),
Rate( Acceleration, 700f, 1200f ),
Rate( TurnRate, 200f, 400f ),
Rate( BrakeForce, 600, 900 )
);
}
/// <summary>
/// Maps a value in [min, max] to an integer rating 1-5.
/// </summary>
private static int Rate( float value, float min, float max )
{
if ( max <= min )
return 3;
var t = ((value - min) / (max - min)).Clamp( 0f, 1f );
return System.Math.Clamp( (int)System.MathF.Round( 1f + t * 4f ), 1, 5 );
}
/// <summary>
/// Returns sensible default stats for a standard car.
/// </summary>
public static CarStatValues Default => new()
{
MaxSpeed = 800f,
ReverseSpeed = 300f,
Acceleration = 1200f,
BrakeForce = 1600f,
TurnRate = 280f,
Drag = 600f,
DriftTurnMultiplier = 1.8f,
MinDriftTimeForBoost = 0.5f,
BoostImpulse = 400f,
DashSideStrength = 0.7f,
HillStrength = 1.0f
};
}