Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SFML Game Development.pdf
Скачиваний:
209
Добавлен:
28.03.2016
Размер:
4.19 Mб
Скачать

Company Atop the Clouds – Co-op Multiplayer

Playing multiplayer games

We've seen multiplayer games since computer games emerged—decades ago. We are used to calling friends and family to play games with us, sometimes in a

co-operative mode with common goals and other times for a competitive experience. The point is that playing with someone else is usually lots of fun!

There was a time when the Internet barely existed, or simply put, people's connections were too slow to actually have a good online experience. By then, it was very usual for games to have a local multiplayer mode. This allowed a big trend for split screen and other types of local multiplayer gameplay. Local Area Network (LAN) multiplayer was also implemented as a way to make the experience more cooperative to players, and as a result, you could actually cooperate or fight with your friends over a cable or wireless network. Unfortunately, as time passed and the Internet became more powerful, the local multiplayer modes became less and less used, and actual online multiplayer modes started to be the dish of the day. Either mode is not extinguished or anything close to that, but the game market seems to mark a tendency for online games.

For the purpose of this book, and to cover the networking field of programming, we will be not be focusing on local modes, but rather will implement a fullynetworked concept. However, fear not! We will show you a concept that game developers use a lot these days which allows you to actually have local co-op on top of a networked architecture!

Interacting with sockets

First of all, in order to go deeper in to network programming, we need to understand how computers communicate with each other. This is the technological base that everyone should know before trying to do anything with networking.

This topic is not simple by itself, but it can be approached more easily without the need to understand the deeper concepts, with the help of SFML's socket classes.

A socket is essentially a gateway for data. You can visualize it as a link between two applications. These applications are virtual, in the sense, they only matter in the network, but are not necessarily different application processes, because you can use sockets to connect an application to itself, as we do in this chapter. These sockets are the base of all networked programs; therefore, they are extremely important. As sockets are a rather complicated concept, SFML provides classes to manage them.

There are the following two main ways of communicating between multiple machines:

[ 236 ]

www.it-ebooks.info

Chapter 10

TCP

Transmission Control Protocol (TCP) is a network convention for transferring data between computers. This means that any operating system or platform that is connected to the Internet and therefore uses the Internet Protocol (IP), which TCP is

built on top of, is able to communicate in a uniform way. This is why in a networked application, we don't care who we are "talking" to, as long as the remote peer can "speak" TCP/IP, communication is possible.

For example, when you use your Internet browser, some websites will be hosted in Linux machines while others will be in Windows. Because they all use TCP/IP, it is not relevant what the operating system is, the website will be transferred to our browser and we will be able to visualize it just the same.

SFML provides two cross-platform classes for using TCP sockets: sf::TcpSocket and sf::TcpListener, which are exactly what we will use to achieve an online gameplay in this chapter. The sf::TcpSocket class initiates TCP connections, while the sf::TcpListener class listens on a certain port for an incoming connection.

Please note that TCP/IP is a high-level protocol in your operating system. When you use it, many things are being managed by the OS, which takes some weight out of your back.

The TCP protocol comes with the following features by default:

Packet ordering: It will ensure packet ordering so you can assume that your data will arrive to the destination in the same order you sent it.

Packet restructuring: It also provides packet restructuring facilities, completely built in. This means that if a packet is too

big, it will be split into smaller ones to make the network transfer possible while still arriving at the destination in a seamless way.

Reliability: It is another strong aspect of this protocol. It will ensure every that packet gets to the destination, without

exceptions. If one packet fails to arrive, the protocol just stalls and is assumed to have lost its connection. However, before a packet is assumed to be impossible to transfer, it is re-sent many times in an attempt to eventually deliver it successfully.

[ 237 ]

www.it-ebooks.info

Company Atop the Clouds – Co-op Multiplayer

In order to exchange data between computers, this protocol demands that a connection or a tunnel is made first. This means that before sending or receiving data, both machines must "shake hands" and create a tunnel of information between them. This is done when one of them enters a listening state on a specific port, using sf::TcpListener, and the other uses sf::TcpSocket to connect to that port. Once that connection is successfully established, data is free to roam!

A network port is an integer number, normally ranging from 0 to

65535, which defines a "gateway" in your network where data and connections can pass through to your application's sockets. You are free to pick what port(s) your game will use for communication as long as you do the following:

Be careful not to pick reserved ports by your operating system.

Avoid picking ports that are commonly used by other programs, which will cause a conflict. For example, port 80 is used very often by web servers, remote desktop apps, and others. As a general rule, avoid using ports below 1024.

Make sure both the client and the server know the same port so communication can happen.

Besides the obligation to establish a connection in order to communicate, this protocol offers advantages such as, ordered arrival of data and reliable data sending.

The first means that the order in which you send your bytes to the remote peer matters because they will get there in the same order! The latter means that the data is guaranteed to arrive at the destination. This is very good for many uses, even essential, but unfortunately, it adds an extra overhead to the network performance that some real-time games cannot cope with. Imagine you send packet A, B, and C, in order. Let's say your Internet connection isn't in its best shape and packet B keeps getting lost before arriving at the remote peer. This means that A will get to the destination, but B and C won't until B is sent successfully.

That said, we can conclude that this protocol is very adequate for file transfers and other reliable data transfers, as well as for smaller games which are less hungry for network performance. But it may be too slow for some real-time action games, which have higher speed requirements.

UDP

User Datagram Protocol (UDP) is another often used tool for network programming. Communicating data to another computer means simply pushing an array of bytes to the network, so it is very similar to TCP/IP in this matter; however, UDP has a very different set of rules.

[ 238 ]

www.it-ebooks.info

Chapter 10

The first important thing about this protocol is to know that it is connectionless. You can't establish a tunnel of reliable data. You just take your data and send it somewhere and it either gets there or not, and you are not notified of it.

This may seem strange at first. You may think "Why would I want to send data that may not even get there?" and it is normal to be suspicious about the utility of such a network protocol at first, but you'll understand how powerful it can become if made right.

The strong aspect about this protocol is that data is sent fast and there is no overhead on ensuring packet ordering or arrival. So, people usually implement a custom protocol on top of UDP that allows sending some data reliably, by sending data continuously until a confirmation of arrival is received, while other data is sent unreliably.

Another important key difference of UDP and TCP is that UDP will not split a packet into smaller parts when it exceeds the maximum limit of data size; you have to take care of that manually. While in TCP you can neglect such things, in UDP, it's important to keep packets small and efficient.

To use such sockets, SFML provides sf::UdpSocket. You just need to create an object of this type, bind to a port with the sf::UdpSocket::bind() function, and then either send data through it or check if anything was received using the

sf::UdpSocket::send() and sf::UdpSocket::receive() functions respectively.

We won't be covering UDP sockets in the chapter, but the SFML documentation and tutorials on www.sfml-dev.org should provide what you need in order to understand them in detail.

Socket selectors

Another facility that SFML provides is the sf::SocketSelector class. This one is not used in the book's game, but it is very useful and will make your life easier if you choose to use it.

This class will act as an observer for your sockets. It will hold pointers to every socket you choose to register in it. Then, you may simply call

sf::SocketSelector::wait() and it will return when one or more of the sockets receive some data. Once this happens, you handle the data somehow and call the function again. This will ensure you always are notified of packets and handle them in a simple and centralized manner.

You can call sf::SocketSelector::add() for any type of socket and listener: sf::TcpListener, sf::TcpSocket, or sf::UdpSocket.

[ 239 ]

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]