About Selectionator

Selectionator is an asset for the Unity Game Engine that provides weighted random selections and allows for bonus sweetening (often known as magic-find bonuses).
It is quick, powerful, flexible, and boasts an extremely easy setup. You can find Selectionator in the Unity Asset Store

This page contains instructions and examples for setting up and using Selectionator, a reference guide for the selection modes and how they influence selection sweetening, and contact information if you've found a bug or are having trouble using the asset.


Selectionator Documentation

Contents



Setup

Selectionator can be found in the Unity Asset Store, and once downloaded can be imported into your unity project through the asset store window, or through the Assets Import Package Custom Package menu option.

Once imported, Selectionator is ready to go and requires no special initialization. Just add using Selectionator; to the top of your script.

However, any class that you want to use Selectionator with (that is to say, any class that you want to be able to select) must implement the ISelectable interface, like so:

public class MyClass : ISelectable
{
        public float SelectionWeight { get; set; }
}
SelectionWeight is what the Selector looks at internally, and the weight it returns is the object's selection weight. This can come from anywhere, but it must be a float value. It is recommended that selection weights are set in the class constructor. Items with null selection weights default to weight 0, and will not be selected.



Use

Selectionator will work over any enumerable collection (so Arrays, Lists, ArrayLists, LinkedLists, etc. Basically, if LINQ can touch it, so can Selectionator).

Let's assume that we have an enumerable collection of MyClass objects, where MyClass implements ISelectable. We'll call this collection MySelectableCollection. The first step in getting a selection from this collection is to create a new selector, like so:

 Selector mySelector = new Selector()

An instantiated selector without parameters defaults to SelectionPivot.Mean and SelectionRange.All. If different parameters are supplied, we can change the way the selector handles bonus values. For an in-depth look at how selection pivots and ranges work, please click here.


Now that we have our selector, we can make selections. There are two selection methods: Single and Multiple.


Single takes a collection as its first parameter, and from it returns single item selection, like so:

 var myItem = mySelector.Single(MySelectableCollection);

Without a second parameter, Single will return a selection based only on selection weight. To apply a "sweetener" (a bonus adjustment, such as magic-find), we add a float value as a second parameter:

 var myItem = mySelector.Single(MySelectableCollection, 25.2f);

For a detailed description of how bonus values work, and exactly how they manipulate item weights, please click here.


Multiple works the same way as Single, but it returns an IEnumerable and takes an additional parameter: a quantity integer.

var basicMultiSelection = mySelector.Multiple(MySelectableCollection, 5);
	// returns an IEnumerable<MyClass> with 5 items.
		
var multiSelectionList = mySelector.Multiple(MySelectableCollection, 5).ToList();
	// Casting is often a good idea. This returns a List<MyClass> with 5 items.

var bonusMultiSelection = mySelector.Multiple(MySelectableCollection, 5, 50);
	// returns an IEnumerable<MyClass> with 5 items, using a selection bonus of 50.



Selectionator contains an additional useful function: GetWeightDictionary
This function takes a collection of selectable objects and a bonus value, and returns a Dictionary<T, float>, where T is the type of the collection. The dictionary values represent the selection weights of the items after the bonus has been applied.

 var myWeightDictionary = mySelector.GetWeightDictionary(MySelectableCollection, 10);
The dictionary is used in the Demo to get the selection probabilities of the items.




Example

    public class SelectionExample
    {
        public List SelectableItems;

        public void Example()
        {
            var SelectableItems = new List
            {
                new ExampleSelectableItem {Data = "Item A", SelectionWeight = 1},       // Selection Weight Notes:
                new ExampleSelectableItem {Data = "Item B", SelectionWeight = 2},       // Overlapping weights...
                new ExampleSelectableItem {Data = "Item C", SelectionWeight = 2},       // ...are valid.
                new ExampleSelectableItem {Data = "Item E", SelectionWeight = 3.3f},    // Explicit decimals are valid as well.
                new ExampleSelectableItem {Data = "Item F", SelectionWeight = 0},       // Values of zero, like this, will never be selected
                new ExampleSelectableItem {Data = "Item H", SelectionWeight = (5*2)},   // Anything that can be parsed as a float, like this...
                new ExampleSelectableItem {Data = "Item I", SelectionWeight = (1/9)},   // ...or like this, is valid.
            };
			
			Selector selector = new Selector();
			float bonus = 25;
			int itemCount = 5;
			
			Debug.Log(selector.Single(SelectableItems).Data);
			Debug.Log(selector.Single(SelectableItems, bonus).Data);
			Debug.Log(string.Join(", ", selector.Multiple(SelectableItems, itemCount).Select(item=>item.Data).ToArray()));
			Debug.Log(string.Join(", ", selector.Multiple(SelectableItems, itemCount, bonus).Select(item=>item.Data).ToArray()));
        }

Console

Item H
Item E
Item H, Item H, Item B, Item E
Item A, Item H, Item E, Item C


Selection Reference

Selections can (and should!) be tested in the demo, which is both a demonstration of the system and a useful tool to ensure you've selected the optimal selection parameters for your projects.

Selectionator Demo

Default Reference

Selectionator's default Selector is set to SelectionPivot.Mean and SelectionRange.All. This means that the selector will push all items in the collection towards the average weight of all items in the selection. Items adjusted by the bonus value approach the mean asymptotically — they'll get close at very high values, but never quite get there.


Pivots

The "pivot" is the middle range that weights are adjusted to, if a bonus is being applied.
Selectionator can select from two built-in pivots: SelectionPivot.Mean and SelectionPivot.Median. When adjusting weights, Selectionator will push in-range weights towards the mean or median, respectively, of the entire selection.
In most cases, pivoting at the mean will result in a more dramatic shift at the range outliers. Over selection sets that have very different extremes, it may be more useful to use a median pivot, or, break the selection into a series of sets.

For example, let's say we are developing an RPG and want a treasure chest to have a very small chance to drop one of a number of rare treasures, and we want an extremely small chance to drop a particularly rare ring of that set of rare treasures.
Just for the sake of the example, we'll say our treasure chest contains one of three items:
  A sword, of selection weight 100
  A gem, of selection weight 0.1
  A ring, of selection weight 0.001
A mean pivot selector jumps the ring to a 0.3% drop chance at a bonus value of only 1, and by bonus=50 the ring has over a 9% chance to drop! The table is just too swingy to use a mean pivot here. A median pivot, on the other hand, keeps the ring extremely rare.
However, a median pivot might keep the ring too rare if players can get bonus values in the hundreds or thousands. In these cases, it might be best to break up the drop tables. Execute a median-pivot selection on a list of potential drop tables (just have your tables themselves implement ISelectable), then execute a mean-pivot selection on the selected table. In this way, you can fine-tune drop rates even in situations where selections can be executed over hugely variant weights.

Ranges

The "range" is the subset of weights that the selector will adjust, if a bonus is being applied. Selectionator can select from three built-in ranges:
SelectionRange.BelowPivot, SelectionRange.AbovePivot, and SelectionRange.All. "BelowPivot" causes the selector to only adjust weights below the pivot (median or mean, as set by the SelectionPivot parameter), while "AbovePivot" operates only over rates above the pivot. "All" allows the selector to operate over all weights, regardless of their relationship to the pivot.
All-range adjustments produce a more dramatic, but more universally consistent, result. Below- and above-pivot range adjustments are best used over selection sets that are more heavily weighted towards a single "end" (that is to say, a majority of high-weighted or low-weighted items) and produce far more subtle results.


Selector Parameter Reference


Support

Provided you've included the Selectionator namespace and your selectable objects implement ISelectable, it'll be difficult to run into problems while using Selectionator. That said, if you've found a bug or need some help, here's how you get in contact:

Direct e-mail    Unity Forum Thread    Tweet @evilwizards