The upcoming X-Plane 11.10 release (and before you ask, we’ll let you know as soon as we have an ETA! 🙂 ) will include Version 3.0 of the X-Plane SDK (XPLM).
NB: The code samples linked below will not work yet—in part because X-Plane 11.10 isn’t in beta yet, and in part because we haven’t updated the sample code downloads with the new XPLM300 headers. But, that doesn’t mean you can’t look at the code itself right now!
There are a handful of really important features here for plugin developers:
- Instanced drawing (via the new XPLMInstance header). This is a really important one for improving plugin drawing performance. More info on the theory behind this in Ben’s recent post. The good news for developers still working on X-Plane 10 plugins is that we’ve created a “wrapper” to provide backward compatibility with old versions of the SDK. Using the wrapper, you don’t get the performance benefit that you’d see in X-Plane 11, but you’ll at least be able to use the same API. See the sample project here.
- Map APIs (via the new XPLMMap header). Based on our RFC, this provides an interface for drawing text labels, PNG icons, and arbitrary OpenGL within the X-Plane 11 maps. See the sample project here.
- Two minor features for menus (in the XPLMMenus API; see the new menu SDK sample for examples):
- Aircraft-specific menus. Plugins that get loaded with the user’s aircraft will now have access to XPLMFindAircraftMenu(), to which you can append new menu items or submenus.
- Menu items that show keyboard shortcuts. When you add a menu item via XPLMAppendMenuItemWithCommand(), if the user has a key bound to that command, the key will be displayed on the right-hand side of the menu, just like X-Plane’s native menus.
- More joystick axes & buttons, to match X-Plane 11.10’s support for 20 USB devices (up from the previous cap of 10).
- Lots and lots of new features for plugin-created UI in the XPLMDisplay API, including:
- Support for styling windows like the built-in X-Plane 11 windows (sample project here)
- Support for “popping out” windows into first-class OS windows (demoed in the same sample project above)
- Support for automatic UI scaling of all drawing in your window (this comes for free in all windows created with XPLMCreateWindowEx that are compiled against the XPLM300 API)—this means users with hi-DPI/4k monitors who have set a 150% or 200% scale for the X-Plane UI will get the experience they do with built-in windows.
- Support for windows that automatically “stick” to certain edges of the screen, via the XPLMSetWindowGravity() API (sample project here)
Just to be 100% clear, to get any of these features (with the exception of the backward-compatibility wrapper for instanced drawing, of course), you’ll need to compile against the XPLM300 API.
[Edited to add:] Using the XPLM300 API is 100% optional. Old plugins will continue to function, and you could even write new plugins and compile them against the old API (I’m not sure why you would you want to…), and they’ll work in X-Plane 11.10 and beyond.
Very, very cool, Tyler. The devs that work on drawing complex items will certainly take note.
What about XPLMNavigation?
The only thing coming in 11.10 that’s not listed above is a handful of bug fixes.
I hope the new XPLMNavigation is on Philipp’s schedule, after the G1000 for 11.10 and visiting several flightsim conventions in Europe 😉
Nice when the SDK is updated. But maybe some things are missing.
1. Deleting a menu item in the plugins menu should be possible. XPLMDestroyMenu() deletes only the submenu, but not the item in the plugins menu.
2. The plugin menu should also understand such entries “Visible\tCtrl+F12”. \t should be extended to a right-aligned tab.
3. There is no possibility to move the aircraft around the world to runways, parking spaces or water surfaces. XPLMPlaceUserAtAirport() is unsatisfactory.
Re: #2, that’s actually something I missed in my new feature list. (Thereby making my post above replying to Steve Wilson a lie!) See XPLMAppendMenuItemWithCommand(). This allows you to create a menu item the same way we do for the X-Plane menus, and if the user binds a key to the underlying command for your menu item, the key shortcut will show up in the menu as well.
Re: #3, I’ve heard this from a handful of people now, and it’s likely a bug. I’m looking into it, and hope to have it fixed in time for 11.10b1.
Post edited to include XPLMAppendMenuItemWithCommand().
XPLMAppendMenuItemWithCommand () is good, but the command management unfriendly to the user of X-Plane. It is unacceptable that the user must manually parameterize the hotkeys of a plugin. A function similar to XPLMRegisterHotKey (char inVirtualKey, XPLMKeyFlags inFlags, …) is necessary, which assigns a hotkey to the XPLMCommandRef. If the hotkey is already assigned somewhere or in a previous session the command already assigned a hotkey, the function makes nothing. As a pedant for this function, a second is required, which returns the hotkey of an XPLMCommandRef.
Re: your first concern about menu items, there’s been some confusion on this topic. I just talked to Ben, and it looks like our previous examples were wrong (maybe for years?)! Specifically, they didn’t create the menus quite right.
The menu sample has been updated with the correct code, such that deleting the parent menus you create actually works. The long and short of it is:
1) You first add a menu item to the Plugins menu
2) You then create a menu within that menu item
Then, to later delete the menu (and remove the entry from the Plugins menu), you would:
3) Destroy the menu that housed all your subitems
4) Remove the menu item from the Plugins menu
(The menu sample code has the destroy/remove stuff commented out—uncomment to give it a try.)
Unfortunately removing a menu item from the plugins menu is not safe. XPLMRemoveMenuItem() uses the index of the item as a parameter. However, this index is not reliable, because maybe another plugin has deleted an item above it. This invalidates the index of my item, and XPLMRemoveMenuItem() deletes the wrong item.
Hm, right you are. Let me look into it…
Ah, okay, I see what’s going on here. I believe we do correctly handle the case of two separate plugins removing a menu item—the menu index that XPLMAppendMenuItem() returns is actually relative only to the menu items your plugin has created. So, when you remove menu items, you’ll be invalidating the indices for only the menu items you created. You’re responsible for keeping track of the changes in that case—if you removed the menu item at (your) “index 1,” you’d need to decrement the indices for items 2 through n. Does that make sense?
Of course, if you can produce sample code that shows I’m wrong, I’m happy to take a look, but I just ran a test with two plugins creating their own menu items in the Plugins menu, and deleting those menu items in any order produced the expected results.
Right – the design is: plugins are entirely firewalled from each other’s resources. So even if you stuff your XPLMHandle in a dataref and another plugin reads it, that plugin can’t call XPLMMenu APIs because the owner IDs won’t match.
The plugin menu is obviously a shared resource – it works by having each menu item be owned by a specific plugin that created it, and all indexing is from the view of that plugin. So the first item _you_ create is item 0, which is fine – if there was a real item 0 that another plugin made, you’re not allowed to mess with it anyway.
This lets plugin developers code under the fantasy that you are the only plugin in the universe, and not worry about bugs exposed by other plugins in production systems.
The plugin-related indexing of menu items is unexpected because contrary to all experience. Therefore no plugin developer dared to delete items in the Plugins menu. At least this is my observation when comparing with other plugins.
The information should be present in the description of XPLMAppendMenuItem().
Nevertheless joy with me, because one of my problems was eliminated without effort.
Point taken re: documentation! 🙂
Hi Tyler, while you’re at it, you might want to consider a cross-pluggin “XPLMFindMenuItem”. This could work like this:
// returns -1 or menu id.
id = XPLMFindMenuItem( XPLMFindPluginsMenu(), “my plugin menu” );
id = XPLMFindMenuItem( id, “menu sub 2” );
id = XPLMFindMenuItem( id, “item 1” );
[plugins]
– Dataref Editor
– my plugin menu
– menu sub1
– item1
– menu sub2
– item1 // returns this menu id
This could help some plugin specific features to be activated based on some other plugin menu items present or not.
We’ve actually been really careful to isolate each plugin’s access to the menu system—a policy I don’t see changing any time soon. (In general, “you,” the developer of your plugin, should know a lot more about what’s supported by your plugin than anyone else!) I think the right solution in this case would be for the two plugins to be aware of each other—possibly by looking for things like custom datarefs—and for each to manage its own menu in response to the presence of the other. I realize the realities of the market are such that sometimes plugins get abandoned and such, but we would lose a lot of safety by allowing plugins to manipulate each other’s menus.
Jean-Luc, under what conditions do you not know the position of all of your menu items?
The expected use of the APIs is that you’d record your item number from each original item creation if you need to refer to it, e.g. for decorating check-marks.
You are right Ben and this is exactly what we do.
Tyler, The suggestion is more about plugins needing to know one other plugin menu, and not wanting to interfere or alter it, just to discover. In the API example I’ve posted, the ID could be ‘poisoned’ (MSB to 1?) and only serve this API purpose and none other.
Mind you, I don’t know much other plugins than ours that contextually change the menu depending on the aircraft changes and other user selections, and we have requests from aircraft vendors to follow these changes live so as to adapt their 3D model live accordingly. The suggestion is just for the sake of completeness for the cases it can help, especially in keeping plugins decoupled from custom-coded inter-plugin and per-plugin signalling schemas, otherwise you are right there are many other ways to do the same.
Hi Jean-Luc,
The menu system is _entirely_ fire-walled. You can’t see other plugins menus, they can’t see you, you can’t change them, they can’t change you. So there should be no situation where the menu IDs are not what you expect.
Will the SDK be changed again when X-Plane will be available on Vulkan, or is 3.0 future-proof?
I think I might not have been clear—plugins based on old versions of the SDK are still supported. They don’t have access to the newest features, but they will still work. (And if we’ve broken any plugins, that’s a high-priority bug for us!)
So the answer to your question is: yes, we will continue to add features to the SDK, and yes, v3 (like v2) will be compatible with those future versions to the absolute best of our abilities.
It’s only partly future proof. We hope that if you use the new object instance APIs, that just works, and 2-d UI should just work too. But 3-d rendering will require some kind of Vulkan specific…something.
What I hear is XP is very limited on access to weather..
This is what we hear for the different Weather Add-on companys.. They are having a hard time. Getting good/perfect weather in XP due to SDK access ( and other things )
So was hoping for more weather SDK… Can you elaborate more on this and what LR’s approach to weather is..
Weather is a BIG portion of flying !!!
regards
Henrik
Weather access is provided mainly via file formats, e.g. you can provide the real weather data/wind data, or you can read it. We do not have a complex C++-based low level API for interacting with our weather system. We’re very conservative in creating new APIs, and weather doesn’t fit this model particularly well.
Hello X-Plane team,
The new SDK will gives access to the FMC/FMS/GNS to send flight plan to them ?
Cheers
Stef
There’s no -new- functionality in the nav APIs for 11.10.
“Thanks” Ben
When it is planned to have the ability to have a bite control on FMS, GNS, … ?
Cheers
Stef