Global, Aircraft, and Scenery Plugins¶
From an X-Plane perspective, there are three types of plugins: Global, Aircraft, and Scenery. Internally, these plugins are identical: They have access to the same SDK calls, receive the same messages, and must follow the same set of rules.
They differ in where they are placed in the filesystem, and when they are intialized:
Type
Located
Lifetime
Global
Resources/plugins
Loaded first at startup Unloaded at program exit.
Aircraft
Aircraft/<aircraft>/plugins
Loaded when User Aircraft is initialized or changed. Unloaded when User Aircraft is changed or program exit.
Scenery
Custom Scenery/<scenery>/plugins
Loaded (after Global) at startup. Unloaded (after Global) at program exit.
You can create XPPython3 plugins of any type by placing your PI_<plugin>.py
file(s) in the appropriate PythonPlugins
directory, under the
relevant plugins
directory. (The plugins
directories contain the C/C++,
XLua, and other plugin types: we look for PythonPlugins
directory there
to find any XPPython3 plugins.)
For Aircraft the plugins
directory is contained in the same folder
as the aircrafts .acf
file: That’s how we located it, by getting the
.acf
file and then looking for plugins/PythonPlugins
.
To have a plugin activated only for Laminar Cessna 172, place it in a new folder:
<XP>/Aircraft/Laminar Resource/Cessna 172SP/plugins/PythonPlugins/You can have any number of XPPython3 plugins in that directory.
For Scenery the plugins
directory is in the same location
as the scenery’s Earth nav data
and objects
folder.
To have a plugin for KSEA Demo Area, place it in a new folder:
<XP>/Custom Scenery/KSEA Demo Area/plugins/PythonPlugins/You can have any number of XPPython3 plugins in that directory.
Warning
Scenery plugins are always loaded and enabled (if the scenery package is loaded). This means your KSEA plugin will be running even when you’re flying in South Africa. For this reason, make sure your plugin does very little when the User Aircraft is no where near it.
Access to Python Modules¶
Note that XPPython plugins of one type may access python modules (i.e, ‘code’) of another type: We load each as a package.
Internal plugins are loaded using the XPPython3
package, so you can always
access them from any plugin as, for example, import XPPython3.xp
.
Global plugins are loaded using the PythonPlugins
package, so you can
always access them from any plugin as, for example, import PythonPlugins.PI_MyPlugin
,
or perhaps more likely, import PythonPlugins.myplugin.utils
Aircraft plugins are loaded using a long package name (it’s unlikely you’ll be cross-referencing these.) But they are available, for example:
import importlib
importlib.import_module("utils.py", "Laminar Resource.Baron B58.plugins.PythonPlugins")
Similarly, Scenery plugins are loaded using a long package name, for example:
import importlib
importlib.import_module("utils.py", "KSEA Demo Area.plugins.PythonPlugins")
A more useful technique would be to place your shared utilities under the Global directory (i.e., under Resources/plugins/PythonPlugins/) and then import them into (each) of your Aircraft or Scenery plugins:
# PI_MyAircraft.py
import PythonPlugins.abc_aircraft.aircraft_utils as aircraft_utils
Python modules which don’t have to be shared can be (should be) stored with the aircraft plugin and can be loaded directly using a relative import:
# PI_MyAircraft.py
from . import cessna_utils
Startup Sequence¶
Plugins are started in a particular sequence. In general, you should code as much as possible to avoid relying on a particular sequence. Laminar suggests you register your data references in you XPluginStart() routine, but look for other data references in your XPluginEnable() routine, as this most plugins will be Started prior to any plugin becoming Enabled.
Note
With a particular grouping, order is not guaranteed. While it may appear that plugins are loaded alphabetically, this may not always work.
On program startup, the sequence is:
X-Plane Started
Global Plugins Started
-----------------------
START Resources/plugins/abc.xpl
START Resources/plugins/XPPython3.xpl
START XPPython3/I_PI_<plugin1>.py
XPPython3/I_PI_<plugin2>.py
START PythonPlugins/PI_<plugin1>.py
PythonPlugins/PI_<plugin2>.py
START Custom Scenery/.../PI_<plugin1>.py
Custom Scenery/.../PI_<plugin2>.py
START Resources/plugins/ZYX.xpl
Scenery Plugins Started (Non-python)
-----------------------
START Custom Scenery/.../plugins/abc.xpl
Global Plugins Enabled
-----------------------
ENABLE Resources/plugins/abc.xpl
ENABLE Resources/plugins/XPPython3.xpl
ENABLE XPPython3/I_PI_<plugin1>.py
XPPython3/I_PI_<plugin2>.py
ENABLE PythonPlugins/PI_<plugin1>.py
PythonPlugins/PI_<plugin2>.py
ENABLE Custom Scenery/.../PI_<plugin1>.py
Custom Scenery/.../PI_<plugin2>.py
ENABLE Resources/plugins/ZYX.xpl
Scenery Plugins Enabled (Non-python)
-----------------------
ENABLE Custom Scenery/.../plugins/abc.xpl
This is followed by the loading of the selected User Aircraft:
Aircraft Loaded
Aircraft Plugins Started & Enabled
------------------------
START Aircraft/.../plugins/abc.xpl
ENABLE Aircraft/.../plugins/abc.xpl
START Aircraft/.../plugins/PythonPlugins/PI_<plugin1>.py
START Aircraft/.../plugins/PythonPlugins/PI_<plugin2>.py
ENABLE Aircraft/.../plugins/PythonPlugins/PI_<plugin1>.py
ENABLE Aircraft/.../plugins/PythonPlugins/PI_<plugin2>.py
When the user changes the selected aircraft:
Aircraft Changed
Aircraft1 Plugins Disabled & Stopped
------------------------
DISABLE Aircraft/.../plugins/abc.xpl
STOP Aircraft/.../plugins/abc.xpl
DISABLE Aircraft/.../plugins/PythonPlugins/PI_<plugin1>.py
DISABLE Aircraft/.../plugins/PythonPlugins/PI_<plugin2>.py
STOP Aircraft/.../plugins/PythonPlugins/PI_<plugin1>.py
STOP Aircraft/.../plugins/PythonPlugins/PI_<plugin2>.py
Aircraft2 Plugins Started & Enabled
------------------------
START Aircraft/.../plugins/abc.xpl
ENABLE Aircraft/.../plugins/abc.xpl
START Aircraft/.../plugins/PythonPlugins/PI_<plugin1>.py
START Aircraft/.../plugins/PythonPlugins/PI_<plugin2>.py
ENABLE Aircraft/.../plugins/PythonPlugins/PI_<plugin1>.py
ENABLE Aircraft/.../plugins/PythonPlugins/PI_<plugin2>.py
On program exit:
X-Plane Exit
Global and Scenery Plugins Disabled
-----------------------------------
DISABLE Resources/plugins/abc.xpl
DISABLE Resources/plugins/XPPython3.xpl
DISABLE PythonPlugins/PI_<plugin1>.py
DISABLE PythonPlugins/PI_<plugin2>.py
DISABLE XPPython/I_PI_<plugins>.py
DISABLE Custom Scenery/.../PI_<plugins>.py
DISABLE Custom Scenery/plugins/abc.xpl
Aircraft Plugins Disabled
------------------------
DISABLE Aircraft/.../plugins/abc.xpl
DISABLE Aircraft/.../plugins/PythonPlugins/PI_<plugin1>.py
DISABLE Aircraft/.../plugins/PythonPlugins/PI_<plugin2>.py
Global and Scenery Plugins Stopped
----------------------------------
STOP Resources/plugins/abc.xpl
STOP Resources/plugins/XPPython3.xpl
STOP PythonPlugins/PI_<plugin1>.py
STOP PythonPlugins/PI_<plugin2>.py
STOP XPPython/I_PI_<plugins>.py
STOP Custom Scenery/.../PI_<plugins>.py
STOP Custom Scenery/plugins/abc.xpl
Aircraft Plugins Stopped
------------------------
STOP Aircraft/.../plugins/abc.xpl
STOP Aircraft/.../plugins/PythonPlugins/PI_<plugin1>.py
STOP Aircraft/.../plugins/PythonPlugins/PI_<plugin2>.py
Note that XPPython3 Custom Scenery plugins are loaded with Global plugins, before the loading of non-python Custom Scenery plugins.
If you reload X-Plane Scenery, loaded Scenery plugins are DISABLED, STOPPED, and then they are STARTED, ENABLED.