Tower Defense Game: Getting Started
Python package management is not the easiest thing to wrap your head around. Nevertheless, it’s important that we capture the requirements our game has, properly, and commit them to a Python package.
Configuring your Python Environment
You need Python 3.8 or higher to easily follow this course. The demo itself explicitly requires 3.8 or higher. You can use older versions, but certain, minor, Python language features and standard library additions are unavailable if you do.
You must ensure that your version of Python is installed with
tkinter, a UI toolkit used in the demo to handle opening and saving levels, if you want to run the demo.
It’s not a strict requirement for your own game, but you may need to install
python3.X-tk on Ubuntu, or ensure TKinter is selected during installation on Windows and Mac.
You can check that it works by typing
I also recommend you develop in a virtual environment, a way of separating your packages so they don’t overlap with other projects.
Now, let’s create a package to host our game.
Creating a Python Package
Python’s package management gets a (deserved) bad reputation for complexity and confusion. But knowing how to create packages is one of those things that is difficult until you’ve done it a few times. Luckily, most packages – even ones you may end up deploying on a server somewhere – will usually work with the simple method I show you below.
Our goal is to have a proper package with a given package name – the demo is called
tower, but you should pick a name of your own – that hosts the package requirements, source code and assets.
Create an empty directory. I’m naming it
towerin this example.
git initif you want it version-controlled.
Now, we need to create two files. First,
And this placeholder file that’ll help futureproof your code. It’s called
And now for the most important file,
This is the example file used in the demo (but with the comments stripped and a few things tweaked for simplicity’s sake.) You can replace the details with your own.
The important bits deserve scrutiny though:
install_requiresis a newline-separated list of packages to install when the package is installed. This is important, of course, because we need these dependencies to run our code.
nameis the name of the package that is installed.
packagesdetects your packages automatically.
[options.package_data]is a list of locations where Python should look for things that it would not ordinarily include, like our media assets.
console_scriptscreates a shortcut you can invoke from your command prompt or terminal. It’s called
tower, and it runs the
This declarative configuration specifies the structure of your package.
Now the directory structure. Create a directory called
tower(or whatever you prefer.)
towerdirectory, create a blank file called
__init__.py. This is the root of your project, so that when you type
import tower, everything works.
If you want to use the same directory structure as I specified in the
setup.cfgexample above, you will need a few more directories and files:
setup.py setup.cfg tower/ ├── assets │ ├── __init__.py │ ├── audio │ │ ├── __init__.py │ ├── gfx │ │ ├── __init__.py │ └── levels │ └── __init__.py ├── __init__.py └── main.py
Feel free to shift things around; the important thing to remember is that each sub-directory of
tower has an
__init__.py file. If you don’t want
main.py, then don’t forget to update
Now you’re ready to test that your project installation works. To start, we’ll install it in editable mode, that means we tell setuptools (and thus Python) to find the code in the directory that you created the files instead of an opaque directory structure usually reserved for packages you install but don’t want to edit.
To do this, go to the root of your package with
setup.cfg and run this:
$ python -m pip install --editable .
Pip will now install your package. When it’s done, you should see something like this:
[ ... lots of output ... ] Successfully installed tower-1.0
You can confirm it works by typing this in a
If you encounter errors, check that you’ve replicated the package structure correctly and that, if you renamed things, you did it consistently. Alternatively you can use the structure in the demo to get you started.
If everything worked correctly, you’ll import your package successfully, and you’re ready to go.
- Understanding package management is important
Yes, we’re just writing a game, but this knowledge will work just as well with a large webapp as it would almost anything else. Our requirements – and indeed that of all but the most complex packages you find on PyPi – is a simple case of capturing requirements and, if you have non-python-code you want to include, the location of those assets.
- Doing it properly will help you down the line
I see a lot of Python developers subvert the packaging process by amending
sys.pathor other such trickery. That approach works just fine until it doesn’t – like when you want to share your code with someone else, or use the ability to dynamically import resources from your package (and we’ll be doing just that with our media assets.)
Spend a bit of time to familiarize yourself with this process. You may one day be called upon to create a package or resolve problems with one.
- If you mess up, revert to a known state
This is easiest to do with source control systems like Git. You should also ensure that you delete the
<package name>.egg-infodirectory as setuptools loves to cache state in that directory.
- There are third-party alternatives available also
Tools like Poetry promise to make the process easier or more manageable, but we’re a long, long while away from deprecating and replacing the existing package machinery. So even if you do use Poetry, most other packages don’t. You’ll eventually find yourself interacting with, and debugging or extending, the standard method of writing packages.
Installing & Playing the Tower Defense Demo
This course ships with source code that demonstrates all the concepts you’ll learn about. I recommend you install and play with it, just to get a feeling for what the end-goal is, and to serve as working example that you can refer back to in case you run into problems with your own game.
First, download the demo and extract it to a directory.
Next, you must install it:
$ cd <demo path> $ python -m pip install --editable .
If done in a virtual environment, you now have a clean slate to edit, run and experiment with the demo. You can launch it by typing
tower launch or
python -m tower.main launch.
Done right, you should see the main menu appear.
The game ships with a demo level to demonstrate the game play. You can find it by selecting “Play” in the game, and navigating to the
tower/assets/levels directory and opening “demo.json”.
Sound and Graphical Assets
You can find a selection of assets – or you can use your own, itch.io is a fine source – in the demo under
tower/assets. The assets are part of the package hierarchy, so we can use Python’s import mechanism to import them without having to worry about finding out where they’re located on the file system.
Spending a little bit of time getting a proper package structure set up and working will pay dividends down the road.
- Packages capture third-party requirements
Keeping track of the versions of third-party packages your package depends on avoids version drift and compatibility issues. It’s a common problem where a newer version of a package is released and you inadvertently end up utilizing a package version that your software was never tested against.
- You can also include non-Python assets, like data files
Python packages can include data file assets – like images, sound effects, etc. – if you tell it to. We’ll use it later to load our assets into pygame in a maintainable way that avoids messing with explicit file paths.