This RC has two simple fixes that are non-breaking and totally awesome.
#347: Optimization that brings export time down by a third to a half. The file size remains the side and nothing is needed to activate it. Using the “Optimize” checkbox was not optimized this time around.
#350, #351: Two animation bugs that would cause strange offsets when using bones. You may or may not have experienced this. Again, there is nothing to do to activate this, it is part of every export.
If you run into problems, please file a bug. If you do not notice a decreased export time with large models, also please tell us. We’d love to benchmark this on more data.
XPLM_MSG_EXITING_VR—Note that when moving back to the 2-D monitor, you’ll also want to reposition the window—if you just change your positioning mode, the window will be offscreen.
I’ve updated the VR sample plugin to take advantage of all the new stuff here, minus the widget API—really, once you enable native widget windows, your widget window becomes “just another XPLM window” as far as the display APIs are concerned.
****EDIT: There’s apparently an issue for people running the Vive and WMR where they’re seeing reduced resolution. We’re looking into it and will post an update as soon as possible.
****EDIT2: We’ve found the issue affecting Vive and WMR. We’re testing a fix internally and will release an update hopefully in the next 24 hours. Please do not submit any more bug reports about Vive/WMR resolution.
11.20 VR4 is Live on the servers. Aside from the usability fixes that Ben already mentioned, the major ‘feature’ in VR4 is…Oculus users will no longer need SteamVR. If you downloaded it just for X-Plane, go ahead and remove it. It will no longer be necessary.
As we said we would do from the very beginning, we investigated the relative performance of X-Plane through the native Oculus SDK versus SteamVR and what we found, through data collection,is that the overall experience for Oculus users was better by going through the Oculus SDK directly. I know many of you are thinking “Duh! I told you that a month ago ya big dummy!” and yes…yes you did. Fortunately/Unfortunately, we try not to make engineering decisions based on gut feelings and anecdotal evidence when we have a way to collect actual numbers. We wanted to tackle a majority of the usability issues affecting everyone before we looked into performance.
In the various A/B tests that we performed, we found that going to the Oculus SDK directly got us about 25% improvement in frame rate. This does not necessarily indicate that there’s anything wrong with SteamVR itself. There are several factors influencing the performance in VR. First, Oculus has their “home”, that little bachelor pad where you hang out while waiting for games to load. SteamVR has their “home” as well. When you use SteamVR, BOTH are running on your machine. Those houses are not free and X-Plane is already CPU bottlenecked so anything consuming CPU resources is going to directly affect performance. (I noticed an Autodesk updater in my task manager that was stealing 5% of my CPU consistently. That too was decreasing my performance….every bit matters!). Going directly to the Oculus SDK removes the SteamVR house from the equation.
Sure, getting 25% improvement is a huge win, but that’s NOT the biggest win. The biggest win, in my opinion, is that Asynchronous Space Warp (ASW) works MUCH better even at very low frames rates down to about 22.5fps. It appears as though the timing of the frames is critical for ASW to work properly. Being at 22.5, 30, 45, 90fps feels smooth! Being in between those frame timings seems to make ASW lose its mind creating an annoying judder; the opposite of what ASW is supposed to be doing for us. Oculus seems to be V-Syncing us to hit those intervals, allowing their algorithms to make reliable timing decisions and predictions. It’s my suspicion that SteamVR was just not hitting those intervals, causing ASW to flip out.
TLDR; Performance for Oculus will be on par with what Vive users have been seeing all along. The smoothness of the rendering seems consistent even down to 22.5fps. If you’re a Vive user, you will still, of course, need SteamVR as that IS your native SDK. If you’re a WMR user, you will still need SteamVR. I have not seen any reprojection issues with WMR like we have with Oculus. Supposedly the upcoming versions of SteamVR have some performance improvements coming for WMR users as well so we’ll be sticking with SteamVR for all headsets other than Oculus. That can always change in the future…based on data.
These smaller features are likely to be overshadowed by the release of the G1000 for default aircraft in 11.10, so I decided to dedicate a blog post to promote the articles I’ve written – you can find them among all the guides for aircraft developers: http://developer.x-plane.com/docs/aircraft/
Electric and remote gyro systems
Back in April, I flew a Mooney M20J with a KCS55A HSI in it, and realised that it was impossible to model in X-Plane correctly, so I got to work. See the manual for an explanation of this popular HSI/remote gyro system.
I’ve written a usage guide on the new datarefs and commands that I added, along with some more detailed explanation of all the different gyro systems X-Plane simulates, in this guide for aircraft developers. I also talked about the systems at length in a Youtube live stream earlier this year.
Separate GPSS autopilot mode
This is a feature that many add-on aircraft already simulate to some degree, but by means of more or less reliable plugin trickery. The X-Plane 11 default 737 and 747 are no exception. With X-Plane 11.10, a separate GPS steering mode for the autopilot becomes a standard feature. The new datarefs and commands are explained in detail here.
Screen-only popup instrument windows
Several people who build home-cockpit setups have asked about removing the bezels from the popup displays, so they can have only the screen of a GNS430/530, FMS or G1000 instrument to put on an external monitor, with a hardware bezel around it. While this can already be achieved through some clever hacking in the Miscellaneous.prf file, we now offer a more straightforward way to do this: The popup and pop-out windows now get their bezel graphics from the library system, so you can override the bezel graphics. How to override the bezel with nothing, if your bezel is made of hardware? Simply supply a 1×1 pixel blank .png as a bezel graphic, and X-Plane will know that you really want no bezel at all. In the case of a bezel-less 430, you’d put a 1×1 pixel png as the “cockpit/radios/GPS FMS/Garmin_430_2d.png” resource of your plane.
#294 – A case where autodetect off was not fully trusting the author for Aircraft exports
An uncaught spelling mistake __upgradeLocRot vs __updateLocRot. The fix for the updater altering the animation types was written for object’s dataref animations and bone’s dataref animation troubles. However, with this spelling mistake and Blender’s uncanny ability to eat exceptions from addons, it wasn’t realized until later that bone’s weren’t also getting updated. Fortunately, the updater can be run-again without fear of messing something else up.
At the bottom of the Scene Settings, check “Plugin Development Tools”. Use the Re-run Updater tool at the bottom: Put in 3.3.9 in Fake Version, and click the button. You should see your bone values corrected, as long as you successfully reverted any bad changes from v3.4.0-beta.1. Please e-mail me if you have problems!
Some spelling and capitalization in the UI. Great care has been taken to ensure that none of the actual value or order of the addon properties has changed!
We’re working now on updating the map drawing SDK for compatibility with X-Plane 11.
This post is a request for comments from programmers who write plugins that used to draw to the map—it is not a place for general feature requests for the map, or for off topic comments. (And off topic comments will be deleted.)
Background: What broke the map drawing in the first place?
Long story short, the map has changed drastically since the X-Plane 10 version—it didn’t just get a fresh coat of paint.
The biggest obstacle to backward compatibility comes from the fact that we now use an honest-to-God cartographical map projection for map coordinates. Moreover, the map projection changes for different map types—the normal map UI uses a transverse Mercator projection, while the GPS units use a stereographic projection. For that reason alone, just “splatting” old drawing code on top of the new map would not give you the results you want… the old OpenGL local (x, y, z) coordinates do not have a straightforward mapping to the new projected latitude/longitude locations.
A second major change is the fact that the map can now rotate to match the heading of the user’s aircraft. Unless you like the possibility of your map labels being printed upside down, this requires awareness of the map’s rotation and the fact that north isn’t necessarily “up”.
The final big change comes from the draw order. The map is now very strongly divided into layers, and we draw in 3 stages:
Backgrounds (e.g., terrain)
Icons (e.g., airports, NAVAIDs, etc.)
An individual layer can draw in any or all stages. (For instance, the airports layer draws both airport icons and labels for each icon.) We draw each stage from the bottom layer up, beginning with the terrain at the bottom, then the NAVAIDs & airports somewhere in the middle, and then finishing with the aircraft at the very top. This layering ensures that bigger or less important elements don’t cover up smaller or more important elements—your aircraft, for instance, will always be visible (and selectable), even if it’s in the exact same place as a fix or NAVAID. Likewise, the label for your element will always be visible even if the actual icon is obscured by something above it. (In practice, of course, readability is going to be poor if you have labels overlapping, but that’s not really solvable without much more powerful cartographical tools than we have now.)
While it’s not essential that plugin drawing code respect the layering draw order, it would certainly be nice—it would allow you to ensure that a) your plugin-drawn layer doesn’t cover more important info, and b) less important info doesn’t cover your layer.
With all that in mind, our proposed API for map drawing looks like this:
Plugin code would call the SDK to create a new map layer. To do so, you would provide:
An optional drawing callback for OpenGL drawing (which would be layered beneath all built-in icons & text, but above things like X-Plane’s terrain drawing).
OpenGL drawing here is more or less a “free for all,” with one exception: manipulating the Z buffer is not allowed, due to our reliance on the Z buffer as a means of preserving layer ordering.
An optional icon callback, where you would provide a set of PNG icons to be drawn, along with their heading, opacity, etc., and X-Plane would “splat” them onto the map above all built-in icon types except the aircraft
An optional label callback, where you would provide a set of strings for X-Plane to draw above all built-in labels except the aircraft label
An optional “prepare cache” callback, called whenever the map’s total bounds change (e.g., when the scenery loader loads new DSFs). This allows you to keep your drawing callbacks fast, since you can cache only the data you need for drawing in the current area.
A flag to indicate whether you’d like your new layer to be disablable from the UI (if so, we would add a checkbox to the right-hand sidebar like we have now for the flight path and compass rose)
Drawing, icon, & label callbacks would receive:
The currently visible bounds of the map
The current zoom level of the map
The map units per unit of UI coordinates (useful for drawing text at a fixed size regardless of map scale)
If your layer is drawing in the standard X-Plane map window, this is map units per boxel; if you’re drawing within the GPS unit, it’s map units per “virtual device pixel,” whose size in real screen pixels is of course fluid since the user can move the camera relative to the GPS in the panel.
The map’s current mode (currently one of either sectional, low enroute, and high enroute)
An opaque handle that provides access to the new projection APIs. The projection APIs would provide the following functions:
project a latitude & longitude into map coordinates for drawing
unproject an (x, y) pair of map coordinates into a latitude & longitude
get the scale, in map coordinates, of 1 meter at a given (x, y)
get the heading (in degrees clockwise from “up”) corresponding to north on the map for a given (x, y)—this is necessary since the X-Plane 11 map can be rotated to match your aircraft’s orientation
Relative ordering of plugin-created layers would not be guaranteed. So, if you had two plugins which drew the same icon in the same place, but one drew in red and the other in blue, we would make no guarantees about which color the user saw. (And, indeed, some users may see red and others may see blue.)
Questions we have
While the proposal above meets what we believe the needs of third-party developers to be, we almost certainly haven’t considered every use case for this API. (And it’s possible we’re missing important features even for the use cases we have considered!)
To that end, here are some question you, dear plugin developer, can answer for us:
What’s your use case for the map drawing API?
Does the proposal above sound workable for your use case? (If not, what’s missing, or what would you change?)
Do you like the idea of allowing plugin developers to specify whether their new layer is togglable from the standard map UI? (If not, why, and what policy would you like to see instead?)
Do you have a use case for click selection and click-and-drag functionality in your plugin-created map layers? (This isn’t on the table for the initial update to the map API, but it’s a possibility for future updates.)
You might have noticed we’ve been working our tails off to make X-Plane 11 an amazing sim, with tons of new features, and during that time we didn’t have the resources to do anything further with our proposal to publish X-Plane usage data. The good news about our delay is: we now have usage data for both X-Plane 10 and X-Plane 11.
Since one of us (ahem) remembered we had promised to provide this at intervals, here’s the latest data update. It’s still not particularly pretty, but we have a handful of easy-to-digest charts, plus the raw data at the bottom of the post for those that are interested.
Items of note
All data in these charts are for users of the full version only—we’ve filtered out demo users.
If an aircraft’s name, studio, or number of engine fields in Plane Maker are changed at any point, the aircraft will show up in the data as two different entries.
There are four files here: hardware data and aircraft data, for X-Plane 10 & 11. Each contains all the information we have since September 2015, for paying customers only (no demo users).
[This post was co-authored with Tyler Young of Laminar Research to provide more insight into the design process for X-Plane 11, and cross-posted on the Blind Pig blog.]
A few years ago, we ran a survey of X-Plane users. One of the questions was: If you could improve one area of X-Plane, what would it be?
The most common response was, overwhelmingly… the flight model (cue rimshot). Yeah, right. Of course the number one response was the user interface. We took that criticism seriously, but we didn’t want to incrementally improve the user interface and the experience of using X-Plane when improvements were needed throughout the entire application.
So instead, we decided to redesign the user interface from the ground up. Now, two and a half years later, we can finally talk about it!
Back to Basics
Unless a strong brand is already established, I like to start with typography on most projects like this. Font weights, text colour, letter spacing and line height are carefully considered for each typeface option. And the results are always viewed on screen since that is where users will be experiencing the product. Often when going through this exercise, I frequently find a font family I think will work for the interface, only to discover its legibility is less than ideal. We explored several font families and decided on Roboto. It offered a comfortable reading experience for UI elements and the ability to easily extend the brand online. An updated colour palette was also developed for X-Plane 11. I tend towards monochromatic colour schemes with gradations of each colour filling out the palette. I started with the blue value from previous versions of X-Plane but created a darker overall scheme to use.
All of this was collected into a Component Library. This made extending the interface fast and easy and provided a consistent point of reference for UI elements.
Let’s Get Visual
For X-Plane 11, we wanted to make everything as visual as possible—long, condensed lists of aircraft, airports and settings were dropped in favour of tiles, maps and ‘wizard-type’ user flows. Previously, if you wanted to pick where you were going to start at an airport, you had to navigate through a long text list of runways and ramps; now you can use the visual location picker and just click on the map.
For weather, there’s no more text descriptions of cloud and wind layer heights; just click and drag! You also get visual indicators of precipitation, and real weather gives you a preview that looks exactly the same.
Under the settings screens, joystick configuration has been vastly improved. We’ve worked hard to provide a comprehensive list of interactive images of your hardware, so you don’t just have a text list of buttons that don’t mean anything.
Filters, Search and Settings
In some cases, there’s no avoiding text lists. X-Plane is a very comprehensive and powerful flight simulator, and as such, there’s an incredible amount of configuration that needs to take place before taking flight. For version 11, all text-based selections support filters and/or search. Gone are the folder views and unmanageably long text lists; instead, users can now filter along all sorts of dimensions.
Ready for Takeoff
Overall, I was extremely happy with the re-design process—I really enjoyed working with the team at Laminar Research and we feel we really improved the user experience on X-Plane 11. But what matters most is what you think. So far, initial reviews are positive—if you’ve tried it out, please let us know your thoughts.
This morning I found out why certain plugins (e.g. SeaTraffic, etc.) are crashing X-Plane 10.50 beta 1 on startup. Beta 2 was being uploaded when I found this, but I’m going to fix this bug first and recut the beta, as it’s a big bug (since it renders many users’ systems to be dead-on-boot). Beta 2 should be up by tomorrow morning but might go live some time today if things go well.
The plugin-crash bug is a regression bug – X-Plane used to do something right and has now “regressed” and is doing it wrong in X-Plane 10.50 beta 1. This is our bug to fix, and we will fix it in beta 2; no plugin will need any changes, and the plugins crashing in beta 1 will start working again in beta 2.
That’s everything you need to know about the plugin crash bug. What follows is a very long and verbose write-up of the crash (think of it like an NTSB accident report). Perhaps it will provide plugin authors with some insight into where compatibility problems come from, and why early betas can be unstable.
A Proximate Cause: Loading an OBJ “Too Early”
We’ll work backward from the proximate cause (e.g. literally why did the plugin crash) and work our way backward to eventually understand the “why” of this crash. The fix for the bug is relatively simple, but you can’t know if a bug fix is correct without understanding the complete why; bugs like this take a lot more time to diagnose than to cure.
The crashing plugins are all calling XPLMLoadObject from their XPluginStart callback – that is, they are asking X-Plane to load an OBJ at the earliest possible time they can. This is totally legal! But it turns out that:
X-Plane isn’t ready to load an object at plugin start and
The penalty for doing so is a lot worse (a crash always) in 10.50 than in 10.45 (a crash rarely).
Why isn’t X-Plane ready to load objects? The answer lies in a little-known part of the OBJ file format called “conditionals.” Conditionals are a lot like C preprocessor macros – they are IF-THEN statements in an OBJ that let you make parts of your OBJ file only run in certain settings. For example, we use conditionals to remove the artist-drawn shadows from the static aircraft when X-Plane is in a mode that can draw shadows dynamically; this prevents “double-shadow”.
Conditionals are weird – they work not by evaluating the condition when we draw, but rather when we load; if a conditional is false in the OBJ, that text in the file is literally not used.* This means we need conditionals to work at load time, which in our case means when XPluginStart is called.
Unfortunately, conditionals are set up when we load preferences, and we load preferences after we call XPluginStart. So when these plugins load an object, the conditional system isn’t inited, and the OBJ loader crashes. Since we called the OBJ loader from a plugin, the plugin gets blamed. (A plugin author looking at the plugin crash can easily tell what happened – “I called XPLMLoadObject and it exploded!”.**)
Is this typical? Yes. Often it’s the combination of special rules for initialization, plugins using code in a way the sim doesn’t, and multiple subsystems that cause crashes.
When I found the code path that was causing the crash, my first reaction was “this is a mess…how did this work in X-Plane 10.45???”. So I went back to the X-Plane 10.45 code and found that this was broken in X-Plane 10.45 too! So what changed?
The answer is that in X-Plane 10.45, the conditional system would only crash (due to not being inited) if it was used; in other words, any object with IF SCENERY_SHADOWS (for example) would crash if loaded from a plugin at XPluginStart. But if you didn’t use the conditionals, things worked fine. And my guess is that very few plugin authors use conditionals in their objects.
What changed is that X-Plane 10.50 uses the conditional system for every object load, even if you don’t have an IF statement. So now the crash is 100% reproducible, not a rare “five things must all go wrong at once” kind of crash.
Is this typical? Yes. This is a bug where something was fundamentally broken for a long time, and an incremental internal change in how our code works changed the symptoms from ‘rare’ to ‘always’. This is very typical of beta bugs.
There may be other bugs like this too – it looks to me like objects loaded from XPluginStart with named lights might not get their named lights.
Why Do You Need Conditionals If I Don’t?
The next question this raises is: why did you monkeys change the OBJ loader code? What was wrong with what we had before? What kinds of X-Plane features cause this code change that break plugins?
The conditional code changed to fix a bug that shipped in X-Plane 10.45. The bug is: if you start the sim with HDR off and then turn HDR on, some spill lights don’t appear. The cause is that the OBJs are loaded with spill lights stripped out for performance*** (since HDR is off). In X-Plane 10.45 when you turn on HDR, we reload a lot of objects – but not necessarily the ones we need to, and the spill lights are lost. Rebooting brings the lights back.
To fix this, I modified the OBJ engine to track which conditionals any given object uses. If you add “DEBUG” to the end of your object to view the diagnostics, you’ll now see this in the output. When you change a rendering setting in X-Plane 10.50, only the objects that use a conditional that was affected by the settings change are reloaded.
That’s a big improvement in loading rules compared to X-Plane 1045. Turn on HDR and only objects with spills are reloaded; turn on shadows and only objects with optionally baked shadows are reloaded. But it means we need to use the conditional system on every object load to set up those flags; that’s what exposed the bug.
Is this typical? Yes! What we have is a simple refactor making different use of an internal API to fix a bug, and the results make a separate existing bug worse; that separate bug is reproducible only via plugins.
Is There an Ultimate Cause To All of This?
When fixing bugs like this I have to ask myself “is there a way this could have been avoided?”
The root of this bug is the root of a large number of plugin quirks and edge cases: XPluginStart (the first thing a plugin does) is called insanely early in X-Plane’s load process; as a result, a lot of the SDK isn’t actually available.
The decision to call XPluginStart early is a bad decision, and it is one that I made, well over a decade ago, to solve one specific problem. At the time, X-Plane (6!) had no option to save the selected AI aircraft to preferences. XSquawkBox needed specific AI aircraft loaded to support multiplayer, and it was really slow to let X-Plane load 20 random aircraft, then reload them all later.
To “solve” this (and I use the term loosely, since this one fix has been the source of so many bugs) I put XPluginStart before almost all parts of sim load, so that the XPLMAircraft API could let a plugin pick the AI aircraft before they were loaded, influencing the first load.
If I had a time machine, I’d go back to 2000 and kick myself in the ass. This early in load, virtually all rules of how X-Plane work are wrong since so much of the sim is not yet loaded. Plugin authors already cope with this by “deferring” their work until the sim has fully loaded; our advice for a while has been to not touch any aircraft before this point.
So is this typical? Yes – it’s yet another edge case introduced by plugins starting unnecessarily early.
* If you are wondering why conditionals work at load time and not run time, the answer is instancing. X-Plane does the complex analysis to categorize an object as instancing-friendly when it is loaded; attributes disable instancing. The conditionals run at load time so that if attributes like ATTR_poly_os are removed for shadowing, are removed by conditionals, then the object becomes instancing-friendly (because the conditional is like removing the text).
In other words, by having conditionals “pre-process” the OBJ file, you don’t pay for what you don’t use.
** If you call a plugin API from your plugin and the plugin code crashes, it could be X-Planes fault or your fault; plugin APIs may crash if given bad arguments (e.g. a junk pointer for a string argument).
*** This is the same idea as above; by removing stuff you don’t use like a spill light that isn’t seen with HDR off, we can get X-Plane onto a faster path. For example, if an object contains a spill light with a dataref, it can’t be instanced; if the spill light will never be drawn, deleting it makes the object instancing-eligible.