BO4 CustomStructures

Read first: Custom Objects and Structures (BO2/BO3/BO4 configs)

BO4's are not placed based on seed, but rather plotted and generated as the world is being explored. This approach is intentionally different from vanilla and BO3 structures, so as to allow for different features. BO4 structures support fine control over placement and distribution and can blend in with terrain. Any number of BO4 structures can be spawned in a biome, and use collision detection so as not to overlap. Advanced branching features support structures of any shape or size, and allow for randomised structures that can shape to fit any available space.

## BO4 creation

BO4's can be created via the /otg export command with the -bo4 flag, or can be converted from .schematic files. BO4's can be max 16x16 blocks per file, and can include Branch() tags to connect them to other BO4's. When an object larger than 16x16 is exported to BO4 or converted from .schematic, multiple BO4 files are created, with Branch() tags included to connect them.

A single master BO4 file acts as the start of the structure and its branching pattern. For example, "/otg export RuinedCity -bo4" for a 32x32 WorldEdit selection would create:

* RuinedCity.BO4
* RuinedCity/RuinedCity\_C0R0.BO4
* RuinedCity/RuinedCity\_C0R1.BO4
* RuinedCity/RuinedCity\_C1R0.BO4
* RuinedCity/RuinedCity\_C1R1.BO4

The master BO4 file contains settings that apply to the entire structure for placement, distribution, blending with terrain etc. Users can edit these settings to make the structure spawn as they like. The master BO4 does not contain any blocks or branches, these are stored in the BO4's in the accompanying folder, ending with C0R0, C0R1 etc. C0R0 indicates column 0 row 0, each of these BO4's has a Branch() that spawns the BO4 in the next row or column. This is a simple pattern used when exporting large objects, users can also create their own branches and branching patterns. The master BO4 does not contain any blocks or branches, but inherits them from the C0R0 BO4, so users can re-export a structure and override all files in the accompanying folder to update blocks, while preserving their master BO4 to keep their spawning settings.

## Branching

Exported or converted BO4's use a static branching pattern, meaning their branches always spawn in the same configuration with a 100% success rate. This is useful for spawning large structures that must either spawn in their entirety, or not at all. Static BO4's are easy to use and can be added to a BiomeConfig's resourcequeue after configuring placement, distribution and blending settings in the master BO4.

BO4's also provide features for creating randomised branching patterns, using collision detection and rollback mechanics to create branching patterns according to chance and available space. Randomised BO4's require manual editing of individual BO4's to configure Branches() and settings. Randomised branching mechanics are a complex subject and still under development, documentation will be written a.s.a.p. See the Dungeons preset for an example of what can be achieved (infinitely branching dungeons), ask us on the Discord for help making your own randomised BO4's.

## Plotting / Placement

Unlike BO3's and vanilla structures, BO4's use collision detection to plot structures neatly inside biome borders and make sure none overlap. Instead of using rarity, BO4's use Frequency and BO3Groups/BO4Groups in the master BO4 file to define a minimum distance between each BO4 and each group of BO4's. This allows fine control over structure distribution. Unlike BO3's, BO4's cannot use block checks to determine spawn location eligibility, they can only check for biome, water vs land, or use height bounds. This is offset by the ability to use smoothing areas and replace blocks to biome-specific blocks, effectively allowing BO4's to make the terrain suit them.

BO4's allow any number of structures to be added to biomes. When multiple BO4 structures are configured for the same biome, OTG tries to plot the largest first, if it doesn't fit, it tries the next, and so on, until a structure is found that fits in the available space (or the end of the queue is reached). This means BO4's will fill available space as efficiently as possible, but their placement depends on the order chunks are generated in while exploring. In other words, when using the same world seed to generate multiple worlds, BO4's may appear in different places, depending on the order of chunk generation.

When adding a BO4 to the resourcequeue of a BiomeConfig:

* Use CustomStructure(BO4Name,100.0) to allow the structure to start here, or spawn branches here if it started in a neighbouring biome.
* Use CustomStructure(BO4Name,0.0) to forbid the structure from starting here, but allow it to spawn branches here if it started in a neighbouring biome.
* When a CustomStructure() is not present in the resourcequeue, the structure may not start or spawn any branch here.

Add as many CustomStructure() resources as you like to each BiomeConfig, but keep in mind that more structures has an impact on performance. Also, the more attempts that have to be made to plot certain structures, the more time plotting will take. So try to make sure structures have a good chance to fit and spawn in biomes you add them to, and don't add so many (large) structures that they'll just get in each other's way.

## Blending / Smoothing

The master BO4 file can be used to configure terrain smoothing/blending settings for the entire structure, although settings can be overridden for individual branches. Smoothing areas can be configured that attach to structure edges and create a slope to surrounding terrain, blocks can be replaced to biome-specific blocks. See a BO4 file for settings and descriptions, a wiki article will be written a.s.a.p.

## BO4Data

BO4Data are optimised files that are much smaller and faster to spawn than BO4 files, but they cannot be edited with a text editor. Before shipping a preset to users, use /otg exportbo4data to export any BO4's (or BO3's with IsOTGPlus:true) in the WorldObjects folder to BO4Data files. Make sure to ship only the BO4Data files and remove the BO4 files. If both a BO4 and BO4Data file are present with the same name, the BO4Data file is used.

Note: We'll look at adding things like sourceblocks in the future, and removing the 16x16 size/grid limitation.

## BO4 Example File

```
#######################################################################
# +-----------------------------------------------------------------+ #
#######################################################################

# The settings mode, WriteAll, WriteWithoutComments or WriteDisable. See WorldConfig.
SettingsMode: WriteAll

#######################################################################
# +-----------------------------------------------------------------+ #
#######################################################################

# You can use this to make this BO4 spawn in groups or make sure that this BO4 only spawns once every X chunks.
Frequency: 0

# When set to true, uses the center of the structure (determined by minimum structure size) when checking the highestBlock to spawn at.
UseCenterForHighestBlock: true

##############################
# Height Limits for the BO4. #
##############################

# Copies the blocks and branches of an existing BO4 into this BO4. You can still add blocks and branches in this BO4, they will be added on top of the inherited blocks and branches.
InheritBO3:

# Rotates the inheritedBO3's resources (blocks, spawners, checks etc) and branches, defaults to NORTH (no rotation).
InheritBO3Rotation: NORTH

# Defaults to true, if true and this is the starting BO4 for this branching structure then this BO4's smoothing and height settings are used for all children (branches).
OverrideChildSettings: true

# Defaults to false, if true then this branch uses it's own height settings (SpawnHeight, minHeight, maxHeight, spawnAtWaterLevel) instead of those defined in the starting BO4 for this branching structure.
OverrideParentHeight: false

# If this is set to true then this BO4 can spawn on top of or inside an existing BO4. If this is set to false then this BO4 will use a bounding box to detect collisions with other BO4's, if a collision is detected then this BO4 won't spawn and the current branch is rolled back.
CanOverride: false

# This branch can only spawn at least branchFrequency chunks (x,z) distance away from any other branch with the exact same name.
BranchFrequency: 0

# Define groups that this branch belongs to along with a minimum (x,z) range in chunks that this branch must have between it and any other members of this group if it is to be allowed to spawn. Syntax is "GroupName:Frequency, GoupName2:Frequency2" etc so for example a branch that belongs to 3 groups: "BranchFrequencyGroup: Ships:10, Vehicles:5, FloatingThings:3".
BranchFrequencyGroup:

# If this is set to true then this BO4 can only spawn underneath an existing BO4. Used to make sure that dungeons only appear underneath buildings.
MustBeBelowOther: false

# Used with CanOverride: true. A comma-seperated list of BO4s, this BO4's bounding box must collide with one of the BO4's in the list or this BO4 fails to spawn and the current branch is rolled back. AND/OR is supported, comma is OR, space is AND, f.e: branch1, branch2 branch3, branch 4.
MustBeInside:

# Used with CanOverride: true. A comma-seperated list of BO4s, this BO4's bounding box cannot collide with any of the BO4's in the list or this BO4 fails to spawn and the current branch is rolled back.
CannotBeInside:

# Used with CanOverride: true. A comma-seperated list of BO4s, if this BO4's bounding box collides with any of the BO4's in the list then those BO4's won't spawn any blocks. This does not remove or roll back any BO4's.
ReplacesBO3:

# If this is set to true then this BO4 can only spawn inside world borders. Used to make sure that dungeons only appear inside the world borders.
MustBeInsideWorldBorders: false

# Defaults to false. Set to true if the BO4 and its smoothing area should ignore water when looking for the highest block to spawn on. Defaults to false (things spawn on top of water)
SpawnUnderWater: false

# Spawns the BO4 at a Y offset of this value. Handy when using highestBlock for lowering BO4s into the surrounding terrain when there are layers of ground included in the BO4, also handy when using SpawnAtWaterLevel to lower objects like ships into the water.
HeightOffset: 0

# Replaces all the non-air blocks that are above this BO4 or its smoothing area with the given block material (should be WATER or AIR or NONE), also applies to smoothing areas although OTG intentionally leaves some of the terrain above them intact. WATER can be used in combination with SpawnUnderWater to fill any air blocks underneath waterlevel with water (and any above waterlevel with air).
ReplaceAbove:

# Replaces all air blocks underneath the BO4 (but not its smoothing area) with the specified material until a solid block is found.
ReplaceBelow:

# Defaults to true. If set to true then every block in the BO4 of the materials defined in ReplaceWithGroundBlock or ReplaceWithSurfaceBlock will be replaced by the GroundBlock or SurfaceBlock materials configured for the biome the block is spawned in.
ReplaceWithBiomeBlocks: true

# Defaults to GRASS, Replaces all the blocks of the given material in the BO4 with the SurfaceBlock configured for the biome it spawns in.
ReplaceWithSurfaceBlock: GRASS

# Defaults to DIRT, Replaces all the blocks of the given material in the BO4 with the GroundBlock configured for the biome it spawns in.
ReplaceWithGroundBlock: DIRT

# Defaults to STONE, Replaces all the blocks of the given material in the BO4 with the StoneBlock configured for the biome it spawns in.
ReplaceWithStoneBlock: STONE

# Makes the terrain around the BO4 slope evenly towards the edges of the BO4. The given value is the distance in blocks around the BO4 from where the slope should start and can be any positive number.
SmoothRadius: 0

# Moves the smoothing area up or down relative to the BO4 (at the points where the smoothing area is connected to the BO4). Handy when using SmoothStartTop: false and the BO4 has some layers of ground included, in that case we can set the HeightOffset to a negative value to lower the BO4 into the ground and we can set the SmoothHeightOffset to a positive value to move the smoothing area starting height up.
SmoothHeightOffset: 0

# Should the smoothing area be attached at the bottom or the top of the edges of the BO4? Defaults to false (bottom). Using this setting can make things slower so try to avoid using it and use SmoothHeightOffset instead if for instance you have a BO4 with some ground layers included. The only reason you should need to use this setting is if you have a BO4 with edges that have an irregular height (like some hills).
SmoothStartTop: false

# Should the smoothing area attach itself to "log" block or ignore them? Defaults to false (ignore logs).
SmoothStartWood: false

# Define groups that this BO4 belongs to along with a minimum range in chunks that this BO4 must have between it and any other members of this group if it is to be allowed to spawn. Syntax is "GroupName:Frequency, GoupName2:Frequency2" etc so for example a BO4 that belongs to 3 groups: "BO4Group: Ships:10, Vehicles:5, FloatingThings:3".
BO3Group:

# Defaults to false. Set to true if this BO4 should spawn at the player spawn point. When the server starts the spawn point is determined and the BO4's for the biome it is in are loaded, one of these BO4s that has IsSpawnPoint set to true (if any) is selected randomly and is spawned at the spawn point regardless of its rarity (so even Rarity:0, IsSpawnPoint: true BO4's can get spawned as the spawn point!).
IsSpawnPoint: false

# Defaults to true. Set to false to make the BO4 ignore any ReplacedBlocks settings in Biome Configs.
DoReplaceBlocks: true

#######################################################################
# +-----------------------------------------------------------------+ #
#######################################################################

#  spawns the bottom part of an igloo.

#######################################################################
# +-----------------------------------------------------------------+ #
#######################################################################

# MaxChanceOutOf - The chance all branches have to spawn out of, assumed to be 100 when left blank

#######################################################################
# +-----------------------------------------------------------------+ #
#######################################################################

# curly braces to a .txt file, for instance for: "/summon Skeleton x y z {DATA}"

#######################################################################
# +-----------------------------------------------------------------+ #
#######################################################################

# velocityX,velocityY,velocityZ - Spawn the enemy with the given velocity. If this is not filled in then a small random velocity is applied.

#######################################################################
# +-----------------------------------------------------------------+ #
#######################################################################

# velocityX,velocityY,velocityZ,yaw,pitch - Spawn the enemy with the given velocity and angle, handy for making traps and launchers (shooting arrows and fireballs etc).

#######################################################################
# +-----------------------------------------------------------------+ #
#######################################################################