Skip to content
You're reading the docs for Railroader 0.6 (the MoW Update), currently available on the Experimental branch.

Extending the UI

Available via from railroader import ui in Main.rl.

ui provides APIs for extending built-in UI panels (the car inspector’s tabs and customization section) with custom content, plus APIs for custom windows, console commands, and car customization editors. See also:

extensionPoint string Extension point identifier, e.g. "carInspector.equipment"

Registers a UI section at an extension point, returning a builder to configure it. Returns null (and logs a warning) if extensionPoint is empty or isn’t one of the known extension points.

ui.extend("carInspector.equipment.customize")
.id("my-customization")
.matching({"identifier": "rr/my-car"})
.priority(100)
.with(buildUI)
func buildUI(builder, car) {
builder.section("My Section")
builder.rebuildOnPropertyChange(car.properties, "customize.option")
builder.fieldToggle("Enable Option",
() => car.properties["customize.option"] ?? false,
(value) => { car.properties["customize.option"] = value }
)
}
Extension PointContextDescription
carInspector.equipmentCarEquipment tab of the car inspector
carInspector.equipment.customizeCarCustomization section (paint, options) of the car inspector’s equipment tab
carInspector.operationsCarOperations tab of the car inspector
companyWindow.main—Reserved for a future company window integration; accepted by ui.extend() but not yet invoked anywhere in-game

The object returned by ui.extend(). Every method except .with() returns the same builder, so calls chain together.

id string Unique identifier for this extension

Sets the extension’s ID. Re-registering the same ID on the same extension point replaces the previous registration. Defaults to the calling asset pack’s identifier if never called.

criteria dict String key/value pairs to match against the extension point's context

Restricts this extension to contexts matching all given key/value pairs. See Matching Keys. Call it more than once to match any of several sets: the extension applies when every pair in at least one call matches. Omitting this call, or passing an empty dictionary, makes the extension apply to every context.

ui.extend("carInspector.equipment.customize")
.id("my-customization")
.matching({"identifier": "mymod/boxcar-40ft"})
.matching({"identifier": "mymod/boxcar-50ft"})
.with(buildUI)

Throws if criteria isn’t a dictionary, or holds a non-string key or value.

priority int Ordering value; lower values are invoked first

Sets the extension’s ordering among other extensions on the same extension point. Defaults to 0.

builderFunc (UIPanelBuilder, Car) => void Called as (builder, car) for car inspector extension points, or (builder) (no car argument) for other extension points

Registers the extension with the given builder function. Ends the chain. See UIPanelBuilder for what builder can do.

For car inspector extension points, .matching() criteria are checked against:

KeyDescription
identifierDefinition identifier (e.g. "rr/boxcar-40ft")
carTypeAAR car type code (e.g. "XM")

Omitting .matching() makes the extension apply to every context.