Alternate multiplayer environment
This article is a stub. You can help the wiki by expanding it. |
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 |
Contributor(s) |
|
Status | RFC as of 02/2016 |
Objective
Motivation
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]
Ideas
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]
Gallery
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]
Status
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 http://www.users.on.net/~denis.sjostrom/BlackBox.zip 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 "http://127.0.0.1:1392" 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>
Testing
Background
Note To learn more about the limitations of the existing FlightGear multiplayer system, please refer to Distributed Interactive Simulation |
Multiplayer Protocol
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 https://gitorious.org/fg/flightgear?p=fg:flightgear.git;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: https://gitorious.org/fg/flightgear?p=fg:flightgear.git;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. |
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. |
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] And there's more stuff to be found: [3] |
These are probably the most relevant responses:
|
XDR
Features
Authentication
Publish/Subscribe
- Publish–subscribe pattern
- https://strongloop.com/strongblog/introducing-strongloops-unopinionated-pubsub/
- http://faye.jcoglan.com/node.html
Persistence
Server-side Heuristics
Script-able
Multi-Crew
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.— Hooray (Dec 29th, 2015). Re: Global Feature Suggestion for FlightGear: Cockpit Sharin.
(powered by Instant-Cquotes) |
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.— Hooray (Dec 29th, 2015). Re: Global Feature Suggestion for FlightGear: Cockpit Sharin.
(powered by Instant-Cquotes) |
Roadmap
Development
HLA
Prototoype
Intro
Code
Note This assumes that you have nodejs installed (sudo apt-get install nodejs on Ubuntu)
|
Testing
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,127.0.0.1,1393 --multiplay=in,10,127.0.0.1,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 }, space: { position: [ -2654750.3914057035, -4255606.772294729, 3926698.3671609065 ], orientation: [ -2.327756881713867, -0.2209641933441162, -0.6654425859451294 ], linearVelocity: [ 7.242040283017559e-7, 1.0121321025735597e-7, -0.0000011992135569016682 ], angularVelocity: [ 4.591711189050329e-8, -3.363935263678286e-7, -7.22820026055615e-10 ], linearAcceleration: [ 0, 0, 0 ], angularAcceleration: [ 0, 0, 0 ] }, properties: { '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 } }
Related
Multiplayer
- ↑ https://forum.flightgear.org/viewtopic.php?p=276911#p276911
- ↑ XrayHotel (Feb 17th, 2016). Re: Operation Red Flag (KSUU Crew).
- ↑ XrayHotel (Feb 17th, 2016). Re: Operation Red Flag (KSUU Crew).
- ↑ XrayHotel (Feb 17th, 2016). Re: Operation Red Flag (KSUU Crew).
- ↑ XrayHotel (Mar 24th, 2016). Re: Operation Red Flag (KSUU Crew).
- ↑ XrayHotel (Mar 23rd, 2016). Re: Operation Red Flag (KSUU Crew).
- ↑ XrayHotel (Feb 19th, 2016). Re: Operation Red Flag (KSUU Crew).
- ↑ XrayHotel (Feb 22nd, 2016). Re: Operation Red Flag (KSUU Crew).
- ↑ XrayHotel (Mar 27th, 2016). Re: Operation Red Flag (KSUU Crew).
- ↑ XrayHotel (Feb 29th, 2016). Re: Operation Red Flag (KSUU Crew).
- ↑ XrayHotel (Mar 9th, 2016). Re: Operation Red Flag (KSUU Crew).