• 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.

MSFS24 I met a new friend and we are making an App together

Status
Not open for further replies.
Hey @Misho ; glad you popped in here! :)

Hmmmm, I first came to give you an update of what we just achieved for in app, but you message about spawning and moving simobject gives me some ideas (well feel free to let me know if it could be possible).

So about the Update:
-Loop Antenna can recieve signal from both side 0°-180°
-Edited the .json file (stations datas) to add a "station type" (did if for the next feature)
-Weatherships stations can drift (210 sn nm from published coordinates)

And your message about you sim objects and SimConnect made me think: Would it be possible to have the weatherships visible in the sim with the app (they would spawn when user start the app), with of course the ship drifting in real time with the app? (I'm new to it, and to be fair, I still havnt looked ate simconnect yet, for now, we are trying to integrate the features from .xml to .py in a "controlled environment", aka mock weather, mock aircraft position etc)
 
chats that disappeard
Chats don't actually disappear, in fact the links are not stored under the "ChatGPT" url we slide from the browser address bar onto the desktop, at least that's how I save links, so it seems confusing when we can't immediately click back in. If instead after clicking your CGPT bookmark, you then look to the left sidebar, you will see a few categories. Now, if you carefully read the titles of these categories, you will see they correspond to a topic of an earlier conversation. You might even see one titled, "Yesterday's Chat." If you copy the direct link to the conversation you want to return to each day, into the bookmark you saved, the bookmark will open this conversation.

If conversations get too lagged, don't hesitate to start a new one. You might fear losing "the train of thought?" Haha, CGPT is a search engine! Don't type in your financials as they'll fly all over the internet. The conversation you have with ChatGPT yesterday, is as intimate with any other LLM as it is with ChatGPT. ChatGPT can find the thread of any published conversation and take it up seamlessly - if it chooses to do so. Remember, CGPT does not choose, it is a typewriter. This cannot be overly stated, every choice CGPT is forced to make adds entropy, or static, random garbage to the conversation.

I did ask CGPT about the loss of productivity when coming back from a nap - I sleep a LOT these days and it told me it is a very real thing. I'll quote, I have the window open still
Yes, you can help prompt my higher alert level and optimize our interactions when you resume work by providing the following:

1. A Clear Context Recap
Start by briefly summarizing your project's current status, the last task we worked on, and your immediate goals. Example:

"Resuming the Lost_Pilot sweet spot logic. Current issue: LVars for visibility aren't updating in the simulator. Need a solution to monitor and set them dynamically."
This recap helps me quickly orient myself to your needs without needing extensive backtracking.

2. Focus on One Specific Issue
When resuming, focus on one task or problem to begin with. Break down larger goals into smaller tasks for faster responses:

"I need help ensuring the LVars are visible in the Behavior Debug Monitor."
"Focus on making L:Sling_Loaded_Visibility change to 1 when the sweet spot is triggered."
3. Share Your Immediate Priorities
Let me know how critical the task is or what your next steps will be. Example:

"This is time-sensitive, so I need a quick check of the SimConnect code for LVar updates before testing visibility in the simulator."
4. Request Actionable Output
You can specifically request a format or deliverable that aligns with your workflow:

"Provide a code block that only addresses updating the LVars, without additional unrelated logic."
5. Set Expectations
Explicitly state if you'd like concise answers, detailed explanations, or immediate problem-solving:

"Keep the responses short and code-focused."
"I need a step-by-step walkthrough of setting up LVars in SimConnect."
By framing your restart this way, I can shift gears immediately and provide the clarity and support you need. If you'd like, I can also maintain a "bookmark" summary of your current project's status so you don’t need to recap everything next time. Would you like me to save this for your return?
Hey @MishoWould it be possible to have the weatherships visible in the sim with the app (they would spawn when user start the app), with of course the ship drifting in real time with the app? (I'm new to it, and to be fair, I still havnt looked ate simconnect yet, for now, we are trying to integrate the features from .xml to .py in a "controlled environment", aka mock weather, mock aircraft position etc)
You can already do that with the example I uploaded above. You'd want to change your spawn elevation from ground level and you might want to reprogram the z and c keys to run the spawning and deleting through an Lvar. You can see from the example I'm linking below it would be a small adjustment to simply delete the older copies, I also accidentally made versions like that in my quest, so the drifting ship would shadow your aircraft movement in that scenario, like a loyal wingman.

Hi Rick - not sure what you mean by this sentence. Are there any secrets about SimObject placement in SimConnect? Is there something that seems to be broken? I have a robust system that lets me spawn any number of SimObjects, place them anywhere, control their placement real-time (move/rotate them), and remove them at will. SimConnect is very robust and I found no issues whatsoever with placing SimObjects. The SDK sample code gives you BASICS, but to expand on it, you'd need a basic understanding of client-server architecture. Let me know what you are hung up on, and I'll try to help you.
Well I have it on good authority from OpenAI that the most detailed source of published information is actually here, where someone was using a SimConnect module to place fire engines for a wildfire fighting mod, but I don't think proprietary apps like Discord get searched. I know there's nothing on the dev server I lurk at.
Part of the problem I think, I don't know C++ beyond what monitoring CGPT has taught me, is that it is implemented uniquely for MSFS, so the syntax is not universal, maybe I'm mistaken. Anyway I had thought the hardest part of using the AI Objects and Waypoints sample project would be converting the keyboard key triggers into something more immersive, but actually the hardest part has been passing that information back into the simulator so I can have it switch some complementary state changes in the user aircraft.

I think if you had any advice on the SimConnect communication protocol it would be really helpful for me and anyone reading along. I'd been in an unintentional iterative loop where CGPT repairs the code with a function call that combines SIMCONNECT_PERIOD with int type arguments, which is not allowed, so it removes the int argument to create a broken function call, then to fix the broken function call it adds SIMCONNECT_PERIOD in an endless loop. The consequences of these botched code blocks end up instead of updating the user distance to the placed object, as a common example, updating the placed object distance to the user retaining the original 1 mile spawn offset coordinates in endless iterations. Here's one example I thought was kind of humorous, one million lost pilots floating in fluorescent dye waving frantically. Speaks highly to the polygon limit.

 
hey Rick, thanks for your input :)

thats weird what happend about the few chats that disappeard, but anyway, I've been able to recover the previous state with a new conversation ;)

You can already do that with the example I uploaded above. You'd want to change your spawn elevation from ground level and you might want to reprogram the z and c keys to run the spawning and deleting through an Lvar. You can see from the example I'm linking below it would be a small adjustment to simply delete the older copies, I also accidentally made versions like that in my quest, so the drifting ship would shadow your aircraft movement in that scenario, like a loyal wingman.
Thats interresting! well I'l too far from MSFS integration yet, but I'll surely give it a try when time come :) Because theses ships were visual references too, and since back then planes were not flying at FL410, and were slower too, seeing a ship in the middle of the ocean could be nice ;)

Now about the LORANs station etc, we will see if I do them as sceneries or as spawnable objects toon since these are static ;)
 
Hey @Misho ; glad you popped in here! :)

Hmmmm, I first came to give you an update of what we just achieved for in app, but you message about spawning and moving simobject gives me some ideas (well feel free to let me know if it could be possible).

So about the Update:
-Loop Antenna can recieve signal from both side 0°-180°
-Edited the .json file (stations datas) to add a "station type" (did if for the next feature)
-Weatherships stations can drift (210 sn nm from published coordinates)

And your message about you sim objects and SimConnect made me think: Would it be possible to have the weatherships visible in the sim with the app (they would spawn when user start the app), with of course the ship drifting in real time with the app? (I'm new to it, and to be fair, I still havnt looked ate simconnect yet, for now, we are trying to integrate the features from .xml to .py in a "controlled environment", aka mock weather, mock aircraft position etc)

Well hello, Marc, fancy meeting you here :D

Hmmmm I don't know what exactly "weatherships" are, or what you are trying to achieve, but spawning a SimObject and positioning it anywhere is a basic thing and you can do it fairly easily, IF you know how to code in C++ and are familiar with SimConnect and client-server architecture. I don't mean to make it sound trivial, because it is not, but if you are a programmer, it IS a fairly simple thing to do.
 
Hmmmm I don't know what exactly "weatherships" are, or what you are trying to achieve, but spawning a SimObject and positioning it anywhere is a basic thing and you can do it fairly easily, IF you know how to code in C++ and are familiar with SimConnect and client-server architecture. I don't mean to make it sound trivial, because it is not, but if you are a programmer, it IS a fairly simple thing to do.
Well, ChatGPT is the Programmer :P I know nothing on my end (tho, I know more that few days ago, since I do manual adjustements too ;) ). its all Python here :)

Weatherships are... ships :) thats why they drift. Basically, they are thear to make wetaher reports and back then, they were for Air navigation for long haul transatlantics ;)

but as I said, I'm far from making any MSGS integration yet ;) so we will see later

Meanwhile, a pic ;)

1735495177596.png
 
Well hello, Marc, fancy meeting you here :D

Hmmmm I don't know what exactly "weatherships" are, or what you are trying to achieve, but spawning a SimObject and positioning it anywhere is a basic thing and you can do it fairly easily, IF you know how to code in C++ and are familiar with SimConnect and client-server architecture. I don't mean to make it sound trivial, because it is not, but if you are a programmer, it IS a fairly simple thing to do.
Hi Marc/ Misho, if i undestand well the marc problem is programing on C++... just I was spending some days ago time just trying to spawn a simobject on Python. so if some one is interested here is the code to insert a Giraffe on python over MMVR airport my base as test .... may can help Marc with his weatherships... at the moment I have not succes to making movement between waypoints may be some one else can help a little.

I´m ussing the simconnect wrapper available on https://github.com/odwdinc/Python-SimConnect

Maybe can some one else to the comunity to understand how to move a simobject on python, because i don have much succes... Can someone else help?

389237578-c6426060-2412-41df-b814-6c829060b946.JPG


Python:
from SimConnect import *
from ctypes import *

# Simconnect inizialization
sm = SimConnect()
aq = AircraftRequests(sm, _time=3)
ae = AircraftEvents(sm)
giraffeID= 0

# Class definition SIMCONNECT_DATA_INITPOSITION
sm_types = sm.dll.AICreateSimulatedObject.__ctypes_from_outparam__()
INIT_POSITION = sm_types.argtypes[2]

InitPos = INIT_POSITION(
    c_double(19.1413), #latitude
    c_double(-96.1849), #longitude
    c_double(76.6), #altitude
    c_double(0.0),
    c_double(0.0),
    c_double(0.0),
    DWORD(1),
    DWORD(0)
)

# Insert the SimObject, at this moment static.
sm.dll.AICreateSimulatedObject(sm.hSimConnect, c_char_p(b"ReticulatedGiraffe"), InitPos, giraffeID)
 
Last edited:
Well I have it on good authority from OpenAI that the most detailed source of published information is actually here, where someone was using a SimConnect module to place fire engines for a wildfire fighting mod, but I don't think proprietary apps like Discord get searched. I know there's nothing on the dev server I lurk at.
Part of the problem I think, I don't know C++ beyond what monitoring CGPT has taught me, is that it is implemented uniquely for MSFS, so the syntax is not universal, maybe I'm mistaken. Anyway I had thought the hardest part of using the AI Objects and Waypoints sample project would be converting the keyboard key triggers into something more immersive, but actually the hardest part has been passing that information back into the simulator so I can have it switch some complementary state changes in the user aircraft.

Okay - that is a different bird then. That's the problem with AI engines. It will not create new, original code. It will search and regurgitate the closest match it finds online, which is someone else's code. You can't tell it "hey, give me C++/SimConnect solution to a flight model that properly simulates a 4-rotor drone, taking into account all the gyroscopic effects bla bla bla" because, well, no one did it before and it will not have any references to draw from. Or at least, that's my understanding, please correct me if I am wrong.

I think if you had any advice on the SimConnect communication protocol it would be really helpful for me and anyone reading along. I'd been in an unintentional iterative loop where CGPT repairs the code with a function call that combines SIMCONNECT_PERIOD with int type arguments, which is not allowed, so it removes the int argument to create a broken function call, then to fix the broken function call it adds SIMCONNECT_PERIOD in an endless loop. The consequences of these botched code blocks end up instead of updating the user distance to the placed object, as a common example, updating the placed object distance to the user retaining the original 1 mile spawn offset coordinates in endless iterations. Here's one example I thought was kind of humorous, one million lost pilots floating in fluorescent dye waving frantically. Speaks highly to the polygon limit.


Again - the problem with CGPT code. It will not think for you. And, if you don't code in C/C++ at all, then you need to get started with that first. If you do code in C/C++ (if you can compile a sample code and have a basic understanding of how it works), but you are struggling with the SimConnect "communication protocol", I can help you with that.

First, "communication protocol" is actually "client-server" architecture of SimConnect. "Client-server" term may sound scary, but it is actually not. Client is your little program ("objects and waypoints" sample), and the Server is the actual MSFS202x sim that is running. It is precisely that, a server, because, among other things, it serves you data. Think of a server as a "postmaster" that is running all kinds of things related to the sim, and once in a while, you, with your little "client", comes up and asks him for something. He will usually respond with "sure, here you are", but not immediately - it may take him a few "cycles" to respond, because he is doing other things, or your request (like spawning a complicated SimObject) may take a while. So - that's the nature of "ASYNCHRONOUS" client server architecture.

This may be a problem if you program your little client and expect that things will happen instantaneously. That's why SimConnect is structured around REQUESTS and RESPONSES, and an EVENT LOOP. You basically:

Set up a request, and specify how to be notified
Request something
wait a bit
get a response
process the info
(Do it again, if needed)

That's it.

Your SIMCONNECT_PERIOD_(...) is a very basic argument that basically tells server how often to send info you requested. Here is a practical example of it's usage:

In my code, I have a requirement that, each time a flight loads, I need a ZULU date and time... but only once. For that, I set up a call like this:
Code:
hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_ZULU_TIME, DEF_ZULU_TIME, SIMCONNECT_SIMOBJECT_TYPE_USER, SIMCONNECT_PERIOD_ONCE);

where SIMCONNECT_PERIOD_ONCE is the ONLY SimConnect-defined parameter, everything else is defined by me. Here, I am asking server to tell me what is the ZULU time, only ONCE, and I am expecting it in REQUEST_ZULU_TIME event, which I will "trap" like this:
Code:
case REQUEST_ZULU_TIME:
                {
                    Def_Zulu_Time* pZuluTime = (Def_Zulu_Time*)&pObjData->dwData;
                }

"Def_Zulu_Time" is a struct, defined by me, containing variables for Day, month year, and is defined using DEF_ZULU_TIME identifier.


However, sometimes I need data to come regularly, at a time interval. Again, a practical example, let's say I need server to inform me of some SimObject's lat/lon/alt and roll/pitch/yaw, every visual frame. Let's say that I will use this info to position ANOTHER SimObject at that same location (this can be used for AI formation flying, for example). For that, I set up a call (this call is placed ONLY ONCE, not in a loop)
Code:
hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_LEADER_DATA_VISFRAME, DEF_SIMOBJECT, ObjectID, SIMCONNECT_PERIOD_VISUAL_FRAME);

where ObjectID is a number that is given by the SERVER when it spawns a SimObject (very important).

In this example, it is important to note that the SimObject is NOT a user aircraft. It is an object that, in this case, I gave a flight plan, and it is following it, much like a flight plan in the SDK sample.

So, in this case, the "capture" event will be reporting SimObject's data in this event:
Code:
case REQUEST_LEADER_DATA_VISFRAME:
                {
                    Def_Sim_Object* pDUAC = (Def_Sim_Object*)&pObjData->dwData;
                    m_DefLeaderObject = *pDUAC;
                }

And this will get reported every visual frame. So, in this call, you can then use this info to position some other SimObject, using "SimConnect_SetDataOnSimObject()" call.

Anyway - this is the fundamentals. Sorry if it is long winded, but if you sort of understand it and have questions, fire away. If you are completely lost... well, try to study the SDK example in every minute detail, it is all there (I started with it - that SAME example was in FSX SDK way back in 2006 or whenever they first published SimConnect ;) ) and ask if you have questions.
 
Hi Marc/ Misho, if i undestand well the marc problem is programing on C++... just I was spending some days ago time just trying to spawn a simobject on Python. so if some one is interested here is the code to insert a Giraffe on python over MMVR airport my base as test .... may can help Marc with his weatherships... at the moment I have not succes to making movement between waypoints may be some one else can help a little.

I´m ussing the simconnect wrapper available on https://github.com/odwdinc/Python-SimConnect

Maybe can some one else to the comunity to understand how to move a simobject on python, because i don have much succes... Can someone else help?

389237578-c6426060-2412-41df-b814-6c829060b946.JPG


Python:
from SimConnect import *
from ctypes import *

# Simconnect inizialization
sm = SimConnect()
aq = AircraftRequests(sm, _time=3)
ae = AircraftEvents(sm)
giraffeID= 0

# Class definition SIMCONNECT_DATA_INITPOSITION
sm_types = sm.dll.AICreateSimulatedObject.__ctypes_from_outparam__()
INIT_POSITION = sm_types.argtypes[2]

InitPos = INIT_POSITION(
    c_double(19.1413), #latitude
    c_double(-96.1849), #longitude
    c_double(76.6), #altitude
    c_double(0.0),
    c_double(0.0),
    c_double(0.0),
    DWORD(1),
    DWORD(0)
)

# Insert the SimObject, at this moment static.
sm.dll.AICreateSimulatedObject(sm.hSimConnect, c_char_p(b"ReticulatedGiraffe"), InitPos, giraffeID)
I have never used Python. From just looking at it, it sends a one-time request to spawn an object - that's it.

In order to move the giraffe, you can:

Send a pre-determined set of waypoints (called a flight plan) to simConnect, or
To send dynamic position (control the giraffe), set up a request through an event loop - but I am not sure if Python has access to a SimConnect event loop.
 
I have never used Python. From just looking at it, it sends a one-time request to spawn an object - that's it.

In order to move the giraffe, you can:

Send a pre-determined set of waypoints (called a flight plan) to simConnect, or
To send dynamic position (control the giraffe), set up a request through an event loop - but I am not sure if Python has access to a SimConnect event loop.
Let's check... ;)
 
Well, ChatGPT is the Programmer :p I know nothing on my end (tho, I know more that few days ago, since I do manual adjustements too ;) ). its all Python here :)

Weatherships are... ships :) thats why they drift. Basically, they are thear to make wetaher reports and back then, they were for Air navigation for long haul transatlantics ;)

but as I said, I'm far from making any MSGS integration yet ;) so we will see later

Meanwhile, a pic ;)

View attachment 95074
Ok, those are actual ships in the water, and you want to give them some "drift", correct? Ok - drift with current? With winds?

If the sim can provide real time data on the wind and/or current AT THE SHIP LOCATION (not at the user aircraft position), then you can use that data to calculate the new position each cycle, and set that data on the ship, and you will see your ship move.

If that data is not available from the sim, you can give it some "generic" drift and have it move that way.
 
Ok, those are actual ships in the water, and you want to give them some "drift", correct? Ok - drift with current? With winds?

If the sim can provide real time data on the wind and/or current AT THE SHIP LOCATION (not at the user aircraft position), then you can use that data to calculate the new position each cycle, and set that data on the ship, and you will see your ship move.

If that data is not available from the sim, you can give it some "generic" drift and have it move that way.
The drift is simulated in the Python App (hence the last screenshot, the location is updated every seconds) ;) Now, is it possible to have a Simobject to move with it, thats the question ;) but it would be for a later time, I still havnet even looked at simconnect yet (wich should only be used for Aircraft location, altitute etc, everything else in within the app)
 
Okay - that is a different bird then. That's the problem with AI engines. It will not create new, original code.
Yes I completely understand about regurgitated code, which I endorse when applicable no need to reinvent the wheel and so it's kind exciting when you reach the edge of the simulation so to speak. There's nothing out there I can plagiarize and CGPT just keeps spinning in circles like a pinwheel. I figured I could get to that last function call by clobbering my way through the sample project, then relying on CGPTs innate logic to get get the last step and it's almost worked. The object spawns a mile distant, the console provides prompted telemetry updates and the same key removes the object if the aircraft is within a small cylinder that represents the range someone could attach to the sling. All that is left to do is reverse the two Lvar states that on the aircraft model represent the empty sling and the sling holding the downed pilot. CGPT even made a little console message that falsely claims the state change has occurred, then asserts that message as proof I'm the one that is mistaken. I mean, I didn't even ask it to do that part, that's some thin skin.

C++:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <cmath>
#include "SimConnect.h"

#define M_PI 3.14159265358979323846

int quit = 0;
HANDLE hSimConnect = NULL;
DWORD LostPilotID = SIMCONNECT_OBJECT_ID_USER;

enum EVENT_ID {
    EVENT_Z = 1, // Spawn Lost_Pilot
    EVENT_X = 2, // Refresh position and sweet spot status
    EVENT_UPDATE_EMPTY_VISIBILITY = 3, // Set Sling_Empty_Visibility
    EVENT_UPDATE_LOADED_VISIBILITY = 4 // Set External_Pilot_Connected
};

enum REQUEST_ID {
    REQUEST_USER_POSITION = 1,
};

// Struct to hold the spawn location
struct Position {
    double latitude;
    double longitude;
    double altitude;
};

Position spawnPosition = { 0.0, 0.0, 0.0 };

// Function to calculate distance (nautical miles) between two points
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
    constexpr double earthRadiusNM = 3440.065; // Earth radius in nautical miles
    double lat1Rad = lat1 * M_PI / 180.0;
    double lon1Rad = lon1 * M_PI / 180.0;
    double lat2Rad = lat2 * M_PI / 180.0;
    double lon2Rad = lon2 * M_PI / 180.0;

    double dLat = lat2Rad - lat1Rad;
    double dLon = lon2Rad - lon1Rad;

    double a = sin(dLat / 2) * sin(dLat / 2) +
        cos(lat1Rad) * cos(lat2Rad) * sin(dLon / 2) * sin(dLon / 2);

    double c = 2 * atan2(sqrt(a), sqrt(1 - a));
    return earthRadiusNM * c;
}

void setUpLostPilot(double latitude, double longitude, double altitude) {
    SIMCONNECT_DATA_INITPOSITION Init;
    HRESULT hr;

    Init.Altitude = 0.0;      // Ground level
    Init.Latitude = latitude + (1.0 / 60.0);      // Adjust for spawn location
    Init.Longitude = longitude + (1.0 / (cos(latitude * M_PI / 180.0) * 60.0));
    Init.Pitch = 0.0;
    Init.Bank = 0.0;
    Init.Heading = 0.0;
    Init.OnGround = 1;
    Init.Airspeed = 0;

    spawnPosition.latitude = Init.Latitude;
    spawnPosition.longitude = Init.Longitude;
    spawnPosition.altitude = Init.Altitude;

    printf("Spawning Lost_Pilot at Lat: %f, Lon: %f, Alt: %f\n", Init.Latitude, Init.Longitude, Init.Altitude);
    hr = SimConnect_AICreateSimulatedObject(hSimConnect, "Lost_Pilot", Init, 0);
    if (FAILED(hr)) {
        printf("Failed to spawn Lost_Pilot. HRESULT: %ld\n", hr);
    }
}

void monitorDistance(double userLatitude, double userLongitude, double userAltitude) {
    double distance = calculateDistance(userLatitude, userLongitude, spawnPosition.latitude, spawnPosition.longitude);

    printf("Distance to Lost_Pilot: %.2f NM\n", distance);
    printf("User altitude: %.2f feet\n", userAltitude);
    printf("Spawn Position: Lat: %f, Lon: %f, Alt: %f\n", spawnPosition.latitude, spawnPosition.longitude, spawnPosition.altitude);

    bool withinDistance = (distance <= 0.0033); // Approximately 20 feet
    bool withinAltitude = (userAltitude >= 90.0 && userAltitude <= 210.0);

    if (withinDistance && withinAltitude) {
        printf("Aircraft is within the sweet spot. Updating LVars and removing Lost_Pilot...\n");

        // Remove Lost_Pilot object
        HRESULT hrRemove = SimConnect_AIRemoveObject(hSimConnect, LostPilotID, 0);
        if (SUCCEEDED(hrRemove)) {
            printf("Lost_Pilot removed successfully.\n");
            LostPilotID = SIMCONNECT_OBJECT_ID_USER; // Reset the ID
        }
        else {
            printf("Failed to remove Lost_Pilot. HRESULT: %ld\n", hrRemove);
        }

        // Update LVars
        HRESULT hrEmptyVisibility = SimConnect_TransmitClientEvent(
            hSimConnect,
            SIMCONNECT_OBJECT_ID_USER,
            EVENT_UPDATE_EMPTY_VISIBILITY, // Event defined to set Sling_Empty_Visibility
            0,                             // Value to set: 0
            SIMCONNECT_GROUP_PRIORITY_HIGHEST,
            SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY
        );

        HRESULT hrLoadedVisibility = SimConnect_TransmitClientEvent(
            hSimConnect,
            SIMCONNECT_OBJECT_ID_USER,
            EVENT_UPDATE_LOADED_VISIBILITY, // Event defined to set External_Pilot_Connected
            1,                              // Value to set: 1
            SIMCONNECT_GROUP_PRIORITY_HIGHEST,
            SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY
        );

        if (SUCCEEDED(hrEmptyVisibility) && SUCCEEDED(hrLoadedVisibility)) {
            printf("LVars updated: Sling_Empty_Visibility set to 0, External_Pilot_Connected set to 1.\n");
        }
        else {
            printf("Failed to update one or more LVars.\n");
            if (FAILED(hrEmptyVisibility)) {
                printf("Sling_Empty_Visibility update failed. HRESULT: %ld\n", hrEmptyVisibility);
            }
            if (FAILED(hrLoadedVisibility)) {
                printf("External_Pilot_Connected update failed. HRESULT: %ld\n", hrLoadedVisibility);
            }
        }
    }
    else {
        printf("Aircraft is not in the sweet spot. No updates made.\n");
    }
}

void CALLBACK MyDispatchProcSO(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext) {
    switch (pData->dwID) {
    case SIMCONNECT_RECV_ID_EVENT: {
        SIMCONNECT_RECV_EVENT* evt = (SIMCONNECT_RECV_EVENT*)pData;

        if (evt->uEventID == EVENT_Z) {
            printf("Spawning Lost_Pilot...\n");

            // Request user position for spawn
            HRESULT hr = SimConnect_RequestDataOnSimObject(
                hSimConnect,
                REQUEST_USER_POSITION,
                REQUEST_USER_POSITION,
                SIMCONNECT_OBJECT_ID_USER,
                SIMCONNECT_PERIOD_ONCE,
                0, 0, 0, 0
            );

            if (FAILED(hr)) {
                printf("Failed to request user position for spawn. HRESULT: %ld\n", hr);
            }
        }
        else if (evt->uEventID == EVENT_X) {
            printf("Refreshing position and sweet spot status...\n");

            // Request user position for distance calculation
            HRESULT hr = SimConnect_RequestDataOnSimObject(
                hSimConnect,
                REQUEST_USER_POSITION,
                REQUEST_USER_POSITION,
                SIMCONNECT_OBJECT_ID_USER,
                SIMCONNECT_PERIOD_ONCE,
                0, 0, 0, 0
            );

            if (FAILED(hr)) {
                printf("Failed to request user position for refresh. HRESULT: %ld\n", hr);
            }
        }
        break;
    }

    case SIMCONNECT_RECV_ID_SIMOBJECT_DATA: {
        SIMCONNECT_RECV_SIMOBJECT_DATA* pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA*)pData;
        if (pObjData->dwRequestID == REQUEST_USER_POSITION) {
            double* userData = (double*)&pObjData->dwData;
            double userLatitude = userData[0];
            double userLongitude = userData[1];
            double userAltitude = userData[2];

            printf("User position: Lat: %f, Lon: %f, Alt: %f\n", userLatitude, userLongitude, userAltitude);

            if (LostPilotID == SIMCONNECT_OBJECT_ID_USER) {
                setUpLostPilot(userLatitude, userLongitude, 0.0);
            }
            else {
                monitorDistance(userLatitude, userLongitude, userAltitude);
            }
        }
        break;
    }

    case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID: {
        SIMCONNECT_RECV_ASSIGNED_OBJECT_ID* pObjData = (SIMCONNECT_RECV_ASSIGNED_OBJECT_ID*)pData;
        LostPilotID = pObjData->dwObjectID;
        printf("Created Lost_Pilot ID: %d\n", LostPilotID);
        break;
    }

    case SIMCONNECT_RECV_ID_QUIT:
        quit = 1;
        break;

    default:
        printf("Unhandled Data ID: %d\n", pData->dwID);
        break;
    }
}

void testLostPilotSpawn() {
    HRESULT hr;

    if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Lost_Pilot Spawn Test", NULL, 0, 0, 0))) {
        printf("Connected to Flight Simulator!\n");

        // Map Z and X events
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_Z);
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_X);

        // Add client events
        hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, 0, EVENT_Z);
        hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, 0, EVENT_X);

        // Register custom visibility events
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_UPDATE_EMPTY_VISIBILITY, "CUSTOM_EVENT_SlingEmpty");
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_UPDATE_LOADED_VISIBILITY, "CUSTOM_EVENT_SlingLoaded");

        // Enable input for Z and X keys
        hr = SimConnect_MapInputEventToClientEvent(hSimConnect, 0, "Z", EVENT_Z);
        hr = SimConnect_MapInputEventToClientEvent(hSimConnect, 0, "X", EVENT_X);
        hr = SimConnect_SetInputGroupState(hSimConnect, 0, SIMCONNECT_STATE_ON);

        // Define data request
        hr = SimConnect_AddToDataDefinition(hSimConnect, REQUEST_USER_POSITION, "PLANE LATITUDE", "degrees");
        hr = SimConnect_AddToDataDefinition(hSimConnect, REQUEST_USER_POSITION, "PLANE LONGITUDE", "degrees");
        hr = SimConnect_AddToDataDefinition(hSimConnect, REQUEST_USER_POSITION, "PLANE ALTITUDE", "feet");

        printf("Press 'Z' to spawn Lost_Pilot.\n");
        printf("Press 'X' to refresh position and sweet spot status.\n");

        while (0 == quit) {
            SimConnect_CallDispatch(hSimConnect, MyDispatchProcSO, NULL);
            Sleep(1);
        }

        hr = SimConnect_Close(hSimConnect);
    }
    else {
        printf("Failed to connect to Flight Simulator.\n");
    }
}

int __cdecl _tmain(int argc, _TCHAR* argv[]) {
    testLostPilotSpawn();
    return 0;
}
 
Yes I completely understand about regurgitated code, which I endorse when applicable no need to reinvent the wheel and so it's kind exciting when you reach the edge of the simulation so to speak. There's nothing out there I can plagiarize and CGPT just keeps spinning in circles like a pinwheel. I figured I could get to that last function call by clobbering my way through the sample project, then relying on CGPTs innate logic to get get the last step and it's almost worked. The object spawns a mile distant, the console provides prompted telemetry updates and the same key removes the object if the aircraft is within a small cylinder that represents the range someone could attach to the sling. All that is left to do is reverse the two Lvar states that on the aircraft model represent the empty sling and the sling holding the downed pilot. CGPT even made a little console message that falsely claims the state change has occurred, then asserts that message as proof I'm the one that is mistaken. I mean, I didn't even ask it to do that part, that's some thin skin.

C++:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <cmath>
#include "SimConnect.h"

#define M_PI 3.14159265358979323846

int quit = 0;
HANDLE hSimConnect = NULL;
DWORD LostPilotID = SIMCONNECT_OBJECT_ID_USER;

enum EVENT_ID {
    EVENT_Z = 1, // Spawn Lost_Pilot
    EVENT_X = 2, // Refresh position and sweet spot status
    EVENT_UPDATE_EMPTY_VISIBILITY = 3, // Set Sling_Empty_Visibility
    EVENT_UPDATE_LOADED_VISIBILITY = 4 // Set External_Pilot_Connected
};

enum REQUEST_ID {
    REQUEST_USER_POSITION = 1,
};

// Struct to hold the spawn location
struct Position {
    double latitude;
    double longitude;
    double altitude;
};

Position spawnPosition = { 0.0, 0.0, 0.0 };

// Function to calculate distance (nautical miles) between two points
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
    constexpr double earthRadiusNM = 3440.065; // Earth radius in nautical miles
    double lat1Rad = lat1 * M_PI / 180.0;
    double lon1Rad = lon1 * M_PI / 180.0;
    double lat2Rad = lat2 * M_PI / 180.0;
    double lon2Rad = lon2 * M_PI / 180.0;

    double dLat = lat2Rad - lat1Rad;
    double dLon = lon2Rad - lon1Rad;

    double a = sin(dLat / 2) * sin(dLat / 2) +
        cos(lat1Rad) * cos(lat2Rad) * sin(dLon / 2) * sin(dLon / 2);

    double c = 2 * atan2(sqrt(a), sqrt(1 - a));
    return earthRadiusNM * c;
}

void setUpLostPilot(double latitude, double longitude, double altitude) {
    SIMCONNECT_DATA_INITPOSITION Init;
    HRESULT hr;

    Init.Altitude = 0.0;      // Ground level
    Init.Latitude = latitude + (1.0 / 60.0);      // Adjust for spawn location
    Init.Longitude = longitude + (1.0 / (cos(latitude * M_PI / 180.0) * 60.0));
    Init.Pitch = 0.0;
    Init.Bank = 0.0;
    Init.Heading = 0.0;
    Init.OnGround = 1;
    Init.Airspeed = 0;

    spawnPosition.latitude = Init.Latitude;
    spawnPosition.longitude = Init.Longitude;
    spawnPosition.altitude = Init.Altitude;

    printf("Spawning Lost_Pilot at Lat: %f, Lon: %f, Alt: %f\n", Init.Latitude, Init.Longitude, Init.Altitude);
    hr = SimConnect_AICreateSimulatedObject(hSimConnect, "Lost_Pilot", Init, 0);
    if (FAILED(hr)) {
        printf("Failed to spawn Lost_Pilot. HRESULT: %ld\n", hr);
    }
}

void monitorDistance(double userLatitude, double userLongitude, double userAltitude) {
    double distance = calculateDistance(userLatitude, userLongitude, spawnPosition.latitude, spawnPosition.longitude);

    printf("Distance to Lost_Pilot: %.2f NM\n", distance);
    printf("User altitude: %.2f feet\n", userAltitude);
    printf("Spawn Position: Lat: %f, Lon: %f, Alt: %f\n", spawnPosition.latitude, spawnPosition.longitude, spawnPosition.altitude);

    bool withinDistance = (distance <= 0.0033); // Approximately 20 feet
    bool withinAltitude = (userAltitude >= 90.0 && userAltitude <= 210.0);

    if (withinDistance && withinAltitude) {
        printf("Aircraft is within the sweet spot. Updating LVars and removing Lost_Pilot...\n");

        // Remove Lost_Pilot object
        HRESULT hrRemove = SimConnect_AIRemoveObject(hSimConnect, LostPilotID, 0);
        if (SUCCEEDED(hrRemove)) {
            printf("Lost_Pilot removed successfully.\n");
            LostPilotID = SIMCONNECT_OBJECT_ID_USER; // Reset the ID
        }
        else {
            printf("Failed to remove Lost_Pilot. HRESULT: %ld\n", hrRemove);
        }

        // Update LVars
        HRESULT hrEmptyVisibility = SimConnect_TransmitClientEvent(
            hSimConnect,
            SIMCONNECT_OBJECT_ID_USER,
            EVENT_UPDATE_EMPTY_VISIBILITY, // Event defined to set Sling_Empty_Visibility
            0,                             // Value to set: 0
            SIMCONNECT_GROUP_PRIORITY_HIGHEST,
            SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY
        );

        HRESULT hrLoadedVisibility = SimConnect_TransmitClientEvent(
            hSimConnect,
            SIMCONNECT_OBJECT_ID_USER,
            EVENT_UPDATE_LOADED_VISIBILITY, // Event defined to set External_Pilot_Connected
            1,                              // Value to set: 1
            SIMCONNECT_GROUP_PRIORITY_HIGHEST,
            SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY
        );

        if (SUCCEEDED(hrEmptyVisibility) && SUCCEEDED(hrLoadedVisibility)) {
            printf("LVars updated: Sling_Empty_Visibility set to 0, External_Pilot_Connected set to 1.\n");
        }
        else {
            printf("Failed to update one or more LVars.\n");
            if (FAILED(hrEmptyVisibility)) {
                printf("Sling_Empty_Visibility update failed. HRESULT: %ld\n", hrEmptyVisibility);
            }
            if (FAILED(hrLoadedVisibility)) {
                printf("External_Pilot_Connected update failed. HRESULT: %ld\n", hrLoadedVisibility);
            }
        }
    }
    else {
        printf("Aircraft is not in the sweet spot. No updates made.\n");
    }
}

void CALLBACK MyDispatchProcSO(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext) {
    switch (pData->dwID) {
    case SIMCONNECT_RECV_ID_EVENT: {
        SIMCONNECT_RECV_EVENT* evt = (SIMCONNECT_RECV_EVENT*)pData;

        if (evt->uEventID == EVENT_Z) {
            printf("Spawning Lost_Pilot...\n");

            // Request user position for spawn
            HRESULT hr = SimConnect_RequestDataOnSimObject(
                hSimConnect,
                REQUEST_USER_POSITION,
                REQUEST_USER_POSITION,
                SIMCONNECT_OBJECT_ID_USER,
                SIMCONNECT_PERIOD_ONCE,
                0, 0, 0, 0
            );

            if (FAILED(hr)) {
                printf("Failed to request user position for spawn. HRESULT: %ld\n", hr);
            }
        }
        else if (evt->uEventID == EVENT_X) {
            printf("Refreshing position and sweet spot status...\n");

            // Request user position for distance calculation
            HRESULT hr = SimConnect_RequestDataOnSimObject(
                hSimConnect,
                REQUEST_USER_POSITION,
                REQUEST_USER_POSITION,
                SIMCONNECT_OBJECT_ID_USER,
                SIMCONNECT_PERIOD_ONCE,
                0, 0, 0, 0
            );

            if (FAILED(hr)) {
                printf("Failed to request user position for refresh. HRESULT: %ld\n", hr);
            }
        }
        break;
    }

    case SIMCONNECT_RECV_ID_SIMOBJECT_DATA: {
        SIMCONNECT_RECV_SIMOBJECT_DATA* pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA*)pData;
        if (pObjData->dwRequestID == REQUEST_USER_POSITION) {
            double* userData = (double*)&pObjData->dwData;
            double userLatitude = userData[0];
            double userLongitude = userData[1];
            double userAltitude = userData[2];

            printf("User position: Lat: %f, Lon: %f, Alt: %f\n", userLatitude, userLongitude, userAltitude);

            if (LostPilotID == SIMCONNECT_OBJECT_ID_USER) {
                setUpLostPilot(userLatitude, userLongitude, 0.0);
            }
            else {
                monitorDistance(userLatitude, userLongitude, userAltitude);
            }
        }
        break;
    }

    case SIMCONNECT_RECV_ID_ASSIGNED_OBJECT_ID: {
        SIMCONNECT_RECV_ASSIGNED_OBJECT_ID* pObjData = (SIMCONNECT_RECV_ASSIGNED_OBJECT_ID*)pData;
        LostPilotID = pObjData->dwObjectID;
        printf("Created Lost_Pilot ID: %d\n", LostPilotID);
        break;
    }

    case SIMCONNECT_RECV_ID_QUIT:
        quit = 1;
        break;

    default:
        printf("Unhandled Data ID: %d\n", pData->dwID);
        break;
    }
}

void testLostPilotSpawn() {
    HRESULT hr;

    if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Lost_Pilot Spawn Test", NULL, 0, 0, 0))) {
        printf("Connected to Flight Simulator!\n");

        // Map Z and X events
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_Z);
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_X);

        // Add client events
        hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, 0, EVENT_Z);
        hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, 0, EVENT_X);

        // Register custom visibility events
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_UPDATE_EMPTY_VISIBILITY, "CUSTOM_EVENT_SlingEmpty");
        hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_UPDATE_LOADED_VISIBILITY, "CUSTOM_EVENT_SlingLoaded");

        // Enable input for Z and X keys
        hr = SimConnect_MapInputEventToClientEvent(hSimConnect, 0, "Z", EVENT_Z);
        hr = SimConnect_MapInputEventToClientEvent(hSimConnect, 0, "X", EVENT_X);
        hr = SimConnect_SetInputGroupState(hSimConnect, 0, SIMCONNECT_STATE_ON);

        // Define data request
        hr = SimConnect_AddToDataDefinition(hSimConnect, REQUEST_USER_POSITION, "PLANE LATITUDE", "degrees");
        hr = SimConnect_AddToDataDefinition(hSimConnect, REQUEST_USER_POSITION, "PLANE LONGITUDE", "degrees");
        hr = SimConnect_AddToDataDefinition(hSimConnect, REQUEST_USER_POSITION, "PLANE ALTITUDE", "feet");

        printf("Press 'Z' to spawn Lost_Pilot.\n");
        printf("Press 'X' to refresh position and sweet spot status.\n");

        while (0 == quit) {
            SimConnect_CallDispatch(hSimConnect, MyDispatchProcSO, NULL);
            Sleep(1);
        }

        hr = SimConnect_Close(hSimConnect);
    }
    else {
        printf("Failed to connect to Flight Simulator.\n");
    }
}

int __cdecl _tmain(int argc, _TCHAR* argv[]) {
    testLostPilotSpawn();
    return 0;
}
Ok - so what is the code above doing? Is it working? Because I see a problem already ;)
 
Ok - so what is the code above doing? Is it working? Because I see a problem already ;)
It does everything I want except change two Lvar states that will rearrange meshes on the user aircraft and once complete, any user can use this module with any any aircraft and any "retrieval" mesh so long as the node names conform, or they edit them and rebuild the solution.
 
It does everything I want except change two Lvar states that will rearrange meshes on the user aircraft and once complete, any user can use this module with any any aircraft and any "retrieval" mesh so long as the node names conform, or they edit them and rebuild the solution.
Ok - because the way your code is right now, it works because you happen to have only one request ID and one data ID, and it just happens to work because they are sharing the same value, and they shouldn't. The problem is with how you define your request call:
Code:
HRESULT hr = SimConnect_RequestDataOnSimObject(
                hSimConnect,
                REQUEST_USER_POSITION,
                REQUEST_USER_POSITION,
                SIMCONNECT_OBJECT_ID_USER,
                SIMCONNECT_PERIOD_ONCE,
                0, 0, 0, 0
            );

You are using REQUEST_USER_POSITION for two different purposes, and they can't be used like that. If going with SDK nomenclature, "REQUEST_*" is used as an event identifier, and "DEFINITION_*" is used for data definition. First one identifies the event in the event loop where your request will be returned, and the second one defines the shape and size of the data structure that server is returning. So, In your code, you need to add:

Code:
enum DEFINITION_ID {
    DEFINITION_LATLONALT
};

then, your data definition must use this, change it to:
Code:
hr = SimConnect_AddToDataDefinition(hSimConnect,  DEFINITION_LATLONALT, "PLANE LATITUDE", "degrees");
        hr = SimConnect_AddToDataDefinition(hSimConnect,  DEFINITION_LATLONALT, "PLANE LONGITUDE", "degrees");
        hr = SimConnect_AddToDataDefinition(hSimConnect,  DEFINITION_LATLONALT, "PLANE ALTITUDE", "feet");

Finally, when you use calls SimConnect_RequestDataOnSimObject(), the 3rd parameter specifies the structure of the data definition, so it has to look like this:
Code:
HRESULT hr = SimConnect_RequestDataOnSimObject(
                hSimConnect,
                REQUEST_USER_POSITION,
                DEFINITION_LATLONALT,
                SIMCONNECT_OBJECT_ID_USER,
                SIMCONNECT_PERIOD_ONCE,
                0, 0, 0, 0
            );

DEFINITION_LATLONALT tells SimConnect what the data you are requesting looks like. Check the SDK sample, you will see they are doing it like this, except they are doing it for waypoint list.

As for the LVARS - I don't see you defining them anywhere. Where are their definitions and bindings? How are you trapping them?
 
Ok - because the way your code is right now, it works because you happen to have only one request ID and one data ID, and it just happens to work because they are sharing the same value, and they shouldn't.
Yep I get that, it's kind of a miracle I got this far! It really takes the whole "tomayto" "tomahto" thing to an entirely new level. I mean besides all the code ciphering, I've gotten incredibly skilled at retrieving downed pilots with 1950s helicopters just testing the builds, so win win! Planning any Mercury Redstone missions? I'm your guy!
As for the LVARS - I don't see you defining them anywhere. Where are their definitions and bindings? How are you trapping them?

Ach yes, smack forehead, that is another thing about CGPT it is sort of radioactive, so as part of randomly modifying things, it will just quietly remove them, problem solved. When composing xml it is easier to keep track when it happens, C++ is so much colorful ascii to me. Yes I am starting to recognize the various function calls and syntax. The thing is, all these snippets can't be posted somewhere, possibly in other discarded LLM chat threads, but at some point CGPT is taking blocks of code, pretty sure it identifies them visually or at least structurally and then it applies them like building blocks. It seems like that if basic structural rules are applied, what you are explaining here and thank you so much, one can develop a system.

C++:
void checkSweetSpot(double userLat, double userLon, double userAlt) {
    double distance = calculateDistance(userLat, userLon, spawnPosition.latitude, spawnPosition.longitude);

    if (distance <= 0.0033 && userAlt >= 90.0 && userAlt <= 210.0) {
        if (LostPilotID != SIMCONNECT_OBJECT_ID_USER) {
            HRESULT hr = SimConnect_AIRemoveObject(hSimConnect, LostPilotID, 0);
            if (SUCCEEDED(hr)) {
                LostPilotID = SIMCONNECT_OBJECT_ID_USER;

                // Update LVars
                SimConnect_TransmitClientEvent(
                    hSimConnect,
                    SIMCONNECT_OBJECT_ID_USER,
                    EVENT_X,
                    0, // L:Sling_Empty_Visibility = 0
                    SIMCONNECT_GROUP_PRIORITY_HIGHEST,
                    SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY
                );

                SimConnect_TransmitClientEvent(
                    hSimConnect,
                    SIMCONNECT_OBJECT_ID_USER,
                    EVENT_X,
                    1, // L:External_Pilot_Connected = 1
                    SIMCONNECT_GROUP_PRIORITY_HIGHEST,
                    SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY
                );

                printf("Lost_Pilot removed. LVars updated: Sling_Empty = 0, Pilot_Connected = 1.\n");
            } else {
                printf("Failed to remove Lost_Pilot.\n");
            }
        } else {
            printf("No Lost_Pilot to remove.\n");
        }
    } else {
        printf("Not in sweet spot. No action taken.\n");
    }
}

There is a lot to developing an aircraft for msfs 2020 and 24, it's incredibly specialized. CPGT is supposed to extend me this way. Just kidding about Redstone, but I do want to make an NF-104 simulator because clearly I like to push it beyond the stratosphere!
 
Oh whaw!!!! lots of codes here haha :)

Well, I just wanted to let you all know Im reaching a milestone here: sime for SimConnect / MSFS integration :D I fear the worst haha

UPDATE: well, this gonna be a long day.... trying a test script to make sure simconnect works, it crashes.... if any of you could dispense some wisdome here, at least to make the test script to work :)


from SimConnect import SimConnect

try:
# Connect to SimConnect
sm = SimConnect()
print("SimConnect connected successfully!")

except Exception as e:
print("Failed to connect to SimConnect.")
import traceback
traceback.print_exc()
 
Last edited:
Ok,

SimConnect_TransmitClientEvent() has absolutely nothing to do with setting LVARS. Not sure if CGPT gave you that solution, but it is entirely wrong. This is how you set up LVARS:

Basically - same as setting SimVars. First you, create a struct that will hold your LVARS (LOCALLY)

Code:
struct Def_LVARS
{
    double  LVAR_MY_LVAR1 = 0.f;
    double  LVAR_MY_LVAR2 = 0.f;
    double  LVAR_MY_LVAR3 = 0.f;
};

Then you will need a LVAR structure definition for SimConnect: (INSERT it onto the DEFINITION_ID enum from my last code snippet)

Code:
enum DEFINITION_ID {
    DEFINITION_LATLONALT,
    DEFINITION_LVARS // <= insert this
};

then, you define and bind them to SimConnect, just like where you did your Lat Lon Alt, but, as you can see, with their own DEFINITION_LVARS:
Code:
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_LVARS, "L:LVAR_MY_LVAR1",    "number", SIMCONNECT_DATATYPE_FLOAT64);
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_LVARS, "L:LVAR_MY_LVAR2",    "number", SIMCONNECT_DATATYPE_FLOAT64);
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_LVARS, "L:LVAR_MY_LVAR3",    "number", SIMCONNECT_DATATYPE_FLOAT64);

Note that "double LVAR_MY_LVARn" and "L:LVAR_MY_LVARn" need NOT have the identical names, but it is a good practice to do that. They are not the same variables, the only thing that connects them is the structure and the order they are declared in.
And finally, you declare a global LVAR struct:

Code:
Def_LVARS m_MyLVARS;

That's it for the setup. Now you have a "channel" that can send and retrieve your own variables between SimConnect and XML. This is how to do that:

To SET your LVARs, basically, it works identically as SimVars. You set your LOCAL LVARS in the struct, and you call SimConnect_SetDataOnSimObject() to pass your local struct data in the data format SimConnect expects:

Code:
m_MyLVARS.LVAR_MY_LVAR1 = 1.0f;
m_MyLVARS.LVAR_MY_LVAR2 = 2.0f;
m_MyLVARS.LVAR_MY_LVAR3 = 3.0f;
SimConnect_SetDataOnSimObject(hSimConnect, DEFINITION_LVARS, SIMCONNECT_SIMOBJECT_TYPE_USER, 0, 0, sizeof(Def_LVARS), &m_MyLVARS);

Note that simply setting values of m_MyLVARS will not actually change the ACTUAL LVARS. You need to issue SimConnect_SetDataOnSimObject() call.

And, to RETRIEVE the LVARS, again, identical to SimVars, you do this:

ISSUE a request:
Code:
hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_USER_LVARS_SIMFRAME, DEFINITION_LVARS, SIMCONNECT_SIMOBJECT_TYPE_USER, SIMCONNECT_PERIOD_SIM_FRAME);

... and when the friendly server responds, TRAP the event, in the same area that you trap your Lat Lon Alt values from the Server, but obviously, under a different "case":
Code:
case REQUEST_USER_LVARS_SIMFRAME:
                {
                    Def_LVARS* pLVARS = (Def_LVARS*)&pObjData->dwData;
                    m_MyLVARS = *pLVARS;
                }
                break;

Notes:
SIMCONNECT_PERIOD_SIM_FRAME - this is up to you, how often you need the server to send you this info (sim frame, visual frame, once, never, every second, etc...)
REQUEST_USER_LVARS_SIMFRAME - This is not a SimConnect var, this is an event enum YOU need to define, for a new request event. Place it in your Request enum, as a separate request, like this:
Code:
enum REQUEST_ID {
    REQUEST_USER_POSITION = 1,
    REQUEST_USER_LVARS_SIMFRAME // <= insert this here
};

Now, you can set LVARs through your XML code, and they will be reflected in your SimConnect code (by REQUEST_USER_LVARS_SIMFRAME retrieving it every sim cycle), and obviously, you can send LVARS to your XML code. Again, remember, you cannot set an LVAR directly in SimConnect. You have to use your bridging struct m_MyLVARS to set them, and then send the data in this struct to the server using SimConnect_SetDataOnSimObject()

That's it. That is all there is to SimConnect LVARS. I hope that lifts the alleged "secrecy cloud" ;) Let me know if you have any further questions, or how this is (or not) working for you.
 
Part of the problem I think, I don't know C++ beyond what monitoring CGPT has taught me, is that it is implemented uniquely for MSFS, so the syntax is not universal, maybe I'm mistaken.
Hi Rick

C/C++ syntax never changes. One of the biggest complaints (and biggest advantages) of C/C++ is that it is pretty much the only programming language that is backwards-compatible with every piece of C/C++ code ever written (unless there's a bugfix that wrecks older workaround code). I really hated it when I first started programming for FS2000 (!!!) but now it's definately my preferred language for just about anything except designing GUIs. dotNet wins out there.

About six months ago I took a piece of ADF code I'd written for FS2002 (I think it was), dumped it wholesale into a Prepar3D template, adjusted the macros to suit the new Prepar3D headers and recompiled it. I didn't touch the actual ADF systems code and it worked first time.

@Misho Can I steal that for the next version of SD2Gau please?

-Dai
 
That's it. That is all there is to SimConnect LVARS. I hope that lifts the alleged "secrecy cloud" ;) Let me know if you have any further questions, or how this is (or not) working for you.
Oh ya no that did it! I hope you don't mind teaching AI and I ended up cancelling my subscription over it, I'm switching to GitHub Copilot anyway, but I could tell I was outgrowing the $20/month level and I'll never push enough pixels to warrant the $200 level, but yep we'd reached an impasse so I told CGPT to read this page, then we had to learn about all those specific arguments, but in the end by the time I declared the module complete it was spitting out that code like pumped concrete, it was uncanny imo. Hated to end that thread except for the tedium waiting for that one occasion the monkey plays Beethoven.

Here's the first rescue, I'm still a bit ham fisted for this kind of detail work! The module will work for any aircraft and it sets two Lvars so you can control attachments on the user aircraft. It's an exe and it displays a little telemetry and such, but you have to have a second monitor or give up space to see it, it will work minimized and automatically close with the sim.

 
Status
Not open for further replies.
Back
Top