= Customizable Objects, Classes and Populations
TODO: Diagram of how this works at user level
[[mutable/unreal-engine-4/user-documentation/population/#population|Populations]] generate random [[mutable/unreal-engine-4/user-documentation/basic-concepts/#customizable-object-instance|Customizable Object Instances]] based on their internal configuration, which consists of [[mutable/unreal-engine-4/user-documentation/population/#population-class|Population Classes]] and relative chances to appear.
Each Population Class is based on a single [[mutable/unreal-engine-4/user-documentation/basic-concepts/#customizable-object|Customizable Object]], and it defines its typical traits. It does so by choosing which [[mutable/unreal-engine-4/user-documentation/basic-concepts/#parameter |parameter]] values should be able to be produced on random instances and how often.
---
{anchor #population-class}
= Population Class
This is a new type of asset added to Unreal Engine.
It defines which Customizable Object is this class based on and what are its characteristics.
Each characteristic is a limit to what are acceptable options for one parameter and its relative chances of appearing on random instances of this class generated by a population. Depending on the type of parameter, it allows setting how common it is to find certain options, choosing a single value as valid, or even using a curve to define the chances of appearence of continuous numeric values. The class also allows blacklisting and whitelisting integer and boolean parameters via [[mutable/unreal-engine-4/user-documentation/population/#tags|tags]], both globally and on a per parameter basis.
You can create CustomizablePopulationClasses from the Content Browser Add New menu:
{F238259}
{anchor #population}
= Population
This is a new type of asset added to Unreal Engine.
It produces random instances according to how it's set up: which population classes and how often are they used. It allows a single population to create instances from multiple different customizable objects and/or from the same customizable objects but from different classes.
You can create CustomizablePopulations from the Content Browser Add New menu:
{F238259}
Its customizable object instance generation algorithm is updated each time the population or the population class are saved, using the parameters from the customizable objects of each population class at that time.
It's also updated when the project is packaged, so it's ensured to be up to date.
---
{anchor #population-class-editor}
= Population Class Editor
{F242099,size=full}
The left panel edits the Population Class. It's used to:
(1) Choose which Customizable Object it is based on.
(2) Define characteristics of that class.
(3) Set the global class tag whitelist and blacklist.
There is at most one characteristic per parameter that the base customizable object has.
Each characteristic is defined using constraints: they define what values will be found in random instances of the class, for each parameter, and their chances.
Different types of constraints can be used to define a characteristic depending on the parameter type.
Any parameter that is not specified with a valid characteristic will be randomized, with each of its options having equal chance of being on an instance generated from this particular class.
The central panel defines the Customizable Object's Population Tags. These tags can be used and modified from any Population Class that shares this Customizable Object. Tags are used to control what ends up in the random instances via the global whitelist and blacklist or setting characteristics that are use constraints of type "tag".
The panel allows you to:
(4) Add and remove Tags, to be able to use them. To add tags, type a new tag in the searchbox that opens when you click the dropdown. To remove them, choose one of the dropdown and press on the cross.
(5) Define what tags are appliable to a whole parameter. That tag will be treated as if it was defined on each of the parameter options.
(6) Define what tags are appliable to each of the options of an enum.
The right panel (7) shows a preview of what would be generated with the current settings.
They are generated each time the "Test Population Class" button (8) is pressed. The amount of instances generated can be defined using the down arrow next to the button, the default is ten.
---
{anchor #tags}
= Population Tags
{F242099,size=full}
To use a tag, it first has to be created (4), then assigned somewhere (6) (5), and finally used on whitelists and/or blacklists either globally (3) and/or on a constraint that affects a single parameter (2).
Tags are created on the tag manager, using the search function. When you search for a tag that does not exist, it's automatically created.
Tags are mainly designed to be assigned to each of the options of an enum individually, but they can as well be assigned to boolean and integer parameters as a whole.
Then, they are used to indicate that certain parameter options should be found or not on population classes. That is done by whitelisting and blacklisting those tags. This is defined later in this section, with a truth table at the end.
The tags are stored in the customizable object, so different population classes of the same customizable objects have access to the same tags, on the same parameters and parameter options.
Assigning tags to each of the options of an enum is the main purpose of Population Tags, and together with blacklists and whitelists allow to manage a growing amount of options without manually modifying each Population Class constraint that depends on it each time an option is added or removed.
Assigning tags to whole integer and boolean parameters is mainly used on a specific case: when you want the parameter to be "none", by blacklisting one of those tags.
Each population class has a general whitelist and blacklist, to define in broad strokes what will and will not be found on instances generated from that class.
Integer and boolean parameters can also have tag constraints set on them. Those constraints generally override the global whitelists and blacklists, but only for the specific parameter that is defined by the tag constraint. This allows us to specify exceptions to the general whitelists and blacklists to fine tune specific parts of classes. Constraint tag lists override global tag lists for that single parameter.
Tag lists follow this logic, in order until some condition applies:
1. If none of the tags on any option of an enum are in any tag list for this parameter: All of it's options have the same chance to appear.
2. If one of the tags of at least one option of an enum is in a constraint list for this parameter: Only enum options that don't have any tag on the constraint blacklist appear. If any enum option tag is in the whitelist, only options that have some tag in the whitelist and none in the blacklist appear. The following table details the results:
| The enum option has a tag in constraint whitelist | The enum option has a tag in constraint blacklist | Another option of the same enum has a tag in the constraint whitelist | Can this enum option appear on random instances?
| ----- | ----- | ----- | -----
| no | no | no | **YES**
| **yes** | no | no | **YES**
| no | **yes** | no | **NO**
| no | no | **yes** | **NO**
| **yes** | **yes** | no | **NO**
| **yes** | no | **yes** | **YES**
| no | **yes** | **yes** | **NO**
| **yes** | **yes** | **yes** | **NO**
3. The same as point 2. but on global lists. If one of the tags of at least one option of an enum is in a global list for this parameter: Only enum options that don't have any tag on the global blacklist appear. If any enum option tag is in the whitelist, only options that have some tag in the whitelist and none in the blacklist appear. The following table details the results:
| The enum option has a tag in global whitelist | The enum option has a tag in global blacklist | Another option of the same enum has a tag in the global whitelist | Can this enum option appear on random instances?
| ----- | ----- | ----- | -----
| no | no | no | **YES**
| **yes** | no | no | **YES**
| no | **yes** | no | **NO**
| no | no | **yes** | **NO**
| **yes** | **yes** | no | **NO**
| **yes** | no | **yes** | **YES**
| no | **yes** | **yes** | **NO**
| **yes** | **yes** | **yes** | **NO**