Version 1.0, coming to Fab. Orrery Terrain 1.0 is not on sale yet; this guide can still change before it is.
3. Concepts
Read this once. It explains the words the other chapters use.
One terrain per world
Section titled “One terrain per world”A world has at most one terrain. It is hosted by one terrain actor (AOrreryTerrainActor) and run by one world subsystem (UOrreryTerrainSubsystem). A second actor is refused with a warning.
The actor holds configuration: the source of the ground, the material, and two settings blocks (Settings and Render). It does not hold the ground. The ground lives in the subsystem. Moving the actor does not move the terrain: the grid origin is part of the source asset.
You reach everything through the subsystem, either directly or through the Blueprint function library UOrreryTerrainLibrary.
Truth and features
Section titled “Truth and features”The ground you see is not stored as one big heightmap you edit. It is computed from layers, bottom to top:
- Natural ground. The source: a flat plane, procedural hills, an imported heightmap, a DEM or a Landscape. It never changes at runtime.
- Sculpt layer. What players paint and sculpt at runtime. It is destructive: a stroke changes the ground and is kept until you undo it.
- Features. Earthworks you state as shapes: plates (pads, yards, aprons) and corridors (roads, rail beds, canal banks). A feature is a small description, not a pile of height changes. The terrain works out cuts, fills and slopes from it.
The result is the modified ground. Because features are descriptions, you can remove or replace one later and the ground under it comes back. Every commit returns an exact undo token.
A feature may carry an owner (a domain number and an id). The terrain does not interpret them. You use them to find and remove everything that one of your systems made, with Remove Features By Owner.
Choosing which ground to read
Section titled “Choosing which ground to read ”Queries take a surface:
| Surface | Description |
|---|---|
Modified |
The ground as it is now. The default for everything. |
Natural |
Before features: natural ground plus the sculpt layer. |
Pristine |
The source ground, never edited at runtime. |
Water |
The water surface from channel features. No data where dry. |
Top |
What a character stands on. It equals Modified unless an extension adds cover. |
Save contents
Section titled “Save contents ”A terrain save keeps the feature stack, the sculpt layer and the identity of the natural ground. It does not keep baked tiles. So a save only loads over the same natural ground. A save made over a different source is refused: it does not load.
Render tiers and the far field
Section titled “Render tiers and the far field”The terrain has two renderers, called tiers:
- Heightfield tier. The main renderer. It uses continuous level of detail, draws the whole terrain out to a far-field distance, and works with Lumen and virtual shadow maps. It needs Shader Model 5 or higher; Lumen and virtual shadow maps themselves need Shader Model 6 on DirectX 12.
- Mesh tier. A simple fallback with fixed detail. It draws only the loaded ground, takes any material, and is meant for comparisons, debugging and lower-end hardware.
Auto (the default) picks the heightfield tier where it works.
Within the heightfield tier there are three zones:
- Near chunks around each viewer, at full detail.
- Far ring, an optional band of mid-distance detail. How much you keep is the far detail setting:
Low,BalancedorHigh. - Far field, the rest of the terrain out to
FarFieldDistance_m, drawn from a small always-loaded coarse copy.
See Performance and quality for the numbers.
Residency: what is loaded
Section titled “Residency: what is loaded”The terrain is built from square tiles of 127 cells (128 posts) a side. A post is one height sample; a cell is the gap between two posts, the cell size you set when you make the terrain. Neighbouring tiles share their edge posts. Only tiles near something that needs ground are loaded at full resolution. That is residency.
Full-resolution ground is kept around:
- each streaming source: the World Partition sources when the world uses World Partition, otherwise the player cameras (
bUseWorldPartitionSources); - each invoker you register with Register Invoker: a point (an actor you choose) that keeps the ground around it loaded, such as a construction cursor, a vehicle or an AI agent;
- the footprint of a pending commit.
The default radius is 2000 m (ResidencyRadius_m).
A coarse copy of the whole terrain (posts 32 m apart at a 1 m base spacing, ResidentMipLevel 5) is always loaded. It serves the far field and long-range queries.
Asking for ground that is not loaded
Section titled “Asking for ground that is not loaded”Read functions take an accuracy:
| Accuracy | Answer |
|---|---|
Best |
Exact where loaded, else approximate from the coarse copy, else no data. For cameras, cursors and effects. |
ExactOnly |
The exact answer or none. For server gameplay, and anything that must agree on every machine. Pair it with an invoker or a wait node. |
Coarse |
Always from the coarse copy. It can leave out plates and corridors on some machines (see below). For minimaps and client effects, not for gameplay a server decides. |
Each answer also reports its precision: Exact, Approximate, NoData (outside the terrain) or Pending (not available at this accuracy yet).
Writes (commits) over ground that is not loaded are refused, and the tiles are requested. Use the async nodes, which wait for the ground (Wait For Terrain Ground, Commit Plate (Async) and others).
Determinism
Section titled “Determinism”The terrain stores heights as whole millimetres and brush strokes as integer commands. Two machines that apply the same edits in the same order get the same ground, and Get State Hash returns the same number on both.
Two details matter for your game logic:
Bestaccuracy depends on what each machine has loaded. Do not use it for logic that must agree across machines.ExactOnlyanswers depend only on the terrain’s revision.Coarseover edited ground (Modified) depends on whether the machine keeps far data. The heightfield renderer keeps it while its far field is on, at every far detail, and those machines agree once settled. A dedicated server keeps none, nor does a client on the mesh tier or with the far field off: thereCoarseshows sculpting but leaves out plates and corridors, so it can differ over an embankment.CoarseonPristineis the same everywhere. The same holds for the PCG node’s Coarse option.- Anything that changes the ground is a request to the authority (a server, or a single-player game). A replica applies the authority’s records and refuses local edits.
With the built-in replication, a client’s tools send these requests to the server for you. See Multiplayer.
Threads
Section titled “Threads”Reads never block and run on one consistent snapshot. Writes run on the game thread only. They are refused inside a ground-changed listener. Each change bumps a revision you can read with Get Revision and a ground changed event tells you where.
C++ code on other threads takes a snapshot with AcquireQuery() on the game thread and passes it to the worker.
| Quantity | Unit |
|---|---|
Blueprint nodes, UOrreryTerrainLibrary, brushes, plates, corridors |
centimetres, world coordinates |
Settings ending in _m |
metres |
| Slopes and grades | metres per metre (0.1 is 10 percent); angles in degrees |
| Volumes | cubic metres |