• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

MSFS20 WASM - Setting Simvars

Messages
32
Country
australia
Hey guys,

I'm currently using c++ & WASM to program systems & gauges. I've had no issue getting & setting localvars, as well as getting token simvars and simvars. However I haven't worked out how to actually set/change the value of a Simvar (assuming it is settable).
Is this possible, and if so how would I go about it? I have tried the execute_calculator_code() function but with no success.

I haven't setup Simconnect or anything, I'm not sure if that's required, I just used the SDK gauge sample as a starting point,

Thanks
 
Hi,

Settable Simvars in 2020 are managed the same as in P3D/FSX, with Simconnect.
The good thing is that previous Simconnect functions used for that are compatible with 2020 wasm, so porting the code is almost straight on.

Tom
 
Thank you for the speedy replies. That's disappointing, I was hoping there was a nice convenient function available such as the aircraft_varget() func, from what I've seen of the SimConnect samples it seems to require quite a large amount of code simply to set a var! (Although I'm sure it will start to make more sense as I delve into it).

I will of course begin studying the samples from the SDK, but aside from that, are they any useful documentation/resources available that might assist with simple get/set of vars?

Appreciate the replies. Cheers
 
I fully agree with Mike, this is disappointing. SimConnect should be for communication with external applications only, when you are in the sim, you should be able to read/write sim variables that are readable/writeable like we used to do in FSX/P3D with execute_calculator_code, I regret this doesn't work. I guess you still have the possibility to use "send_key_event" to indirectly set some variables but I am sure it doesn't solve the problem because not all simvars are available this way.
 
Speaking of, what is the difference between send_key_event and trigger_key_event?
Furthermore, can you use register_key_event_handler to replace or supplement event logic with your own, and use one of the above functions to call other events?

The docs seem to indicate so but aren't totally clear to me
 
The difference between send_key_event and trigger_key_event is the same as SendMessage and PostMessage in a Windows app. Send_key_event will send the event immediately and not return until it's processed by the sim. Trigger_key_event will add the event to the sim's "event queue" to be processed and return immediately.

With register_key_event_handler, yes you can intercept and react to sim events... but it's not designed to allow you to prevent the sim from seeing said events. SimConnect is.
 
Thanks guys for all the clarifications; after studying the Simconnect samples it's all making sense now.

One final question I have; in the docs it says I can build SimConnect modules as a Web Assembly Module by simply including SimConnect.h in the WASM project. In practice however, if I make a new project configured as a WASM project, my VS does not find or recognize the <windows.h> include, breaking most of the SimConnect functionality. If I follow the steps to make a new SimConnect project however (using the provided property sheet) it of course works fine, but obviously there's no access to the panel SDK.

Could I make this work by tweaking the includes/dependencies or are they simply not designed to be used together in the same solution/project?

In the docs it states "WebAssembly modules can use SimConnect internally, provided as part of the SDK. It is only required to inlcude "simconnect.h"." But I've seen threads about how to access LVARS from SimConnect, and it didn't look as simple as being able to call from both API in the same project. Can anyone confirm?
 
Last edited:
Mike is there a web link to your project somewhere? I'm interested to know what pushed your gauge development into C++/WASM rather than HTML/JS.
 
Mike is there a web link to your project somewhere? I'm interested to know what pushed your gauge development into C++/WASM rather than HTML/JS.
Hi, no web links or anything unfortunately. I am a 3rd Party dev, so far we've used XML for basic systems/animation coding, but tbh it is a nightmare using the reverse Polish notation and obviously not ideal when more than a few lines of math are required. Therefore I am exploring better options for writing more complex aircraft systems. I'm experienced with C++ but not really in HTML/JS.

So far from my test builds I've observed the Gauges API in WASM is fantastic for (obviously) building gauges & writing logic for simple systems with minimal input (ie when you dont need to set simvars or override default systems). Simconnect seems to be more complex but powerful, allowing events & systems to be overridden. Where does HTML/JS fit in here? I haven't really explored these areas

If anyone has recommendations about the best approach in these situations I'm open to suggestions. Some examples of my intended useage:
  • Overriding the default starter key & creating a custom startup system (custom prop spin logic, correct fuel priming required etc). I'm hoping to use the gauge API event handlers but not sure if it will work here with hooking into the starter event
  • Custom Pneumatic & Hydraulic systems
  • Code driven localvars used in Wwise
Thanks
 
So far from my test builds I've observed the Gauges API in WASM is fantastic for (obviously) building gauges & writing logic for simple systems with minimal input (ie when you dont need to set simvars or override default systems). Simconnect seems to be more complex but powerful, allowing events & systems to be overridden. Where does HTML/JS fit in here? I haven't really explored these areas

My advise: if you are experienced in C++, stay there for everything except (perhaps) gauge display, in where you could take benefit of html/js current base files.
C++ is best suitable for building complex aircraft systems, in where lots of lookup tables might be needed. Also you can easily set simvars values to override default systems, manage local vars, etc. There is still a limitation for handling files in wasm, but that you can do in html/js.

Tom
 
With register_key_event_handler, yes you can intercept and react to sim events... but it's not designed to allow you to prevent the sim from seeing said events. SimConnect is.
Ed: did I read this correctly? You can use SimConnect to override an incoming event? If that's right, I'd be grateful if you could tell me which part of the SimConnect docs to RTFM :D
 
Thanks guys for the feedback & help so far. I've now been able to create a few basic c++ gauges & custom events with the gauge API

The difference between send_key_event and trigger_key_event is the same as SendMessage and PostMessage in a Windows app. Send_key_event will send the event immediately and not return until it's processed by the sim. Trigger_key_event will add the event to the sim's "event queue" to be processed and return immediately.

With register_key_event_handler, yes you can intercept and react to sim events... but it's not designed to allow you to prevent the sim from seeing said events. SimConnect is.

In my tests I wasn't able to call a custom event with this API; are these calls intended for MSFS Default events only? If so is there any way to 'trigger' a custom event from inside your code (gauge API) as opposed to activating it via mouse-click or keybind? Or is this another case where SimConnect is more appropriate?

I'm also wondering - I'm sure it's possible - but in the SimConnect samples usually a client event is associated with an absolute keybind (they often use 'z'). Which call would you use to simply override or map your own event onto an existing simevent? Say I want to override the KEY_TOGGLE_STARTER1 event, but I still want the user to be able to bind it to whatever they want through the MSFS UI. Is this possible?

Thanks all
 
I use custom events all the time... the sim doesn't know what they are, but my own code does. Here's a few code snippets to show how I take over the heading bug events in the sim:

First I map my own client side events to the sim events:
Code:
simConnect->MapClientEventToSimEvent(EVENT_HEADING_BUG_INC, "HEADING_BUG_INC");
simConnect->MapClientEventToSimEvent(EVENT_HEADING_BUG_DEC, "HEADING_BUG_DEC");

Then I add the client side events to a notification group:
Code:
simConnect->AddClientEventToNotificationGroup(GROUP_CONTROLS, EVENT_HEADING_BUG_INC, TRUE);
simConnect->AddClientEventToNotificationGroup(GROUP_CONTROLS, EVENT_HEADING_BUG_DEC, TRUE);

Then I set the notification group's priority (this is where I make it so I can mask the input from the sim):
Code:
simConnect->SetNotificationGroupPriority(GROUP_CONTROLS, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);

I have a function defined to handle incoming events from the SimConnect callback:
Code:
void DoRecvEvent(SIMCONNECT_RECV_EVENT* pEventData, DWORD cbData, void* pContext)

Inside the function I do this to handle the heading bug events from the sim.
Code:
switch (pEventData->uEventID)
{
case EVENT_HEADING_BUG_INC:
    send_key_event(FGC_HDG_ROTARY_CW, 1);
    break;
case EVENT_HEADING_BUG_DEC:
    send_key_event(FGC_HDG_ROTARY_CCW, 1);
    break;
}

The FGC_HDG_ROTARY_CW and FGC_HDG_ROTARY_CCW are events that the sim doesn't know about (custom ones). They are handled by a custom key event handler I've defined and registered for use by the sim. This code effectively prevents the sim from seeing the heading bug event that is defined in SimConnect... yet allows me to see it and act on it with my own custom code.

This kind of coding only belongs inside an aircraft. It should not be in a DLL or a stand-alone app as it could interfere with a third-party product's code.
 
I use custom events all the time... the sim doesn't know what they are, but my own code does. Here's a few code snippets to show how I take over the heading bug events in the sim:

First I map my own client side events to the sim events:
Code:
simConnect->MapClientEventToSimEvent(EVENT_HEADING_BUG_INC, "HEADING_BUG_INC");
simConnect->MapClientEventToSimEvent(EVENT_HEADING_BUG_DEC, "HEADING_BUG_DEC");

Then I add the client side events to a notification group:
Code:
simConnect->AddClientEventToNotificationGroup(GROUP_CONTROLS, EVENT_HEADING_BUG_INC, TRUE);
simConnect->AddClientEventToNotificationGroup(GROUP_CONTROLS, EVENT_HEADING_BUG_DEC, TRUE);

Then I set the notification group's priority (this is where I make it so I can mask the input from the sim):
Code:
simConnect->SetNotificationGroupPriority(GROUP_CONTROLS, SIMCONNECT_GROUP_PRIORITY_HIGHEST_MASKABLE);

I have a function defined to handle incoming events from the SimConnect callback:
Code:
void DoRecvEvent(SIMCONNECT_RECV_EVENT* pEventData, DWORD cbData, void* pContext)

Inside the function I do this to handle the heading bug events from the sim.
Code:
switch (pEventData->uEventID)
{
case EVENT_HEADING_BUG_INC:
    send_key_event(FGC_HDG_ROTARY_CW, 1);
    break;
case EVENT_HEADING_BUG_DEC:
    send_key_event(FGC_HDG_ROTARY_CCW, 1);
    break;
}

The FGC_HDG_ROTARY_CW and FGC_HDG_ROTARY_CCW are events that the sim doesn't know about (custom ones). They are handled by a custom key event handler I've defined and registered for use by the sim. This code effectively prevents the sim from seeing the heading bug event that is defined in SimConnect... yet allows me to see it and act on it with my own custom code.

This kind of coding only belongs inside an aircraft. It should not be in a DLL or a stand-alone app as it could interfere with a third-party product's code.
Thank you for the detailed example & walkthrough! This is fantastic & answers my question about overriding events.

Sorry to go back to event triggers, another useage issue - In my test I'm just working with the gauge API, here is a simple extract of my useage (so far MYEVENT_DOOR is called succesfully upon clicking the door handle). As you can see sim events work fine but no luck passing in my custom event ID

Code:
const int MYEVENT_DOOR{ 0x11011 };
const int MYEVENT_TEST{ 0x11010 };

static void FSAPI EventHandler(ID32 event, UINT32 evdata, PVOID userdata)
{
    printf("Event Handler called\n");
    switch (event)
    {
    case MYEVENT_TEST:
        printf("Test event called\n");
    case MYEVENT_DOOR:
        printf("Success! Door event called \n");
        //trigger_key_event(KEY_TOGGLE_NAV_LIGHTS, 1);                //This works, toggles the nav lights on/off
        //trigger_key_event(MYEVENT_TEST, 1);                                //This does not work
        break;
    default:
        printf("Default called\n");
        break;
    }
}

Is this invalid? I thought maybe calling a custom event inside the handler might not be allowed, however putting the trigger_key_event call inside the pre_update loop also did not work. Once I resolve this I will begin exploring SimConnect more thoroughly with your example

Cheers
 
No. You forgot to add break; command here:

Code:
    case MYEVENT_TEST:
        printf("Test event called\n");
  -->   break;
    case MYEVENT_DOOR:

Tom
Good spot. Unfortunately restoring the break didn't change anything, I'd expect it to still run without the break just going through both cases instead of just the one. I think WarpD may be correct that it's not valid for the handler to call itself

As a general question about SimConnect from my tests so far - the SDK notes that .exe builds are preferred for stability, but also notes that the simconnect cfg and xml setups are depreciated. Are exes still used in aircraft modules - and if so, is an exe.xml all that's required to run the .exe in-sim when appropriate? Or is it better to stick with a WASM for aircraft?

Thanks all
 
I have never used an EXE inside an aircraft. Gauges in prior sim versions were DLLs, not EXEs. I have used SimConnect inside of gauges without issue. There is no need for a simconnect.cfg or simconnect.xml with regards to using SimConnect inside of a gauge.

However, I don't know what you can/can't do with the WASM model that we're being shoehorned into for MSFS when it comes to SimConnect. I have no idea what your project is supposed to be... so, can't really provide anything further.
 
There's nothing wrong with C++, but if you never look in to html/js for MSFS gauges you'll have missed probably the most significant programming change from FSX to MSFS. There's way too much comment in these forums from C++ programmers about how the frameworks compare without real foundation. There is a misunderstanding of how the most complex MSFS gauges are now being written in javascript, not C++, driven particularly by the arrival of digital cockpits.

In the FSX days, gauges were C++ vs. XML and C++ was the only choice for anything other than simple gauges. For MSFS things have very much changed, with C++ compiling to WASM (which is best thought of as a tiny Javascript subset), and the vast bulk of MSFS gauge development is in Javascript (e.g. everything from Asobo, including the digital cockpits).

IMHO if your gauge can be written in html/js, you'll be better off getting up to speed with the new framework the clinging to C++.
 
Back
Top