A very small tower-defense game built with the Panda3D engine.
Mostly as a learning exercise.
Gameplay video: https://www.youtube.com/watch?v=rh-obSMSaN8
![](https://private-user-images.githubusercontent.com/24236225/282378421-14ed1a78-83d6-4f18-b5d7-dd128139dc33.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkxNTE2NzAsIm5iZiI6MTczOTE1MTM3MCwicGF0aCI6Ii8yNDIzNjIyNS8yODIzNzg0MjEtMTRlZDFhNzgtODNkNi00ZjE4LWI1ZDctZGQxMjgxMzlkYzMzLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTAlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjEwVDAxMzYxMFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQ5Y2RlYTkwODEwYmExNjYzYTJlZjA0N2U2NDU0MjZlYjY2MjFhODEzOTQxNjNkMTI1YTU3ODMwYjliYWU4MmUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.u4wua0qpCi1lqoys2eWg6qHV7mAzdpyQNjSE7D6Inx0)
Requires Python 3.11+
Linux:
git clone https://github.com/LiteralGenie/panda-defense
cd /path/to/panda-defense
python3 -m venv venv
source ./venv/bin/activate
python -m pip install -r requirements.txt
python ./src/main.py
Windows:
git clone https://github.com/LiteralGenie/panda-defense
cd C:\path\to\panda-defense
python -m venv venv
./venv/bin/activate
python -m pip install -r .\requirements.txt
python .\src\main.py
The enemies / paths can be configured by editing src/data/scenarios/2_multi.json
.
main.py
launches two processes:
- a "controller" process that periodically updates the game state
- a "view" process that renders the game state to the screen and accepts user input ("actions")
The reason for this split is mostly to isolate the game logic from the rendering engine. Which should make server-validation and multiplayer easier to set up. (Also didn't trust the Panda3d engine much.)
(I realize that despite the terminology, the controller is too fat for this to be MVC ¯\_(ツ)_/¯ )
More gory details
On each tick (250ms), the controller will...
- check for actions from the view process
- validate these actions and apply them to the current state (eg buying towers by subtracting gold)
- apply other changes to the current game state (eg moving units)
- emit all changes that occurred this tick to the view process
Although the game state is technically one giant dictionary, both the controller and view process interact with proxy objects that point to small slices of this state (aka "models").
The view process will typically also generate a view instance for each model to hold rendering-related state (eg track active animations). Invidual view instances (and gui components) are notified of changes to the underlying model via a global RxPY pipe.
- I'm probably going to rewrite this game instead of building on it for a few reasons:
- The data models for units / towers work for this demo, but too rigid for any unique mechanics.
- Building the GUI components is waay too tedious.
- Takes a dozen lines just to position / animate a slide-in-out transition.
- Default components are fugly.
- Layout libraries like DirectGuiExtension may help but probably better to see if any of the CEF integrations or HTML libraries are functional.