Alternate multiplayer environment

From FlightGear wiki
Jump to navigation Jump to search
This article is a stub. You can help the wiki by expanding it.
Alternate MP environment
Started in 02/2016
Description Persistent Multiplayer environment with a focus on combat, virtual airlines and ATC. Server code currently being prototyped in JavaScript using nodejs
  • XrayHotel [1](since 02/2016)
Status RFC as of 02/2016



XrayHotel has been musing about FlightGear development a lot lately, particularly the possiblities for military simulation (Anyone for a simulated Link16 tactical data network?). XrayHotel's background is C/C++, 3D geometry and assorted bits of linear algebra, computer graphics (OpenGL) and Javascript (Nasal seems pretty straightforward). [2]

The major thing XrayHotel is interested in right now, is enhancements to (or a replacement for) the MP server to support some sort of enjoyable abstract warfare. [3]


The basic idea is fairly simple (It's the simplest set of rules I can think of): load the NAV database, and track the status of each airfield (red, blue or empty.) The red team can spawn aircraft at a red airfield, and the blue team can spawn aircraft at a blue airfield. Landing a transport category aircraft at an empty airfield marks it with your team's colour. Dropping a bomb on an airfield marks it empty (so the other team can no longer spawn aircraft there.) My thinking is that the status of airfields would persist over a long period of time to allow for strategy - if nobody is online you can still strategically pilfer some territory. If you log in and find someone about to capture an airfield, you can squabble over it. If multiple people are online simultaneously it becomes a game of tactics. I'm curious to know what you guys think. Is this something worth implementing? What would be the most minimal way to implement it? What are some potential features to consider? (given that the key to getting anything actually written is to Keep It Simple.) [4]

Mongoose / Phi

the stack will run from any web server just fine, it's nearly all client side. The web server component just feeds files to the client, except for an ultra thin RPC mechanism that I'm using to pass decoded multiplayer state to the map code - there's literally one exported function "/blackbox/getMpState". To make the map work from mongoose all you'd have to do is write a piece of Javascript to query the property tree (via the established mongoose API) and massage the data into the format that the map expects, which is not complex. Each entity's information is stored in an object formatted roughly as follows (I've omitted a few fields that aren't relevant to the mapping code):

        header: {
            callsign: <string>,
            modelName: <string>,
        state: {
            position: [<x>, <y>, <z>],
            orientation: [<x>, <y>, <z>]

The map itself is rendered from ESRI shapefiles, which are parsed client side. I decided to use shapefiles because they're a defacto standard for geographic data and there are a ton of sources for them out there. The map is currently based on the natural earth dataset, which is nicely detailed without requiring huge files. Adding extra layers is easy. I'd love to see BlackBox integrated with mongoose/Phi - I love FlightGear and have wanted to give something back for ages. I'm working on cleaning up the code for release at the moment becase I think (hope) that it's reached the point of (minimal) utility - it now does this: (see the linked image) You can either run it standalone and observe aircraft on the MP network, or run it as a proxy and use it as a (very basic) in flight map. From there I'll start thinking about extra features, Since Richard has essentially sovled the problem that I originally set out to solve (custom MP server rules) I think I'll focus on mapping and tactical displays for the time being ... decoding the nav/airport database in javascript is going to be fun... [5]


Technology Stack

The GUI library I'm using is something of my own creation (a big pile of Javascript (15,000 lines) that sits on top of HTTP & HTML5.) [...] BlackBox, at it's core, is just a web server and web page.[6]


I've started on a from-scratch FlightGear multiplayer server that will (hopefully, eventually) allow us to model air warfare at a larger scale. At first I was thinking of a simple drop in replacement (something you'd be able to connect to directly with FlightGear) but at the moment I'm leaning in the direction of a SquawkBox (VatSim/IVAO) style solution, for ... umm ... reasons. You'd have to load a local client, connect to it with FlightGear and then the client would connect to the central server - it's more complex, but (IMO) worth the hassle. [7]

I've settled on the name "BlackBox" for what I'm working on. We need a new thread to coordinate future development efforts. For the time being I have plenty of stuff to go on with (lots of fairly generic FG to Node.js glue.) [8]

BlackBox can decode FlightGear multiplayer properties, so a script could be written to track who shot whom by reading the relevant properties - obviously this is a lot easier if different aircraft use properties in a uniform way (otherwise you need different code to deal with each kind of aircraft.) The good thing is that BlackBox is written in Javascript, which is very similar to Nasal - if you can code one, you can code the other. If anyone is interested in experimenting with writing scripts that listen to the multiplayer network, please feel free to email me (my email can be found in the BlackBox readme, or any source file.) I'm happy to explain how things work! [9]

BlackBox is coming along. I decided to string the various components together (been up all night coding) and make it actually do something, I can now spy on the MP network xD [10]

most of my time has been spent working on BlackBox - I posted a link a while back, but I think it got lost in a quickfire series of posts (not that it's of much interest to non programmers at the moment anyway.) I've been experimenting with maps [11]

I've got some code that can parse ESRI shapefiles, which is a standard format for geographic data. The advantage of using vector data to render a map rather than tiled images (the way Google Maps does) is that the result can be rotated, scaled andoomed without ever seeing pixels. It also means that the data can easily be projected in different ways (instead of being stuck with the usual mercator projection.) What features would everybody's ideal tactical map have? I'm aiming for another release of BlackBox in a few weeks, and for it to be useful to non programmers! |2= XrayHotel (Mar 9th, 2016). Re: Operation Red Flag (KSUU Crew). </ref>

I finally uploaded BlackBox, it can be found at It doesn't do much yet, just creates a web server on port 1392 which displays a list of the pilots currently flying on the public MP network. Once it is running browse to "" Note that it uses the same ports as FlightGear does, so both programs can't connecty to the FGMP network at the same time. </ref> XrayHotel (Mar 7th, 2016). Re: Operation Red Flag (KSUU Crew). <ref>


Cquote1.png I've configured BlackBox to use port 5000 by default, because the majority of FlightGear users will already have the appropriate firewall hole set up. The "-mp-remote <server-name>:<server-port>:<local-port>" option allows you to specify a different port.
— XrayHotel (Mar 27th, 2016). Re: Operation Red Flag (KSUU Crew).
(powered by Instant-Cquotes)


Note  To learn more about the limitations of the existing FlightGear multiplayer system, please refer to Distributed Interactive Simulation

Multiplayer Protocol

Cquote1.png You may also want to take a look at the fgms (server-side) code, there's some interpolation/extrapolation code involved. Also, you may find it easier to directly configure your tool as an "observer" or at least as a "relay", so that it can be easily "connected" to other fgms servers. The other option would obviously be directly modifying fgms itself.
— Hooray (Aug 6th, 2012). Re: FGjobs - Jobs & Airlines Service Tool.
(powered by Instant-Cquotes)
Cquote1.png You really need to take a look at the headers, i.e. the source code - it's all there, and not at all complicated.

The MP protocol is really simple and dumb, which is your advantage now ;-) The data you receive is just a plain C struct, with XDR-encoded values. The format depends on the message types.

All message types are listed in;a=blob;f=src/MultiPlayer/mpmessages.hxx Properties are never transmitted verbatim, they are using so called "property IDs" which are unique and specified here:;a=blob;f=src/MultiPlayer/multiplaymgr.cxx#l70

So whenever you have a property field, you need to do a lookup to see which property is referenced, using the integer ID.
— Hooray (Aug 7th, 2012). Re: FGjobs - Jobs & Airlines Service Tool.
(powered by Instant-Cquotes)
Cquote1.png To see how the position messages are decoded, just see: Geographic Coordinate Systems

Also, I don't mind providing additional help/support, as long as you use the wiki to document your findings, i.e. by adding to the multiplayer protocol page in the wiki, so that others can also use that information.

I'd also suggest to take a look at the fgms side of things (i.e. the server), let me know if you need help understanding the C++ source code.
— Hooray (Aug 7th, 2012). Re: FGjobs - Jobs & Airlines Service Tool.
(powered by Instant-Cquotes)
Cquote1.png I have myself written rather detailed responses on exactly this topic a number of times.

Most of which can be found easily using keywords like "AI", "MULTIPLAYER", "FGMS", "FEED", "TRAFFIC" etc. For example, you could do a search for XDR (which is only used in the MP component): [1] This is a link to the FlightGear forum. And there's more stuff to be found:

[2] This is a link to the FlightGear forum.

[3] This is a link to the FlightGear forum.
— Hooray (Apr 20th, 2012). Re: More than one plane.
(powered by Instant-Cquotes)
Cquote1.png These are probably the most relevant responses:

[4] This is a link to the FlightGear forum.

[5] This is a link to the FlightGear forum.

[6] This is a link to the FlightGear forum.

[7] This is a link to the FlightGear forum.

Most of these pointers could (and should) probably be directly added to the wiki, as a reference for people who are doing similar things.
— Hooray (Apr 20th, 2012). Re: More than one plane.
(powered by Instant-Cquotes)


Cquote1.png TinyXDR itself is just an implementation of XDR that was created by the fgms developer - so it's not a full XDR implementation, it just implements what is required for the MP environment. Some of the code is replicated in sg/fg - but most of it is to be found in the fgms repository IIRC.
— Hooray (Nov 1st, 2013). Re: Magic Number.
(powered by Instant-Cquotes)





Server-side Heuristics



Cquote1.png AndersG implemented the whole system in scripting space - it would be possible to support the whole thing in a "global" fashion with a handful of minor additions, mainly based on looking at related subsystems, e.g. the "instant replay" (flight recorder) feature - and hooking that up to the multiplayer system by XDR-encoding the corresponding properties.

The main thing that aircraft developers would still have to do is to create a corresponding "flightrecorder" configuration for their aircraft/cockpit to encode the transmission/update semantics accordingly.

This could be handled by using XML attributes which are parsed by C++ code to automatically register the corresponding XDR helpers.
Cquote1.png under the hood, it is mainly about formaliing state management - which is overlapping with the way the flight recorder has to work, but also the MP protocol.

To some degree, you can model this analogous to entities (objects) with varying access specifiers (think public, protected and private state). private state would only ever be mutated by the locally running fgfs instance, while public/protected state would need to be channeled through a wrapper. You are right that the MP protocol is not sufficiently flexible for this in its current form, but the way AndersG has implemented the Dual Control system, it is piggy-backed on top of a transport mechanism using "string" properties, which are used as the transport mechanism for "I/O channels" on top of Nasal data. Like you say, HLA should make these things much easier. However, let's be honest: any aircraft that 1) supports multiplayer and 2) supports the flight recorder/replay feature and 3) distributed setups (like those at FSWeekend/LinuxTag), could /in theory/ also support "Dual Control" - certainly once/if the underlying systems are merged. The building blocks to make something like this possible are already there - the difficult stuff is convincing aircraft developers (like yourself) to adopt the corresponding systems (multiplayer and the flight recorder). So the whole "global" thing would be possible to pull off, but it should not be done using Nasal and the existing MP system. In the case of the shuttle, or even just complex airliners, formalizing data dependencies (switch states, annunicator states etc), that would be tons of work to do manually, given the plethora of switches and state indicators - which is why I am not convinced that this should be done manually, but done semi-automatically by annotating properties (and possibly even branches of properties in the tree). A while ago, I did experiment with replicating a Canvas-based PFD/ND display in another fgfs instance using the "brute force" approach - i.e. copying the whole property branch of the corresponding Canvas via telnet and patching it up via Nasal subsequently, the whole thing was not very elegant, but it actually worked. So I do understand how difficult this is, as well as the limitations of the current system - however, if aircraft/cockpit developers had a handful of property attributes to differentiate between different kinds of simulator state (local/remote vs. switches vs. displays), it would be possible to pull this off, pretty much by using the existing technology stack - the main limitation would be bandwidth then, i.e. you would have to be on the same LAN as the other instances, because it simply isn't feasible to replicate a PFD/ND using low-level calls (primitives) - instead, the whole instrument logic would need to be running in each fgfs instance, with only events being propagated accordingly - i.e .in a master/slave fashion. Admittedly, this is a restriction/challenge that even recent MFD cockpits are sharing with ODGauge-based cockpits (think wxradar, agradar, navdisplay etc), but that does not have to be the case necessarily, because we can already readily access all the internal state by looking at the property tree. But even if such a system were in place today, the way we are using Nasal and Canvas to create MFDs would need to change, i.e. to formalize data dependencies, and to move away from low-level primitives that are only understood by Nasal code - which is to say that new Canvas-based features (e.g. MFDs) would need to be themselves registered as Canvas::Element instances, implemented in scripting space, to ensure that a sane property-based interface is provided and used, without adding explicit Nasal dependencies all over the place: Canvas Development#Implementation So we would need both 1) an updated transport/IPC mechanism, and 2) a better way to encapsulate Canvas-based features in a way that properties are the primary I/O means, which is ironically how hard-coded instruments are working already - we are just violating the whole design concept via Nasal currently, which is also making it more difficult to augment/replace Nasal-based components that turn out to be performance-critical.

Given that HLA seems to become increasingly relevant, it does make sense for subsystems to primarily use the property tree for IPC, but to also stop having the assumption that other properties are directly accessible, because an instrument may be created/provided or running by a separate process/computer in a few years time, including Canvas-based MFDs.
Cquote1.png t isn't necessarily too hard to program - it's just a different way of programming, one where configuration of the state changes would be delegated to the aircraft developer - pretty much like the flight recorder subsystem.

In fact, the flight recorder subsystem is the best candidate for implementing "multi-pilot" functionality in a global/general fashion, without being specific to any particular aircraft - and it also is the most likely platform for implementing multi-instance state replication, i.e. setups like those commonly seen during FSWeekend/LinuxTag, where multiple computers running fgfs may be linked together to create a single immersive environment. Which basically means that your best chance of getting "global multi-pilot support" is implementing flight recorder support, i.e. as per $FG_ROOT/Docs/README.flightrecorder While that will not immediately get you this features, it is the most solid platform/framework we currently have in place to implement this feature, because it delegates state management to the corresponding aircraft developer.

At that point, you really only need to file feature requests to extend the flight recorder subsystem so that it can serialie properties to/from XDR types (which are already used by the multiplayer system), and a few more state change directives would be useful ("update-on-change", "update-on-write", "update-at-XX-hz" - which is touching on the HLA effort, but the flight recorder subsystem would remain the most suitable platform for implementing this feature in a generic fashion, so that aircraft developers would only need to update their flight recorder configuration file to configure which properties are relevant, as well as their mutability (i.e. state being read-only/writeable etc)
— Hooray (Feb 8th, 2016). Re: Global Feature.
(powered by Instant-Cquotes)




Cquote1.png My calculation is that, whatever the protocol, MP aircraft will be represented as a state vector and a slice of the property tree. An appropriate amount of abstraction should ensure a relatively painless transition.
— XrayHotel (Feb 22nd, 2016). Re: Operation Red Flag (KSUU Crew).
(powered by Instant-Cquotes)



Cquote1.png I sat down yesterday and wrote a decoder for the FlightGear MP protocol (using node.js). The good thing is that the MP protocol is very simple (and thus trivial to implement.) The bad thing is that the MP protocol is very simple (so we're going to run into limitations, fast.) This is part of the reason why I think a SquawkBox style solution is the way to go - it would allow for "out of band" messages that don't fit into the FG MP protocol. The code, runs in node.js:
— XrayHotel (Feb 19th, 2016). Re: Operation Red Flag (KSUU Crew).
(powered by Instant-Cquotes)


Note  This assumes that you have nodejs installed (sudo apt-get install nodejs on Ubuntu)


If you the fire up the above code in node.js and then tell FlightGear to send it some MP packets using the something like following command line: fgfs.exe --aircraft=f-14b --multiplay=out,10,,1393 --multiplay=in,10,,1394 --callsign=XH

you (should) see a dump of JSON formatted packets, like this:

    { callsign: 'XH',
      aircraft: 'Aircraft/f-14b/Models/f-14b.xml',
      time: { stamp: 2515.7916666714227, lag: 0.1 },
       { position: [ -2654750.3914057035, -4255606.772294729, 3926698.3671609065 ],
         orientation: [ -2.327756881713867, -0.2209641933441162, -0.6654425859451294 ],
          [ 7.242040283017559e-7,
            -0.0000011992135569016682 ],
          [ 4.591711189050329e-8,
            -7.22820026055615e-10 ],
         linearAcceleration: [ 0, 0, 0 ],
         angularAcceleration: [ 0, 0, 0 ] },
       { '100': 0,
         '101': 0,
         '102': 0,
         '103': -0,
         '104': 0,
         '105': 0,
         '106': 3.000059933810917e-8,
         '107': 0,
         '108': 'Disengaged',
         '110': 0,
         '111': 0.29411765933036804,
         '112': 0,
         '200': 0.19800160825252533,
         '201': 1,
         '210': 0.4948127567768097,
         '211': 1,
         '220': 0.49923089146614075,
         '221': 1,
         '230': 0,
         '231': 1,
         '240': 0,
         '241': 1,
         '300': 31.1284122467041,
         '301': 60.644805908203125,
         '302': 0,
         '310': 31.1284122467041,
         '311': 60.644805908203125,
         '312': 0,
         '1001': 0,
         '1002': 0,
         '1003': 0,
         '1004': 1.401298464324817e-45,
         '1005': 1.401298464324817e-45,
         '1006': false,
         '1101': 'nasa',
         '1200': '',
         '1201': 0,
         '1400': '',
         '1500': 1200,
         '1501': -9999,
         '1502': false,
         '1503': 1,
         '10001': '118500000',
         '10002': 'Hello',
         '10100': '',
         '10101': '0.0;0.0;8564;0;0.0;0;0.0;3;0.00;29;1;',
         '10102': '',
         '10200': 0.29411765933036804,
         '10201': 0,
         '10202': 0,
         '10203': 0,
         '10204': 0,
         '10205': 0,
         '10206': 0,
         '10208': 0,
         '10209': 0,
         '10210': 0.8180699944496155,
         '10211': 0.8180699944496155,
         '10300': 0,
         '10301': 0,
         '10302': 0,
         '10303': 0,
         '10304': 0,
         '10305': 0,
         '10306': 0,
         '10307': 0,
         '10308': 0,
         '10309': 0 } }

Cquote1.png If you take off and fly around you'll see various values changing. The "propertyTypeTable" variable (defined at the top of the decoder) enumerates the relationship between MP property numbers and their location in the property tree - I've noticed my setup spitting out a few properties with the id "48" (which is invalid>) at startup.

I'm going to write an MP protocol encoder tonight (maybe.)

One interesting idea I've had is to write some code to allow for server side AI objects - this would be a good way to add shared AI aircraft, SAM sites (if someone can provide the appropriate model) and server side missile tracking. Anyways, that's a long way off.
— XrayHotel (Feb 19th, 2016). Re: Operation Red Flag (KSUU Crew).
(powered by Instant-Cquotes)



  2. XrayHotel (Feb 17th, 2016). Re: Operation Red Flag (KSUU Crew).
  3. XrayHotel (Feb 17th, 2016). Re: Operation Red Flag (KSUU Crew).
  4. XrayHotel (Feb 17th, 2016). Re: Operation Red Flag (KSUU Crew).
  5. XrayHotel (Mar 24th, 2016). Re: Operation Red Flag (KSUU Crew).
  6. XrayHotel (Mar 23rd, 2016). Re: Operation Red Flag (KSUU Crew).
  7. XrayHotel (Feb 19th, 2016). Re: Operation Red Flag (KSUU Crew).
  8. XrayHotel (Feb 22nd, 2016). Re: Operation Red Flag (KSUU Crew).
  9. XrayHotel (Mar 27th, 2016). Re: Operation Red Flag (KSUU Crew).
  10. XrayHotel (Feb 29th, 2016). Re: Operation Red Flag (KSUU Crew).
  11. XrayHotel (Mar 9th, 2016). Re: Operation Red Flag (KSUU Crew).