CS 341
Project 1
Xlib
Game Programming
Due Friday, Februrary, 14th, at 10:00 P.M.

Overview

Project 1 asks you to develop a simple game based on an event loop written in C, with Xlib as the base window system. Emphasis in the assignment is

  1. an attractive functional game interface,
  2. a well-tuned implementation that is both challenging and playable, and
  3. effective use of the events and graphics provided by Xlib.

Introduction

When programming a game it is normal to use programming techniques that allow the tightest possible control over what happens on the display and when it happens. The architecture appropriate for such programming is a low-level one, the event loop, which is a single-threaded flow of control that checks for an event, responds appropriately to it, returns to check for the following event, and so on. There are two types of event loop.

  1. Blocking. The function that gets an event blocks until an event is available.
  2. Non-blocking. The blocking function that gets an event is protected by a test to see if any event is available, allowing the program to change state even when the user provides no event. Non-blocking event loops are essential for interfaces that support animation.

Blocking event loops are paced by user actions; non-blocking event loops must be paced by some other method, usually a real-time clock.

Game programming is usually done assuming that program performance will not be degraded by other users of the computer on which the program runs, which will, unfortunately, not be true for you, at least when you program in the royal environment. (Please remember that I will run your submission on royal, so allow yourself time to port your submission, and to tune it, at a specific machine in Clapp 202, which you should specify in your readme.)

In addition to the event loop you will need a graphics model so that you can draw things to predictable places on the screen and get input from the mouse. Thus, the purpose of this assignment is to give you some implementation experience with three important concepts:

  1. the event loop,
  2. two dimensional graphics, and
  3. managing the sequence of things that occur in a user interface.

In doing this assignment I will give you a starting program that does simple mouse/keyboard interaction. This program is written in C, using the Xlib library, which implements a 2D graphics model similar to the one described in class. You are assumed to be able to familiarize yourself with C programming and I expect you to acquire information about Xlib functions you wish to use from documentation like the examples given below.

The overall process is as follow: you know roughly what you want to do on the screen, and look at functions with suggestive names until you find the right one.

Game Description

The game is played in a window, which can be moved around the screen, iconified and resized without influencing the progress of the game. When this happens, the game should stay the same size, so that making the window smaller makes some of the game invisible, and making the window bigger leaves a blank space in the window.

Drawn in the window is a crate of bottles, each of which contains a jinnee. A jinnee is a magic being, usually evil, who is able to operate without regard for the normal laws of physics. A bottle containing a jinnee should be kept closed at all cost. Escaped jinn – the plural of jinnee is jinn – usually try to do very bad things to the person who helps them escape. Typical jinn reasoning goes like this.

During the first century after the strong magician imprisoned me in the bottle I promised myself that the person to release me would be given the fulfilment of any three wishes they would choose to make. During the second century, I promised myself that the person to release me would be given every benefit I can provide – riches, beauty, respect, love – and that I would be their slave for an entire century. But during the third century I became impatient that the person to release me was being so slow to do it. I decided not to provide them with anything, but as a reward for releasing me I would let them live. Then, during the fourth century I became very angry with the laziness of my releaser, and I swore to eradicate them and their children, and their children's children, until the end of time. But as a reward for releasing me, I would allow them to choose the manner of their death. Now, how would you like to die?

Obviously, the player wants to keep the jinn in their bottles.

Unfortunately, the crate has been jostled, and some of the magical seals loosened. A loosened seal allows the cork of the bottle slowly to push out of the bottle, like the loosened cork of a bottle of champagne. The player has to move the mouse over the bottle, and click the button to push the cork back into the bottle. If the player is too slow the jinnee escapes and the game is lost. The process running the game, and its children and its children’s children, are all terminated with utmost prejudice, but only after the jinnee has a good laugh at the losing player. When every cork has been pushed back into its bottle the game is won.

To answer further questions about the game you have the binary of a prototype solution, which is in the directory /Shared/cs341/public on royal server.

Here is a rough outline of the game, as implemented in the prototype solution.

  1. The crate is a five by five array. Bottles begin to open at random times and speeds.
  2. The mouse controls the position of a fist, which punches a cork back in when any mouse button is pressed.
  3. Punching a bottle when the cork is not opening breaks the bottle and releases the jinnee, losing the game.
  4. Failing to punch a bottle before the cork releases completely lets the jinnee escape and the game is lost.
  5. The game is won when all bottles have been punched exactly once. A notice appears telling the player that they have won.
  6. The game is lost when a jinnee escapes.
  7. 'q', typed at any time, causes the program to exit.

Four factors increase and decrease the difficulty of the game.

  1. The number of bottles in the crate.
  2. The size of the bottle.
  3. The speed at which the corks move in the bottles.
  4. The average interval between subsequent corks starting to move.

Factors 1 & 2 should be held constant in your implementation: the number of bottle being 25, the size of the bottle is fixed to a size you find attractive.

Factors 3 & 4 should be controllable by hot keys (cork speed: '>' to increase, '<' to decrease; average interval: ',' to increase, '.' to decrease) so that you can experiment to get a feeling for the region in which the game is playable. This experimentation is essential for tuning the game, which must be done in order to get the game working well. Unlike normal game practice you should leave the tuning controls active so that I can examine how your game runs at differing speeds. The initial (default) values of these parameters should be those you determined when you tuned your implementation.

Resources

You will find two resources to help you with the project on royal server

/Shared/cs341/public
  1. Source code of a simple event loop program with a blocking event loop to help you see how XLib and C work together. It shows you:
    • how to get events,
    • how to use data from event structures, and
    • how to use a display list for repainting the screen.
  2. The binary, executable but not readable, for a prototype model solution, which you can execute to answer questions about how the game is supposed to work.

Note that this prototype solution assumes that the player has enough imagination to see the jinnee for example. In judging the success of your implementation and I will most highly reward projects that make neat looking solutions using the simplest of means. For example, don't use colour; you will lose marks for doing so.

The prototype solution is intentionally a minimal and incomplete version of the game. Submitting an exact replica of it will not result in a high mark.

In addition there are resources on the web that will help you with programming Xlib using C. Here are a few, far from the only ones.

It is also useful to have some example programs to examine. Here are a few I suggest you to refer to.

You are assumed to be capable of using documentation and examples to find out how to use a novel programming environment.

Hints

Here is a set of helpful hints.

  1. You will need two OS services to make an accurately timed event loop: finding out the current time, and suspending execution for a specific length of time. When you start to poke around the man pages you find that there are lots of ways to do timing on Unix, most of them not that great: too complex, insufficient resolution, etc. Here are the best ways to do so.
    • To find out the current time it is best to use
      int gettimeofday( struct timeval *tp, void * )
      
      for which you need #include <sys/time.h>.
    • The easiest way to sleep is
      int usleep( useconds_t time )
      
      for which you need #include <unistd.h>.
    • nanosleep(...), and napms(...), which requires the curses headers and library, also give adequate sleep capability.
  2. If you want to position text XTextWidth will tell you how long a string is in pixels.
  3. A rough, and easy to program, algorithm for the inside test determining if the mouse is clicked inside a bottle may be sufficient as long as users don't notice its deficiencies.
  4. It is possbile to put corks and bottles into the display list explicitly, leaving the crate and other stuff in the 'display list' implicit in the repaint function.

Hand In

  1. The source code for your game, which may be in one or more files (plus a Makefile that compiles them if you divided your code in multiple files). I will compile your code using either your makefile or using the command listed at the top of your single file.
  2. A readme file. The file should contain the name of the machine you used in Clapp 202 on which you compiled and tuned you game, and pointers so that I don't miss something important. It should also contain answers to the following questions.
    1. What is the most significant improvement in the interface of your implementation? Why?
    2. What is the most significant improvement in the appearance of your implementation? Why?
    3. Did your hot keys adjust the values arithmetically (by adding and subtracting) or geometrically (by multiplying and dividing)? Why?

Marking

The marking procedure used is the following.

  1. Your program is executed and your game played.
  2. Your source code is inspected.
  3. Your readme answers are read.

The project will be marked as follows.