2-player online technique?

Blitz3D Forums/Blitz3D Beginners Area/2-player online technique?

AJirenius(Posted 2006) [#1]
Ok, Ive come to the point where I want to start with all netcoding for my little game.
Now the game is 2-player only and it will contain 2 units fighting each other in a 3d-environment. The units may emit at most 3 bullets each that needs to be synced with each other. Also there will be about 4-6 animated obstacles in the arena so overall there might be around 14 objects that will be synced and transferred over net.

Now to the question:

What is the best way to confront this. I guess having a central server is overkill and as this must be a fair online experience I would like not to have one of the 2 players to host as server. Is there a way that the both clients acts like servers and sync each other?

I know nothing about netcoding (as you already might have noticed).. Could someone out there help me to at least know where to look, libs? example code? even offering their help and team up with me in this game?


Snader(Posted 2006) [#2]
I once was doing this also but my little game stranded on the netcoding part.... so, good luck!


Buggy(Posted 2006) [#3]
I would think that there wouldn't be much unfairness if its only 2 players as each player has to send the same information to the other, regardless of who's the host.

But otherwise I guess you could set up two networks between the two players - one where the host is player 1 and one where the host is player 2 - but I think it would be overkill.


_PJ_(Posted 2006) [#4]
The way the commands are set in Blitz, and for ease of use by default, I would recommend setting it as server/client. Not necessarily overkill even if it's more of a peer-run game, but more of an organised approach. Besides even in a server/client setup, the data can still be transmitted as P2P.


semar(Posted 2006) [#5]
Here a couple of suggestions:

1) Use UDP (peer-to-peer).

2) don't send any position data, instead send which key has been pressed by the player. I mean, if the player_1 presses the "move forward" button, then send once the string "P1_MOVE_F" which means, "player 1 moves forward".

When the other client receives this message, it should then move the player_1 character forward.

When the player_1 releases the "move forward" button, then send another message, for example "P1_STOP" and the remote client will stop the player_1 character.

This way, a very few amount of data is exchanged between the clients.

3) if you have other objects that are not player controlled, but moved by A.I. using random values, then send the random seed once at the beginning of the main loop, and let the two clients move the objects using that seed. That way, you don't need to send each object position between each client, because each client updates each object position automatically, using the same generated random numbers, thus moving each object in the same way.

In fact, if you 'sync' two programs to use the same random seed, they generate the same 'pseudo' random sequence. Try it yourself.

I do this in my BomberLAN game (see my website in my sig) and it works like a charm. In the LAN mode, the monsters are moved with a random A.I. that use the same random seed on each client. This random seed is sent each time a new round begins.

Bare in mind that when you play in Internet you have to deal with lag time, that is, the time interval that a message from a client needs to reach the other client.

You may solve this problem introducing a slight pause before to react to a player action; I mean, when the player presses a key, first send the key info to the other client player, then wait a while before to effectively move the player on the first client. This way, when your model moves on your client, it should move also in - quite the - same moment on the other client.

You have to adjust the pause accordingly with the lag between the clients.

In other words, if the average lag time between two clients is, say, 200 ms, then the pause you may introduce should be of 200/2 = 100 ms.

Obviously, you may NOT use the delay command to freeze the program execution; instead, you have to build up a sort of 'command booking list' which is a list of "commands" to be performed after a defined pause.

Say you press "Fire" on your client. What may happen is:

--> first, the "P1_FIRE" message is sent to the other client

--> the "FIRE" command is put in a new element of the commands type collection.

The commands type collection may contain two fields: the command to be performed as string, and an integer field called pause, which represents the amount of ms to wait before to perform that command. Set the pause to the lag you want to introduce (for example, 100)

--> in your main loop, check all the elements in the command type collection, and update the field "pause" at each loop.When a pause has expired, then perform the related command - in this example, after 100 ms your local player will fire, and if you have a good timing, your player will fire in the same moment also on the remote client, which should have received and performed the same command after the lag time, which is the same pause you used.

Don't forget to delete a command from the collection list, once it has been performed!

An advanced timing can be obtained by checking the lag time at fixed intervals, and updating the pause to be introduced accordingly with the lag variations.

There are also more sophisticated techniques about this topic; for example, you may "preview" where an entity should be, and position it accordingly. You may search this forum or google to gain more infos about.

Hope it helps,
Sergio.