Selection Methods

Selection methods decide how RNGNeeds chooses item indices from a probability list. Your list still defines probabilities, enabled state, locked items, depletion, and repeat prevention — the selection method is the algorithm that turns that data into a result.

Which path should you use?

Use a built-in method

Best when you want default behavior, performance is already fine, and you only need to switch algorithms — not invent a new one.

Extend the system

Best when you need custom selection logic, want a special rule the built-ins do not cover, or are comfortable working at API level.


Built-in selection methods

Built-in methods

METHODLinear Search
Identifier: LSMRegular

Simple linear search. A strong default for smaller lists and common gameplay scenarios.

METHODLinear Search [BURST]
Identifier: LSMBurst

Burst-compiled version of Linear Search. Better suited to larger workloads and large numbers of picks in one operation.

METHODCumulative Probability
Identifier: CPMRegular

Uses cumulative probabilities and binary search. A good general-purpose option across different list sizes.

METHODCumulative Probability [BURST]
Identifier: CPMBurst

Burst-compiled cumulative-probability method. Great when you care about throughput for larger selection jobs.

METHODRandom Selection
Identifier: RSMRegular

Ignores item probabilities entirely and selects from items uniformly at random.


Quick guidance

When each built-in method makes sense

USELinear Search / Linear Search [BURST]

Good fit for many gameplay lists, especially smaller lists or situations where the number of picks per call is low.

USECumulative Probability / Cumulative Probability [BURST]

Good fit when lists get larger or you want a more scalable general-purpose selection algorithm.

USERandom Selection

Use only when you intentionally want a uniform distribution and do not want probabilities to matter.


Full custom path: ISelectionMethod

ISelectionMethod is the lowest-level extension path.

Use it when you want complete ownership of the selection process.

That also means you are responsible for the technical details yourself.

ISelectionMethod contract

PROPERTYIdentifier
string

The unique key used to register and look up the method. This is the value stored in ProbabilityList<T>.SelectionMethodID.

PROPERTYName
string

Human-readable display name for the method.

PROPERTYEditorTooltip
string (Editor only)

Tooltip shown in the Unity editor when applicable.

METHODSelectItems
NativeList<int> SelectItems(IProbabilityList probabilityList, int pickCount)

Performs the actual selection and returns the picked indices.


This base class handles a lot of the heavy lifting around the selection process so you can focus on the part that makes your method unique.

What SelectionMethodBase helps with

Why inherit from SelectionMethodBase

HELPERPrep and item data setup

The base class prepares the probability list, item data, enabled-item tracking, positive-probability tracking, and seeded random state.

HELPERRepeat-prevention integration

It already knows how to integrate with RNGNeeds repeat-prevention options such as Spread, Repick, and Shuffle.

HELPERDepletable-list support

It handles depletion-aware selection flow and applies item unit changes back to the list when required.

HELPERSelection loop lifecycle

The base class owns the common loop and cleanup lifecycle, which means less boilerplate and fewer opportunities to subtly break expected behavior.

The main members you usually care about

SelectionMethodBase members

PROPERTYProbabilityList
IProbabilityList

The active probability list being processed.

PROPERTYItemData
NativeArray<ItemData>

Runtime item data used during selection.

PROPERTYEnabledIndicesWithPositiveProbability
NativeList<int>

Indices of items that are currently eligible and have positive probability.

PROPERTYAllIndicesWithPositiveProbability
NativeList<int>

Indices of all items with positive probability, whether currently selectable or not.

PROPERTYLastPickedIndex
int

The most recently picked item index from the list's history.

PROPERTYItemCount
int

Number of items in the list.

PROPERTYTotalProbability
float

Total probability accumulated during prep.

METHODSelectItem
protected abstract bool SelectItem(out int selectedIndex)

The key method you implement. This is where your custom selection logic usually lives.

METHODPrep
protected virtual void Prep(IProbabilityList probabilityList)

Override only if you need additional preparation before selection starts.

METHODPrepItem
protected virtual void PrepItem(IProbabilityItem probabilityItem, int index, bool isEnabled, bool hasPositiveProbability)

Override when you want to collect per-item data while the list is being prepared.

METHODSpreadResult
protected virtual int SpreadResult(int index)

Hook for repeat-prevention spread behavior.

METHODShuffleResult
protected virtual void ShuffleResult(NativeList<int> indices, int iterations)

Hook for repeat-prevention shuffle behavior.

Minimal custom method example

public class MySelectionMethod : SelectionMethodBase
{
    public override string Identifier => "MySelectionMethod";
    public override string Name => "My Selection Method";

    protected override bool SelectItem(out int selectedIndex)
    {
        selectedIndex = EnabledIndicesWithPositiveProbability[
            m_Random.NextInt(0, EnabledIndicesWithPositiveProbability.Length)
        ];

        return true;
    }
}

Then register it through RNGNeeds Core:

RNGNeedsCore.RegisterSelectionMethod(new MySelectionMethod());

Which custom path is better?

Choose your difficulty level

RECOMMENDEDInherit from SelectionMethodBase

Best for most custom extensions. You keep the familiar RNGNeeds pipeline and concentrate on the part that makes your selection logic special.

ADVANCEDImplement ISelectionMethod directly

Best when you deliberately want total control and are comfortable recreating all required behavior yourself.


Need help with a custom method?

If you want help choosing an approach, shaping a custom method, or sanity-checking the behavior of your algorithm, feel free to drop by our Support page and join the Discord from there.