Plugin Optimization - The Next X-Plane Bottleneck

April 3, 2020
Taylor Broad
nobody, apparently.

About the author: Taylor Broad is an avionics engineer who is contracted with major US-based aerospace companies, as well as part-time flight sim developer with Cardinal Horizon, whose primary products are VAOS, a virtual airline system, and SimVector, a new online flight tracker.

Now that Vulkan/Metal has arrived publicly for X-Plane 11, it’s hard to ignore the performance increase. For developers, like myself, we now have new tools that we can utilize to monitor the behavior of our code within the sim.

For some of you, the end-users, you will see a notable uptick in performance. However, some of you will not see this expected performance gain.

You might be wondering, “where was this performance gain that was promised to me? I thought the limitation was graphics?”

Yes, the prior limitations of OpenGL are gone, however, Vulkan exposed a new barrier to performance… Plugin optimization.

X-Plane 11.50 Beta - Including Vulkan & Metal - Available Now

To dive into these concepts, I will be required to explain a few terms upfront so that way you can fully grasp the content of this article. Don’t worry, these concepts are easy to understand once explained.

Let’s get started.

The X-Plane Plugin Ecosystem

First, we need to go over the basics of the X-Plane plugin ecosystem. For way more detailed information than we’ll go through here, I suggest you go read the complete documentation. It’s definitely a page turner, but it does an extremely good job explaining these concepts to people who have intermediate experience.

To start, the X-Plane plugin is a dynamic library of code that is loaded by X-Plane within its application space. Plugins communicate with the sim through the X-Plane Plugin Manager (XPLM).

Applicable to the discussion at hand, it is important to note the following behaviors of plugins.

  • Plugins run within a single-threaded environment within the context of the X-Plane, which means plugin callbacks (events plugins subscribe to) are executed sequentially, inter-plugin. (Plugin B must wait for its task to complete before Plugin A can work)
  • Plugins, if they elect to, can attach themselves to the XPLMProcessing API, which allows for a developer to run code every frame with the physics (usually used for aircraft physics and systems calculations for addon aircraft)

All addon aircraft (including the stock Laminar fleet) use plugins to drive any form of custom functionality not stock to the simulator.

The plugins loaded by the XPLM are coded in a compiled language, however, in the case of plugins like SASL, Gizmo or xLua, they’re wrappers for use of uncompiled languages. Uncompiled languages for these plugins typically store the source code in a way that’s viewable with any text editor.

For example, the Zibo Mod famously uses the xLua plugin developed by Laminar Research's art department to add functionality to their default aircraft. Lubos, the developer, turned that aircraft into the most popular freeware, study-level aircraft, in flight simulation. He did so by primarily modifying the source code, which was easily accessible within the xLua plugin folder.

The Zibo Mod 737 is an excellent example of adding functionality through xLua.

A topic we’re not going to go into this time around is performance costs based on languages and what’s better. While there are hard limits to how much performance you can get out of a language, the developer’s execution of structuring code plays a huge factor. Look no further than Yandere Simulator, which has many Unity developers screaming and crying because of how inefficient the developer of that game is.

Complexity at The Cost of Performance

Now that you understand the plugin ecosystem, here’s the punchline you’ve been waiting for. Here’s the FlightFactor 767 in the context of framerate.

The giant blue slice is the time it takes for XP11 to do all its work regarding rendering the scene. The rest of it is taken up by plugins on top of the work done by XP11.

The FlightFactor 767 with all the plugins combined to run itself, takes up a whopping 35.85% of extra time, on top of what XP11 has to do, to render a single frame.

To put that into a real-world perspective, on my machine, the sim will run around 55-60 FPS when it’s handling only the sim. With the FF aircraft’s systems put on top, I hover usually around 23-26 FPS with occasional dips down below 20 FPS.

For comparison, here’s the Hot Start TBM-900, which from a system complexity standpoint, would be on par with the FF 757/767.

That’s a nicer number. For me, this gets me a solid 40-45 FPS.

So, how is the TBM9, which is on par with the 767 with complexity, much more efficient? Multithreading and well organized code.

The general goal of multi-threading in XP11 is to take tasks that would normally freeze up the simulator or have long execution times and split them off from the main execution thread, thereby allowing the sim to go to the next task while the other one is being processed in the background. This is also known as being asynchronous.

Since Hot Start built their aircraft with multi-threading in mind for all the systems, the flight event loop, which impacts your framerate the most, is very small and efficient, as the sim is not waiting for any one task to complete.

In a sense, this is how real world avionics work, where sensors are sending data to the FMS at a fixed rate and the actions taken are independent from the sensors of the aircraft. If we wanted to apply that to XP11, our sim is the sensors and the code running in the plugins are the FMS (well in this sense, quite literally!). The sim should not need to wait for the actions of the FMS to be complete before progressing to the next cycle.

How Low Can The Execution Time Go?

The Rotate MD-80, while only coded for XP10, carries a lot of what I consider the gold standard in performance in XP11.

So if you’re wondering, that’s with the aircraft off. However in my testing, it rarely broke 5% of the total time to render a frame.

What I think the Rotate MD-80 excels at is creating a Study-Sim experience with the illusion of study-sim, but not purposefully going down a rabbit hole of code complexity that’ll slow down the flight_loop.

Moving Forward

In the future, I see that there’s a lot of potential in performance improvements for X-Plane 11 in this space. We, as developers, closed one door but just opened another one.

It’s time to take a serious look at multithreading and optimizing these aircraft/avionics to get the most out of the new performance afforded to us. The frames are there for the taking. It’s time to utilize all the overhead to its full potential.

For now, this should cover the basics of a highly complex topic I have yet to dig into the details.

If you'd like to discuss the subject of this article, find Taylor on Twitter here.

This is a subject that can be dug into further, with the potential for a part 2. If you’re interested in a Part 2, leave some feedback and we'll be sure to get Taylor on again - he hints that a certain few developers might be on to help out!

Threshold encourages informed discussion and debate - though this can only happen if all commenters remain civil when voicing their opinions.