MSFS2020 How to Create and Use User Defined Lvars - MobiFlight/MobiFlight-Connector GitHub Wiki

If using MSFS2020, the Mobiflight WASM module allows the user to create, read and write L: variables, also called "Lvars" for short, inside the simulator. Please understand these are value storage locations that are kept inside the simulator, not Mobiflight. This functionality is the main focus of this tutorial. These user-defined Lvars can be useful in cases where you want to create RPN (Reverse Polish Notation) routines to model or control certain functions, beyond what the simulator does out of the box.

Be aware that even though the simulator is managing these Lvars, the simulator code does not use them or check for them, therefore, any changes in the simulator driven by these Lvars, cannot be replicated from the virtual cockpit controls. In other words, you can code the behavior of a chronometer time unit for your external physical panel and it will function correctly, as long as you use the button inputs coded for your panel. Your external chrono unit will most likely not behave properly if you use the onscreen virtual controls. This is because the simulator internal coding does not know how to control your external panel. For most of us, this should not be a problem, as once we have an external panel, we would not use the onscreen controls.

Bear in mind, an alternate method called "Mobiflight Variables" to store and manage values was introduced in Mobiflight version 9.3.0. These Mobiflight Variables store values locally inside Mobiflight and are used mainly for internal panel control functions and cannot be accessed by the MSFS2020 simulator functions. You very likely want to use the internal MobiFlight user variables instead of user-defined L-vars for most cases.

User Defined Lvars

To put it in simple terms, by just making reference to a valid new Lvar name in any RPN statement sent to the simulator, this variable is automatically created and managed by the simulator and can be read and written to by you. By its nature, a useer-defined Lvar should have a unique name that will not be in conflict with any of the Lvars used in the simulator (unless your intention is to modify what the simulator does). I suggest that you prefix all your Lvar names with "MF_" or "MY_" to ensure these names are not used by the simulator functions.

The Lvar syntax consists of the L: type definition, followed by the variable name, a comma, followed by optional unit definition, all enclosed in parethesis.

(L:var name, unit)

  • var name It is case insensitive and can have spaces. Examples: my_flaps_pos, My_Flaps_Pos, MY_flaps_POS all refer to the same variable.
  • unit For user-defined variables this is either "number" or "bool". Units are case insensitive also, so BOOL and bool are the same.
  • Number unit is a real number that can have a decimal part. Example 3.1416.
  • Bool unit is a boolean type number that can only have values of either 0 or 1. Useful for modeling switches.
  • Space after the comma is optional. No space allowed after opening parenthesis or before closing parenthesis.

Typical Uses

You can use these useer-defined Lvars in input event calls within Mobiflight.

Alternating toggle (push-on, push-off). Each call alternates the Lvar between 0 and 1.

(L:mf_Switch1, bool) ! (>L:mf_Switch1, bool)

Increase value by an increment. Each call increments the Lvar by a set increment.

(L:mf_Brightness, Number) 5 + 0 max 100 min (>L:mf_Brightness, Number)

Increase value within a given range. Each call increments the value by 1, after reaching maximum, value wraps around back to minimum value.

(L:mf_RotaryPos, Number) ++ 4 % (>L:mf_RotaryPos, Number)

Decrease value within a given range. Each call decreases the value by 1, after reaching minimum, value wraps around back to maximum value. Note the code is actually adding 1 less than the maximum value and the modulus function results in one less. No lower bound check is needed.

(L:mf_RotaryPos, Number) 3 + 4 % (>L:mf_RotaryPos, Number)

Setting Up a timer. Each call sets a timer that needs to be followed in an output config. This can be from an input config in Mobiflight, but requires an output config to complete the action

(E:SIMULATION TIME, second) 2 + (>L:mf_Timer)

In this example, a 2-second timer is setup by the input action.

Output config. Code to be placed in the Mobiflight output config code box.

(L:mf_Timer) 0 > if{ 
   (E:SIMULATION TIME, second) (L:mf_Timer) > if{ 
      0 (>L:mf_timer)
      *** here goes whatever action is needed after the 2-second timer ***
} }