Game/UpgradeTrack.cs

Defines an UpgradeKind enum and the UpgradeTrack class describing a repeatable shop upgrade (name, icon, costs, growth, max level). Provides cost/effect formulas, per-level text, a static array All with three configured tracks, and a Get(kind) helper.

File Access
namespace DesertPump;

public enum UpgradeKind
{
	/// <summary>Bigger tank, so you sell every few minutes instead of every few seconds.</summary>
	Storage,

	/// <summary>More litres per pump.</summary>
	Power,

	/// <summary>More coins per litre.</summary>
	Value,
}

/// <summary>
/// A shop upgrade you can buy over and over, each level costing more than the last.
/// </summary>
/// <remarks>
/// Cost growth deliberately outruns effect growth by a wide margin. A track where the
/// two are close never stops paying for itself, and the economy runs away - the first
/// pass at this balance finished the whole game in two minutes for exactly that reason.
/// </remarks>
public sealed class UpgradeTrack
{
	public UpgradeKind Kind { get; init; }
	public string Name { get; init; }
	public string Description { get; init; }

	/// <summary>Material icon name.</summary>
	public string Icon { get; init; }

	public double BaseCost { get; init; }
	public double CostGrowth { get; init; }

	/// <summary>What one level multiplies its stat by.</summary>
	public float EffectGrowth { get; init; }

	public int MaxLevel { get; init; }

	public double CostAt( int level ) => BaseCost * Math.Pow( CostGrowth, level );

	public float MultiplierAt( int level ) => MathF.Pow( EffectGrowth, level );

	/// <summary>"+12%" - what the next level buys you.</summary>
	public string PerLevelText => $"+{(EffectGrowth - 1f) * 100f:0}%";

	/// <summary>Re-read on hotload so balance edits apply without restarting - see PumpTier.All.</summary>
	[SkipHotload]
	public static readonly UpgradeTrack[] All = new UpgradeTrack[]
	{
		new()
		{
			Kind = UpgradeKind.Storage,
			Name = "Water Tank",
			Description = "Holds more water, so you can walk away between sales.",
			Icon = "water_drop",
			BaseCost = 150,
			CostGrowth = 1.55,
			EffectGrowth = 1.12f,
			MaxLevel = 200
		},
		new()
		{
			Kind = UpgradeKind.Power,
			Name = "Pump Power",
			Description = "Every pump pulls up more water.",
			Icon = "fitness_center",
			BaseCost = 250,
			CostGrowth = 1.60,
			EffectGrowth = 1.06f,
			MaxLevel = 200
		},
		new()
		{
			Kind = UpgradeKind.Value,
			Name = "Market Contacts",
			Description = "People pay better for the same water.",
			Icon = "handshake",
			BaseCost = 400,
			CostGrowth = 1.68,
			EffectGrowth = 1.05f,
			MaxLevel = 200
		},
	};

	public static UpgradeTrack Get( UpgradeKind kind ) => All[(int)kind];
}