> For the complete documentation index, see [llms.txt](https://giantgrey.gitbook.io/tileworldcreator-v4-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://giantgrey.gitbook.io/tileworldcreator-v4-documentation/custom-generators-and-modifiers.md).

# Custom Generators & Modifiers

With TileWorldCreator you can easily create custom generators of modifiers for blueprint layers.

Simply create a new class and inherit from:

```csharp
BlueprintModifier
```

Add the Modifier attribute to your class:

```csharp
 [Modifier(ModifierAttribute.Category.Generators, "My Generator", "")]
```

Override the **Execute** method and add your logic there. The Execute method must return a HashSet\<Vector2> with the modified/generated positions.

```csharp
HashSet<Vector2> Execute(HashSet<Vector2> _positions, BlueprintLayer _layer)
```

## Example

```csharp
[Modifier(ModifierAttribute.Category.Generators, "Random Noise", "")]
public class RandomNoise : BlueprintModifier
{

    public float weight = 0.5f;
    public int rndSeed;

    private int width;
    private int height;
    
    public override HashSet<Vector2> Execute(HashSet<Vector2> _positions, BlueprintLayer _layer)
    {
        // Get the map width and height
        width = asset.width;
        height = asset.height;
        
        for (int x = 0; x < width; x ++)
        {
            for (int y = 0; y < height; y ++)
            {
                // Use the layers random struct.
                float sample = Mathf.PerlinNoise((float)x / (float)width + _layer.random.NextFloat(0, 100), (float)y / (float)height + _layer.random.NextFloat(0, 100));
                
                if (sample > weight)
                {
                    _positions.Add(new Vector2(x, y));
                }
            }
        }

        return _positions;
    }
}
```

## Create custom UI

You can create a custom UI for your modifier by overriding the **BuildInspector** method.

```csharp
public override VisualElement BuildInspector(Configuration _asset)
{
    var _serializedObject = new SerializedObject(this);

    var _root = new VisualElement();
    
    var _label = new Label();
    _label.text = "Custom UI";

    var _weightField = new PropertyField();
    _weightField.BindProperty(_serializedObject.FindProperty(nameof(weight));
    
    _root.Add(_weightField);

    return _root;
}
```

You may want to hide properties by default when creating a custom UI for those. Simply add the **\[HideInInspector]** attribute to it.

```csharp
[HideInInspector]
public float weight = 0.5f;
```

## Blueprint Layer Dropdown

TileWorldCreator has a custom Blueprintlayer dropdown UI Element which can be used if you want to create a custom UI where the user can select a blueprint layer.

<div align="left"><figure><img src="/files/SPqlUvyNax2ieOscBrxY" alt=""><figcaption></figcaption></figure></div>

```csharp
LayerSelectDropdownElement(Configuration asset, string selectedLayerGuid, Action<string,string> _onSelectedCallback, string _label = "");
```

<pre class="language-csharp"><code class="lang-csharp">[HideInInspector]
public string selectedLayerGuid

<strong>public override VisualElement BuildInspector(Configuration _asset)
</strong>{
    // Use the LayerSelectDropdownElement to assign a blueprint layer guid
    var _selectedLayerField = new LayerSelectDropdownElement(_asset, selectedLayerGuid, SelectLayer, "Selected Layer");
    _root.Add(_selectedLayerField);

    return _root;
}

// Callback called by the LayerSelectDropdownElement on selection
void SelectLayer(string _layerName, string _layerGuid)
{
    // Assign selected GUID
    selectedLayerGuid = _layerGuid;
}
</code></pre>
