Sunday, March 30, 2008

DataRefs, the Cirrus, and Opt-In

There's a bug in X-Plane 900 RC2 that will be fixed in RC3.  Basically when you're flying in the Cirrus with a friend (also using the Cirrus via multiplayer) you'll see your own control deflections on his or her plane.

Understanding this bug gets into the way datarefs and object animation work.  In simple terms, a dataref is an access point to data provided by some other part of the sim...the flight model, or another plugin.  An object references a dataref as its source for animation values.  So if you want to animate the wings, you use sim/flightmodel/controls/lail1def or sim/flightmodel2/wing/aileron1_deg.

Now the question is: when you access this dataref in a multiplayer context, which aircraft's ailerons are you talking about?  It turns out the answer depends.
  • For all datarefs except sim/flightmodel2/ and sim/cockpit2/, if the dataref needs to access a plane, the access is to the user's plane (flight 0), always.
  • For sim/flightmodel2/ and sim/cockpit2/, the access is usually to flight 0.  But if we are drawing an aircraft, these datarefs refer to the aircraft being drawn!
(Note: this second feature only works correctly in RC3.)

So when you want to animate the wings of your plane in X-Plane 9, by using the sim/flightmodel2/ datarefs in your object, you'll get the behavior you want: animation with the first plane's flightmodel when your plane is loaded as plane one, animation with the second plane's flightmodel when your plane is loaded as plane two, etc.

Of course the rule of thumb is simple: if working on v9, always prefer sim/flightmodel2/ and sim/cockpit2/ when possible for animation work.

Could we have simply made the sim/flightmodel/ and sim/cockpit/ datarefs have this "pick the right airplane" behavior?  Possibly, but I took the more conservative opt-in approach.  Basically any time we want to change the behavior of the sim we can do one of three things:
  1. Change it globally - all third party content is affected; don't like it, too bad.  This is how pixel shaders work; if shaders are on you can't disable the different fogging they provide for your airplane or object.
  2. Opt-in - you have to change your content to get the new behavior; old content defaults to unchanged.  This is how the new datarefs work.  You have to edit your content to use the new datarefs to get the new behavior.
  3. Opt-out - you have to change your content to avoid the new behavior.  For a while cockpit lighting was like this, but I received so many reports of version 8 airplanes looking totally strange that I changed the cockpit lighting choices to opt-in.
Generally opt-in is the safest thing we can do to leave previous content working; if we make a change globally then we break any content that doesn't work well with our changes.  Datarefs are used so heavily that a fundamental change in how they work would probably not be safe.

Given a choice between opt-in and opt-out I've come to prefer opt-in; both require the same amount of work for LR (we have to write code to support the old and new behavior) so why not do the thing that provides better compatibility?

Finally a general historical note: sim/cockpit2/ and sim/flightmodel2 are not just there to provide new behavior with objects; they are designed to give us a clean start in providing only authoring-related datarefs in an easier-to-understand format.  The original datarefs were meant only for programmers, so we didn't worry too much about usability.  Since then, datarefs have become the communications medium for panels and a lot of 3-d animation.

So not only do sim/cockpit2 and sim/flightmodel2/ provide correct animation behavior, but they're also easier to read.

An important distinction between sim/cockpit2 and sim/flightmodel2 is that they partition the datarefs based on perception vs. reality:
  • Generally sim/cockpit2 shows datarefs as the pilot sees them in the cockpit, and actions as the pilot commands them.
  • Generally sim/flightmodel2 shows the plane's behavior as it's really simulated, and actions as they actually happen.
In other words, when the pitot tube ices up, sim/flightmodel2 shows the real airspeed and sim/cockpit2 shows the incorrect airspeed.  When the hydraulic system fails, sim/cockpit2 shows that the pilot wants to bank, and sim/flightmodel2 shows that the ailerons aren't really moving much.

What this means is that you should use sim/cockpit2 for cockpit objects and generic instruments and sim/flightmodel2 for objects attached to the airplane exterior.  This will assure that failure simulation works correctly (e.g. failures are perceived correctly by the pilot) and the external control surfaces match the plane's physical behavior.

If you've studied sim/cockpit2 a lot, you know it's pretty incomplete.  We'll be adding the rest of the cockpit systems in 910.  I would have liked to get the entire set of airplane changes into 9.0 but there's a lot more to do - not just more datarefs, but also manipulators for 3-d objects and a new lighting model for aircraft interiors.  I think 910 will finish what 900 has started in terms of new airplane features.

Final random note: RC3 will allow you to pick any dataref for a generic instrument, not just sim/cockpit2 and sim/flightmodel2.  This is mainly so people writing plugins can easily hook their datarefs up to the panel by editing datarefs.txt instead of typing them by hand.

No comments: