Repository navigation
Displays on the Building
Two ways to make the stock visible from outside: a pile that grows along with it, and a board with a number on it. Both sit directly under <placeable>, regardless of whether it is a silo, production point or greenhouse, and need a Revamp placeable type.
Pallets, sacks, crates — whatever the modder has placed in the model appears and disappears with the stock. The display follows a change in stock with a delay of up to five seconds; this is intentional, so that filling does not switch half the model for every liter.
<revampObjectFillLevels>
<revampObjectFillLevel rootNode="revampFillLevelObjects" fillType="FLOUR" maxAtFillLevel="60000"/>
</revampObjectFillLevels>Any number of <revampObjectFillLevel> entries per placeable, e.g. one per good.
| Attribute | Default | Meaning |
|---|---|---|
rootNode |
Required | Node from the i3dMappings whose children are the objects to display |
fillType |
– | One fill type whose stock controls the display |
fillTypes |
– | Several fill types, separated by spaces; their stocks are added up |
fillTypeCategories |
– | Fill type categories instead of individual names, also added up |
maxAtFillLevel |
Required | Stock from which all objects are shown |
firstAtFillLevel |
maxAtFillLevel divided by the number of objects |
Stock from which the first object is shown |
invert |
false |
Reverses it: the objects disappear the fuller the storage gets |
useSubNodesInsteadOfMainNodes |
false |
Uses the second instead of the first level below the root node as objects |
At least one of fillType, fillTypes or fillTypeCategories must be set. If both fillType and fillTypes are set, fillTypes wins and there is a warning in the log. If rootNode or maxAtFillLevel is missing, or the root node has no children, the entry is skipped with a message in the log — the remaining entries keep working normally.
The objects appear in the order in which they hang below the root node in the i3d. The distance between two steps is
(
maxAtFillLevel−firstAtFillLevel) ÷ (number of objects − 1)
Example with 48 objects and maxAtFillLevel="60000" without its own firstAtFillLevel: the first object is shown from 1,250 l, each further one every 1,250 l, all 48 from 60,000 l.
A custom firstAtFillLevel only shifts the start, the end stays at maxAtFillLevel. With firstAtFillLevel="1" the first object is already shown at the first liter and the remaining 47 are spread over the rest.
maxAtFillLevel does not have to be the storage size. A smaller value lets the pile fill up at just a fraction of the storage, which looks better on very large storages than 48 barely distinguishable steps.
A node with the objects as direct children, entered in the placeable's i3dMappings block. The child order is the display order.
The objects must not be dynamic bodies. A hidden object gets collision mask 0 so that it is no longer in anyone's way — a dynamic body falls through the ground at that moment and is gone even after being shown again. Static, or no physics body at all.
The original collision mask is read from the model on loading and set again when the object is shown — so every object keeps exactly the mask the modder gave it. The first level below the object is included as well, because the collision is often attached to a separate shape underneath.
A board that shows the stock as a number, like a real display on a silo. From a certain amount it can change color, or count down instead of up — i.e. show how much still fits in. The number follows a change in stock with a delay of up to one second.
<revampDisplays>
<revampDisplay node="mehlAnzeige" fillType="FLOUR" mask="000000" size="0.25"/>
</revampDisplays>| Attribute | Default | Meaning |
|---|---|---|
node |
Required | Node from the i3dMappings at which the digits are created |
fillType |
Required | Fill type whose stock is displayed |
mask |
000000 |
Digit pattern, see below |
font |
DIGIT |
Name of the font material |
alignment |
RIGHT |
LEFT, CENTER or RIGHT
|
size |
0.13 |
Height of the digits in meters |
scaleX / scaleY
|
1 |
Additional stretching of the digits |
emissiveScale |
0.2 |
Self-illumination, so the number is readable at night too |
color |
0.9 0.9 0.9 |
Color of the digits |
hiddenColor |
– | Color of the unused digit positions, for the look of a real seven-segment board |
reverse |
false |
Counts down from reverseAmount instead of up |
reverseAmount |
– | Value to count down from; required with reverse="true"
|
If node is missing or fillType is unknown, the display is skipped with a message in the log. An unknown font material falls back to DIGIT with a warning. reverse="true" without a usable reverseAmount counts up normally again, with a warning.
Colors are given as three values r g b between 0 and 1 or as a color name such as SHARED_WHITE1. This applies to color, hiddenColor and the color changes. A fourth value for opacity, as was common in FS22, is rejected by FS25. The color is then considered invalid, a warning appears in the log, and the display uses the default color instead.
Every 0 in mask is a digit position, everything else is a separator. The number of characters determines how many digit objects are created.
mask |
Result at 47469 l | Note |
|---|---|---|
000000 |
_47469 |
Leading positions stay empty, not 0 |
0000.0 |
Decimal place | Everything after the separator are decimal places |
If the value is larger than the pattern can hold, it is not cut off; instead the number becomes longer than intended — so choose the pattern generously.
<revampDisplay node="mehlAnzeige" fillType="FLOUR" mask="000000" color="0.2 0.8 0.2">
<colorChange amount="0.75" color="0.9 0.7 0.1"/>
<colorChange amount="0.95" color="0.9 0.1 0.1"/>
</revampDisplay>| Attribute | Default | Meaning |
|---|---|---|
amount |
1 |
Threshold from which value the color applies |
color |
– | Color from this threshold on |
An amount below 1.1 counts as a share of the capacity (0.75 is therefore three quarters of the storage), anything above as a number of liters. Below the first threshold the base color from color on the <revampDisplay> applies. The order of the <colorChange> entries does not matter, the highest threshold reached always wins.
The capacity is fetched again on every update, not once on loading. Proportional thresholds therefore stay correct if the storage size changes in the game.
Only an empty TransformGroup at the spot where the display is to sit, entered in the i3dMappings block. The digits themselves are not in the model — the font material creates them at runtime as children of this node. The rotation of the node determines from which direction the number can be read; the position is the reference point of the alignment, i.e. the right end of the number with alignment="RIGHT".
-
The path is new. Instead of
<silo><siloObjectFillLevels>or<productionPoint><productionObjectFillLevels>, it is now<revampObjectFillLevels>for both, directly under<placeable>; the same applies to<siloDisplays>/<productionDisplays>→<revampDisplays>. Silo and production have become one shared specialization. - The attribute names have stayed unchanged, so existing displays can be taken over one to one.
- In FS22,
useSubNodesInsteadOfMainNodeswas set on the collection node and applied to the whole placeable. It is now set on the individual entry, so a placeable can use one group flat and the next one nested. - The collision of shown objects now comes from the model. In FS22 the script set a hard-coded mask from the old collision system when showing an object; that no longer exists in FS25. A model that relied on this fixed value must now have its mask set in the i3d itself.
- Proportional color thresholds on a silo with several storages were wrong in FS22: the capacity used was always that of the storage read last, even if it did not hold the displayed good at all. Anyone who adapted their thresholds to this behavior back then should recalculate them.