Threads for peer to peer communication - multithreading

I am trying to make a multi-player network game. Each player is represented by a rectangle on the screen. I am using OpenGL for the graphics and also the user input (commands like MOVE-LEFT, MOVE-RIGHT etc ) will be handled by it (or GLUT or sumthing).
I have the following architecture for the game.
There are 4 players(nodes) in the game. Each player is sending and receiving data using UDP. Each player can send data to any other player.
Data is required to be sent by a player if there is any input from the corresponding user. (For example MOVE-LEFT command etc).
Whenever a player (say p1) receives any data from any other player(say p2) (like new position of the player p2 on the screen), the player p1 's screen should be updated immediately.
I am thinking on the following lines :
Create one thread for handling graphics.
Create 2 more threads , 1 each for receiving and sending data, using UDP.
Whenever the graphics thread gets input for 'myposition' from the user, it updates the shared global variable 'myposition'. The network-send thread, which is waiting on this variable, gets activated and tells every other player about its new position.
Similarly whenever 'position' updates are received from any other player 'i', the network-receive thread updates the global variable player[i].position. The graphics thread will now redraw the scene with the updated positions.
Is this design correct. If yes, How good is this design and how can i improve it

Network Game Programming is a monster of a topic, so it is hard to say "yes, this is how you design a network architecture". It is completely dependent on your game requirements. What sort of volume of packets do you plan on sending? Will there be a packet sent every frame that indicates Player A is holding the left key? Is this traffic confined to a LAN?
For something as simple as synchronizing movement between amongst 4 clients, putting send, receive, and rendering in separate threads seems like overkill. Perhaps as a starting point, you should begin with a more simple design and make the move to multithreading when you feel that your packets are not going out fast enough.
For example, you may wish to have a game loop like the following (all within the same thread):
while (running):
readUpdSocketForIncomingPackets();
updateGameObjects();
renderGameObjects();
sendPacketsToPeers();
At the start of each frame, you can read your udp socket for incoming packets and update positions (and whatever else you are sending to your peers), then draw. As game input is processed, packets are created and accumulated in a packet queue. Doing it this way, allows you to perform optimizations, such as cramming/merging multiple messages into one packet, removing duplicate messages (e.g. only send the latest position update), etc. So at the end of each game loop, the final queue of packets are processed and send to the peers.
But again, this is a big topic and I've glossing over a lot of details.
Take a look at gaffer's blog:
http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/
He's got some great articles that address some fundamentals of network game programming.

Related

Updating the game state in a multiplayer game

I am working on a multiplayer game. Each client have a character that moves in a shared environment.
I use socket.io to create rooms and peer.js to create a peer-to-peer connection between clients.
What I am trying to do is to enable each client to update the positions of the characters of the other players in his map.
For that, each client should have the state of the keyboard cursors (arrow keys) of the other players so that he can move their corresponding characters with a walking animation.
P2P: I am thinking of creating duplex streams between the clients so that each client will have the state of the keyboard cursors of the other players, so that he can move their characters with the appropriate animation...
SOCKETS: I can also pass the information via the server using sockets, but i will have to send an update of the cursors state 60 times per second since the game is on 60 fps, which makes a lot of socket messages. I am not sure this is the most efficient way to handle it
What is the most efficient way to keep everybody updated about the state of the other players ? Any suggestion will be appreciated. Thanks.
Actually your game is likely a little demo of a MMORPG game or something like CS/CSGO.
For such a game, we always have a loop in main process (work process) with a frequency like several frames a second(say 20 frame). In every frame, the client will process the packets received from others and the options form the pleyer.
If here is 20 frames, that means every fram can't be more than 50ms, so it will cause some delay if it's in WLAN and some packets drop happend.
If you want to use P2P to synchronized players action, here is a problem: when player number booms, the comlicated of the connection boos too. What's more, you need a reliable connection protocol, that means you need to know how to use something like QUIC or write a reliable UDP by yourself.
So I think the most effcient way may keep use C/S model insetead of P2P only if your game will use in LAN and there is quite a few players.

What is the most effective way to handle multiple objects independent from all players when making a game with sockets?

For example, let's say I have a random game in which I have 500 independent objects and 10 players.
Independent object is an object that moves in a specific direction per update regardless of what players do (there is no need for players to come into contact with these objects).
Now if a player is shooting (lets say) a bullet, it is easier because it belongs to a specific player therefore it's easier to avoid in game lag. Lets look at something simpler, though, for example a player try to update their position. The typical thing I would do on client & server side would be this :
client side : update the coords of the player + send a message to the server as socket X
server side : receives the message from socket X, updates the coords of the player on the server side +
sends a message with the coords of that same player to all other sockets
When you do the communication like this, everyone will receive the new coords of the player and there will be little to no lag. (It is also sufficient for objects like bullets, because they are created upon firing a player event)
How do you handle 500+ independent objects that move in random directions with random speed all across the map and update them for all players efficiently? (Be aware that their velocity and speed can be changed upon contact with a player). What I've tried so far:
1) Put all of the movement + collission logic on the server side &
notifying all clients with a setTimeout loop & io.emit -
Result : causes massive lag even when you have only 500+ objects and 4 connected players. All of the players receive the server's response way too slow
2) Put all of the movement + collission logic on the client side & notifying the server about every object' position-
Result : To be honest, couldn't encounter much lag, but I am not sure if this is the correct idea as every time an object moves, I am literally sending a message to the server from each client to update that same object (server is getting notified N[number of connected clients] amount of times about that same object). Handling this entirely on the client side is also a bad idea because when a player randomly switches tabs [goes inactive], no more javascript will be executed in that players' browser and this whole logic will break
I've also noticed that games like agar.io, slither.io, diep.io, etc, all of them do not really have hundreds of objects that move in various directions. In agar.io and slither you mainly have static objects (food) and players, in diep.io there are dynamical objects, but none of them move at very high speeds. How do people achieve this? Is there any smart way to achieve this with minimal lag?
Thanks in advance
Convert your user interactions to enumerated actions and forward those. Player A presses the left arrow which is interpreted by the client as "MOVE_LEFT" with possible additional attributes (how much, angle, whatever) as well as a timestamp indicating when this action took place from Player A's perspective.
The server receives this and validates it as a possible action and forwards it to all the clients.
Each client then interprets the action themselves and updates their own simulation with respect to Player A's action.
Don't send the entire game state to every client every tick, that's too bloated. The other side is to be able to handle late or missing actions. One way of doing that is rollback where you keep multiple sets of state and then keep the game simulation going until a missinterpretation (late/missing packet) is found. Revert to the "right" state and replay all the messages since in order to get state to correct. This is the idea behind GGPO.
I suggest also reading every article related to networking that Gaffer on Games goes into, especially What Every Programmer Needs To Know About Game Networking. They're very good articles.

Send data from server based on player position

I have 2D multiplayer browser game. Game contains snake-like players and world filled with grid of differently colored blocks.
Currently I send these data from server:
if new player spawn - data about all blocks and players to him and data about newly spawned player to others
if someone change his move - data about his trail, position and direction to everyone
if color of some blocks are changed - data about it to everyone
So I don't send redundant data but I send all data to everyone. Cheater with modified client could see everything! So I need send data to clients based on their viewport.
For snake-like players I will probably check min and max, X and Y of player.
If player A gets close to player B, server will send client A data about player B.
If player A get too far from player B server will remove player B from client A.
Server will send data about changing of player B only if player A is near.
Main question
But I'm not sure how I should send data about blocks. I'm afraid I will send too many redundant data.
When player spawn I will send him data about blocks near him. Also when color of blocks near him will be changed I will send him it.
If player will travel to left I will send him data about blocks in left. But how often I should do it? Should I send him new blocks every time he travel one block distance?
What If player decide to go to place where he already has been? Should I send him again redundant data? Or could I check if blocks there were changed. But how I can remember that player already has seen some blocks? I probably can't remember all blocks that player has seen (amount of blocks is too big). It would be bad for performance.
How can I protect my game against zoom cheaters and don't decrease performance?
So what you are trying to implement is sometimes called a network bubble. Every player gets data around him (like a bubble around him), but not all data. So you could define an amount of blocks around the player that get sent to him. For example send all blocks directly adjacent to his current block.
block1 - block2 - block3
block4 - player - block5
block6 - block7 - block8
For the question of how to remember blocks, you will need some kind of storage array on your client side (for example a hashmap), in which you store your blocks.
Your server then needs to provide a possibility to check if the clients block is still up-to-date. This can be done with a hash-function. Your server calculates a hash of the requested block, if data in the block changes, the hashvalue changes. The hashes of the server and the stored client blocks are compared and then blockdata is only sent when they dont match.

Linux CAN bus transmission timeout

Scenario
There is a Linux-powered device connected to a CAN bus. The device periodically transmits the CAN message. The nature of the data carried by this message is like measurement rather than command, i.e. only the most recent one is actually valid, and if some messages are lost that is not an issue as long as the latest one was received successfully.
Then the device in question is being disconnected from the CAN bus for some amount of time that is much longer than the interval between subsequent message transmissions. The device logic is still trying to transmit the messages, but since the bus is disconnected the CAN controller is unable to transmit any of them so the messages are being accumulated in the TX queue.
Some time later the CAN bus connection is restored, and all the accumulated messages are being kicked on the bus one by one.
Problem
When the CAN bus connection is restored, undefined amount of outdated messages will be transmitted from the TX queue.
While the CAN bus connection is still not available but TX queue is already full, transmission of some most recent messages (i.e. the only valid messages) will be discarded.
Once the CAN bus connection is restored, there would be short term traffic burst while the TX queue is being flushed. This can alter the Time Triggered Bus Scheduling if one is used (it is in my case).
Question
My application uses SocketCAN driver, so basically the question should be applied to SocketCAN, but other options are considered too if there are any.
I see two possible solutions: define a message transmission timeout (if a message was not transmitted during some predefined amount if time, it will be discarded automatically), or abort transmission of outdated messages manually (though I doubt it is possible at all with socket API).
Since the first option seems to be most real to me, the question is:
How does one define TX timeout for CAN interface under Linux?
Are there other options exist to solve the problems described above, aside from TX timeouts?
My solution for this problem was shutting down and bringing the device up again:
void
clear_device_queue
(void)
{
if (!queue_cleared)
{
const char
*dev = getenv("MOTOR_CAN_DEVICE");
char
cmd[1024];
sprintf(cmd, "sudo ip link set down %s", dev);
system(cmd);
usleep(500000);
sprintf(cmd, "sudo ip link set up %s", dev);
system(cmd);
queue_cleared = true;
}
}
I don't know the internals of SocketCAN, but I think the larger part of the problem should be solved on a more general, logical level.
Before, there is one aspect to clarify:
The question includes tag safety-critical...
If the CAN communication is not relevant to implement a safety function, you can pick any solution you find useful. There may be parts of the second alternative which are useful for you in this case too, but those are not mandatorx.
If the communication is, however used in a safety-relevant context, there must be a concept that takes into account the requirements imposed by IEC 61508 (safety of programmable electronic systems in general) and IEC 61784-x/62280 (safe communcation protocols).
Those standards usually lead to some protocol measures that come in handy with any embedded communication, but especially for the present problem:
Add a sequence counter to the protocol frames.
The receiver shall monitor that it the counter values it sees don't make larger "jumps" than allowed (e.g., if you allow to miss 2 frames along the way, max. counter increment may be +3. CAN bus may redouble a frame, so a counter increment of +0 must be tolerated, too.
The receiver must monitor that every received frame is followed by another within a timeout period. If your CAN connection is lost and recovered in the meantime, it depends if the interruption was longer or within the timeout.
Additionally, the receiver may monitor that a frame doesn't follow the preceding one too early, but if the frames include the right data, this usually isn't necessary.
[...] The nature of the data carried by this message is like measurement rather than command, i.e. only the most recent one is actually valid, and if some messages are lost that is not an issue as long as the latest one was received successfully.
Through CAN, you shall never communicate "commands" in the meaning that every one of them can trigger a change, like "toggle output state" or "increment set value by one unit" because you never know whether the frame reduplication hits you or not.
Besides, you shall never communicate "anything safety-relevant" through a single frame because any frame may be lost or broken by an error. Instead, "commands" shall be transferred (like measurements) as a stream of periodical frames with measurement or set value updates.
Now, in order to get the required availability out of the protocol design, the TX queue shouldn't be long. If you actually feel as you need that queue, it could be that the bus is overloaded, compared to the timing requirements it faces. From my point of view, the TX "queue" shouldn't be longer than one or two frames. Then, the problem of recovering the CAN connection is nearly fixed...

realtime midi input and synchronisation with audio

I have built a standalone app version of a project that until now was just a VST/audiounit. I am providing audio support via rtaudio.
I would like to add MIDI support using rtmidi but it's not clear to me how to synchronise the audio and MIDI parts.
In VST/audiounit land, I am used to MIDI events that have a timestamp indicating their offset in samples from the start of the audio block.
rtmidi provides a delta time in seconds since the previous event, but I am not sure how I should grab those events and how I can work out their time in relation to the current sample in the audio thread.
How do plugin hosts do this?
I can understand how events can be sample accurate on playback, but it's not clear how they could be sample accurate when using realtime input.
rtaudio gives me a callback function. I will run at a low block size (32 samples). I guess I will pass a pointer to an rtmidi instance as the userdata part of the callback and then call midiin->getMessage( &message ); inside the audio callback, but I am not sure if this is thread-sensible.
Many thanks for any tips you can give me
In your case, you don't need to worry about it. Your program should send the MIDI events to the plugin with a timestamp of zero as soon as they arrive. I think you have perhaps misunderstood the idea behind what it means to be "sample accurate".
As #Brad noted in his comment to your question, MIDI is indeed very slow. But that's only part of the problem... when you are working in a block-based environment, incoming MIDI events cannot be processed by the plugin until the start of a block. When computers were slower and block sizes of 512 (or god forbid, >1024) were common, this introduced a non-trivial amount of latency which results in the arrangement not sounding as "tight". Therefore sequencers came up with a clever way to get around this problem. Since the MIDI events are already known ahead of time, these events can be sent to the instrument one block early with an offset in sample frames. The plugin then receives these events at the start of the block, and knows not to start actually processing them until N samples have passed. This is what "sample accurate" means in sequencers.
However, if you are dealing with live input from a keyboard or some sort of other MIDI device, there is no way to "schedule" these events. In fact, by the time you receive them, the clock is already ticking! Therefore these events should just be sent to the plugin at the start of the very next block with an offset of 0. Sequencers such as Ableton Live, which allow a plugin to simultaneously receive both pre-sequenced and live events, simply send any live events with an offset of 0 frames.
Since you are using a very small block size, the worst-case scenario is a latency of .7ms, which isn't too bad at all. In the case of rtmidi, the timestamp does not represent an offset which you need to schedule around, but rather the time which the event was captured. But since you only intend to receive live events (you aren't writing a sequencer, are you?), you can simply pass any incoming MIDI to the plugin right away.

Resources