Page 1 of 3

Multiplayer: Dog-Fight and MMOPG

Posted: Mon Jan 03, 2005 12:54 pm
by atze
folks,
i have some thoughts on networking oolite i'd like to share.
let me start with a simple list of how to get to that goal:

Server for simple dogfight:
- awakes (or spawns a thread) when first client enters a new system
- controls one complete system (not a galaxy) per thread
- receives events from client
- moves all entities (ships, asteroids...) and checks for collisions/hits
- sends positions and velocities of visible entities to clients (may differ per client)

Client for simple dogfight:
- enters/connects server by hyperjump
- sends data about player/ship/cargo (cheat possible!)
- sends player movements (events)
- executes events localy (hoping the server agrees)
- receives server corrected data (avoid cheats and de-syncs) of pos. and vel. and adjusts local entities to match server data.

the dogfight-server would be a version of the current client without the graphical stuff. that would involve splitting the Entity-classes in two: one to maintain the physics (position, velocity...) and one for the gui (drawing the ships, asteroids...). the server could then sit there and wait for players. if a player wants to enter a system the server spawns a new thread/port for that system (like apache does) and redirects the client to the new port. other players entering the same system just get redirected to the running port.
the server then collects the events from the clients to move the players ships and all other entities in the system. the new positions and velocities are sent back async to the client. each client gets just the data of entities that are visible to it and not everything in the whole system to reduce traffic and avoid cheating (like maphack in diabloII). the client now adjusts it's local entities to match the servers. to avoid hangs on slow connections the client might just project a course of it's local entities on the latest data and adjust to the server's when the next packet arrives.
udp would be best for this but it needs holes in firewalls. tcp is slower (ack of every package) but goes easily through nat.

for a first proof of concept it might be possible to just extend the current client to act as a server for one system. in this case the player opening the server would not be able to hyperjump, as this would let the system collapse. or the server-output would just act like an observer (ghost-view) without any possibility to play.


extending this ideas to a persistent galaxy:

Persistent Server (MMOPG)
- maintains player/ship/cargo database (cheat resistent)
- persistent universe and cargo-prices
- delivers galaxy and system-info to client

Persistent Client (MMOPG)
- needs login to server to resume game
- no local save-game possible.
- no local knowledge of galaxy/systems/prices...

this is the part i am most interested of. it would make oolite a frontend to any space-trading mmopg. it would allow the server to tell the client what the galaxy looks like, what the prices are and what ships and cargo exists.

this grips me most because i have a mmopg (currently offline) with more than 130.000 suns, up to 15 planets each, up to 7 moons each planet. and i have settlers building colonies on those planets, producing tons of different goods, buildings, vehicles, weapons, and spaceships.
those are the strategy-gamers. existing front-end: html
and i'm still searching for a frontend for the spacers, who won't build colonies but want to fly through the wast space and just trade and fight like in oolite but with real people.
those are the action-gamers. wanted front-end: oolite ;)

any thoughts?

Posted: Mon Jan 03, 2005 1:25 pm
by NoSleep
I like the idea of both concepts... one where you can can go head to head with other players in a dogfight (others are keen to try out their racing skills, too), and another more involved MMO(R!)PG.

I quite like the idea of Oolite interfacing with a game that already has planetside/strategy elements to add to the already open gameplay in deep space.

I would like to see a 'pure' Oolite experience online, too.

Posted: Mon Jan 03, 2005 1:57 pm
by jonnycuba
While a full Oolite Oonline would be the end of all social interaction for me in the 'real world'... 8) (my wife would just love that)!

The dogfight system is the perfect starting block on the road to a full realization. What would happen when your fragged? would you just be bumped off the server & have to re-witchspace into the server/system?

Posted: Mon Jan 03, 2005 2:30 pm
by Frd_Prefect
I think that an online version of an elite type game would be one of those things that would work very well or wouldn't work at all due to the nature of the game, although the dog fighting server sounds like a good idea.

There are various technical issues to be addressed first too, like streamlining the code so as little data as possible is needed to be transmitted across a network as possible, and also a suitable and reliable server to host a multiplayer client. Also as various ports of oolite come out, all would need to be compatible over the network, not a major issue, but it does require a certain amount of collabaration with other programmers who are working on various ports.

Still given all that it probably wouldn't be a major project to create an online version of oolite, but I would happily help to code one, however I think that is still some way off and for the moment I think improving the quality and features of the actual game is a bigger priority.

Posted: Tue Jan 04, 2005 7:27 am
by atze
Frd_Prefect wrote:
I think that an online version of an elite type game would be one of those things that would work very well or wouldn't work at all due to the nature of the game, although the dog fighting server sounds like a good idea.
so let's start with the dog-fight and i'll add the persistent part later.
Frd_Prefect wrote:
There are various technical issues to be addressed first too, like streamlining the code so as little data as possible is needed to be transmitted across a network as possible, and also a suitable and reliable server to host a multiplayer client.
sure. how do we do it? should i just dig into the code and extend it?
nah. the classes are far to big right now. somebody should split them in (at least!) two or exprot some code into categories before we inject networking code.
Frd_Prefect wrote:
Also as various ports of oolite come out, all would need to be compatible over the network, not a major issue, but it does require a certain amount of collabaration with other programmers who are working on various ports.
i have not seen a port by now so i am not able to comment on this. byte order will pose no problems.
maybe switch the code to jME and LWJGL? that's totaly portable - it's java.
Frd_Prefect wrote:
Still given all that it probably wouldn't be a major project to create an online version of oolite, but I would happily help to code one, however I think that is still some way off and for the moment I think improving the quality and features of the actual game is a bigger priority.
i'd call a dog-fight option a feature with a BIG priority ;)
and the quality is already fine.

Parametric changes

Posted: Tue Jan 04, 2005 10:45 am
by aegidian
Frd_Prefect wrote:
like streamlining the code so as little data as possible is needed to be transmitted across a network as possible
I'd favour only transmitting changes in the parametric data for existing entities.

This means that for a given entity rather than transmitting the x y and z position of the entity, you would instead transmit t - the time since the last game-'tick' and delta_x / t, delta_y / t, delta_z / t where delta_x is the change in x since the last game-'tick'. And only transmit those values whose rate of change have altered since the last game-'tick'.

This would apply to the 6DOF (position and rotation), velocity and speed, energy, and indeed any other information that needs to be transmitted from server to client. The client of course, need only transmit the data for the player entity.

This would mean that for the vast number of entities, once their creation has been noted, no further information would need to be transmitted.

Using parametric data would also mean that the client can extrapolate (guess) what an entity is doing when there is a lack of data from the server, although this would mean the occasional corrective jerk when that data is finally received.

Posted: Tue Jan 04, 2005 11:39 am
by Frd_Prefect
Hmm, as there seems to be a lot of interest in this, I might have a look at creating some quick code for this that can be better implemented later on by someone with more time :)

Re: Parametric changes

Posted: Thu Mar 09, 2006 1:45 am
by Odo987
aegidian wrote:
I'd favour only transmitting changes in the parametric data for existing entities.

This means that for a given entity rather than transmitting the x y and z position of the entity, you would instead transmit t - the time since the last game-'tick' and delta_x / t, delta_y / t, delta_z / t where delta_x is the change in x since the last game-'tick'. And only transmit those values whose rate of change have altered since the last game-'tick'.
Sorry for reawakening a thread that's been asleep for two years. But I thought I'd just add a warning. Several years ago I played a 2D space combat game over a null-modem cable between two computers. Can't remember the name of it for the life of me. But the problem was that it only transmitted differences. And due to data loss, rounding errors or other hiccups, the two sides would get progressively out of sync. The result was unplayable.

Thus while diffs are a very good idea, don't forget to have synchronisation frames now and then. Or send across a hash of the way the universe should look, and if the hash fails, resynch.

Posted: Thu Mar 09, 2006 10:13 am
by Cyberian Tiger
I wrote a 3D space game (in C of all languages) which allowed multiple players to fly around in the same space. I never really got as far as collision detection or weapons though :P

The main problem I had was bandwidth, because for every object which is either computer controlled or human controlled you need to transmit x,y,z,dx,dy,dz every few game ticks in order to keep the action smooth.

It's also a good idea to have a <game tick counter> on the server.

Anyway, back to bandwidth, assuming the source code uses doubles (8 bytes) for it's positions, (my game used floats and the action got a little shakey from time to time due to rounding errors).

Anyway, So that's 8 * 6 bytes per ship per packet, to EVERY player every couple of game ticks....

As soon as you get as high as say 16 ships, that's 768 bytes per packet, before you start counting any other state information such as firing weapons, etc.

Now you're sending 25 of these packets a second, that's 25 * 768 bytes, that's 20,000 bytes per second, (20Kb/s).

The basic problem is how to reduce the bandwidth used with more and more entities which arn't fixed or fixed velocity.

Obviously some information needs to be only sent once, (I suggest using a dual tcp/udp protocol for the game, that way one time information about state changes can be sent over the reliable transport, and transient information can be sent over an unreliable protocol.).

I used to play a space game called Eve Online many moons ago, they partially solved this by splitting space up into grid cells, And yes, this meant you could hide more or less invisible in an adjacent cell to the player, and then ambush them. It's not an easy problem to solve in a good way, though I suspect a variation on the grid cell approach (except that you can always see into adjacent cells) would work quite nicely.

The other way to do it parhaps is to calculate what's visible to the player and only send updates on this. However I suspect that currently there is too much that is visible (not only that this can be changed by altering the graphics settings to low detail). I suspect a network game would need to be played on the equivalent of low detail anyway.

Posted: Thu Mar 09, 2006 10:39 am
by winston
You don't need to send packets anywhere near that frequently. You only actually have to send a packet when something changes.

For ships, you send a current position and a vector. If no control inputs are made, the other client(s) can keep updating the ship's position because it knew it started at (x,y,z) and is on such and such a vector. Another packet doesn't need to be sent until the ship's vector actually changes. The receiving client just uses dead reckoning to put the other ships in the right place.

Of course, you want to periodically send an update of (x,y,z) anyway because networks aren't ideal (so there's always a chance that a vector update was in a packet that never made it), but once every half second or so is more than adequate (experimentation should give the answer). Using vectors and dead reckoning rather than 25 (x,y,z) updates per second also makes the game less sensitive to network jitter. (The only thing you can really assume about a LAN is there will be latency jitter and possible lost packets).

You would also probably add things like roll and pitch rates too, so instead of having to send 25 updates per second while a player is rolling, you just send a 'roll rate' packet, and only send new roll rate packets when the player's roll rate changes.

Oolite's netcode would likely be considerably simpler (in terms of coping with jitter and packet loss) than an FPS - unlike an FPS game, all the manoevres in Oolite are smooth. Players cannot instantaneously reverse direction like they can in an FPS - the ships can only roll/pitch/accelerate/decelerate at predetermined maximum rates which are fairly leisurely compared to the jerk reactions in an FPS.

For things that are happening out of the view of a client, for example, if 16 ships are in a given system, and 8 ships are involved in a battle and the other 8 ships are scattered all over the system, the 8 not involved in the battle need to be sent no data (and the battling ships don't need to be sent any data about the 8 scattered ships). The server can work out what each player can see and only send relevant information (for example, the 8 scattered ships may get a packet indicating a distant explosion that they can see, but this will be a small packet with type 'explosion' and some parameters (x,y,z location and strength, for example). If you had things like long range scanners, these don't need to be accurate to the centimeter - these can be updated relatively infrequently and they don't need to be double precision.

The server will have to fudge some things in the interests of anti-lag - measure the lag of each player, and make sure that if player A shot player B on his client, but player B was actually slightly ahead of that position due to lag, make a decision on whether to make the hit count or not (by determining what player A was likely to have seen).

Anyhow, Spooky and team seem to have volunteered to look at this sort of thing. We'll see if they can come up with something.

Posted: Fri Mar 10, 2006 1:44 pm
by JensAyton
A random note: for a cross-platform game, the combination of deltas and floats is dangerous because different hardware, different compilers and different optimisation settings will cause rounding behaviour to vary. Generally, it’s better to use a fixed-point encoding as the canonical format for sending over the wire and to sync the game’s internal float representations to. Fixed-point encodings are also easier to compress. (The idea here is to express values in a form that’s likely to be close to zero, e.g. offset from last value or from predicted value, then use Huffman coding or similar.)

Posted: Fri Mar 10, 2006 2:28 pm
by winston
Ahruman wrote:
A random note: for a cross-platform game, the combination of deltas and floats is dangerous because different hardware, different compilers and different optimisation settings will cause rounding behaviour to vary.
SDL does have a cross-platform communications library :-)

However, the most recent person who looks willing to tackle this was Spooky, who says he has a cross platform library that they developed for one of their games already (and since they have a mix of hardware including SGI MIPS stuff, I'd hope they are aware of this <g>)

Oh, and where I said LAN in the last post, I really meant WAN.

Posted: Sun Mar 12, 2006 1:05 pm
by Commander Gralen
Sounds like there really is work being put into Multiplayer Oolite!

I can't wait!

What about calling it "Project MultiSpace"
Or "Operation Cooperation"
Or something :lol:

Posted: Mon Mar 13, 2006 10:03 am
by Spooky
Sounds like there really is work being put into Multiplayer Oolite!
Yup, I'm afraid so :wink:

We were thinking simple for the name... MOolite (cows rule).
However, the most recent person who looks willing to tackle this was Spooky, who says he has a cross platform library that they developed for one of their games already (and since they have a mix of hardware including SGI MIPS stuff, I'd hope they are aware of this <g>)
Yup, that's me. We've been disecting for around a week so far (on and off, real world projects are eating up huge amounts of time at the moment. It being end of the financial year and first quarter). We haven't completely profiled the data requirements for the 'client' yet so to discuss bandwidth usage and transport mechanisms is purely conjecture. However, suffice to say if we can't get it less than 20K/s per client then I'll eat my own arse :lol:

As for being aware of cross platform 'inconsistancies'? It's the bane of our very existence...

I'm happy that this is sparking a good deal of interest but please remeber that this is a titanic undertaking. I don't want to give anyone false expectations, nor are we viewing this with rose-tinted TFTs :wink:

Posted: Mon Mar 13, 2006 10:12 am
by winston
I was thinking of the ultimate direction of a Moolite - obviously, start off simple (Oolite where you can see and interact with other players), and then add perhaps 'server OXP' expansions. Cooperative missions would be great. Competitive ones even better (where you have two teams doing a mission - you can have good vs bad, or even just a race to complete the objectives - the universe is the limit!)

But all that's a long way off. (If you have a berlios account, let me know what it is if you want to make a branch in the repo).