IR's overlay gui framework is built with nested elements. You always start with a top level element, then add sub elements.
{
"someattribute": "somevalue",
"anotherattrib": 6,
"elements: [
{...},
{...},
{...}
]
}
In a stock's json file (locomotive, freight, etc...)
{
// existing stock.json properties...
"overlay": "immersiverailroading:gui/mypack/somegui.json"
}
It is highly recommended that you don't overwrite Immersive Railroading's default assets and instead put your GUIs in their own directories.
IR also ships with some reasonable defaults that you can reference as examples when reading through this document.
"x" and "y" are element attributes that are a relative offset to the parent block. The pixel coordinates
are relative to the parent, and wrap around the edges of the screen. This means that the top left corner is x0, y0.
Any positive numbers therefore move the position toward the bottom right of the screen. Any negative numbers will wrap
around the bottom/right of the screen.
For example, if you have x=10 and y=-95, the actual screen position would be 10 pixels from the left of the screen, and 95 pixels up from the bottom.
Additionally any time you nest elements, you are building on top of the previous elements positioning (both x,y and rotation/translation/scale, etc...)
The following would result in a parent at 10, screenheight-20 and child at 15, screenheight-15:
{
"comment": "parent,
"x": 10,
"y": -20,
"elements": [
{
"comment": "child",
"x": 5,
"y": 5
}
]
}
If you want to align a block to the center of the screen, it's recommended you use the "centered" attribute at one of the top levels in your layout.
Example:
{
"elements": [
{
"comment": "center panel",
"x": -64,
"y": -30,
"centered": {
"x": true
},
"elements": [
...
]
}
]
}
This will put the center panel 30 pixels up from the bottom of the screen, and 64 pixels to the left of the horizontal center of the screen (which would work well with a 128 pixel wide image).
An element can display nothing (used for positioning/grouping), an image, or text.
Image is specified with "image": "immersiverailroading:gui/mypack/someimage.png"
and is rendered pixel for pixel.
Text is a little more involved.
{
"text": {
"value": "some text",
"height": 8
}
}
The "value" attribute is a string that will either render as is, or have parts substituted in it. label.brake
,
label.throttle
, and label.reverser
will all be replaced with their translated equivalent. Any of the stats in
Stat.java
can be substituted into the string with stat.statname
(lowercase).
The "height" attribute is a bit simpler and simply scales text to fit within the desired number of vertical pixels. The default is 8.
These are quite similar to the in game IR controls and are either driven by the value of a Readout or Control group
"readout": "somereadout"
are driven by the same logic as gauges in IR Controls, with similar names. A comprehensive list can be found in
Readout.java.
"control": "somecontrolgroup"
are driven by the current value of a control group defined in the model.
"translate": {}
defines how an element should be moved (x, y) as the readout or control value changes.
Example:
{
"translate": {
"x": 5,
"y": 10,
}
}
"rotate": {}
defines how an element should be rotated as the readout or control value changes.
{
"rotate": {
"x": <x pixels to offset the rotation center by, this allows you to rotate around a point other than the current coordinates>,
"y": <y pixels to the same effect",
"degrees": <degrees to rotate, starting at 0 and moving toward the specified value>
"offset": <degrees to rotate always, regardless of the control value>
}
}
"scale": {}
defines how an element should be scaled in x, y as the readout or control value changes.
Only specify the x or y that you want to be modified. Any value that is not specified will not be changed.
Example of only scaling on the y axis and leaving the x dimension alone:
{
"scale": {
"y": 1
}
}
"color": {}
allows you to specify different colors to tint the element as the value changes. Values are specified in standard html
format and can include a alpha component as the first two hex chars.
"0x99FF6600" would be slightly transparently (99) orange (FF6600).
Example going from green, to orange, to red:
{
"0.0": "0xFF00FF00",
"0.5": "0xFFFF6600",
"0.9": "0xFFFF0000"
}
Inverts the readout/control value
Does not show the element (and children) unless the control/readout value is 1.