Project (Zuma: Tower Defense)
Overview
Zuma is a classic game that involves a shooter and a continuous sequence of balls that roll along a predetermined path. The shooter must insert balls of varying colors in the sequence to form streaks of consecutive colors that disappear from the sequence. The goal is to avoid having the balls reach the end of the path.
You may view this video for some sample gameplay.
A tower defense game is a game where there is a sequence of enemies that go along a path, and you can build towers that (primarily) stop the enemies from reaching the end of the path.
You may view this video for some sample gameplay of a tower defense game.
For the CS 12 Project, you will make a game that combines aspects of Zuma and classic tower defense games.
Your group of four is to develop a Python-based implementation of such a game using Pyxel and MVC.
You may view this video for a sample demo of what the game should look like.
Implementation
The project is divided into six phases that are built incrementally on top of one another. Each phase is worth a varying amount of 🔴 and ♥️ points. Only the highest phase accomplished will be checked.
Each phase has a list of features to be implemented. Starting Phase 2, all features of Phase \(k−1\) must be properly implemented to be eligible for points for Phase \(k\).
We will use the following terms to describe the different aspects of the game:
- The player is the one controlling the game. That's you. The player has a certain number of lives.
- The grid is where the game takes place. The grid consists of rows, and each row consists of cells.
- The shooter is what the player primarily controls throughout the game. The shooter can shoot bullets of varying colors. The shooter occupies \(1\) cell.
- A path is a sequence of cells on the game screen. Each pair of consecutive cells in this sequence must be orthogonally adjacent.
- The enemies go along the path throughout the game. Each enemy has a color, a certain number of lives, and grants a certain amount of \(\mathsf{EXP}\) when defeated. An enemy loses a life if they are shot with a bullet that has the same color as that enemy. The player loses a life if an enemy reaches the end of the path it is on.
- Towers can be placed by the player between rounds. Towers have various effects that can influence the other aspects of game. A tower occupies at least \(1\) cell, and costs some amount of \(\mathsf{EXP}\) to place.
Base settings and behavior
The following are game constants that affect the base features and gameplay as described in Phases 1 through 6 (see Phases below). Your implementation is expected to follow them.
These values can be altered during gameplay via difficulty progression, upgrades, or bonus features.
Player
- Base rate of fire: \(0.9\) bullets / second
- Bullet size: radius at least \(5\) pixels
- Bullet movement: "smooth"
- Bullet "speed": \(5\) seconds to travel the diagonal length of the game screen
- Bullet hits: \(1\) (no piercing behavior)
- Color of next bullet: picked with uniform probability (e.g. \(5\) colors, each color has \(20\%\) chance of being picked)
- Range: infinite
Towers
- Tile size: square side length at least \(15\) pixels
- Base tower rate of fire: \(0.5\) bullets / second
- Tower bullet "speed": \(5\) seconds to travel the diagonal length of the game screen
- Tower bullet hits: \(1\) (no piercing behavior)
- Color of next tower bullet: picked with uniform probability (e.g. \(5\) colors, each color has \(20\%\) chance of being picked)
- Range: up to you
Enemies and paths
- Tile/enemy size: square side length at least \(15\) pixels
- Enemy movement: "tile by tile"
- Enemy speed along path: move one square forward along path every \(2\) seconds
-
Enemy base hit points: \(1\)
-
Path intersections: up to you
Phases
Phase 1 (0 🔴 + 30 ♥️)
Feature 1a: Entities
- The game starts with the shooter in the middle of the screen.
- The shooter can only shoot directly upwards. The shooter can shoot by left clicking. The shooter can only shoot bullets of one type of color.
- There is \(r = 1\) round.
- In each round, there are \(e = 5\) enemies, all with the same color.
- Shooting an enemy makes it disappear from the screen and gives you \(1 \ \mathsf{EXP}\).
- There are no towers yet.
Feature 1b: Stage
- The stage is a single horizontal line, where enemies appear on the left and go rightwards.
Feature 1c: Gameplay loop
- The player has \(\ell = 2\) lives.
- The game ends if the player runs out of lives or if all enemies are gone.
Feature 1d: Graphics and sound effects
- Simple graphics for the shooter, the enemies, and the path.
- No need for animations or sound effects.
Feature 1e: Setup and implementation details
- FPS must be set to \(30\)
Phase 2 (0 🔴 + 45 ♥️)
Feature 2a: Entities
- The shooter can shoot upwards, downwards, leftwards, or rightwards. The shooter can change direction using the
WASDkeys. The shooter can now shoot bullets of two types of colors. - There are \(r = 2\) rounds.
- In each round, the number of enemies is now configurable. Each enemy has one of two colors.
- Between rounds, you may place a tower that shoots upwards. One of these towers costs \(5 \ \textsf{EXP}\) to place.
Feature 2b: Stage
- The stage consists of several lines, where consecutive lines form a right angle. Enemies start at one end and make their way to the other end.
Feature 2c: Gameplay loop
- The number of lives of the player is now configurable.
Feature 2d: Graphics and sound effects
- Enemies with different colors must be easily distinguishable.
Feature 2e: Setup and implementation details
- A
settings.jsonfile formatted as JSON must exist. - Each
settings.jsonmust contain the following key-value pairs (you are free to define key names):- Number of enemies per round (\(e\), an integer greater than zero)
- Number of lives of the player (\(\ell\), an integer greater than zero)
Phase 3 (20 🔴 + 40 ♥️)
Feature 3a: Entities
- The shooter can shoot in all directions, depending on the location of the mouse cursor with respect to the center of the screen. The shooter can now shoot bullets of three types of colors.
- There are \(r = 3\) rounds.
- Each enemy has one of three colors.
- Towers can be upgraded at a cost of additional \(\mathsf{EXP}\). When upgraded, the tower shoots two bullets of different colors at a time.
Feature 3b: Stage
- The stage may consist of at most two paths.
Feature 3c: Gameplay loop
- The number of lives of the player is now configurable.
Feature 3d: Graphics and sound effects
- There should be sound effects for defeating enemies.
Feature 3e: Setup and implementation details
- Your code must be structured using the MVC architecture.
Phase 4 (60 🔴 + 30 ♥️)
Feature 4a: Entities
- The shooter can now shoot bullets of four types of colors.
- There are \(r = 4\) rounds.
- Each enemy has one of four colors.
- The tower can now shoot in the four cardinal directions (set using the
WASDkeys). The direction of fire can be set during rounds.
Feature 4b: Stage
- The stage may consist of at most two paths.
- Paths can have tunnel sections, where enemies are shielded from bullets. Tunnel sections are at least two cells long, but occupy no longer than five consecutive cells. A path can have at most two tunnels, and the total length of the tunnels must not exceed half the full length of the tunnel.
Feature 4c: Gameplay loop
- (no new features)
Feature 4d: Graphics and sound effects
- The game should have background music (BGM). The BGM can be as simple as a repeating phrase of notes.
Feature 4e: Setup and implementation details
- (no new features)
Phase 5 (80 🔴 + 20 ♥️)
Feature 5a: Entities
- The shooter can now shoot bullets of five types of colors.
- There are \(r = 5\) rounds.
- Each enemy has one of five colors.
- Some enemies can be Regenerators: they gain 1 hit point every time they are able to move \(h\) cells (should be configurable).
- Some enemies can be Chameleons: they can change color every so often (frequency should be configurable).
Feature 5b: Stage
- (no new features)
Feature 5c: Gameplay loop
- (no new features)
Feature 5d: Graphics and sound effects
-
You are required to create sprites (Pyxel editor sample) for the enemies. The hitbox of the sprites are still squares, but their design does not need to fill up the whole square. Here are some samples of
-
Regenerators and Chameleons should be visually distinguishable from normal enemies.
-
The game should have background music (BGM). The BGM can be as simple as a repeating phrase of notes.
Feature 5e: Setup and implementation details
- (no new features)
Phase 6 (100 🔴 + 10 ♥️)
Feature 6a: Entities
- The shooter can now shoot bullets of six types of colors.
- There are at least \(r = 12\) rounds.
- Each enemy has one of six colors.
- More enemies have more hit points.
Feature 6b: Stage
- (no new features)
Feature 6c: Gameplay loop
-
The game should have two modes: Campaign and Endless
-
Campaign: Consists of the 12 (or more) rounds, highlighting all the features of the game
- Endless: Endless Mode consists of an infinite series of rounds. The player's goal is to survive as many rounds as possible before losing. The difficulty of the game must continuously increase at some pace as more rounds get cleared.
Feature 6d: Graphics and sound effects
- The game should have fully-functioning menus and screens, which are:
- Start menu: Choose between game modes, access leaderboard, configure game settings
- Pause screen: Shows if you pause the game during the Campaign or Endless mode
- Game over screen: Shows when the player either wins or loses, prompts for a nickname for the leaderboard, with an option to play again
- Leaderboard: Shows top scorers (Campaign and Endless). The leaderboard must be persistent (save the results in an external file).
Feature 6e: Setup and implementation details
- (no new features)
Phase 7 [Bonus Points] (0 ♥️ to 100 ♥️)
Additional features may merit extra points. Here are some possible bonus features:
- Additional types of enemies (at least two new types)
- Additional types of towers (at least two new types)
- Special types of bullets, powerups (chain lightning, etc.)
- Mechanics to recover player lives
- In-game shop, accessible in the main menu and in between rounds
- "Microtransactions" in the shop
- Additional unique game modes
- In-game achievements
Grading
This project is worth \(15\%\) of your final grade.
Peer evaluation
A peer evaluation form will be made available after the submission deadline in which you will:
- List down granular contributions of each member
- Give a percentage grade to each member of your group (excluding yourself)
Your total score for the project will be affected by this in the following manner:
- Drop lowest percentage, then average remaining percentages
- Multiply average percentage to total score
Warning regarding contributions
Project grades may be withheld for students having problematic listed contributions.
LLM policy
In exchange for allowing the use LLMs, we ask that you place all prompts and responses in llm.txt in the root of your repository.
Kindly note that LLM attribution in README.md is required if you will be uploading this to a public repository for portfolio purposes (kindly do this only after the deadline and with the explicit permission of the CS 12 25.2 handlers).
Submission
- GitHub Classroom: link
- Deadline: June 6, 2026 11:59pm
Project Structure
For the project, you will be using uv. uv is a tool that combines the roles of several other prominent Python tools into one. And it's also very fast!
We expect to see pyproject.toml and uv.sync files in your project repo. Your game should be runnable when we clone your repo and run the following commands:
uv sync
source .venv/bin/activate
pyxel run game.py