The CEF post generated a lot of controversy, and rather than replying directly in the comments (and doing a bunch of copy & paste), I thought I’d collect my responses to the major objections here.
Objection: Nobody wants to browse the web in X-Plane!
Yes and no. I agree that, unless you’re in VR, a full-fledged web browser is totally useless. Nobody wants to be browsing cat pictures while flying. But CEF is really not designed to power a traditional web browser.
Consider this list of a bunch of other applications that nobody wants a web browser in:
- Adobe Acrobat
- The Steam client
- The Atom text editor
- The GitHub desktop client
What do all those applications have in common? They’re built on CEF, or the closely related Electron project.
My point is this: the primary use case for CEF is not to build a full-fledged browser—it’s to support things like HTML5 user interfaces, which massively lower the bar for creating nice, easy-to-use plugins. It could also support things like displaying PDF charts or other electronic flight bag features—things that are theoretically possible without a webview, but which have such a high barrier to entry that nobody wants to tackle them.
We are always looking for ways to both
- get more people involved in creating X-Plane add-ons, and
- give existing plugin developers better tools so that they can create things they couldn’t have before.
Doing so makes the X-Plane community stronger, and supports the creation of add-ons that might otherwise not have existed.
Objection: This is a waste of time. What you should be working on is [some other feature].
As I mentioned previously, CEF is being used in X-Plane right now to enable in-app upgrades. This is obviously the most boring non-feature we could ever ship, and I understand why power users (people who might have bought X-Plane 11 on day 1!) are irritated.
The reality is: some features we ship for end-users*, and some we ship to “pay the bills.” Paying the bills is boring, but important: having X-Plane be financially successful ensures that we can continue improving the sim (ahem, in ways that end users actually care about!) for decades to come. In this particular case, we have reason to believe the current purchasing process is convoluted enough that it’s losing us sales. In-app upgrades will increase sales by some (small) percentage, so even though it’s not a direct improvement to the sim for existing users, it’s funding future development.
One more thing worth mentioning on the topic of “I wish you’d do x instead” is that we have a handful of full-time developers now, with people specializing in very different areas, so we tend to have a lot of features in progress at any one time. It’s certainly not the case that, say, Sidney stopped working on improving performance while I was off integrating CEF. 🙂
Objection: I don’t want X-Plane plugins using webviews!
The reason we’re having this discussion is that plugin developers are already using CEF—and they’re doing so in ways that are incompatible with other developers’ implementations.
It’s certainly an option for us to bury our heads in the sand and ignore this—we could force users to choose between, say, installing a Flight Factor plane and installing a fancy new web-based plugin (or using future X-Plane core features). Ultimately, though, this hurts both the end users who would have otherwise chosen “all of the above,” and it hurts the add-on makers who lose sales because users were forced to choose.
We can’t stop add-on makers from using webviews, but we can make sure that doing so doesn’t lead to a compatibility nightmare for end users.
Objection: CEF represents a massive security hole!
This is absolutely a concern for us. Webviews in X-Plane present two major attack surfaces:
- The possibility of running untrusted code (e.g., a nefarious site exploits a browser vulnerability to execute harmful code on your machine)
- The possibility of sending data somewhere you didn’t want it to go (e.g., a nefarious site masquerades as your bank’s web site, and sends your login info to bad guys)
We’re still in the “exploration” phase here, trying to understand plugin developers’ needs, but there are a lot of ways we could mitigate these threats. A few possibilities, listed from most extreme to least:
- Don’t allow remote connections at all; plugin-created webviews could only load local assets (HTML, JS, etc.) that were bundled with the plugin
- Require plugins to provide a whitelist of URLs that are deemed safe to send & receive data from
- Allow user preferences to control the above policies (or even disable webviews entirely)
Objection: CEF will slow the sim down. This is bloatware!
That’s for measurement to decide! In our tests, having CEF displaying static pages while flying didn’t slow down the sim by any amount we could measure. And since CEF doesn’t run on the main X-Plane thread, the OS can schedule CPU-intensive things like page loads around X-Plane’s work. There is definitely some memory overhead involved (a few hundred megabytes), but considering the existing footprint of X-Plane, it’s not a crazy amount.
And, like everything in X-Plane, if you want to tune it to get the last drop of performance, you’d be free to avoid using features & add-ons that depend on webviews.
Objection: Don’t use CEF—You should use WebKit, Gecko, Servo, etc. instead.
I did a lot of research and test implementations (on Windows, I went so far as to use Trident, the underlying engine to Internet Explorer!), and the only webview framework I found that meets X-Plane’s requirements was CEF.
* Aside: What does 11.20 include for end-users? A few highlights from the release notes:
- VR support
- New Sydney, Australia landmarks
- A new Aerolite 103 model
- An overhauled Columbia 400
- 1,315 airports with new 3-D scenery
Plugin developers, Beta 5 includes a few new VR-specific APIs in the XPLMDisplay header.
The complete list of VR-specific APIs is now:
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.
In the X-Plane 11.20b1, we’re shipping a web browser for the first time. We’re using the Chromium Embedded Framework (CEF)—essentially the same guts as Chrome, wrapped inside X-Plane.
For the time being, it’s being used in one place only*: to support in-app upgrades, so that if you have the demo, you can buy the full version of X-Plane without having to go to the web site. The web view is seamless—you can’t tell by looking at the app that it’s not just part of the native X-Plane user interface.
While its present use is quite limited, if all goes well, we’d like to expand its use elsewhere in the sim—in The Glorious Future™, we could potentially use it to load online charts and the like.
But, there’s a hitch!
There’s not a good way to load two copies of CEF at a time. And, since some plugins (like the ones used in the new Flight Factor A320 Ultimate) depend on a version of CEF provided by a (global) plugin, we have to disable X-Plane’s web browser functionality in the presence of that plugin. This isn’t a big deal right now—after all, if you’ve installed payware, you probably already own the sim anyway—but it will be a shame if, in The Glorious Future™, you have to choose between your payware and core X-Plane functionality.
The situation is even worse than you might expect: CEF absolutely doesn’t support multiple initialization calls in the lifetime of an app—you can’t initialize it, shut it down, then re-initialize it. That means it’s not even possible for plugin authors to be good citizens and “relinquish” CEF to X-Plane, such that you could at least use X-Plane’s browser whenever you’re not using an add-on that depends on it. It’s all or nothing! In fact, you’ll have to uninstall the CEF plugin before X-Plane can use a web view itself.
There are two possible fixes here:
- At some point in the future, we provide access to CEF via the plugin SDK. If we did, it would have to be to the C API only—no fancy C++ wrappers for you. Speaking as someone with the memory of writing for the C API fresh in his mind, let me say: this isn’t a whole lot of fun, and it’s rife with the potential for memory leaks. Moreover, this would break any existing addons that depend on CEF—they would be forced to migrate to the SDK version of the API.
- We could (theoretically) compile an X-Plane-specific version of CEF that would not conflict with the version plugins are using. This would require renaming all the Objective-C symbols on Mac, and renaming the DLL on Windows. I’ve not investigated this for feasibility, but it’s certainly theoretically possible. This would allow X-Plane’s version of CEF to coexist with (one) plugin-provided copy, albeit at double the CPU and memory cost.
Having us expose CEF via the SDK is not an unequivocal win. CEF is notoriously incompatible between versions—you can more or less guarantee that even minor updates will break compatibility of the API somewhere. That means X-Plane would be stuck at a fixed version of CEF for at least the lifetime of a major version to prevent breaking plugins. X-Plane 11.20 uses CEF release 3202; it would be at least the next major version before we updated CEF to a newer version. There are two major downsides to this:
- When X-Plane updates to that newer version, it would break plugins compiled against old versions of the SDK that depend on CEF. That’s a lot more aggressive than our normal deprecation policy, and it makes CEF plugins a potential maintenance headache for plugin devs.
- If your add-on really, really needs features from the latest and greatest CEF release, you’re out of luck—wait a couple years (!!) and maybe we’ll update.
So, here’s what I’d like to hear from plugin devs:
- Are you currently, or are you planning to use CEF in the future?
- Would you be willing to use the C version of the CEF API only?
- Would you be able to accept the limitations and potential headaches (outlined above) of X-Plane-determined CEF versions and compatibility?
If you don’t mind telling me a bit about your intended use cases, that’d be very helpful as well!
EDITED TO ADD: There’s a third option here that I didn’t consider: X-Plane could provide a “wrapper” around CEF that offers “just” a browser surface, and simple interfaces like the ability to change the URL programmatically. This has the advantage that we could update CEF regularly without breaking the API (though there’s always the risk that a new version of Chromium would change how it handles your HTML + CSS + JS). The disadvantages are twofold:
a) If a plugin developer really, really needs the full power of the CEF API, they’re out of luck (or we’re back to square one with respect to having to disable core X-Plane functionality in order to support the plugin).
b) New XPLM APIs are a massive tax on our development time. Every time we need to make a change, we have to go test a dozen plugins… then go through an extensive beta… then inevitably hear about a show-stopping bug we introduced three hours after a release goes final. 😀 In contrast, providing a (major-version-stable), transparent copy of CEF costs us very little dev time; time that would otherwise be spent maintaining the XPLM API can be spent on, like, major features.
* Aside: This is actually how we test a lot of new tech in X-Plane: we find a single, relatively out-of-the-way place to make use of it, ship it in a major version update, and wait to see if it blows up. Betas catch a lot of bugs, but not all, so this is a way of hedging our bets when it comes to code that hasn’t been battle-hardened. This is how we worked the bugs out of the user interface framework (Plane Maker’s panel editor was the testbed), the X-Plane 11 particle system (behind the scenes, it was used for some very minor effects in X-Plane 10.51), and more.
One of the biggest requests we received with the previous VR previews (1, 2, 3, 4, 5) is to allow plugin-created windows to join the VR fun. I’m happy to say the initial implementation of this—allowing windows to float in 3-D space, Minority Report-style—is live in VR6. Read More
Posted in VR
by Tyler Young
This may come as a shock to you, but… we hear a lot of complaints about the X-Plane 11 ATC.
I have good news: We want to improve the ATC!
The problem we’re facing is that a lot of the feedback we get is indistinct—hearing “ATC sucks” doesn’t help us understand how we could do better. So, here’s what we’d like from you: Tell us the specific issues you have, or the specific features you’d like to see implemented. At this point, we can’t promise a timeframe for any given improvements, but we can promise to consider everything you say.
Please note: Any comments on this post that don’t directly relate to ATC will be deleted. Moreover, please don’t slag on other people’s wishlists—arguments against other people in this thread will not inform our decisions about how we prioritize this stuff.
TL;DR: Running X-Plane with
sudo is a bad idea. Instead, create proper udev rules (per this and this).
During the 11.10 beta, I’ve gotten a lot of bug reports from Linux users who report that their keyboard is being recognized as a joystick. This is… sort of a bug, but mostly intentional.
(If you’re not a Linux user, this won’t apply to you… but it will bore you! 😉 )
Background: What changed?
On Linux, prior to X-Plane 11.10, we were very picky about what USB devices we considered to be a joystick: we required a device to present a so-called “absolute” axis (in contrast to a “relative” axis like a mouse uses). The downside of this is that it prevented home cockpit builders from creating button-only hardware.
So, in 11.10 and beyond, we relaxed the requirements: if a USB device presents us with either an axis, button, or hat switch, we’ll treat it like a joystick.
The problem with this policy seems obvious: keyboards have “buttons”! Like, 104+ of them!
The reason we didn’t worry about this is that the keyboard is only accessible (as a USB device) to programs running as root. So long as X-Plane runs as a normal user, it doesn’t even have the option of treating the keyboard as a joystick.
Why do people run as root?
The impetus for running as root (via
sudo) is simple: if your Linux distro doesn’t recognize your joystick hardware as something that should be available to normal applications, running as root is a brute-force way to let X-Plane use your joystick.
Let me say emphatically: This is a bad idea.
Especially with early, buggy betas, running as root makes it possible for X-Plane to do way more damage to your system than would ever be possible as a normal user. Consider the unlikely—but possible!—scenario where somebody made a typo in the code which inadvertently tries to delete a system folder. There are two possible outcomes here:
- If you’re running as a normal user: Nothing happens. The operating system refuses to let X-Plane hurt your system.
- If you’re running as root: The operating system silently obeys. You curse X-Plane for breaking your system.
Running X-Plane as root is like giving a blank check to every cashier you buy something from—it’s way more power than they need to do their job, and it’s liable to burn you at some point!
The Right Way™ to let X-Plane use your joystick
As described in the latter half of this old dev blog post, you don’t have to run with
sudo. Instead, you can create udev rules to tell your operating system to let normal applications use your joystick. The GUI tool linked at the end of that post makes it even easier.
(Some users found the instructions there confusing; this post on the Org might help.)
Remember that after you create your rules, you can even submit them to your distro to make life easier for other flight simmers!
There’s one hitch: after running with root, your file permissions (especially your prefs) may have gotten screwed up. This can be fixed from the terminal by making your normal user account the owner of your X-Plane directory, like this:
$ sudo chown -R <username>:<username> /path/to/X-Plane/
(So, in my case, my username is tyler, and X-Plane is installed to ~/Documents/X-Plane/, so I’d run
$ sudo chown -R tyler:tyler ~/Documents/X-Plane/.)
Now, to those of you who have been running as root… “go, and sin no more”! 😉
AI planes face two major issues in X-Plane 11:
- AI aircraft are often way more resource-intensive than they need to be. Users are fine paying a performance penalty to load, say, a super detailed 3-D cockpit model for their own aircraft, but for AI planes, where you’re never going to be in the cockpit, there’s no reason for that sort of thing. A significantly “dumbed down” version of the same aircraft would allow users to load more AI planes at once, with no visible downsides during normal use.
- Many aircraft, for one reason or another, simply won’t function at all when used as AI planes. This is most commonly due to one of two issues:
- reliance on third-party plugins (which only work for the user’s plane)
- lack of support from X-Plane for flying aircraft like this (for instance, the X-Plane AI doesn’t know how to fly gliders, seaplanes, or rockets)
As a user, this is really frustrating, because it’s difficult or impossible to know in advance which aircraft will work as AI planes and which will either a) just sit on the runway, never able to take off, and/or b) tank your frame rate.
Coming in X-Plane 11.10: AI-Only and User-Only Aircraft
In the upcoming X-Plane 11.10 beta, we’ve added two new options to Plane Maker’s Author window: “supports user flight” and “supports AI flight.” By default, all aircraft support user flight, and do not support use as AI aircraft.
If a plane is configured for AI flight only, it will never be shown in the normal aircraft grid—only in the AI aircraft window.
If a plane is configured for user-flight only (or if it’s a pre–11.10 aircraft with no “supported flight type” info), it will be hidden in the AI aircraft window by default, but for the sake of backward compatibility with old planes, users will still be able to reveal them by checking a box labeled “Show aircraft without AI support.”
The upshot for aircraft authors
In the Glorious Future, we envision third parties shipping two versions of their aircraft:
- one marked user only, which include all the bells and whistles, plugin-enhancements, and as much detail as possible
- one marked AI only, which is stripped down for performance, only using plugin enhancements that have been tested in AI configurations.
The result will be a faster, more consistent, less error prone experience for users.
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.
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.)
We’re looking to add two developers—one junior, one senior—to the Laminar Research team this spring.
As a member of our team, you would:
- Work on stuff that matters. Real pilots fly safer because of training in X-Plane, and real aerospace organizations (like Boeing, Cessna, and NASA, to name just a few) prototype aircraft in X-Plane before they build them in the real world.
- Work on a product that millions of people will see. You’ll get feedback from users, and that feedback will drive future development.
- Have tremendous input on the direction of the product. Because X-Plane is an exceedingly small team, every team member has a lot of say about what we work on and how we make the simulator better for our users.
- Set your own schedule. As far as we’re concerned, if you’re shipping features and fixing bugs, it’s your business when you do so.
- Work remote. No commute, no cubicles, nothing to impede you from doing great work. (But the rest of the team is just a Skype call away!)
- Work on a variety of technologies and products. At various points, you might work on X-Plane, Plane Maker, WED, the X-Plane installer, the Scenery Gateway web app, or even the X-Plane.com web site.
A qualified junior candidate will:
- Have a computer science degree.
- Be a quick learner. We expect most of what you need to know (beyond computer science fundamentals) to be learned on the job.
- Have the self-discipline to work from home and set your own schedule. (It’s not for everyone.)
In additions to the above, a qualified senior candidate will:
- Have experience shipping major features in production applications with minimal oversight.
- Have specific experience relevant to X-Plane. There’s no exhaustive list of skills we could use, but some possible examples include:
- Real-time graphics
- Real-time C++ development
- Mobile development
- Game development
- GIS data processing
- The X-Plane plugin system
How to Apply
Send an email introduction to me that includes:
- Which position you want to apply for
- A brief overview of a project (or projects) you’ve enjoyed working on
- Discussion of projects you have not enjoyed working on
The introduction is really just a means for me to get a handle on who you are as a developer, so do not stress over it!
My email is my first name at X-Plane.com. Please do not attempt to apply in comments!
(Not sure if this is a good fit for you? Email me anyway and we can talk. 🙂 )