Displaying information in an MSFS window (SimConnect_Text replacement) via WASM?

Now that the SimConnect_Text function has been deprecated, I was wondering if
I could implement similar/replacement functionality in a WASM module.
Initially this would be to display fixed or scrolling text, and maybe later
add menu display and item selection functionality. Initially I would just like
to be able to display a window/panel with some text, be able to update this
text, and also to remove the window/panel. It would also be nice if the window
could be removed/resized by the user, with the new size/position being
available for re-use the next time the same window was displayed. However,
looking at the available APIs, I have no idea on how to go about this or if
this is even possible. Does anyone have any ideas on how this can be achieved,
or any pointers to examples or relevant documentation/APIs? Thanks in advance.

Unfortunately, given the lack of L:VARS capability to use string values I
don’t see how you could do this from WASM. You best shoot is an in game panel,
however communicating between JS to WASM is incredible difficult as well since
L:VARS are only numeric. R.

Thanks - I guess a JS in-game panel is what i am looking for. Is it possible
to declare and use my own simvar / A-type variable for the communication?

L:VARS are only numeric

Well, they are 8-bytes and can be interpreted as an 8-byte string if you so
wish - I do this in C/C++. So I could break the string down into 8-byte chunks
for communication purposes, setting a bunch of lvars in the WASM and
rebuilding the actual string in the js panel, maybe… It has been many years
(>10) since I have done any JS programming though - I will take a look at the
JS API documentation and any examples or samples. Thanks for your input. John



std::vector encode_string_to_floats(const std::string& s) {
    size_t len = s.length();
    size_t num_floats = (len + 7) / 8;
    std::vector float_nums(num_floats);

    for (size_t i = 0; i < num_floats; ++i) {
        char buffer[8] = { 0 };
        std::memcpy(buffer, s.c_str() + i * 8, std::min(size_t(8), len - i * 8));
        double float_num;
        std::memcpy(&float;_num, buffer, 8);
        float_nums[i] = float_num;

    return float_nums;

std::string decode_floats_to_string(const std::vector& float_nums) {
    std::string decoded_s;

    for (double float_num : float_nums) {
        char buffer[9]; // Increase the buffer size by 1
        std::memcpy(buffer, &float;_num, 8);
        buffer[8] = '\0'; // Explicitly set the last byte to '\0'

    return decoded_s;

int main() {
    std::string input_string = "Hello, this is a test string to encode and decode.";
    std::vector encoded_floats = encode_string_to_floats(input_string);
    std::string decoded_string = decode_floats_to_string(encoded_floats);

    std::cout << "Input string: " << input_string << std::endl;

    std::cout << "Encoded floats:";
    for (double f : encoded_floats) {
        std::cout << " " << std::setprecision(17) << f;
    std::cout << std::endl;

    std::cout << "Decoded string: " << decoded_string << std::endl;

    return 0;


function decodeFloatsToString(floats) {
  const buffer = new ArrayBuffer(8 * floats.length);
  const view = new DataView(buffer);

  for (let i = 0; i < floats.length; i++) {
    view.setFloat64(i * 8, floats[i], true); // Little-endian

  const byteArray = new Uint8Array(buffer);
  const textDecoder = new TextDecoder('utf-8');
  const decodedString = textDecoder.decode(byteArray);

  const cleanString = decodedString.replace(/\0/g, '');

  return cleanString;

// Example usage
const encodedFloats = [2.3159673291547693e+251, 7.227620496412683e+159, 8.764318813487392e+252, 1.876734488476244e-152, 7.203562252230563e+159, 6.2106179165081945e+175, 5.868e-320]; // These are the float values obtained from the C++ code
const decodedString = decodeFloatsToString(encodedFloats);

console.log("Decoded string from JS:", decodedString);

The code is courtesy of ChatGPT 4, I know it’s here to take all our jobs but,
in the meantime, we can use it for something useful. I tested both the C++
part and the Javascript part, works perfectly fine, although the C++ part
works only with ASCII strings ( the JS part works with UTF-8 too ), should be
fairly easy to adapt it to use a series of LVars instead. Can we get a better
way to exchange strings between WASM and Javascript, please ?

Yea please!, I asked to allow L:VARS with string values exactly to avoid this
conversions. R.

I just had to do something similar. My code is uglier than Umberto’s but does
the same job. It would be very useful to be able to pass strings without going
through all of that.