Skip to main content

Simple 3D FPS Demo Engine with PyQt6 and procedural world

Project description

Game Engine 🎮

A simple FPS engine in Python with PyQt6 — featuring procedural world generation, collisions, minimap, and custom objects support.


✨ Main Features

  • 🕹 FPS camera — smooth movement, mouse look, sprint, jump, reset position
  • 🌍 Procedural world generation — world divided into chunks, dynamic point loading
  • 🧱 Static objects — defined by pattern or generated automatically
  • 🛡 Collision system — supports AABB collisions for static objects
  • 🗺 Minimap — can rotate with the camera, displays objects and chunks
  • 🎨 Color support — every object can have its own color
  • 🧩 Simple API — easy to add custom objects, worlds, and behaviors
  • Optimizations — FOV filter, loading chunks around the camera

🛠 Installation

1. From GitHub

pip install git+https://github.com/antoninsiska/Game-Engine.git@latest

2. Local Development

git clone https://github.com/antoninsiska/Game-Engine.git
cd Game-Engine
pip install -e .

3. Requirements

  • Python 3.9+
  • PyQt6 6.5+

🎮 Running the Demo App

After installation you can run the default demo:

game-engine

⌨️ Controls

Key Action
W / A / S / D Move
Mouse Camera rotation
Shift Sprint
Space Move up
Ctrl / C Move down
B Reset position
M Toggle minimap rotation
P Pause
ESC Release mouse

🧩 Project Structure

game_engine/
│── __init__.py      # public package API
│── gui.py           # FPSDemo class — GUI logic & rendering
│── world.py         # ChunkWorld and StaticWorld — world generation
│── objects.py       # StaticObject — object definitions
│── main.py          # entry point for `game-engine` command

🔹 Basic Usage in Python

import sys
from PyQt6.QtWidgets import QApplication
from game_engine import FPSDemo

app = QApplication(sys.argv)
demo = FPSDemo()
demo.show()
sys.exit(app.exec())

🧱 Adding Custom Objects

1. Static Object

from game_engine import StaticObject

cube = StaticObject.from_size(
    3, 3,
    pos=(5, 0, 5),
    color="blue",
    name="cube",
    collision=True  # ✅ player cannot pass through
)
game.static_world.objects.append(cube)

🛡 Collisions

Collisions work automatically for all objects with collision=True.
The engine uses AABB collisions (axis-aligned bounding boxes).

How to add a collidable object

tree = StaticObject.from_size(
    2, 5,
    pos=(10, 0, 5),
    color="green",
    name="tree",
    collision=True
)
game.static_world.objects.append(tree)

How to add decoration without collisions

flower = StaticObject.from_size(
    1, 1,
    pos=(3, 0, 3),
    color="yellow",
    name="flower",
    collision=False  # ✅ player can pass through
)
game.static_world.objects.append(flower)

🌍 Procedural World

ChunkWorld

Generates procedural points into "chunks".

from game_engine import ChunkWorld

world = ChunkWorld()
world.ensure_chunks_around(0, 0, 60)  # create chunks around the camera
points = world.points_near(0, 0, 30)
print(points)

🧩 StaticWorld API

StaticWorld

Manages all static objects.

from game_engine import StaticWorld, StaticObject

world = StaticWorld()
cube = StaticObject.from_size(3, 3, pos=(5, 0, 5))
world.objects.append(cube)

Methods:

Method Description
points_near(x, z, radius) Returns points near the camera
solids_aabb() Returns AABB boxes of all collidable objects

🎨 StaticObject API

Creating a custom object

obj = StaticObject(
    pattern=[[1,1,1],[1,1,1],[1,1,1]],
    pos=(5, 0, 5),
    name="cube",
    color="red",
    cell_size=1.0,
    collision=True
)

Parameters:

Parameter Type Description
pattern list[list[int]] Object pattern
pos tuple Position (x,y,z)
name str Object name
color QColor/str Color
cell_size float Size of one cell
collision bool Enable collisions

🕹 Creating Your Own Game (MyGame)

import sys
from PyQt6.QtWidgets import QApplication
from game_engine import FPSDemo, StaticObject

class MyGame(FPSDemo):
    def __init__(self):
        super().__init__()

        # Custom collidable object
        cube = StaticObject.from_size(
            3, 3,
            pos=(5, 0, 5),
            color="blue",
            name="cube",
            collision=True
        )
        self.static_world.objects.append(cube)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    game = MyGame()
    game.show()
    sys.exit(app.exec())

Run:

python main.py

🧰 Debugging & Tips

  • Show collision boxes – add a debug overlay
  • Adjust FOV – change VFOV_DEG in gui.py
  • Change player speed – set self.move_speed
  • Adjust chunks – modify CHUNK_SIZE in world.py
  • Toggle minimap – built-in, press M

🛠 Development

Update the engine

pip install --upgrade git+https://github.com/antoninsiska/Game-Engine.git@latest

Local Development

git clone https://github.com/antoninsiska/Game-Engine.git
cd Game-Engine
pip install -e .

📜 License

MIT © 2025 Antonín Šiška

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

game_engine-0.1.6.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

game_engine-0.1.6-py3-none-any.whl (11.8 kB view details)

Uploaded Python 3

File details

Details for the file game_engine-0.1.6.tar.gz.

File metadata

  • Download URL: game_engine-0.1.6.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.2

File hashes

Hashes for game_engine-0.1.6.tar.gz
Algorithm Hash digest
SHA256 931262c0e55c5273719a3fef7d34ee6e186dec9b65f80ed737c274eace1176ea
MD5 7e68889b317f142975da1f67418a65a8
BLAKE2b-256 330389e7c9ecc247821d43f9d952a56eaa275fab27bad75f96863429b2904538

See more details on using hashes here.

File details

Details for the file game_engine-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: game_engine-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 11.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.2

File hashes

Hashes for game_engine-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 6bce193a4ed0e3490b97cd296ef6ff330784fb64e508ecc67a558cbd81c3f418
MD5 bdcdbef2560dc444b30825eae171f718
BLAKE2b-256 ee6929a30734a6e11d0682bc8ffcb5653890c013af527d2a9b6df43915f65683

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page