A side scroller built with Pygame-ce — first project at this scale, so expect quirks, experiments, and plenty of "could be betters."
You will notice some questionable architectural choices. I started this project when I was fairly new to coding, and the effort of rewriting some of it doesn't outweigh the benefits, though I am slowly working through and tweaking some parts to make them cleaner, this is also a hobby project and I'm having fun with it, which is what matters to me : )
I do understand that there is a "right" way to structure some of these systems, proper decoupling, dependency injection, event buses, the whole works. But for a solo indie project, I've found that the pragmatic approach of having a central game object that everything can access saves me an enormous amount of boilerplate and lets me iterate faster and although it is less then ideal, there is some method to the madness, over simply just making everything global, dependencies are namespaced under Game
current nitpick: no dedicated sprite handler or audio handler atm
I went heavy on composition (inheritance is yucky), and while I did some testing with rendering in ModernGL, I decided to stick with Pygame for now since rewriting everything would be painful.
I also experimented with building a full ECS (Entity Component System), but decided against a traditional implementation. In Python, a true data-oriented ECS introduces significant overhead due to object indirection, dynamic lookups, and poor cache locality.
Instead, I opted for a more pragmatic approach:
- Systems are more targeted and explicit (e.g. per-entity-type updates)
- Data is grouped where it makes sense rather than fully abstracted
- Focus is on keeping things fast and maintainable within Python's constraints
So while this isn't a "pure ECS," it follows similar ideas where useful, without sacrificing performance or readability.
Note: All assets are from itch.io. Also use pygame-ce not pygame.
This project is more of a showcase of different systems:
- Entity system (drag-and-drop with mouse)
- Inventory system
- Debugging tools (memory debugger, hitbox view, etc.)
- Lighting system (toggleable via in-game terminal)
- Save/load system
- Basic combat + movement mechanics
In-game:
Lighting example:
| Action | Key |
|---|---|
| Move | W A S D |
| Dash | Shift |
| Attack | Space |
| Pickup item / Talk to NPC | E |
| Consume item | E |
| Drop item | Q |
| Open inventory | I |
| Open map | T |
| Save | G |
| Back to menu | B |
| Open memory debugger | M |
| Close memory debugger | Esc |
| Open terminal (inside debugger) | Tab |
Debug / Extra:
| Thing | How |
|---|---|
| Toggle lighting | Open terminal → game_context.lighting = True, then press N |
| Show hitboxes | Open terminal → debugging = True |
| Drag entities | Click + drag with mouse |
You'll need Python installed.
pip install -r requirements.txt

