# Save harvested foliage and instanced meshes

> Trees players fell, bushes they pick, crops they plant and crowds of instanced skinned meshes keep their removed, moved, recoloured and added instances across...

Product: Rolly Save 1.0.0 | Sheet: guide | Updated: 2026-10-31 | HTML: https://rolly-docs.pages.dev/save/guides/harvest-and-instances/

## Turn on saving for foliage

Instances save through an actor's **Instances** settings, which are off by default: a level's instanced meshes cost nothing until you choose them. Turn them on before levels load: a component the settings take only after its level was built has no design, so each save holds all its instances, and a map of painted foliage can then pass a file's bound of 8,388,608 instance entries: saves leave out the changes of each component past it, and the Message Log names them (InstancesLeftOut). Meshes keeps such a late switch small. Set them where the actor's other saving settings are (see [Choose what saves](https://rolly-docs.pages.dev/save/guides/choose-what-saves/)):

| For | Set |
|---|---|
| Foliage and PCG output, or every instanced mesh, of the project | Tools > Rolly Save > Set Up Project... > **Harvested foliage and instances** |
| Every actor of the project | Project Settings > Plugins > Rolly Save > Actor Defaults > **Instances** |
| Foliage painted with the Foliage tool | A Save Rule whose Match lists the class **Instanced Foliage Actor**, with **Instances** ticked under its overrides |
| One actor, such as a farm field | Its Rolly Save component's **Instances** |

The last source that sets Instances gives all of its fields: a Save Rule's Instances replace Actor Defaults' whole, and a component's replace the rule's.

The setup panel's answers write Mode and Components of Actor Defaults' Instances and leave Meshes as it is: Not saved sets Mode Off; Saved for foliage and PCG output sets Changes of Foliage and PCG Output, the cheap answer for a world of painted foliage; Saved for every instanced mesh sets Changes of Every Instanced Mesh, which also takes Blueprints and Packed Level Actors. With Whole List in Actor Defaults no answer is selected.

![The setup panel at Harvested foliage and instances](https://rolly-docs.pages.dev/save/_files/Images/SetupPanel_Instances.png "Saved for foliage and PCG output chosen, with its help, and the two settings Apply writes: Instances > Mode and Instances > Components.")

| Mode | A load keeps |
|---|---|
| Off | Nothing: the level's design shows |
| Changes | The instances removed, moved, recoloured and added since the level's design, each matched to its design instance by its place, so level updates keep what players harvested |
| Whole List | Every instance: the load replaces the component's instances, for components your game fills, such as a farm's crops |

An actor saves once its instances differ from the design, even without a variable that saves. Only the server or a standalone game saves instances.

## Choose which components and meshes save

![DA_Foliage in the rule editor](https://rolly-docs.pages.dev/save/_files/Images/RuleEditor_Foliage.png "A Save Rule for Instanced Foliage Actors and PCG Volumes: Instances open with every field, Changes of Foliage and PCG Output for SM_Pine and SM_Bush, regrowing after 3 days, SM_Bush after an hour, and PCG Values at All Values; its checks pass.")

**Components** at **Every Instanced Mesh** takes the actor's Instanced Static Mesh, Hierarchical Instanced Static Mesh, foliage and Instanced Skinned Mesh components; **Foliage and PCG Output** takes only foliage painted with the Foliage tool. Both take the output of the actor's PCG components (see [Save PCG worlds](https://rolly-docs.pages.dev/save/guides/procedural-content/)). **Meshes** limits them to components that show one of the listed static meshes or skinned assets, such as your harvestable trees; empty, every component Components takes. Data Validation reports an entry of Meshes that is empty, cannot be loaded or is no mesh (BadMesh), and settings of a Save Rule or Rolly Save component that take none of the actor's components, with the reason (NotTracked).

Each instance of a component that saves holds about 56 bytes, plus 4 per custom data value, while its level is loaded: Rolly Save keeps a copy of the level's design of it from the moment the level's actors initialize, before any saved value applies. Once instances were removed or added it holds 8 more, and after the first key lookup about 20 more. List harvestable meshes in Meshes to keep that small. A component with more instances than **Max Instances per Component** (Actor Defaults, 1,048,576 by default, 1 to 16,777,216) saves none of their changes, and the Message Log says so once (TooManyInstances).

## Harvest an instance in your game

Change instances with the engine's own functions: **Remove Instance**, **Remove Instances**, **Update Instance Transform**, **Set Custom Data Value**, **Add Instance**, **Add Instances** and **Clear Instances**. Rolly Save follows which instance is which through the events those functions send, so the indexes they move never mix instances up. Code that writes a component's instance data directly sends none: Rolly Save then matches the instances to the level's design by place, an instance such a write moved saves as removed and added, and the Message Log says so once per component class (IndexMapRebuilt).

To swap a tree for a falling actor, spawn the actor at the instance's transform and remove the instance; the spawned actor saves as any spawned actor does.

### Blueprint

In your axe's hit event, take the **Hit Component** and **Hit Item** of the hit result, then call **Remove Instance** on the component with Hit Item as its **Instance Index**. For a growth stage, call **Set Custom Data Value** with the stage as **Custom Data Value**.

### C++

```cpp
#include "Components/InstancedStaticMeshComponent.h"

// In the axe's hit handler: Hit is the FHitResult of the swing.
if (UInstancedStaticMeshComponent* Trees = Cast<UInstancedStaticMeshComponent>(Hit.GetComponent()))
{
	Trees->RemoveInstance(Hit.Item);
}
```

## Keep your own data per instance

An instance's index changes as other instances are removed, so data kept by index, such as the wood a tree has left, ends up on another tree. Keep it under the instance's key instead: **Get Rolly Instance Key** gives a **Rolly Save Instance Key** that names the instance across saves and loads while the level's design of it stays the same, and an instance your game added has one too. **Find Rolly Instance by Key** gives its component and current index back, and false once the instance is gone. **Equal (Rolly Save Instance Key)** compares two keys. Keys work as map keys and save in SaveGame variables. An update that moves the instance in the level gives it another key, so data kept under the old one names nothing; so does moving an instance your game added, whose key is the place it had when you asked for it. For an Instanced Skinned Mesh component, pass and read the **Instance ID** the component's own nodes use. Its key names the instance by its design place, as a static instance's does, and holds its design ID only where design instances stand in one place, so it is the same whenever your game first asks for it, with one exception: instances Begin Play adds in one place, or where the level placed one, get their own keys only once Begin Play ended, so ask for theirs after it, or place them apart. A level update that puts another instance at exactly a skinned instance's place, or removes the one that shared it, gives it another key. An instance your game adds that takes the ID of one removed before it has that instance's key, and the data you keep under it. Get and Find are false on a client.

Both cost the same in a component of a hundred instances and in one of a hundred thousand, so call them in every hit. An Instanced Skinned Mesh component tells no index changes: after a removal moved an instance, the first Find of its key reads every instance's ID once.

### Blueprint

Add a variable **Wood Left**, a map from Rolly Save Instance Key to Integer, with SaveGame ticked. In the hit event, call **Get Rolly Instance Key** with the Hit Component and Hit Item, then **Find** the key in Wood Left, subtract one and **Add** it back; when it reaches 0, remove the instance.

### C++

```cpp
#include "Game/RollySaveSubsystem.h"

// A UPROPERTY(SaveGame) TMap<FRollySaveInstanceKey, int32> WoodLeft of your actor.
FRollySaveInstanceKey Key;
if (URollySaveSubsystem::GetInstanceKey(Hit.GetComponent(), Hit.Item, FPrimitiveInstanceId(), Key))
{
	int32& Wood = WoodLeft.FindOrAdd(Key, 3);
	--Wood;
}
```

## Save instances your game adds

Set **Mode** to **Whole List** for components your game fills, such as a farm's crops or a building system's walls: each save holds every instance with its custom data, and a load replaces the component's instances with them. A Whole List component your game adds to a saved actor during play with **Add Instance Component** or an **Add Component** node is made again by a load, with the saved mesh and custom data count; one your C++ code makes with New Object waits for your code to make it again.

With Changes, instances your game adds during play save too, beside the changes to the level's design. The level's design is what a component holds once its level is built or its actor spawned and its actor's Begin Play ended; a component your game adds during play, one the Begin Play of an actor its level holds makes, or one the settings take only after its level was built has none, so it saves every instance it holds, as a whole list, also when it holds none. A load makes such a component again when it was added with Add Instance Component or an Add Component node, so a Begin Play that adds one checks **Was Restored by Load** first; one your C++ code makes waits for your code to make it again. An actor spawned during play runs its Begin Play inside its spawn, so a component that Begin Play makes has a design, the instances it holds then: set that actor's Instances to Whole List, with a Save Rule or its Rolly Save component, so a load that makes the component again sets every saved instance and its Begin Play can check Was Restored by Load. With **Save Custom Data** off, custom data your game changes never makes a component save, and a load leaves it as it is.

Instances an actor's **Begin Play** adds are part of its design, and keys asked for in Begin Play keep naming them, but for skinned instances Begin Play stacks in one place (see Keep your own data per instance): a load that opens the map or streams in the level sets that component's saved changes once the actor began play, and an actor spawned again after a load takes them after its Begin Play, so the instances Begin Play adds again are set as they were and never double. Begin Play that places its instances differently at every start, such as at random, gives each start other places, which the saved changes do not match (InstancesNotMatched): use a Random Stream with a fixed seed, or Whole List. Code that adds instances later at every start, such as on a timer, adds them again after each load: check **Was Restored by Load** before adding, or use Whole List.

One save of a component holds at most 1,048,576 instance changes; a component past it saves none of them, and the Message Log says so once (TooManyChanges). A save holds at most 256 custom data values per instance, the first of each when a component has more (TooManyCustomFloats). An instance whose place or custom data is not a number a save holds, such as a value divided by zero, is left out of the save, and the Message Log says so once per component (NotFinite).

## Save crowds of instanced skinned meshes

Instanced Skinned Mesh components save their instances' transforms, custom data and **animation index**, matched by their instance IDs and, when an ID names an instance elsewhere, such as after the level changed, by place. A new instance that takes the ID of one removed before it saves as that instance changed, and has its key. Bone attachments between instances and playback positions are not saved, and neither are components that keep their instances only on the GPU.

## Keep saves working when you change the level

Each saved change names its design instance by the place the design gave it. A load matches it to the instance nearest that place within **Match Tolerance** (1 cm by default, 0.01 to 1,000), so an update that reorders instances or nudges one keeps every change; a nudged instance keeps its new place when the save only recoloured it. A change that matches no instance, such as one for a tree moved past Match Tolerance or a repainted forest, is listed in the load's Issues (InstancesNotMatched). With **Keep Unmatched** on, the default, the next save writes it back, so undoing the update matches it again; off, the next save drops it.

Identical instances in one place, as duplicates stack, are matched lowest index first, so a load removes the same ones every time.

Foliage keeps its changes in the record of each foliage actor, under that actor's name, and of each of its foliage components, under the component's name. In a World Partition map the engine names foliage actors after the grid they belong to, so changing the foliage grid size after release loses the saved changes of the foliage it moves. The engine numbers an actor's foliage components as foliage types are added (FoliageInstancedStaticMeshComponent_0, _1 and on): removing a foliage type from a level, or adding one before others, can give a saved component's name to another mesh's foliage, whose changes then report MeshChanged. Add new foliage types after the shipped ones and keep the old ones, even empty. A load never makes a foliage component again: its foliage actor makes them, so a foliage type an update removed stays removed.

A construction script that places instances at random places other ones each session, so saved changes match nothing: use a Random Stream with a fixed seed, or Whole List for that actor.

A change saved for another mesh than the component shows now is not set, and the Message Log says so once per load (MeshChanged). With Keep Unmatched on, every later save keeps those changes beside the component's new ones, so setting the mesh back brings them back; the changes made for the new mesh are then kept the same way. **Meshes** takes such a component by the mesh its changes were made for. A component whose Num Custom Data Floats changed since the save takes the first values of each saved instance, reported once per component class and load (CustomFloatsChanged).

## Regrow removed instances

**Regrow After**, under Instances, brings a removed instance back as the level designs it now once that many seconds have passed on **Reset Clock** (Project Settings > Plugins > Rolly Save > Reset Areas), such as 259200 for three days; 0, the default, keeps removed instances removed. **Regrow After per Mesh** gives meshes their own time, such as 3600 for bushes while trees use Regrow After: a mesh's entry beats Regrow After, and 0 keeps that mesh removed. Times run from 0 to 315,360,000 seconds; Data Validation reports one outside that range (BadRegrowTime) and an entry that names no mesh (BadMesh). Saves hold when each instance was removed, never when it is due, so an update that shortens a time reaches old saves.

Pick Reset Clock before you release: times saved on one clock are read on the other after you change it.

| Reset Clock | Removals are timed | Due instances come back |
|---|---|---|
| Play Time | as they happen | by one world timer set for the earliest due time, which no removal waiting means no timer; a pause stops it, as it stops play time, and slow motion counts in play time's seconds |
| Game Clock | at the next save, the next leave of the level or the next Check Rolly Regrowth, each asking your Game Clock once, so the time counts from then, not from the harvest | as their level is built, and at **Check Rolly Regrowth**, which you call after your clock moves, such as after the player slept; nothing wakes on its own |

Data Validation warns when Reset Clock is Game Clock without Game Clock Class, since nothing then regrows (NoGameClock).

A Reset Area set to **Never** with Reset Instances on keeps the removed instances inside its shapes removed, such as around a player's base, in a streamed level or World Partition cell as it streams in too; they regrow by their kept time once no such area holds them, as when the base is destroyed or the area turned off with Set Enabled. Whole List components, and components that started without a build, hold no removed instances and never regrow. A due removal that matches no instance of the level's design any more is dropped, unless a Never area holds its saved place, which keeps it. A Regrow After you change during play applies from the next save or load. Changes kept for another mesh (see MeshChanged above) do not regrow until they apply.

**On Instances Regrown** fires for every instance that comes back, by Regrow After or because a Reset Area reset it, with the component, the instances' indices now and their keys, the keys they had before their removal. While a level is being built it fires once the level's actors began play. Reset the data you keep per instance there, and destroy actors you spawned for a removal, such as a stump: they stay. Regrowth does not check what stands at the place. Only the server or a standalone game regrows instances.

### Blueprint

In your Game Mode's Begin Play, bind **On Instances Regrown** of the Rolly Save subsystem; in the event, remove each of **Keys** from your Wood Left map. On a Game Clock, call **Check Rolly Regrowth** after your clock moves, such as at the end of your sleep.

### C++

```cpp
#include "Game/RollySaveSubsystem.h"

// In BeginPlay. HandleRegrown is a UFUNCTION of this actor.
GetGameInstance()->GetSubsystem<URollySaveSubsystem>()->OnInstancesRegrown.AddDynamic(this, &AForestKeeper::HandleRegrown);

void AForestKeeper::HandleRegrown(UPrimitiveComponent* Component, const TArray<int32>& InstanceIndices, const TArray<FRollySaveInstanceKey>& Keys)
{
	for (const FRollySaveInstanceKey& Key : Keys)
	{
		WoodLeft.Remove(Key);
	}
}

// After the player slept and your Game Clock moved on.
URollySaveSubsystem::CheckRegrowth(this);
```

## Reset instances with Reset Areas

A Reset Area with **Reset Instances** ticked, the default, resets the instances inside its shapes as its level is next built: removed ones come back, moved ones go home, and ones added inside go (see [Place save points, checkpoints and reset areas](https://rolly-docs.pages.dev/save/guides/place-level-tools/)). The removed ones it brings back fire On Instances Regrown. Each instance counts by where the level's design places it, or for an added one where it was saved, never by where its actor's pivot is, so an area around a grove resets the grove's trees, not every tree of a foliage actor that spans the map. **Filter** and **Except** check the instances' actor. A Whole List component loses the saved instances inside the area.

## Keep harvested foliage out of distant HLODs

HLODs are built from the level's design, so a felled tree still shows in an HLOD while its cell is unloaded. Untick **Include Actor in HLOD** on actors that hold harvestable instances.

## Play with several players

The server, or a standalone game, saves and sets instances. The engine does not replicate instanced meshes' instances, so a client sees the level's design after a load: send harvests to clients yourself, such as with a multicast event that names the instance's key.

## What is never saved

- Landscape grass, which the landscape builds again as the view moves: paint plants players change with the Foliage tool.
- HLOD instances, copies built from other actors.
- Instanced Skinned Mesh components that keep their instances only on the GPU.
- Mass visualization components, whose instances Mass sets from its entities, and the components of the Instanced Actors plugin, which keeps its own saved state.
- A geometry collection's embedded geometry and the components of an ISM pool, the deprecated geometry collection ISM pool's included, which render other components' pieces: save the geometry collection instead.
- Output PCG graphs spawn on the GPU. Other PCG output saves its changes through its PCG component, which makes its components again (see [Save PCG worlds](https://rolly-docs.pages.dev/save/guides/procedural-content/)).
- Instanced components of a player's pawn: the engine makes the pawn again with its own.
- Bone attachments between instances and animation playback positions.

## See saved instances while you test

The Rolly Save component's **Effective Settings** shows Instances as one value, such as "Changes · Every Instanced Mesh · 1 mesh · regrows after 1 d", every field in its tooltip, and where each source sets it in the row's tooltip. Under it the Takes line counts what the settings take of the actor's components by the rule a game uses, such as "Takes 1 of 2 instanced components, 300 instances, about 16.4 KiB while its level is loaded: Trees.", with the output of its PCG components; settings that take nothing show a warning icon and the reason, such as "Takes no component: Components is Foliage and PCG Output, and it has neither." Destruction and the PCG rows are subdued and read "not used" in their tooltip on an actor without such components. Components a construction script or your game adds are taken the same way while playing, but the Takes line counts only those in the Components panel.

![Effective Settings with instances](https://rolly-docs.pages.dev/save/_files/Images/EffectiveSettings_Instances.png "BP_Orchard_1's component: Instances from this component, the Takes line naming Trees, its 300 instances and their memory, and Destruction and the PCG rows not used.")

The Rolly Save column of the outliner reads Instances, Destruction or PCG for an actor that saves only through Actor Defaults' settings of those, and its tooltip names the source that decides each, such as "DA_Foliage (Priority 0): saves instances (Changes, Foliage and PCG Output)", with a line counting the components taken, their instances and their memory. A foliage actor whose settings take none of its components saves nothing of them. While playing, the Gameplay Debugger's RollySave category counts each tracked component's changes (see [See what an actor saves while you play](https://rolly-docs.pages.dev/save/guides/debug-while-playing/)).

In the Save Inspector (see [Inspect, compare and edit saves](https://rolly-docs.pages.dev/save/guides/inspect-saves/)), a component record's **Instances** group sums up its changes, such as "3 removed, 1 changed, 1 added", or "Whole list of 40". It holds the **Mesh**, its path in the tooltip; what it **Saves**, Changes or Whole List; the **Design**, the instances the level's design gave the component and their custom data values each; and the **Removed**, **Changed** and **Added** instances, in pages of 1,000 when there are more. Each instance shows its place, a changed one where it is now and how far it moved. Open one for its **Transform**, **Custom Data**, **Removed At** on Reset Clock (Unknown until a save timed it), and for an Instanced Skinned Mesh component its **Design ID** and **Animation Index**; a changed instance holds its **Design** and **Now**. The rows are read only: change instances in your game and save again, or drop all of the component's changes with **Remove Record**. Changes a load kept for another mesh show under Other Sections, and so do changes a later version wrote, marked "Flags 0x00000008: kept for the version that wrote them".

With an instance selected, **Frame Instance** on the record line moves the editor camera to it in the editor world: where the level's design has it for removed and changed instances, where the save adds it for added ones, which have no mesh there in the editor. It is disabled while the actor is not loaded, is in another map or exists only while playing, and when the component is not on the actor in the editor world.

![The Save Inspector's Instances group](https://rolly-docs.pages.dev/save/_files/Images/Inspector_Instances.png "A foliage record: SM_Pine, Changes, a design of 1,200 instances with 2 custom data values each, 120 removed pines, a changed one open to Design and Now, the two added ones, and Frame Instance's tooltip.")
