Skip to content

Core.Utilities.RandomEnum

Dennis Steffen edited this page Jan 4, 2026 · 1 revision

The RandomEnum<T> helper is a utility class designed to handle weighted random selection for enumeration types. Unlike a simple Random.Next(), which gives every value an equal chance, this helper allows you to define specific probabilities (weights) for each enum member and even organize them into groups.

How it Works

  1. Weights: When you add an enum value using .Add(value, weight), the "weight" determines its likelihood. For example, a value with a weight of 10 is twice as likely to be picked as one with a weight of 5.
  2. Groups: The helper maintains a list of Group objects. Each group contains its own set of enum values and weights.
  3. The Selection Process (Get()):
    • It first picks a random Group.
    • It then picks a random Value within that group based on the accumulated weights.

Use Cases

1. Sound Effects Randomization (As requested)

In game development, playing the exact same sound effect repeatedly (like a footstep or a sword swing) can feel mechanical and repetitive ("machine-gun effect"). RandomEnum helps solve this by allowing you to:

  • Shuffle between multiple variations of the same action.
  • Make "standard" sounds common while making "unique" variations rare.
  • Group sounds by intensity or surface type.

Example:

public enum SwordClang { Light, Standard, Heavy, Critical }

var sfxSelector = new RandomEnum<SwordClang>()
    .Add(SwordClang.Standard, 70) // Happens most of the time
    .Add(SwordClang.Light, 20)    // Occasionally
    .Add(SwordClang.Heavy, 9)     // Rarely
    .Add(SwordClang.Critical, 1); // Extremely rare easter-egg sound

// To play a sound:
SwordClang soundToPlay = sfxSelector.Get();
AudioManager.Play(soundToPlay);

2. Loot Tables and Rarity

You can use it to determine the rarity of an item dropped by an enemy.

Example:

public enum Rarity { Common, Uncommon, Rare, Legendary }

var lootRoller = new RandomEnum<Rarity>()
    .Add(Rarity.Common, 60)
    .Add(Rarity.Uncommon, 30)
    .Add(Rarity.Rare, 9)
    .Add(Rarity.Legendary, 1);

3. NPC Dialogue or AI Behavior

You can group behaviors into "Calm" and "Aggressive" states using the grouping feature.

Example:

public enum IdleBehavior { Whistle, ScratchHead, LookAround, CheckWatch }

var aiBrain = new RandomEnum<IdleBehavior>()
    .AddGroup() // Group 1: Passive actions
        .Add(IdleBehavior.LookAround, 50)
        .Add(IdleBehavior.Whistle, 50)
    .AddGroup() // Group 2: Impatient actions
        .Add(IdleBehavior.CheckWatch, 80)
        .Add(IdleBehavior.ScratchHead, 20);

Implementation Details to Note

Based on the code provided in RandomEnum.cs:

  • Fluent Interface: The methods Add and AddGroup return this, allowing you to chain calls together in a single statement.
  • Random.Shared: It uses the modern .NET thread-safe random instance, which is efficient for performance.

Summary of the Selection Logic

The Get() method calculates the "Total" weight of a group. It then picks a number between 0 and that total. It iterates through the values, adding up their weights until it hits the randomly selected number, returning the enum value associated with "bucket."

Clone this wiki locally