Due date: Wednesday, March 2nd, 2016 at 11:59pm
You will take a game with a traditional client-server architecture and create a working "cloud" version. In the cloud, a server will do the heavy-weight game computations, sending the game screen frame by frame as a sort of "video" to the client. The thin client ("thin" because it does not do game engine computations) receives and displays the game-video. The client also captures player input (keystrokes and mouse) and sends it to the server for processing.
Before undertaking your cloud-game implementation, work through the Saucer Shoot tutorial, making a simple game using Dragonfly. The tutorial helps better understand a game engine by developing a game from a game programmer's perspective, and familiarizes you with some of the knowledge needed for extending Dragonfly to a cloud-based system. Your new game will be a direct port of Saucer Shoot, only to the cloud.
The server starts up the game engine and gets ready for a client to connect by waiting on a well-known port. Once the client connects, the server does all the game computations - keeping track of objects, determining object collisions and even rendering frames on the screen. However, unlike in a traditional game, there is no player viewing the game and providing input where the game is running. Instead, the server "scrapes" the screen every frame it renders, sending the frames down the network socket to the client. Player input, which usually arrives by keyboard and mouse on the computer where the game is running, arrives instead by the network socket, sent from the thin client. All input received over the socket is applied to the game as if they player were at the keyboard and mouse of the server.
The server only has to handle one client for one game. When the one game ends, the server closes the network connection and then exits. Subsequent games would restart the server (and client).
The client starts up and immediately connects to the server using the hostname provided by the player and the well-known port. Once connected, the client receives input over the network socket in the form of the game frames to be displayed, displaying them one at a time on the screen. The client also captures keyboard and mouse input from the player, sending all to the server.
When the game is over and the network connection closes, the client exits.
You will do the tutorial first, as this will help set up your Dragonfly development environment and understand the relationship between the game you are porting and the Dragonfly game engine. Once done with the tutorial, you can begin your design and implementation. Your client and server must use the pre-compiled Dragonfly game engine, obtained from the Dragonfly Web Page.
You will work alone for this project. While you can discuss the project with other students and even help each other debug code, you must write all code yourself.
You will need to include a Makefile that allows your program to be built and a README.txt explaining how to run your game system. See Hand In for details.
There are many ways to design and implement the functionality necessary for this project. However, a strong suggestion is to adopt/use two main elements from Dragonfly: 1) Managers and Events applied to networking, and 2) SFML.
In Dragonfly, major game engine functionality is done by individual managers (e.g., the WorldManager that handles the game world state, and the GraphicsManager that handles game graphics). These managers all inherit from the base Manager class and implement the singleton pattern (the latter limits the engine to one instance of the class and also provides global access to the manager).
Managers communicate information to interested Objects via Events (e.g., the EventStep that occurs once each game loop, and the EventKeyboard that occurs each time there is keyboard input). These events all inherit from the base Event class, providing additional attributes and methods of access, as appropriate for the event type.
You should next design, implement and test classes in support of Dragonfly networking. Refer to the online document Dragonfly Networking for details.
Graphics in Dragonfly
are managed by the
using the Simple and Fast
Multimedia Library (SFML). The window running on the server
(running the game) can be "scraped" as an image. This image can then
be sent from the server to the client, where the client, in turn
displays the image. To do this, the SFML window
sf::RenderWindow) can be obtained from the GraphicsManager
getWindow()) and the window captured as an image
sf::Image). The image can then be sent to the thin
client. The client receives the network data, then draws the image on
its window as a sprite (
For the cloud server, the "scraping" should be done once every game frame, about 30 frames/second. This most easily done from a game object each step event.
On the thin client, input is captured normally using the InputManager. This is most easily done by having a game object register for input events, sending any input to the cloud server.
Properly implemented, your cloud server and thin client can run most any game supported by Dragonfly with few modifications. For this project, however, you must demonstrate support for Saucer Shoot from the tutorial. A normal, full-featured single player version of Saucer Shoot must work, including GameStart and GameOver screens. Note, however, that sound (sound effects and music) does not need to be supported.
Suggestions on the server and client tasks, and breakdown, are as follows:
SERVER (main.cpp) Start GameManager Start NetworkManager Load game resources Start Host Run game Cleanup and exit HOST (a game object) Register for step event Register for network event Wait for client to connect Each step event Scrape screen Send to client If network input Generate network event Each network event Apply network input to game CLIENT (main.cpp) Start GameManager Start NetworkManager Start Player Connect to server Cleanup and exit PLAYER (a game object) Register for network event Register for step event Each step event Check network input If network input Generate network event Each network event Receive data Draw frame on screen Each input event Send input to server
Since TCP is a stream-oriented protocol, the client can receive part of a frame even though the server sends only complete frames. It may be easier to only display full sized frames by not taking data from the network socket until an entire frame is available. Note, if the client only plays one frame per step event, this will result in a client falling behind in the visual representation, which to the player will feel like lag. To avoid this, the client may want to read and display all complete frames in a buffer that are available.
Sockets are by default blocking, meaning if a process reads from
them and there is no data available, the process blocks until there is
data. Non-blocking behavior can be achieved with the MSG_DONTWAIT
flag for a
By default, a
recv() call that retrieves data from a
socket removes it from the OS buffer such that subsequent reads do not
get the same data. The
MSG_PEEK can be used to retrieve
the data but leave it in the buffer for subsequent reads.
ioctl() call can be used to see the number of
bytes available in a socket before reading using the FIONREAD
parameter as the second argument (e.g.,
After you have successfully implemented (and tested!) your Cloud Saucer Shoot, you then design experiments to measure: 1) the network data rate from server to client and 2) the network data rate from client to server.
Make sure to consider in-game aspects, such as data rate over time and gameplay during measurements, since the amount of network traffic will depend upon the player actions (e.g., frantic moving and shooting).
To measure the network data rates, consider instrumenting your code to write data out to a logfile for each packet sent/received. Analysis would then provide information on packet sizes, packet rates and bitrates. Provide at least one graph of network bitrate (e.g., Kb/s) over time.
The analysis must also compare the measured data rates you record and analyze with published (from peer-reviewed, scientific literature) data for at least one other cloud-game system. The comparison should include brief details on the other experiments (noting particularly important differences) and interpretation of similarities and differences. All sources must be cited with full citation information.
When your experiments are complete, you must turn in a brief (1-2 page) write-up with the following sections:
You must hand in the following:
Include your experiment writeup in a clearly labeled file. Format must be pdf.
Please stay tuned for information on submitting your completed project.
A general rubric follows:
100-90. The game system meets all specified requirements. Both client and server are robust in the face of possible errors, such as being unable to connect to the network or network errors in flight (TCP loss or broken connections). Game plays flawlessly with no visual glitches or input problems. All code builds and runs cleanly without errors or warnings. README.txt has sufficient details to easily compile and run programs. Experimental writeup has the required sections, with each clearly written and the results clearly depicted.
89-80. The game system meets most of the specified requirements. Both client and server have solid communication, but may have occasional problems due to the network or other system conditions. The game plays well and is definitely playable, but may have a few visual glitches. All code builds cleanly and runs. The README.txt has sufficient details to compile and run the programs. Experimental writeup has the required sections, with details on the methods used and informative results.
79-70. The game system meets some of the specified requirements. Both client and server can connect and communicate, but may have limited connection abilities. The game can be played, but may feel laggy or have considerable visual glitches. Code builds and runs but may have warnings. The README.txt may be missing some details on how to run the programs. Experiments are incomplete and/or the writeup does not provide clarity on the methods or results.
69-60. The game system meets some of the specified requirements. Both client and server can connect but communication is limited. The game may start but is only somewhat playable, with input difficulties and visual glitches, and/or terminates prematurely. Code builds and runs but may have warnings. The README.txt may be missing some details on how to run the programs. Experiments are incomplete and the writeup does not provide clarity on the methods or results.
59-0. The game system does not meet the specified requirements. Both client and server can be started but may fail to connect or stay connected. The game may start but is not displayed at the client and/or the client does not get input back to the server. Code may build, but has warnings or may not even compile. The README.txt may be missing some details on how to run the programs. Experiments are incomplete with a minimal writeup.
Send all questions to the TA mailing list (cs4513-staff at cs.wpi.edu).