---
title: Scripted Brushes
type: docs
weight: 1
---

Scripted brushes allow creating complex, programmable brush operations through JSON asset definitions.

**Package:** `com.hypixel.hytale.builtin.buildertools.scriptedbrushes`

## Architecture

```
Scripted Brushes
├── Assets
│   └── ScriptedBrushAsset - Brush definitions
├── Operations
│   ├── BrushOperation - Base operation class
│   ├── SequenceBrushOperation - Sequential operations
│   └── GlobalBrushOperation - Global modifiers
├── Categories
│   ├── Shape Operations - Set, fill, shape
│   ├── Mask Operations - Mask, history mask
│   ├── Flow Control - Loops, jumps, conditions
│   ├── Material Operations - Pattern, replace
│   └── Transform Operations - Offset, dimensions
├── Config
│   ├── BrushConfig - Runtime configuration
│   └── BrushConfigEditStore - Edit state
└── Commands
    └── BrushConfigCommand - /brushconfig
```

## ScriptedBrushAsset

Brush definitions loaded from JSON:

**Asset Location:** `BuilderTools/Brushes/`

```yaml
# BuilderTools/Brushes/terrain_sphere.json
{
  "Id": "terrain_sphere",
  "Operations": [
    {
      "Type": "Shape",
      "Shape": "Sphere"
    },
    {
      "Type": "Dimensions",
      "Width": 5,
      "Height": 5,
      "Depth": 5
    },
    {
      "Type": "Material",
      "Pattern": "[Rock_Stone]"
    },
    {
      "Type": "Set"
    }
  ]
}
```

### Asset Access

```java
// Get brush asset
ScriptedBrushAsset brush = ScriptedBrushAsset.get("terrain_sphere");

// Get operations
List<BrushOperation> operations = brush.getOperations();

// Load into executor
brush.loadIntoExecutor(executor);
```

## Operation Types

### Shape Operations

| Operation | Description |
|-----------|-------------|
| `Set` | Apply blocks at positions |
| `Shape` | Define brush shape (Sphere, Cube, Cylinder) |
| `Delete` | Remove blocks |
| `Smooth` | Smooth terrain |
| `Erode` | Erode terrain |
| `Lift` | Raise terrain |
| `Melt` | Melt terrain |

```yaml
{
  "Type": "Shape",
  "Shape": "Sphere"  // Sphere, Cube, Cylinder
}
```

### Dimension Operations

```yaml
{
  "Type": "Dimensions",
  "Width": 10,
  "Height": 5,
  "Depth": 10
}
```

```yaml
{
  "Type": "RandomizeDimensions",
  "MinWidth": 3,
  "MaxWidth": 7,
  "MinHeight": 3,
  "MaxHeight": 7
}
```

### Material Operations

```yaml
{
  "Type": "Material",
  "Pattern": "[50%Rock_Stone, 50%Rock_Shale]"
}
```

```yaml
{
  "Type": "BlockPattern",
  "Pattern": "[Rock_Stone]"
}
```

```yaml
{
  "Type": "Replace",
  "From": "[Grass]",
  "To": "[Dirt]"
}
```

### Mask Operations

```yaml
{
  "Type": "Mask",
  "Mask": "[!Air]"
}
```

```yaml
{
  "Type": "AppendMask",
  "Mask": "[!Water]"
}
```

```yaml
{
  "Type": "HistoryMask"
  // Only affect previously modified blocks
}
```

```yaml
{
  "Type": "UseBrushMask"
  // Use mask from tool arguments
}
```

### Offset Operations

```yaml
{
  "Type": "Offset",
  "X": 0,
  "Y": 5,
  "Z": 0
}
```

```yaml
{
  "Type": "RandomOffset",
  "MinX": -2,
  "MaxX": 2,
  "MinY": 0,
  "MaxY": 5,
  "MinZ": -2,
  "MaxZ": 2
}
```

### Flow Control

#### Loops

```yaml
{
  "Type": "Loop",
  "Count": 5,
  "StartIndex": 2,
  "EndIndex": 6
}
```

```yaml
{
  "Type": "LoopRandom",
  "MinCount": 3,
  "MaxCount": 8
}
```

```yaml
{
  "Type": "CircleOffsetAndLoop",
  "Radius": 5,
  "Count": 8
}
```

#### Conditionals

```yaml
{
  "Type": "JumpIfBlockType",
  "BlockType": "Air",
  "Index": 10,
  "ElseIndex": 5
}
```

```yaml
{
  "Type": "JumpIfClickType",
  "ClickType": "Primary",
  "Index": 3
}
```

```yaml
{
  "Type": "JumpIfCompare",
  "Variable": "height",
  "Operator": ">",
  "Value": 5,
  "Index": 8
}
```

```yaml
{
  "Type": "JumpToIndex",
  "Index": 0
}
```

```yaml
{
  "Type": "Exit"
  // Stop brush execution
}
```

### Special Operations

```yaml
{
  "Type": "Echo",
  "Message": "Brush applied!"
}
```

```yaml
{
  "Type": "RunCommand",
  "Command": "/fill [Stone]"
}
```

```yaml
{
  "Type": "PastePrefab",
  "PrefabId": "tree_oak"
}
```

```yaml
{
  "Type": "HeightmapLayer",
  "Layer": 0
}
```

### Save/Load Operations

```yaml
{
  "Type": "LoadOperationsFromAsset",
  "AssetId": "common_setup"
}
```

```yaml
{
  "Type": "SaveBrushConfig",
  "Key": "my_config"
}
```

```yaml
{
  "Type": "LoadBrushConfig",
  "Key": "my_config"
}
```

## Global Operations

Operations that affect the entire brush:

```yaml
{
  "Type": "Debug",
  "Enabled": true
}
```

```yaml
{
  "Type": "DisableHoldInteraction"
  // Only trigger on click, not hold
}
```

```yaml
{
  "Type": "IgnoreExistingBrushData"
}
```

## Brush Config Command

Manage brush configurations via command:

| Command | Description |
|---------|-------------|
| `/brushconfig` | Base brush config command |
| `/brushconfig load <id>` | Load brush config |
| `/brushconfig list` | List available brushes |
| `/brushconfig clear` | Clear current config |
| `/brushconfig exit` | Exit brush mode |
| `/brushconfig debugstep` | Step through operations |

## API Usage

### Load Brush

```java
ScriptedBrushAsset brush = ScriptedBrushAsset.get("terrain_sphere");
```

### Execute Brush

```java
BrushConfigCommandExecutor executor = new BrushConfigCommandExecutor();
brush.loadIntoExecutor(executor);
// Execute operations sequentially
```

### Access Operations

```java
List<BrushOperation> operations = brush.getOperations();
for (BrushOperation op : operations) {
    if (op instanceof SequenceBrushOperation) {
        // Sequential operation
    } else if (op instanceof GlobalBrushOperation) {
        // Global modifier
    }
}
```
