Panthera's Box is a terminal-based game about putting everything that has escaped the box back in.
All of life’s miseries had been let out into the world. She slammed the lid of the box back down. The last thing remaining inside of the box was hope. Ever since, humans have been able to hold onto this hope in order to survive the wickedness that she had let out.
Panthera's Box can be installed and run using two different methods:
-
Install with
pip
:1.1a
pip install .
(Local)or
1.1b
pip install git+https://github.com/Willd14469/cj8-patient-panthers
(Git)This will install the game as the package
pantheras_box
. -
Run the game:
pantheras-box
-
Install dependencies:
pip install -r dev-requirements_[win|unix].txt
-
Run the game:
python main.py
--flush-log
- truncate the log file
--flush-score
- delete the high-scores file
Turn down the channel that is running the terminal, as the game sounds can be fairly loud.
The terminal should be at least 75x40, in order to render the board correctly.
The game consists of a ball and sets of redirector arrows. To complete each level, guide the ball towards the goal, by rotating the arrows. Hidden story tiles are scattered throughout the maps, requiring the player to take different paths.
On each level, a random set of mutators will be activated, modifying the gameplay slightly; this includes inverted controls, limited field of view and increased speed.
Scores are determined by the number of moves and time taken during a level. The maximum score attainable is relative to the board size. If a player's score reaches zero, the game is over.
Levels are stored in pantheras_box/backend/levels/
.
In short, levels are images that define the layout of the initial board. After parsing colour and co-ordinates, they are translated into a two-dimensional list of tiles.
- rich - front-end graphical library
- Pillow - parse level images
- boombox - cross-platform audio player
- PyYAML - configuration file format
- keyboard - keyboard handler (Windows)
- pynput - keyboard handler (Unix)
The game works and has been tested on both Windows and Linux (Arch & Debian).
In theory, the game should work on MacOS, but this has not been tested.
For best results:
- Use Powershell within Windows Terminal on Windows
Panthera's Box has 5 main modules:
backend
- state of the gamefrontend
- displaying the gamekeyboard_handlers
- receiving input from the usersounds
- playing soundsstory
- loading and displaying the correct story for the game state
Each of these modules are responsible for a cornerstone of the application. Communication between these modules is
handled by an event system (backend.events
) that allows modules to add a callback to hook into events that have been emitted.
This allows each module to be independent and not need context of other modules. The backend module emits events such as
ball_movement
and level_loaded
to broadcast the fact that the game state has changed fundamentally.
The frontend module is responsible for the render loop as well as prompting the backend to advance the game a single
tick.
Mutators (backend.mutators
) are responsible for changing the parameters of the backend module to alter gameplay.
These effects increase the variety of gameplay.
Keyboard input has its own module, due to having multiple packages for handling the input. A factory pattern is used to
determine which type of keyboard handler to use. keyboard
is used on Windows, as it provides a very clean way to
handle inputs. However, on Unix, root is required to access input devices (uinput
kernel module), so pynput
is used
instead for its xorg
backend.
Panthera's Box logs all the events that get emitted, if logging is set to DEBUG
, to get full visibility of the communication
between the core components. If logging is set higher than DEBUG
, then the events will only write warnings to the logger to
save on performance.
pantheras_box/config.py
provides a simple way to alter file location of score and log files. It also allows for modifying the logging
level.
- Implement all the core modules as singletons
- They can be referenced without having to implicitly pass them as arguments
- Ensures only one instance of each module exists
- Improve render loop so only updated elements are re-rendered to decrease load
- Add trap tiles
- Mutators with positive effect