Network programming @ Noppa | @ wiki - Updated: — Jussi Laakkonen 2012/12/01 12:59


Updates:

15.11.2012: Initial version
15.11.2012: Updated demostration times and dates + deadline
15.11.2012: Added missing chatting implementation specification
16.11.2012: Updated the example code package (moved library flag as last parameter in Makefile) + note about this.
16.11.2012: Added the academic honesty contract. Updated the disconnection/crash detection with lost message handling.
20.11.2012: Updated the time reservation link and subject line.

Home Examination: Multiplayer deathmatch game (DEADLINE 3.12 @ 9:00)

Idea is to design and implement a protocol for a real time multiplayer deathmatch game. The code for single-player version including the UI (done with ncurses-library) is available as basis. The game implementation is done with UDP, chat (and server notifications) with TCP and map transfers with TCP. You'll have to implement a server and a client.

Ncurses HOWTO @ tldp.org

Example code

  • Build with make
  • Run with ./game
  • A note about library usage; here we need ncurses library so -lncurses -library flag is needed. In Ubuntu (not in Debian) it seems to have significance at what position this library flag is; it works if it is as last parameter on the line.

Use the same UI as in the example. Show only 5 last lines of chat/notifications. Remember that this is played in terminal and the ncurses will wrap the UI if there is not enough rows/columns on the current terminal. Therefore, do not use huge maps.

Both IPv4 and IPv6 must be supported. Do not use threads or fork(). All code must be your own and as this is the final exam of the course you should not show the code to others.

Description

You'll have to implement a client and a server. Server runs one game at a time and serves the amount of players the current map can handle at maximum (from 2 to 6 players). The game is played on a map selected by the server, the map rotation list should be stored into mapcycle.txt that contains only the map names that are to be loaded in order.

When a client joins to the server the server checks if there is space left on the current map. If a slot is open server replies to client with:

  • map id (id = 0 is the default map that can be hardcoded)
  • amount of players, the id assigned to this player (from 1 to player count)
  • the health amount assigned to each player (server startup parameter).

Or if there is no space left an error message is sent.

If a client does not have the map with the id reported by the server it has to request the map from the server. The server stores the maps in serverdata folder and client stores the downloaded maps in clientdata folder. Each map is identified with an id formed from your student number, e.g. with student id 0123456 the map names are 0123456.map 1123456.map … 9123456.map. Remember to verify the length of the transferred file.

After client has received the map or already has the map the client replies to client that it is ready. Then the server sends a confirmation message containing the starting position for the player and sends a notification to others that a new player has joined.

When the game is running the player can move in 4 directions (up,down,left,right) using arrow keys (as used in the example). One keypress creates one event that is sent to the server. If a player hits a wall or an obstacle the player loses one health point and when it reaches zero player dies (fragcount -1) and has to respawn. If a player (1) moves to a coordinate that already contains some another player (2) the player in that coordinate (2) dies and has to respawn. The player (1) continues to that new coordinate and receives one frag.

Since the server processes the messages in received order the player whose message was first received will kill the player located in the coordinates. So if both players, 1 and 2, are moving towards each other and player 1 arrives to (5,6) and the player 2 is in (6,6) it is a matter of reaction time, processing delays and network delays that decides who kills who. If both are still moving towards each other the one who first “hits” the other wins this battle.

After each movement event the client can receive 5 types of replies from server:

  • moving ok
  • hit a wall + updated health
  • suicide + updated fragcount
  • killed player with id X + updated fragcount
  • killed by player id X (with optional 3: add hit player X and was hit by player X).

Each message contains also the coordinates of the event occurred (the new coordinate). Each message has to identify what player the message concerns. Each movement ok event is sent to every other player as player X moved message. The kill and death messages are sent as server notifications to all.

If a player dies the server awaits for 3 seconds before sending the respawn message with the starting coordinates. During this time movement events from the dead client are discarded, chat messages are allowed. If there is a player (1) in the respawn spot of a respawning player (2) the player (1) will get stomped to death and player (2) gets a frag.

The game runs continuously until the frag limit is reached. There is 5 second delay between map changes. Before starting this waiting period the server sends the statistics to each player

  • The winner of the map
  • frag count of the top 3 players as separate server notification messages (incl. the winner).

During this time no actions from clients are allowed (no moves or chat).

After this the server picks the next map on the list and reports the new map id to every player. If a player does not have this map it has to be requested from the server.

When client wants to quit it can do it at any time. Server notifies other players about this event. The scores of the quitting player are set to 0.

If a client crashes the server will handle these in 2 ways:

  1. Ordered List ItemIf chatting is implemented the lost TCP connection will indicate that client has dropped and it can be removed
  2. Ordered List ItemThe server keeps track of events on each player and if there is no action (game: UDP or chat: TCP) received within 20 seconds the server kicks the player out.

If the server crashes the client can detect it:

  • Unordered List ItemOrdered List ItemLost TCP connection if chat was implemented
  • Unordered List ItemNo acknowledgement to movement messages is received within one second → resend and if no response still the client disconnects

Game initialization

Server can serve from 2 to 6 players depending on the map specification. First map is loaded at startup from mapcycle.txt list, which includes all maps in rotation. After each map change the server loads the next map on the list and reports this map id to clients who request it if the map is not found on client.

Server can either ACCEPT the player or REJECT (game full) the player. In ACCEPT message the server informs the player:

  • Map id - if client has no such map it must request that from the server
  • Player count on the server
  • Player id assigned to this player
  • Amount of health points for each player

When the map is transferred and client replies to be ready the server sends the respawn message with the starting coordinates to the client.

The map

Map has following parameters:

  • id = the map file name, e.g. map with id 0123456 is saved as 0123456.map
  • width
  • height
  • obstacle count
  • list of obstacle positions (x,y coordinates)
  • player count
  • player starting positions (e.g. each corner of the map for 4 player game)
  • fraglimit

Server always has the maps in “serverdata” folder and client maps are saved to “clientdata” folder.

Maps can be saved as regular text files (easy editing of maps)

The top left corner of the map is the 0,0 coordinate and they grow to right and down

Obstacles are single coordinates in the map, e.g. 2,10 that player cannot go through

The default map

Can be hardcoded to client and server. Does not need to be transferred.

  • width: 20
  • height: 20
  • obstacles 4, at: (1,1) (1,18 ) (18,1) (18,18)
  • player count: 4
  • start positions (in order from player id 1 to player count) (0,0) (0,19) (19,0) (19,19)
  • fraglimit: 20

Players

The players are identified with an user id starting from 1. If, e.g. player 3 leaves and a new player joins and this is the only available id on the server it will be assigned to the new player.

Each player is assigned a color on the UI as according to ncurses color definition. Show this color in the UI as it is done in the example. The colors:

  1. : COLOR_RED
  2. : COLOR_GREEN
  3. : COLOR_YELLOW
  4. : COLOR_BLUE
  5. : COLOR_MAGENTA
  6. : COLOR_CYAN

Game rounds

The game is continuous, clients can come and go, round (map) is changed when fraglimit is reached. Each kill is one point, i.e. a frag. Each suicide reduces the fragcount by one.

At each round start the server sends each player their start positions and awaits a READY reply from the clients. When each client has replied the server sends START message to clients indicating round start. Movement messages are discarded by the server when game is not STARTED. When a round is running players can join to game (if there are places left) and leave as they wish.

After the fraglimit is reached the server sends the game winner and the scores of the three best as separate notification messages. There is a 5 second delay between rounds to view scores – during this time chat messages are not accepted by the server

Gameplay

Each player starting from their start coordinates can move with arrow keys (KEY_UP, KEY_DOWN, KEY_LEFT and KEY_RIGHT) on the map. Moves are sent to server as keycodes and server replies with:

  • MOVE_OK + new coordinates – new coordinate was empty
  • HIT_WALL + new coordinates – there was a wall in new coordinate, player keeps in the previous coordinate and loses one healthpoint
  • SUICIDE + updated frag count – player loses one frag and is now killed, awaiting for RESPAWN message
  • KILL + playerid who was killed + updated frag count + new coordinates – player stepped on some other player who was in the new coordinates. The killed player receives KILLED + playerid who killed and 3 seconds after this event the same player gets RESPAWN + coordinates message telling the new start position and the killed player can continue the game.

Chatting implementation

Users can send max 128 character long messages to server. Server relays the messages to every player and after the message is received it is printed to screen. The messages have no nicknames but player id's are used. Use the implementation in the example to get the typed characters (feel free to implement a better one) and send the message when newline is detected (do not send this character) or enter is pressed or when the message limit is reached.

Server can send notifications (128 characters max) via chat connection that are different messages than the relayed ones:

  • Player A was killed by Player B
  • Player A committed suicide
  • Round winner A
  • Round ending score of top3 player A
  • Player A left
  • Player A was kicked

OPTIONAL

OPTIONAL 1 implement spectator-mode as you see fit.

OPTIONAL 2 implement a way to check if the maps are the same on both client and server.

OPTIONAL 3: utilize the health in “battles”, each hit reduces the health in same way as the wall hit and whose health first goes to 0, dies.

OPTIONAL 4: implement a way to detect duplicate movement messages.

OPTIONAL 5: implement a latency measurement of the connection and show it on the screen. Update latency every second (and update the screen).

Startup parameters

Client:

./game -h <server> -p <port>

Server:

./server -p <port>

Returning and demonstrating the assignment

  • Send the implementation as the other assignments: via SVN by given deadline.
    • If you have drawn additional state diagrams, MSC charts etc. for demonstration purposes please put them also into the same archive along implementation. (+2 points for full protocol documentation)
    • Follow the rules given on these wiki pages for other assignments
    • Late returns: x hours late equals to x amount of minus points
      • E.g. 3 hours late = -3 points
  • EACH PERSON WHO RETURNS THE HOME EXAMINATION HAS TO DEMONSTRATE THE APPLICATION PERSONALLY!
  • Time reserved for each demonstration: 45min (so prepare yourself and the material!).
    • READ, FILL and BRING a copy of academic honesty contract.
      • EVERYONE ON THE COURSE HAS TO RETURN THIS even though you are not participating in the home exam. 3 ways to return (deadline: ):
        1. During demonstration sessions
        2. Directly into assistant (room 2517, usually present from 10:00 to 18:00)
        3. Assistants post box in the post room (2414, usually open from 8:30 to 16:00)
  • If you are sick - don't come, another time can be arranged later.
  • Demonstration times (reserve via email from assistant: Subject line:CT30A5001_NP_TimeReservation), these times are given on FIFO order:
    • Tuesday 4.12.2012 @ 6218
      • 10:15 - 11:00 [ ]
      • 11:00 - 11:45 [ Sergey Vlasov ]
      • 11:45 - 12:30 [ Niko Reunanen ]
      • 13:15 - 14:00 [ ]
      • 14:15 - 15:00 [ ]
      • 15:00 - 15:45 [ ]
      • 15:45 - 16:30 [ Veli Kiiskinen ]
    • Wednesday 5.12.2012 @ 6218
      • 10:45 - 11:30 [ Tommi Kankaanranta ]
      • 11:30 - 12:15 [ Mihai Iusan ]
      • 13:15 - 14:00 [ Kalle Koponen ]
      • 14:15 - 15:00 [ Juri Pesonen ]
      • 15:00 - 15:45 [ Pablo Caro Martín ]
      • 15:45 - 16:30 [ Juan Antonio Aldea Armenteros ]
  • NOTE 1: To avoid unnecessary email flood, give also a secondary time that would fit for you. The list will be updated many times during a day (assistant will try to update it always when someone reserves a time for demonstration).
  • NOTE 2: There will be no exercises during the week 49, these personal demonstration sessions replace the exercises.

Grading of the home examination

There will be 30 points available from this assignment. Each feature gives given amount of points, partial points are possible.

Points for features:

  • 4: Game initialization (UDP)
  • 6: Map loading (from files) and transferring (TCP)
    • 2: Map loading from file (at least one own map has to be made)
    • 3: Transferring properly
    • 1: Basic map verification
  • 5: Chat and notification implementation
  • 10: The game implementation
    • 2: Movement
    • 4: Hit detection
    • 2: Frag counting, winner detection and round changes
    • 2: Player id handling
  • 5: Crash/disconnection detection on both + handling of lost messages.

Minus points will be given if the implementation is faulty (major errors in compile or doesn't compile at all, implementation crashes, no comments in the code or huge amounts of leaking memory).

Bonus points can be given if the implementation of some feature is excellent/ingenious. Just remember to point out these solutions. These bonus points can be used for replacing points if some features are not implemented. Each optional feature can be used to compensate 2 points missing from other features.

EXTRA

Additionally, 2 EXTRA points will be given for a good demonstration (can answer tricky questions, explain code well without scrolling around for 5 minutes, etc.).

Another 2 EXTRA points will be given for creating documentation of your protocol. Draw packet structures and MSC charts. Send (commit) them in a PDF document describing the protocol along the home examination (filename: protocol.pdf).