Multiplayer shared L:VARS

Dear Asobo, Current we as developers are experiencing a particular issue with
L:VARS under multiplayer sessions. When the model matching occurs and another
3rd party player aircraft has the same model as the user playable aircraft,
for example user is flying Airplane FSREborn A… and 3 multiplayer users are
also flying airplane FSReborn A… the model matching takes place and
everything looks awesome… Now, unfortunately lots of animations / status of
the aircraft gets messy because L:VARS are not send and shared with the
multiplayer session aircraft’s. What does this mean? If the flyable users
opens the canopy for example, all 3 multiplayer FSReborn A airplanes will show
the canopies opened… similarly if USER number 3, opens the canopy… none of
the MP users are aware he has done such thing and see him with the canopy
closed. This also occurs with other animations, or specific events… such as,
if you want to enable smoke and you use an L:VAR for example, L:SMOKE_ON… if
other users turn on their smoke… the flyable user doesn’t see it… and if the
flyable user turns on his own smoke, he will see all other users with the
smoke enabled. It would be ideal to find a way to synchronise these variables
states with multiplayer users, so they become independent and react in
accordance to what each pilot is really doing during their MP session. I
appreciate this can be a tricky subject and request for a flight simulator,
but it is not something uncommon with many multiplayer games out there. For
example with Call Of Duty each individual player guns, shooting and actions
are independent and each MP user can see and appreciate what other players are
doing. The equivalent behaviour vs MSFS would be that if the first person
player jumps… all MP players starts jumping… By enabling a way to share a
variable to be independent during MP sessions, many group flights and
multiplayer experiences will be heavily enhanced. We are not requiring to
share all L:VARS… just a few that are required to enhance the experience, so
for example, Exits status L:VARS, Smoke L:VARS, some animations L:VARS… and
some visibility L:VARS. Perhaps the quickest way is to put something inside
gameplay.cfg, where you list the variables that are required to be shared /
linked to MP status when model matching occurs… and have a maximum
number of them… 10 to 15 would be more than enough in my view., maybe even
less… Open to other suggestions of course as long as it delivers the same
results. NOTES: We use L:VARS in preference because the capability to
debug these very easily via the model behaviours window under the “local
variables” tab, we open this tab filter a variable name and we can see clearly
not only the value but also how it is changing, etc. As opposed to I:VARS or
O:VARS… which would isolated the variable for sure from affecting the other
MP animations, however we are unable to debug these easily and we still would
have the issue that each MP users would be unable to see what others are
really doing. Once again, many thanks for the time to read this idea, All the
best, Simbol

Hi Simbol. Did you ever get any feedback regarding the above? I have only just
discovered that animations are not actually independent when in a multiplayer
session and can’t quite believe that is how it works by design. Your
idea/suggestion certainly has my vote and I would actually consider it to be
fairly essential.

Hi Striker, Not yet, this is an idea / request. Asobo discuss these ideas from
time to time… eventually we get an answer with a tag that says if it can be
done, if it is under investigation, approved, etc. Let’s be patient, they will
take it in consideration I am sure. In the meantime, try to set most of your
animations via A:VARS, and then they will be independent, if you can’t and
some of them are absolutely necessary to run on a L:VAR, then you could try
some tricks such as store the value of the var on some un-used slots for
lights, like a logo light, wing lights or something like that, and then use
that to control the anim for the multiplayer airplane. Another trick is to put
an extra condition in the model behavior, such as the Sim var (A:IS USER SIM,
bool), if this is “false” it is a multiplayer aircraft and you can use a
different logic from your L:VAR to drive the anim… Is limited what we can do,
and these are very quirky ways around the problem, and very limited as well
since most of the time there are no alternative slots on lights to be used, or
even worst any alternative logic for an animation. So I would rather have a
better way to implement this as per my original request. Hope I have give you
something to work with in the meantime until we get a feedback on this. All
the best, Raul

Thank you for posting this and in a way that clearly describes the issue. I
have suspected this over the last few months but have not been able to verify
it myself yet. We do not have very many options for local variables so it’s
important that they do not have unwanted side effects like you describe with
other multiplayer aircraft. I would support a change to make a new type of
local variable that will not affect other instances of the same model or to
even change the behavior of LVARS so they only affect the user’s aircraft.

Just out of interest. I have recently seen a number of discussions on the
forums in regard to multiplayer and 3rd party planes landing gear not visibly
updating. It appears the general consensus is that it is a bug but just
wondering if it is also a result of the above issues?

I really don’t know, better for each 3rd party dev having this issue to open a
question so it can be investigated. R.

This sounds a seriously dangerous area to me. My understanding is L: vars are
NOT shared between piloted aircraft in multiplayer. Changing the default for
that would break every aircraft with my code in it.
Having a per-aircraft
config file that lists L: vars that should be shared would protect existing
planes from breaking but might be award to implement. Hijacking A: vars is a
hack that has been used in FSX/MSFS forever, but it’s seriously problematic
risking conflict between different developers. Having a new variable type that
defaults to being shared might be the safest option, if it could be
implemented efficiently without one bloated aircraft tanking the experience of
every pilot in multiplayer.

The request is to enable “some” L:VARS, the ones you decide it is important to
you to share in multiplayer for the desired behaviour. Also remember, my
L:VARS ( ** _ the ones for my aircraft)_** are for my aircraft and
only my aircraft, therefore if I set one of these vars to work in multiplayer
it is my decision as developer so things works in accordance to my own design
and required specifications, it should not affect any other products since the
variables were created for my project, not any other. In any case if a new
variable type is created for this purpose it is also a valid solution. We just
need means to sync certain animations, I do not want to have to resort to
hijack A:VARS in hence this proposal as an idea. Best, Raul

I’d suggest that in order to keep L:vars local in scope (which is really, an
absolute necessity) yet expose them to other players for use in a multiplayer
environment (which would be incredibly useful), is to have a different
variable type that simply copies / repeats the L:vars, but in a manner that
defines them as external and non-writable. Essentially, if you as an aircraft
developer were to initialize a L:var in your aircraft, all other aircraft
could read it as a ‘Z’:var. Therefore you could, if you wanted, target code to
read and respond to the value of these external ‘Z’ vars, without the
messiness of having to figure out the scope of specific L:vars and the danger
inherent in accidentally reading values set by other aircraft. Then the only
concern would come from a multiplayer environment where the potential might
exist for many players all exposing / transmitting a ton of these new
variables…

This is a good discussion… I think if we had a new multiplayer-shared var
(let’s say “Z:”), or the equivalent named set of other vars, then it might be
a good design up front to limit the use of those vars to one place so that
looks a bit like an ‘interface’ as used in regular modular code. The current
‘local’ use of “L:” vars understandably has them scattered throughout the
package filesystem in the model XML and the html/js gauges with reads and
writes happening anywhere which is ok for local vars but probably chaos if
those were shared. Maybe (just maybe) a good idea would be to limit these “Z:”
vars to a defined element in the model behaviours XML. That ‘’ or whatever
could include RPN code which copies L:values to Z:values, or vice versa so
that’s under the developer control, and you or another developer can be
confident which Z: vars have been defined - that gives a definitive list of Z:
vars but puts more of a constraint on usage than e.g. a list in a separate
.cfg file. Maybe the component would be pre-defined with two sections for
‘piloted aircraft’ and ‘multiplayer aircraft’, or maybe that would just be the
typical structure of the RPN in there anyway. I think the ‘defined list’ idea
is crucial, because you don’t want to leave MSFS guessing what to transmit and
so sending a load of data unnecessarily, and MSFS could always put a limit on
how many Z: vars are reasonable.

But we also need means to debug vars… currently L:VARs are the easiest to
debug and test of course… pretty straight forward via the behaviour menu, you
can even alter the value there manually and see if your project behaves
accordingly, etc. We can also write and read L:VARS via WAMS. So If a new
variable type is added, it should also be capable to be altered via WASM. My
concern by adding a new var type is this, I would like to see the current
debug methods and capabilities from WASM to change them just as we do with
L:VARS. Best, Raul

Can anyone help explain the current (Sept 2022) status of L:vars in
multiplayer? Are they being propagated in multiplayer now or not? I’ve been
assuming IF those var values are propagated in multiplayer, then local
exterior model XML code will used to animate the AI-slave version of the
remote player aircraft for the local sim user that has matching model from
some remote user. I’m also assuming the AI-slave aircraft isn’t running the
html/js at all. I have many L:vars from html/js gauges controlling external
animations (like the ailerons, which have a complex behaviour in some
gliders). It seems like these should work fine in MSFS multiplayer, where the
remote player moves his control stick, his html/js calculates the correct
deflection of the aileron (it depends on the flap setting) and writes the
L:var which moves his ailerons AND gets broadcast to other multiplayer users,
where the L:var should animate the ailerons on the AI-aircraft representing
that specific remove user. This does not seem to be happening, as far as I can
tell, but in a bizarre twist in a multi-player test with the same aircraft
yesterday, both of us parked on the same runway, when the remote pilot
adjusted his flaps and watched MY glider he could see the flaps on MY glider
change (i.e. on the AI aircraft) as he looked at it. In my local instance of
the sim, my flaps remained fixed as expected. How could that even be possible?
(I’m not asking how to change L: vars to something else, or move html/js code
into model XML, all of which are possible - I’m trying to work out what
propagation of L: vars in multiplayer actually does and the scenario where a
local pilot manipulates their own plane but see an effect in AI slaves of
other planes in their own instance is puzzling. I did NOT see the effect, so
it is possible this is misreported, but the guy was pretty clear).

  1. when the remote pilot adjusted his flaps and watched MY glider he could see the flaps on MY glider change (i.e. on the AI aircraft) as he looked at it. In my local instance of the sim, my flaps remained fixed as expected.
  2.  
  3. How could that even be possible?

Don’t think as L: variables as “names”, what they really are are integer IDs,
associated to a name, and the association of the numeric ID to the name is not
necessarily the same on different instances of the simulator, because it
changes depending on what other add-on each user has that might have defined
L: variables on its own and the add-ons loading order. And, L: variables are
global to the currently loaded flight, they are not “object based” which
means, if you have many AI airplanes using the same L: variables linked to
some kind of event, when the event happens, ALL visible AIs will show whatever
visibility or animation linked to that variable, all at the same time, that
explains why in your example, when the remove plane adjusted his flaps, he
could see them moving on HIS own local representation of YOUR glider, simply
because that L: variable is global to HIS session. If there were other users
connected using the same airplane model, they would all move the flaps at the
same time, following the L: variable of HIS session. And, it explains why
flaps didn’t move on your model, even the variable name is the same, I don’t
think there’s any synchronization of L: variables in multiplayer (it might be
affecting network load if there was, since there might possibly be hundreds of
them in a session) but even if there was, you would still have to contend with
the fact L: variables are by design “global” so, assuming a network sync
between them, what would have happened in your example is, when the remote
user operated his flaps, you would have seen them moving on his model in
your own session, which is ok, but you would also see them on your model of
your session, and to any other model of the same airplane you could have in
your session if other users or AI using the same model were present in the
scene. So, the real issue is not the lack of sync of L: variables in
multiplayer session, but more that using L: variables, which are global by
design ( shared by all models in a session ), in a multiplayer session that is
supposed to show each airplane with its own state simply can’t work properly.
Ideally, multiplayer airplanes should only use those Events which are
transmitted over a multiplayer session, and react to those Events by setting
Object-based variables only (assuming there isn’t an A: variable that could be
used) and have their behaviors linking visibilities and animations to those
variables. This way each model can transmit changes to its state to other
multiplayer clients, and the remote representations of that model can react to
those events without affecting any other model than their own.

This sounds quite challenging indeed. I’d have to cross-check but AFAIK user
var names were referenced via a hashed id internally in previous versions, not
indexed like the stock vars, so in this case, it could still work for MP if
the var names were hashed using an aircraft unique id salt maybe? But isn’t
there already a mechanism that was added to FSX C SDK especially to deal with
MP synchronisation of MP aircraft state? Maybe this FSX code was deactivated
with FS2020?

“L: variables are global to the currently loaded flight, they are not “object
based” which means, if you have many AI airplanes using the same L: variables
linked to some kind of event, when the event happens, ALL visible AIs will
show whatever visibility or animation linked to that variable” LOL, that is
such a major thing to know. Of course it means L: variables absolutely cannot
be used for any common programming e.g. between html/JS and the model XML
code. I can easily replace my purely ‘local’ L: vars with something else (Z:,
probably) and accept the L: vars were useful for dev debugging in the
behaviours window but had to be swapped afterwards. But what about the
multiplayer scenario equivalent to ONE pilot lowering their gear (I know
there’s an A: var for that!) - other planes should see the gear go down on
that plane but not others. I have custom unique animations on my aircraft that
are similar but the animation var is a relatively complex calculation. I
suspect I could hijack multiple writeable/shared A: simvars but do none of the
new var types provide this functionality ?

Promoting & summarizing the replies mini-thread above to a post: L: unitless
vars
are effectively BROADCAST WITHIN THE LOCAL USER SIM, so any AI aircraft
(representing other pilots in multiplayer) will receive those L: var values
into their ‘Exterior’ model XML processing loop in your local sim. This means
if you use an L: var to control an animation in your aircraft, the same value
will be applied to all animations of matching aircraft (or scenery,
presumably) within the current sim. L: vars are not propagated to other sim
users to animate their matching AI aircraft. L: vars can be inspected in real-
time using the ModelBehaviours ‘variables’ window. Z: unitless vars remain
local to the current user aircraft, must not name clash with A: or other
built-in vars. This means a reasonable development process can be to use L:
vars at first for the debug advantages, then swap the “L:” to “Z:” for
production use assuming you don’t want the (effective) local broadcast feature
of L: vars. A: vars have some examples (use browser to sub-search SDK docs
vars pages for “All Aircraft”) which are communicated across multi-player from
the user aircraft to the AI-instance of the equivalent aircraft visible to
other players in multi-player. These are mostly control surfaces (not ailerons
or engine rpm?), gear and lights which makes sense for the most visible
animations. I’ve not checked whether the sim model means other variables are
locally computed for each AI aircraft such as SIM ON GROUND etc. There doesn’t
seem to be a way to have a custom animation on an aircraft propagate to the
matching AI aircraft in multi-player unless you re-purpose one of the A: vars.

There doesn’t seem to be a way to have a custom animation on an aircraft
propagate to the matching AI aircraft in multi-player unless you re-purpose
one of the A: vars.
Not a bad work around – you can control up to 64 Bool
variables in just one Bit encoded A:Var The added advantage is that over MP,
its just one updating A:Var that refreshes and controls all of those potential
64 MP Bools… as opposed to 64 different ones all going over MP and consuming
bandwidth.

This means a reasonable development process can be to use L: vars at first
for the debug advantages, then swap the “L:” to “Z:” for production use
assuming you don’t want the (effective) local broadcast feature of L: vars.

__ Unless you want the user to be able to access those variable as L vars (say
for hardware interfacing) with simconnect. Currently, I don’t believe that
Simconnect can natively see Z Vars ? It can all be done with SMOKE and
Mirrors !!! (forgive the pun)

  1. Not a bad work around -- you can control up to 64 Bool variables in just one Bit encoded A:Var

This would surely make the 18-years old me, as a former ASM programmer on the
C64, very happy and, in fact, one might even decide to encode strings in a 64
double Var but, aren’t we like 40 years late to have to rely on these methods
? It’s not we need to invent new things or are doing strange request, it might
be enough if: - The JS framework could be officially documented, considering
it has been on the "To-Do list for more than two years - More importantly,
there should be some kind of integration between the JS framework and
Simconnect.

100% agree, but a solution was needed, and rather than wait an unknown amount
of time, for that solution from Asobo, " what we hope is a Temporary work
around
" allowed the problem to be solved, and then we were able to move on
to other Dev tasks

Re encoding data into multiplayer simvars: FYI re SMOKE: 42 (>A:SMOKE ENABLE,
number) seems to set that simvar to “1” for any value bigger than zero, so
encoding is not an option. (A:COM ACTIVE FREQUENCY:1…3) and (A:COM STANDBY
FREQUENCY:1…3) are both listed as “All Aircraft” in the SDK variables docs,
and I’m optimistically encoding animation values into those using e.g.
(>K:COM2_STBY_RADIO_SET_HZ) and
SimVar.SetSimVarValue("K:COM2_STBY_RADIO_SET_HZ
",“number”,parseInt(“12ABCD000”)) where AB=00.99CD = 00,25,50,75 to keep to
legit frequencies. I haven’t tested to see if that makes its way through
multiplayer yet though. QUESTION: Is there a ‘normal’ way to have the prop
speed pass through to the multiplayer AI aircraft? It seems likely FSX/MSFS
would want props stopped/rotating reasonably on the multiplayer planes but I
can’t see any reference to a suitable simvar. Maybe it’s like the position and
orientation of the plane - these are obviously communicated but the simvars
are not mentioned.