Mutable Populations is an additional plug-in that automatically generates customized crowds or populations from an existing Mutable Object.
Within the Population Editor, you can control randomness to create variations and content in realtime or in the production pipeline. You can also use the editor to define generation rules for different populations to create cohesive groups that communicate a common origin, culture, or guild. After release, new assets can be tagged to automatically increase the variability of existing populations.
This plugin is offered as an example on how to generate populations with Mutable. This is something very specific for each project, and can be used as a template to create your own system.
Customizable Objects, Classes and Populations
Mutable Populations generate randomly Customizable Object Instances based on their internal configuration, which consists of Population Classes and relative chances to appear.
Each Population Class is based on a single Customizable Object that defines its typical traits. It does so by choosing which Parameter values should be produced on random Customizable Object Instances and how often.
Customizable Population Class
The Customizable Population Class is a new type of asset added to Unreal Engine. The Population Class defines which Customizable Object it is based on and what are its Characteristics.
Each Characteristic is a range of acceptable options for one parameter and its relative chances of appearing on random Customizable Object Instances based on this Population Class and generated by a Population. Depending on the type of parameter, it is used to set how common it is to find certain options, choosing a single value as valid, or using a curve to define the chances of appearance of continuous numeric values. This class also can use denylisting and allowlisting integer and boolean parameters via Tags, both globally and on individual parameters.
You can create a Customizable Population Class from the Content Browser’s Add New menu:
Customizable Population
This is a new type of asset that produces random Customizable Object Instances according to which Population Classes are chosen and how often they are used.
A single Population can create Customizable Object Instances from multiple different Customizable Objects and from the same Customizable Objects but from different Population Classes.
You can create Customizable Populations from the Content Browser Add New menu:
The Customizable Population updates the Customizable Object Instance generation algorithm each time the Population or the Population Class is saved, using the parameters from the Customizable Objects of each Population Class at that time. It also updates when the project is packaged to ensure it is up to date.
Population Class Editor
The left panel contains the Population Class options:
Choose which Customizable Object it is based on.
Define characteristics of that class.
Set the global class tag allowlist and denylist.
The Customizable Object has one characteristic per parameter.
Each Characteristic is defined using Constraints. Constraints define what values are found in random Customizable Object Instances of the Population Class, for each parameter, and their probability.
Different types of Constraints are used to define a Characteristic depending on the parameter type.
Multiple Constraints can be used on a single Characteristic, each with a chance to be applied relative to the others, defined by its weight.
Any parameter that is not specified with a valid Characteristic is randomized by the Population Class, with each of its options having equal chance of being on a Customizable Object Instance generated from the Population 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 Customizable Object Instances via the global allowlist and denylist or setting Characteristics that use constraints of type "Tag".
The panel contains:
4. Add and remove Tags, to be able to use them. The text box can be used to add new Tags. Below it, there is the list that shows the existing Tags, where they can be deleted.
5. Choose which parameter we are going to be setting Tags for.
6. Define what Tags are applicable to each of the options of the enum.
The Curve Editor is located in the upper right panel (12). It shows the last curve constraint for which the button Open in Editor was pressed, and can be used for the tuning of the curve.
The lower right panel (7) shows a preview of what is generated with the current settings. They are generated each time the Test Population Class button (8) is pressed. The amount of Customizable Object Instances generated can be defined using the down arrow next to the button and the default value is 10.
Here you can select instances to inspect them; in this image the left-most instance is chosen. With the Inspect Instance (10) button you are able to check and modify the chosen Customizable Object Instance in the editor. With the Inspect Skeletal Mesh (11) button you can check the resulting skeletal mesh.
The Generate Instances button (9) can be used to generate random Customizable Object Instance assets. These are normal Customizable Object Instances, to use as game assets from the editor, and will have nothing else randomly generated after being created.
To generate random Customizable Object Instances at runtime, you can use the functions Generate Population and Regenerate Population found in the Population asset.
Population Tags
Tags are created using the Tag Manager text box. Tags are designed to be assigned to each of the options of an enum parameter individually. Then they are used to indicate that certain parameter options should be found or not on Population Classes. This is done by allowlisting and denylisting those Tags. This is defined later in this section with a truth table at the end and is a way to filter what parameters are used by the Population Class.
To use a Tag, create it (4), then assign some parameter options (6) (5), and finally use them on allowlists and denylists either globally (3) or on a Constraint that affects a single parameter (2).
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 denylists and allowlists can be used 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.
Each Population Class has a general allowlist and denylist to broadly define what will and will not be found on Customizable Object Instances generated from that Population Class.
Integer and boolean parameters can also have Tag Constraints set on them. Those Constraints override the global allowlists and denylists, but only for the specific Characteristic that defines the Tag Constraint. This gives the ability to specify exceptions to the general allowlists and denylists to fine tune specific parameters of Population Classes.
Tag lists follow the logic below until some condition applies:
If none of the Tags on any option of an enum are in any tag list for this parameter, then all of its options have the same chance to appear.
If one of the Tags of at least one option on an enum is in a Constraint list for this parameter: Only enum options that don't have any Tag on the Constraint denylists appear. If any enum option Tag is in the allowlist, only options that have some Tag in the allowlist and none in the denylists appear (the table at the end describes the result)
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 denylist appear. If any enum option Tag is in the allowlist, only options that have some Tag in the allowlist and none in the denylist appear. The table at the end describes the result:
Truth table for allowlists and denylists:
| The enum option has a Tag in allowlist | The enum option has a Tag in denylist | Another option of the same enum has a Tag in the allowlist | Can this enum option appear on random Customizable Object 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 |