Valheim Wiki
Advertisement

The construction system in Valheim implements a stability mechanic to encourage more realistic buildings and drive gameplay. If the player places a building piece that is not sufficiently stable, it will collapse. Stability is primarily dictated by a piece's material, its position and orientation, and the pieces to which it is attached.

Mechanically, the stability of a component is described by a number called its "support". This number is calculated and then checked to determine whether the component should break. A higher support value indicates more stability and less likelihood of breakage.

The support system does not work like it does with real materials and resembles more how pressure propagates in a plumbing system. Or a magic force coming from ground and trees and flowing through the building pieces. For example, there is no limit on how many other pieces a single beam could support.

Materials[]

Each building structure is made of one of several materials:

Building Materials
Name Prefixes MaxSupport MinSupport VerticalLoss HorizontalLoss
Wood Wood, Thatch roof, Shingle roof, Darkwood, Ashwood 100 10 1/8 1/5
Hardwood Log (core wood) 140 10 1/10 1/6
Stone Stone 1000 100 1/8 1/1
Iron Wood iron, Cage, Dvergr metal, Flametal 1500 20 1/13 1/13
Marble Black marble 1500 100 1/8 1/2
Ashstone Grausten 2000 100 1/10 1/3

The properties of the component's material influence its stability.

  • MaxSupport: The maximum support value that a component can have. This is the support it will have if it is placed directly on the ground (or on natural features like rocks and trees). It will also be capped at this value if it is placed on something with a much higher support value (e.g. wood on well-supported stone).
  • MinSupport: The minimum support value a component can have. If its support is less than or equal to this value, the item will break.
  • VerticalLoss / HorizontalLoss: factors that influence how much support is lost for components that are built on other components rather than directly on the ground.

Support[]

A component is "in contact" with something when any part of its surface (including edges and corners) touches part of that other item's surface. When a component is directly in contact with the ground, its support is set to its material's MaxSupport value. When a component is not in contact with any other object, its support value will be zero and it will break. When a component is in contact only with other building components (called "parents"), its support will be calculated by a complex series of formula depending on the following factors:

  • Its material
  • The support values of each parent
  • The distances between it and each parent (distances are generally calculated from midpoints or centers of mass)
  • Its position relative to its parents

Single Parent[]

Before the support value can be calculated for a component that is supported by a single parent, two other values need to be calculated: distance and angled loss. Both values depend on the relative locations of the two components' midpoints.

The distance is calculated between centers of two pieces, using the standard Pythagorean method. However, a "fudge factor" of 0.1 meters is added to the distance for most calculations. Distance can generally be calculated with the following formula:

Distance = SquareRoot( ([component's height]/2 + [parent's height]/2)2 
                     + ([component's width]/2 + [parent's width]/2)2 ) + 0.1

For example, a Log pole 4m has a height of 4 meters and a width of 0, and a Log beam 2m has a width of 2m and a height of 0, so if a Log beam 2m is placed on a Log pole 4m (making a Г-shape), the distance between them will be 2.336 meters.

The angled loss is calculated by interpolating between VerticalLoss and HorizontalLoss based on the angle between the component's midpoint and its parent's "support point". The parent's support point is usually (but not always) the point where the component is attached. Angled loss uses the following formula:

Angle = cos-1( 1 - [height above support point] / [distance to support point] ) / π/2

NOTE: the "distance" in this formula does not include the 0.1 meter "fudge factor".

In simple terms, this means:

  • when one piece is exactly above another, VerticalLoss value is used
  • when two pieces are connected horizontally, HorizontalLoss value is used
  • for all other situations the loss is somewhere between vertical and horizontal depending on how steep is the angle. E.g. in a strip of 45° roof, each next piece the coefficient would be (HorizontalLoss + VerticalLoss) / 2, for 26° it's 0.7 * HorizontalLoss + 0.3 * VerticalLoss


AngledLoss = [HorizontalLoss] * [Angle] + [VerticalLoss] * (1 - [Angle])

Once the distance and angled loss are obtained, the support can be calculated as follows:

Support = [parent's support] * (1 - [AngledLoss] * [Distance])

For example, for the simple case of a Wood Pole 2m on top of another Wood Pole 2m that is on the ground, we can plug in the values as follows:

Distance = 2.1 = SquareRoot( (2/2 + 2/2)2 + (0/2 + 0/2)2 ) + 0.1
Angle = 1 = cos-1( 1 - 1 / 1 ) / π/2
AngledLoss = 0.2 = 0.2 * 1 + 0.125 * (1 - 1)
Support = 58 = 100 * (1 - 0.2 * 2.1)

If we use 1m poles, the support will go as:

Distance = 1.1 = SquareRoot( (1/2 + 1/2)2 + (0/2 + 0/2)2 ) + 0.1
Angle = 1 = cos-1( 1 - 1 / 1 ) / π/2
AngledLoss = 0.2 = 0.2 * 1 + 0.125 * (1 - 1)
Support = 78 = 100 * (1 - 0.2 * 1.1)

But obviously we go only 1m up this way, so if we need to calculate loss per 2m, we need to apply loss twice (square the number), which result in 60,84. Slightly more than using 2m poles, but the win is insignificant.

Multiple Parents[]

If a component is attached to multiple parents, the support from each individual parent is computed as in the single parent method, but total support is not just a sum of all parents.

If two parents' support points are more than 100 degrees opposite each other (relative to the component) and are both below (at least 0.05m lower) the component's midpoint, the parents support the component together. Any pair of parents can support a component together, even if one or both parents are already supporting the component with another parent. The support for a component is calculated similarly to single support, except that only VerticalLoss is used, regardless of the angle, and the two support values are averaged. Thus, the formula for Parent A and Parent B would be:

MutualSupport = ( [Parent A's support] * (1 - [VerticalLoss] * [Distance to A]) 
                + [Parent B's support] * (1 - [VerticalLoss] * [Distance to B]) ) / 2 

Once all supports—single and double—have been calculated, the maximum support from all of them is chosen as the final support value for the component.

A practical use of that feature is building non-ground stone floors. In a single support case, it is impossible to extend horizontally with stone, because HorizontalLoss for stone is 1 (i.e. 100% loss). But it is e.g. possible to build as big as 7x7 (49 blocks, 14x14 in meters) grid with stone floor pieces and metal support only on corners. Keep in mind that such structure holds together only as a whole, removing any block result in significant part of the structure falling apart.

Dynamic stability[]

Components do not break immediately, even if they are not properly supported. This is because support calculations are iterative, and must propagate throughout a structure before settling to their final values.

When placed, a component's support is set to its Material's MaxSupport value. Then, every 0.5 seconds*, its support is calculated based on the current support values of its parents. This means, for example, that placing a component on another component but not touching anything else will often briefly raise the support value of its parent, because its parent views the component as a parent with a maxed support value. However, as the support value of the child component drops, it will cease to have an effect on the parent (because the parent is already better supported by other components).

*A maximum of 50 components are recalculated every 0.5 seconds. Thus, in an area with many components, it may take longer.


Attribution

All formulas and values were derived from the source code of Valheim, specifically the "WearNTear.GetMaterialProperties" and "WearNTear.UpdateSupport" functions.

Advertisement