Electrics

Electrics is a section in Jbeam that allows for defining custom electrics values and assigning smoothers to them. It consists of 2 tables: customValues, which defines the name of the value and the function it is derived from, and smoothers, which assigns smoothers to values by name. Custom electrics values can be used for gradual transitions between binary inputs, for example for sealed beam headlights which smoothly turn on and off. They can also be used to add or multiply several inputs together, which can be used to achieve the effect of vehicle lights dimming when the electrical system of the car is under load, for example when using the starter.

"electrics": {
    "customValues": [
        ["electricsName", "electricsFunction"],
        ["customValue1","electrics.existingValue1 * electrics.existingValue2"],
    ]
    "smoothers": [
        ["electricsName", "smootherType", "params"],
        ["customValue1","temporalNonLinear", [10,10]],
    ]
}

The whole electrics section can exist inside of the components section and it will still be read normally. This is useful for deep table merging, such as adding a new custom value or smoother in a different part of the vehicle.

"components": {
    "electrics": {
        "customValues": [
            ["electricsName", "electricsFunction"],
            ["customValue1","electrics.existingValue1 * electrics.existingValue2"],
        ]
        "smoothers": [
            ["electricsName", "smootherType", "params"],
            ["customValue1","temporalNonLinear", [10,10]],
        ]
    }
}

CustomValues arguments

string
type
Name of the new custom electrics value.
Cannot be the same as one of the existing values on the vehicle. The list of values can be printed in console by using the dump(electrics) with the car selected
string
type
Lua expression to calculate the value output.

Example expression:

"(electrics.lowhighbeam  + electrics.brakelight_signal_L) * electrics.electricalLoadCoef"

The expression cannot contain assignments, or single standalone ‘=’ signs! It can contain:

  • numbers
  • all standard lua operators
  • all standard lua math functions and constants
  • names of existing electrics values with the “electrics.” prefix applied
  • names of variables existing on the vehicle with the “$” prefix applied
  • whitelisted words: “not”, “true”, “false”, “nil”, “and”, “or”, “dt”
  • custom functions listed below.

Available functions

Name
Description
Example
Notes
Name
dump(table)
Description
prints the string representation of the table in the console, including all nested tables
Example
dump(electrics)
Notes
Name
dumpz(table, depth)
Description
prints the string representation of the table in the console, up to the provided depth level in case of nested tables
Example
dumpz(electrics, 1)
Notes
Name
round(x)
Description
rounds x to an Integer
Example
round(electrics.val1 / electrics.val2)
Notes
Name
square(x)
Description
squares x
Example
square(electrics.val)
Notes
Produces the same effect as ‘(electrics.val)^2’
Name
clamp(x, y, z)
Description
clamps x to y (min) and z (max) values
Example
clamp(electrics.val, 0, 1)
Notes
Name
smoothstep(x)
Description
performs the Smoothstep sigmoid interpolation function
Example
smoothstep(electrics.val)
Notes
From the Smoothstep interpolation and clamping family, commonly used in game engines and graphics
Name
smootherstep(x)
Description
performs the Smootherstep sigmoid interpolation function
Example
smootherstep(electrics.val)
Notes
From the Smoothstep interpolation and clamping family, commonly used in game engines and graphics
Name
smoothmin(x)
Description
performs the Smoothmin sigmoid interpolation function
Example
smoothmin(electrics.val)
Notes
From the Smoothstep interpolation and clamping family, commonly used in game engines and graphics
Name
sign(x)
Description
Returns 1 if x is positive, -1 if negative, 0 if 0
Example
sign(electrics.val)
Notes
Name
case(selector, …)
Description
case selector, works in two ways:

1st way: if 1st param is a bool, if true returns 2nd param, if false returns 3rd param

2nd way: if 1st param is an integer ’n’ it returns the ’n’th+1 param (returns last param if ’n’ is > # of params).
Example
case(electrics.val == nil, 0.25, electrics.val)
if electrics.val = nil: return 0.25
if electrics.val = 0.5: return electrics.val

case(electrics.val, ‘foo’, ‘bar’, ‘baz’)
if electrics.val = 1: return ‘foo’
if electrics.val = 2: return ‘bar’
if electrics.val = 3: return ‘baz’
Notes
Cannot be used to perform arithmetics within the expression on variables that might have nil values
Name
pwm(input, frequency, dutyCycle, timeOffset)
Description
Generates a PWM signal based on a sine wave normalized to [0, 1] with the given frequency in Hz and time offset in s, with the given duty cycle
Example
pwm(electrics.val1, 0.5, 0.5, 1.0)

pwm(electrics.val1, 0.5, 0.5)
Notes
timeOffset argument is optional. Lowest supported frequency is 1/3600 Hz, or 1 cycle per hour. Can be used for repeating flashing lights
Name
logValue(value, label)
Description
Prints in console: ‘Custom Electric: [label] = [value]’
Example
logValue(electrics.val, name)
logValue(electrics.val)
Notes
If no label provided, it will print ’no label’ in its place

Example expression with functions:

"pwm(sign(electrics.lightbar), 0.5, 0.5) * electrics.electricalLoadCoef"

Smoothers arguments

string
type
Name of the custom electrics value the smoother will be applied to.
string
type
Type of the smoother.

Supported smoother types:

  • “exponential” - exponential smoothing
  • “temporal” - linear temporal smoothing
  • “temporalNonLinear” - non-linear temporal smoothing
table
type
Parameters for the selected smoother.

For exponential smoothing, usually only the first one is used:

  • window - number of frames smoothed over
  • startingValue - defaults to 0 if not provided
  • fixedDt - time difference in seconds, defaults to 0.0005 if not provided

For temporal smoothing, usually the first two are used:

  • inRate - defaults to 1 if not provided
  • outRate - defaults to inRate if not provided
  • autoCenterRate - only exists for linear variant, defaults to inRate if not provided
  • startingValue - defaults to 0 if not provided

The most useful type of smoother is a temporal non-linear one with in and out rates declared, used for the on-off transitions of halogen and sealed beam lights:

"smoothers": [
    ["electricsName", "smootherType", "params"],
    ["lowbeam_filament","temporalNonLinear", [10,10]],
    ["highbeam_filament","temporalNonLinear", [10,10]],
]

Some electrics values have an exponential smoother by default:

  • With a 10 frame window: wheelspeed, gear_A, rpm, lights, turnsignal, airspeed, airflowspeed, altitude
  • With a 100 frame window: fuel, oiltemp, watertemp

Simple example

Custom electrics values for simple halogen and sealed beam lamps which smoothly turn on and off and react to electrical system load.

"electrics": {
    "customValues": [
        ["electricsName", "electricsFunction"],
        ["lowbeam_filament","electrics.lowbeam * electrics.electricalLoadCoef"],
        ["highbeam_filament","electrics.highbeam * electrics.electricalLoadCoef"],
        ["lowhighbeam_filament","electrics.lowhighbeam * electrics.electricalLoadCoef"],
        ["taillight_filament","electrics.lowhighbeam * electrics.electricalLoadCoef"],
        ["brakelight_filament","electrics.brakelights * electrics.electricalLoadCoef"],
        ["brakelight_signal_L_filament","electrics.brakelight_signal_L * electrics.electricalLoadCoef"],
        ["brakelight_signal_R_filament","electrics.brakelight_signal_R * electrics.electricalLoadCoef"],
        ["lowhighbeam_signal_L_filament","electrics.lowhighbeam_signal_L * electrics.electricalLoadCoef"],
        ["lowhighbeam_signal_R_filament","electrics.lowhighbeam_signal_R * electrics.electricalLoadCoef"],
        ["reverselight_filament","electrics.reverse * electrics.electricalLoadCoef"],
        ["foglight_filament","electrics.fog * electrics.electricalLoadCoef"],
        ["signal_L_filament","electrics.signal_L * electrics.electricalLoadCoef"],
        ["signal_R_filament","electrics.signal_R * electrics.electricalLoadCoef"],
    ]
    "smoothers": [
        ["electricsName", "smootherType", "params"],
        ["lowbeam_filament","temporalNonLinear", [10,10]],
        ["highbeam_filament","temporalNonLinear", [10,10]],
        ["lowhighbeam_filament","temporalNonLinear", [10,10]],
        ["taillight_signal_L_filament","temporalNonLinear", [15,15]],
        ["taillight_signal_R_filament","temporalNonLinear", [15,15]],
        ["taillight_filament","temporalNonLinear", [10,10]],
        ["brakelight_filament","temporalNonLinear", [10,10]],
        ["brakelight_signal_L_filament","temporalNonLinear", [15,15]],
        ["brakelight_signal_R_filament","temporalNonLinear", [15,15]],
        ["lowhighbeam_signal_L_filament","temporalNonLinear", [15,15]],
        ["lowhighbeam_signal_R_filament","temporalNonLinear", [15,15]],
        ["reverselight_filament","temporalNonLinear", [10,10]],
        ["foglight_filament","temporalNonLinear", [10,10]],
        ["signal_L_filament","temporalNonLinear", [15,15]],
        ["signal_R_filament","temporalNonLinear", [15,15]],
    ]
}

Advanced examples

Custom electrics values for combined halogen function lights.

"electrics": {
  "customValues": [
    ["electricsName", "electricsFunction"],
    ["lowhighBrakeSignal_L_filament","(electrics.lowhighbeam + electrics.brakelight_signal_L)*electrics.electricalLoadCoef"],
    ["lowhighBrakeSignal_R_filament","(electrics.lowhighbeam + electrics.brakelight_signal_R)*electrics.electricalLoadCoef"],
  ]
  "smoothers": [
    ["electricsName", "smootherType", "params"],
    ["lowhighBrakeSignal_L_filament","temporalNonLinear", [5,5]],
    ["lowhighBrakeSignal_R_filament","temporalNonLinear", [5,5]],
  ]
}

Custom electrics value for an animated halogen police flasher that fades in and out constantly when the light bar is turned on.

"electrics": {
    "customValues": [
        ["electricsName", "electricsFunction"],
        ["police_flasher_filament","pwm(sign(electrics.lightbar), 0.5, 0.5) * electrics.electricalLoadCoef"],
    ]
    "smoothers": [
        ["electricsName", "smootherType", "params"],
        ["police_flasher_filament","temporalNonLinear", [4,4]],
    ]
}
Last modified: December 10, 2024

Any further questions?

Join our discord
Our documentation is currently incomplete and undergoing active development. If you have any questions or feedback, please visit this forum thread.