- Overview
1.1. Features - Mechanics
2.1. File Structure
2.2. Logic
2.3. Code - Usage
3.1. Installation of Dependencies
3.2. How to Run (Python Files)
3.3. How to Play (App) - Legal Stuff
4.1. Credits
4.2. License
4.3. Contributing
This is an online multiple player game where the intention is to shoot other boats and to stay alive. It is a constant lobby in which there can be a winner at any given time, given who is surviving.
- Online multiplayer game
- Account system
- Fluid UI interface/animations
- Sounds and background music
- Both keyboard and controller input
├── .github/ GitHub configuration (workflows, issue templates, etc.)
├── Assets/ Fonts, music, sound effects (button clicks, etc.)
│ ├── DynaPuff Font/ Font files for text in game
│ └── Sounds/ Music, boat sounds, cannonball sound effects, etc.
├── Button-Test/ HTML test page for button animations
├── Game_Code/ Core game source code
├── Graphics/ Visual assets
│ ├── Maps/ Map tiles & items
│ ├── Sprites/ Character & object sprites
│ ├── Buttons/ UI buttons
│ └── Menus/ Game menus & screens
├── Logos/ All project logos and icons
├── docs/ GitHub Pages website source
├── .gitignore Files and folders ignored by Git
├── requirements.txt Python dependencies (for Dependabot)
├── CODE_OF_CONDUCT.md Contributor Covenant Code of Conduct
├── LICENSE Project license
├── MyIcon.icns macOS app icon
└── README.md You’re reading this right now!
The game's codebase is modular and loosely follows the Model-View-Controller (MVC) pattern to keep concerns separated and the project maintainable:
- Model: Manages game data and logic (players, projectiles, items, networking, prediction).
- View: Handles all rendering and visual presentation (renderer, shaders, buttons).
- Controller: Processes input, orchestrates the game loop, and ties everything together (primarily
main.py).
The files interact through targeted imports, shared constants (config.py), and utility functions (utils.py). Execution starts at main.py, which initializes systems, runs the central game loop (handling events → updates → networking → rendering), and manages scene transitions (menus → lobby → gameplay).
How the files work together:
config.py: The foundation—defines global constants (screen dimensions, colors, speeds, Supabase credentials, asset paths). Imported by nearly every other file to ensure consistent settings and avoid hardcoding.utils.py: Provides reusable helper functions (vector math, collision detection, angle calculations, distance checks). Imported byplayer.py,cannonball.py,items.py,prediction.py, and others for physics and logic calculations.player.py: Defines thePlayerclass (boat state: position, rotation, health, velocity). Handles local input, movement, and shooting (spawns cannonballs). Depends onconfig.py,utils.py, andcannonball.py. Instances are created/updated inmain.pyand synced vianetwork.py.cannonball.py: Defines theCannonballprojectile class (trajectory, speed, damage, lifetime). Created byplayer.pywhen shooting; updated in the main game loop. Usesutils.pyfor physics/collisions and interacts withplayer.py(applying damage on hit).items.py: Manages pickups/power-ups on the map (position, type, effects like health restore). Updated in the main loop; players collect them via collision checks (usingutils.py). May be synced over the network for fairness.prediction.py: Implements client-side prediction and reconciliation to reduce perceived lag in multiplayer. Simulates future player/cannonball positions locally usingutils.pymath, then corrects based on authoritative data fromnetwork.py.network.py: Handles all multiplayer communication with Supabase (authentication, real-time database sync for player positions, shots, lobby state). Called frequently in the main loop; serializes/deserializes model data (player.py,cannonball.py) and works closely withprediction.pyfor smooth movement.shaders.py: Contains GLSL (OpenGL Shading Language) shader programs for advanced visual effects (water distortion, lighting, particles). Loaded and used exclusively byrenderer.py.renderer.py: The core View—uses ModernGL to draw everything: players, cannonballs, items, UI, backgrounds, and effects. Loads textures from Graphics/ and Assets/, applies shaders fromshaders.py, and is called every frame bymain.py.buttons.py: Defines interactive UI buttons for menus (login, play, etc.), handling hover/click states, animations, and sound feedback. Drawn viarenderer.pyand processed inmain.py's event loop.main.py: The primary Controller and entry point. Initializes Pygame/ModernGL, loads assets, sets up the window, authenticates vianetwork.py, and runs the infinite game loop: process input/events, update model (players, cannonballs, items), sync/predict network state, render viarenderer.py, and cap FPS.multiplayer-tester.py: A standalone development tool that imports most of the above modules to simulate multiple clients or test networking/prediction in isolation (e.g., fake players). Not used in production but shares the same core logic.
This structure ensures loose coupling: rendering changes don't affect physics, and multiplayer logic can be tested independently. All assets (Graphics/, Assets/) are loaded dynamically at runtime, primarily by renderer.py and buttons.py.
This project uses the dependencies pygame-ce, asyncio, imageio, moderngl, numpy, and supabase, which are not built in to the Python system. To install these dependencies, you will have to use pip in your terminal if you are in a local environment.
NOTE: If you are running in an app, you will not need to install these dependencies. Please proceed to section 3.3
-
- First, get the
get-pip.pyfile from the following link:
https://bootstrap.pypa.io/get-pip.py - Run it in your local Python environment or alternatively use
cdin your terminal to get into the file and run it withpython3:
- First, get the
cd /Directory/to/get-pip.py
python3 get-pip.pyNOTE: Replace "/Directory/to/get-pip.py" with the actual directory to
get-pip.py
If you don't have pygame installed, you may skip the following step to delete the basic pygame. If you do have this command, run the following in your terminal to delete pygame so that you may replace it with pygame-ce.
pip uninstall pygameIf that did not work, you can alternatively try the following command:
pip3 uninstall pygameWe decided to use
pygame-ce, the community fork of pygame, because of its continuous updates and security fixes. It also helps our game work faster than the original. Codewise, it's very similar; you can just callimport pygamejust like the original!
You may now install the dependencies:
cdinto repository folder:
cd /Directory/to/repositoryNOTE: Replace
"/Directory/to/repository"with the actual directory to the repository.
- Install dependencies:
pip install -r requirements.txtIf that did not work, you can alternatively try the following command:
pip3 install -r requirements.txtNOTE: These directions are assuming you are running Python verison 3 or higher.
- Clone the repository with the following command:
git clone https://github.com/DaNoob8157/boat-man-shooters.gitcdinto the repository folder:
cd /Directory/to/repositoryNOTE: Replace
"/Directory/to/repository"with the actual directory to the repository
- Run
main.pyusingPython:
python /Game_Code/main.pyIf that did not work, you can alternatively try the following command:
python3 /Game_Code/main.pyDownload the app for your desired operating system:
Website: https://DaNoob8157.github.io/boat-man-shooters/
Releases Page: https://github.com/DaNoob8157/boat-man-shooters/releases
- Install the dependencies as described in section 3.1 as well as the dependency
nuitka:
pip install nuitkaIf that did not work, you can alternatively try the following command:
pip3 install nuitkaNOTE: These directions are assuming you are running Python verison 3 or higher.
- Clone the repository with the following command:
git clone https://github.com/DaNoob8157/boat-man-shooters.gitcdinto the repository folder:
cd /Directory/to/repositoryNOTE: Replace
"/Directory/to/repository"with the actual directory to the repository.
- Run the following command:
cd 'Directory/to/repository' && \
python -m nuitka --standalone \
--macos-create-app-bundle \
--macos-app-icon=MyIcon.icns \
--product-name="Boat Man Shooters" \
--macos-signed-app-name=com.DaNoob8157.BoatManShooters \
--include-data-dir=Assets=Assets \
--include-data-dir=Graphics=Graphics \
--include-data-dir=Logos=Logos \
--include-data-dir=Documentation=Documentation \
--include-data-file="./Assets/DynaPuff Font/DynaPuffFont.ttf"="Assets/DynaPuff Font/DynaPuffFont.ttf" \
--output-dir=dist \
Game_Code/main.pyIf that did not work, you can alternatively try the following command:
cd 'Directory/to/repository' && \
python3 -m nuitka --standalone \
--macos-create-app-bundle \
--macos-app-icon=MyIcon.icns \
--product-name="Boat Man Shooters" \
--macos-signed-app-name=com.DaNoob8157.BoatManShooters \
--include-data-dir=Assets=Assets \
--include-data-dir=Graphics=Graphics \
--include-data-dir=Logos=Logos \
--include-data-dir=Documentation=Documentation \
--include-data-file="./Assets/DynaPuff Font/DynaPuffFont.ttf"="Assets/DynaPuff Font/DynaPuffFont.ttf" \
--output-dir=dist \
Game_Code/main.pyThis will create a folder called dist in the repository folder with the built app.
NOTE: Replace
"/Directory/to/repository"with the actual directory to the repository. Also, these directions are assuming you are running Python verison 3 or higher.
You can use the repository's GitHub Actions workflow (build-boat-man-shooters.yml) to automatically build standalone executables for macOS, Windows, and Linux using Nuitka. This runs entirely in the cloud on GitHub's servers—no local installation, dependencies, or code changes required on your part.
The workflow triggers automatically on pushes to the main branch and uploads the built apps as artifacts (downloadable files) to each workflow run.
How to get the builds yourself (without editing the repo):
-
Go to the repository's Actions tab: https://github.com/DaNoob8157/boat-man-shooters/actions
-
In the left sidebar, select the workflow named
Build App With Nuitka. -
You will see a list of past workflow runs. Look for the most recent successful run (marked with a green checkmark).
-
Click on that run to open its details.
-
Scroll down to the
Artifactssection at the bottom of the page. -
Download the artifact that matches your operating system:
- macOS: a
.appand the build data in a seperate folder - Windows: an
.exeand the build data in a seperate folder - Linux: a
.binand the build data in a seperate folder
- Extract/unzip the downloaded artifact if necessary, then run the app directly.
NOTE: Artifacts are available for about 90 days after the run completes. Always use the most recent successful run for the latest build.
NOTE: New builds are only created when the repository owner pushes changes to the main branch. If no recent successful builds are available or you need one for the current code, you’ll need to ask the repository owner to trigger a new build (e.g., by making a small commit). Users cannot start the workflow manually without the owner enabling that feature.
Background Music: Ocean wave loops by DesiFreeMusic found on Pixabay:
https://pixabay.com/music/upbeat-ocean-wave-loops-377890/
Under the following license:
https://pixabay.com/service/license-summary/
Cannonball: found on pngimg.com:
https://pngimg.com/image/108033
Under the following license:
Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
Button Sounds: Casual Click Pop UI 3 and casual Click Pop UI 2 by floraphonic found on Pixabay:
https://pixabay.com/sound-effects/casual-click-pop-ui-2-262119/
https://pixabay.com/sound-effects/casual-click-pop-ui-3-262120/
Under the following license:
https://pixabay.com/service/license-summary/
Boat Moving Sounds: Boat on River by paulprit (Freesound) found on Pixabay:
https://pixabay.com/sound-effects/boat-on-river-26388/
Under the following license:
https://pixabay.com/service/license-summary/
Boat Resting Sound big motor by Kibelon (Freesound) found on Pixabay:
https://pixabay.com/sound-effects/big-motor-90117/
Under the following license:
https://pixabay.com/service/license-summary/
Loading GIF load-33 by BlenderTimer found on Pixabay:
https://pixabay.com/gifs/load-loading-process-wait-delay-33/
Under the following license:
https://pixabay.com/service/license-summary/
Sprites (Including Player and Enemy) Made by Liam Blackmon
This project is made open-source by the MIT license, which can be found in LICENSE on the main page of the repository.
Please read our Code of Conduct before contributing, which can be found in CODE_OF_CONDUCT.md on the main page of the repository.


