# 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://giantgrey.gitbook.io/tileworldcreator-v4-documentation/custom-generators-and-modifiers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
