---
title: Snapshots
type: docs
weight: 5
---

The snapshot system provides undo/redo functionality for builder tools by capturing and restoring state.

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

## Architecture

```
Snapshots
├── Base
│   └── SelectionSnapshot - Snapshot interface
├── Block Snapshots
│   └── BlockSelectionSnapshot - Block selection state
├── Clipboard Snapshots
│   ├── ClipboardSnapshot - Clipboard interface
│   ├── ClipboardContentsSnapshot - Clipboard contents
│   └── ClipboardBoundsSnapshot - Selection bounds
└── Entity Snapshots
    ├── EntitySnapshot - Entity interface
    ├── EntityAddSnapshot - Track entity addition
    ├── EntityRemoveSnapshot - Track entity removal
    └── EntityTransformSnapshot - Track transform changes
```

## SelectionSnapshot Interface

Base interface for all snapshots:

```java
public interface SelectionSnapshot<T extends SelectionSnapshot<?>> {
    // Restore to previous state
    // Returns inverse snapshot for redo
    T restore(Ref<EntityStore> ref, Player player, World world,
              ComponentAccessor<EntityStore> accessor);
}
```

### How Undo/Redo Works

The snapshot pattern creates inverse operations:
1. Snapshot captures current state before operation
2. Operation modifies the state
3. Calling `restore()` reverts changes
4. `restore()` returns new snapshot for redo

## Block Selection Snapshots

### BlockSelectionSnapshot

Captures block selection state:

```java
public class BlockSelectionSnapshot implements SelectionSnapshot<BlockSelectionSnapshot> {
    private final BlockSelection selection;

    public BlockSelection getBlockSelection();

    // Create copy of selection
    public static BlockSelectionSnapshot copyOf(BlockSelection selection);
}
```

### Usage

```java
// Before modifying selection
BlockSelectionSnapshot snapshot = BlockSelectionSnapshot.copyOf(selection);

// Perform modifications...

// To undo - restore returns redo snapshot
BlockSelectionSnapshot redoSnapshot = snapshot.restore(ref, player, world, accessor);
```

## Clipboard Snapshots

### ClipboardSnapshot Interface

Extended interface for clipboard operations:

```java
public interface ClipboardSnapshot<T extends SelectionSnapshot<?>>
        extends SelectionSnapshot<T> {

    T restoreClipboard(Ref<EntityStore> ref, Player player, World world,
                       BuilderToolsPlugin.BuilderState state,
                       ComponentAccessor<EntityStore> accessor);
}
```

### ClipboardContentsSnapshot

Captures clipboard contents:

```java
public class ClipboardContentsSnapshot implements ClipboardSnapshot<ClipboardContentsSnapshot> {
    private final BlockSelection selection;

    // Create copy of clipboard contents
    public static ClipboardContentsSnapshot copyOf(BlockSelection selection);
}
```

### ClipboardBoundsSnapshot

Captures selection bounds only:

```java
public class ClipboardBoundsSnapshot implements ClipboardSnapshot<ClipboardBoundsSnapshot> {
    public static final ClipboardBoundsSnapshot EMPTY;

    private final Vector3i min;
    private final Vector3i max;

    public ClipboardBoundsSnapshot(BlockSelection selection);
    public ClipboardBoundsSnapshot(Vector3i min, Vector3i max);

    public Vector3i getMin();
    public Vector3i getMax();
}
```

## Entity Snapshots

### EntitySnapshot Interface

Interface for entity-related snapshots:

```java
public interface EntitySnapshot<T extends SelectionSnapshot<?>>
        extends SelectionSnapshot<T> {

    T restoreEntity(Player player, World world,
                    ComponentAccessor<EntityStore> accessor);
}
```

Entity snapshots handle thread safety automatically, ensuring restoration runs on the world's tick thread.

### EntityAddSnapshot

Tracks entity creation (undo removes entity):

```java
public class EntityAddSnapshot implements EntitySnapshot<EntityRemoveSnapshot> {
    private final Ref<EntityStore> entityRef;

    public Ref<EntityStore> getEntityRef();

    // Restore removes the entity
    // Returns EntityRemoveSnapshot for redo (re-add)
}
```

### EntityRemoveSnapshot

Tracks entity removal (undo adds entity back):

```java
public class EntityRemoveSnapshot implements EntitySnapshot<EntityAddSnapshot> {
    private final Holder<EntityStore> holder;

    public Holder<EntityStore> getHolder();

    // Restore adds entity back
    // Returns EntityAddSnapshot for redo (remove again)
}
```

The `Holder<EntityStore>` stores a complete copy of the entity and its components.

### EntityTransformSnapshot

Tracks entity position and rotation:

```java
public class EntityTransformSnapshot implements EntitySnapshot<EntityTransformSnapshot> {
    private final Ref<EntityStore> ref;
    private final Transform transform;      // Position and rotation
    private final Vector3f headRotation;    // Head direction

    // Stores current transform state
    public EntityTransformSnapshot(Ref<EntityStore> ref,
                                   ComponentAccessor<EntityStore> accessor);

    // Restore returns snapshot of current state before restoration
}
```

## Snapshot Pairs

Snapshots come in complementary pairs:

| Add Operation | Undo (Remove) | Redo (Add) |
|---------------|---------------|------------|
| `EntityAddSnapshot` | Removes entity | `EntityRemoveSnapshot` |
| `EntityRemoveSnapshot` | Adds entity back | `EntityAddSnapshot` |

| Modification | Undo | Redo |
|--------------|------|------|
| `EntityTransformSnapshot` | Restores previous transform | Returns new snapshot |
| `BlockSelectionSnapshot` | Restores previous blocks | Returns new snapshot |
| `ClipboardContentsSnapshot` | Restores previous contents | Returns new snapshot |
| `ClipboardBoundsSnapshot` | Restores previous bounds | Returns new snapshot |

## Edit History Integration

Snapshots integrate with the edit history system:

```java
// History stores snapshots for each operation
// /undo command restores from history
// /redo command uses inverse snapshots

// Commands related to history:
// /undo [count]
// /redo [count]
// /clearedithistory
// /settoolhistorysize <size>
```

## Thread Safety

Entity snapshots automatically handle world thread requirements:

```java
// EntitySnapshot.restore() implementation
default T restore(...) {
    if (!world.isInThread()) {
        // Run on world tick thread
        return CompletableFuture.supplyAsync(
            () -> this.restoreEntity(player, world, store),
            world
        ).join();
    }
    return this.restoreEntity(player, world, store);
}
```

## API Usage

### Working with Block Snapshots

```java
// Before operation
BlockSelectionSnapshot before = BlockSelectionSnapshot.copyOf(selection);

// Perform operation that modifies blocks
// ...

// Store snapshot in history for undo
```

### Working with Entity Snapshots

```java
// Before adding entity
Ref<EntityStore> newEntity = world.spawnEntity(...);
EntityAddSnapshot snapshot = new EntityAddSnapshot(newEntity);

// To undo (remove the entity)
EntityRemoveSnapshot inverse = snapshot.restore(ref, player, world, accessor);

// To redo (add entity back)
EntityAddSnapshot restored = inverse.restore(ref, player, world, accessor);
```

### Working with Transform Snapshots

```java
// Before moving entity
EntityTransformSnapshot before = new EntityTransformSnapshot(entityRef, accessor);

// Move entity
transformComponent.setPosition(newPosition);

// To undo (restore original position)
EntityTransformSnapshot after = before.restore(player, world, accessor);
```
