GamEngine3D
A Unity-style 3D engine for Python. Build interactive 3D worlds — rooms, puzzles, parkour courses, horror arenas — with clean Python and a few files of behavior scripts.
GamEngine3D wraps pygame + moderngl so you get a real OpenGL renderer (lighting, shadows, materials, a free camera) without fighting the graphics stack. You describe the scene; the engine renders it, lights it, and runs your scripts.
pip install gamengine3d
Try it in 10 seconds
Every install ships with playable demos. Pick one and press W A S D to move, Space to jump, E to interact, M to grab the mouse.
gamengine3d demo basics # a quiet lit scene, easy on the eyes
gamengine3d demo player_movement # a first-person walking sim: coins, sprint, flashlight
gamengine3d demo parkour # leap floating discs over a bottomless pit — in the dark
gamengine3d demo reactor # a full mission: restart four breakers to restore the core
Run gamengine3d demo -h to list everything. A display is required — demos open a real window.
Your first scene
from gamengine3d import *
# 1. Initialize the engine
engine = Engine(1200, 800, background_color=Color.light_blue)
# 2. Create objects
floor = Cuboid(size=vector3d(5, 0.1, 5), color=Color.light_grey, name="Floor")
player = Cuboid(name="Player", color=Color.light_red,
size=vector3d(0.2), pos=vector3d(0, 1))
# 3. Give the scene some light
engine.add_light(Light(position=vector3d(0, 6, 0), color=Color.white, intensity=1.0))
# 4. Add objects to the engine
engine.add_object(floor)
engine.add_object(player)
# 5. Attach behavior to objects (movement, input, game logic)
player.attach("player_controller.py", engine.context)
# 6. Run it. dynamic_view=True gives you orbit / zoom / pan with the mouse.
engine.run(dynamic_view=True)
That is the whole engine in six steps:
| Step | What it does |
|---|---|
Engine(...) |
Opens the window and the renderer (lights, shadows, camera). |
Cuboid(...) |
Any object — a box, sphere, cylinder, .obj mesh, or text. |
engine.add_light(...) |
Add point, directional, or area lights. |
engine.add_object(...) |
Put an object in the world. |
.attach("script.py", ctx) |
Attach behavior — see Scripting below. |
engine.run(...) |
Start the main loop. |
What can you build? The demos
reactor — the showpiece. An 80-meter reactor hall with a dead core, four breaker stations, and a director script orchestrating the whole mission:
stare down the motion gate, reboot the shock coil, override the shield vault, decode the breach code — then watch the petals peel away and confetti rain.
parkour — a pitch-black arena over a void. Sixteen floating discs snake across the room while lamps stutter, void lights breathe, and a beating eye watches you climb to the summit.
player_movement — the classic first-person room: sprint, jump, collect eight glowing coins, watch the HUD count them, and check out the flashlight (press F).
basics — the minimal scene: floor, column, two spheres, warm lighting. The pace-setter for learning the API.
All demos are plain Python files in gamengine3d/examples/ — copy one and start hacking.
Building blocks
Engine— owns rendering, lights, the main loop, scene save/load, and even raycasting (pick_forward,pick_at_screen).- Objects —
Cuboid,Sphere,Cylinder,ObjModel(load.objfiles),Text(real 3D text, perfect for in-world HUDs),ImageOverlay(screen-space sprites). vector3d/vector2d/Color— friendly helpers;Color.RGB(255, 200, 150),Color.hex("#ffc896"), or constants likeColor.light_blue.- Lights —
Light(point) andDirectionalLight, each casting real-time shadows.
Every object has pos, size/radius, rotation, color, visible, and emit (glow without lighting) — and can be hidden but still collide.
Scripting: bring it to life
Attach a Python file to any object, and the engine instantiates its class and calls update(dt) every frame. The class name must match the file (PascalCase): player_controller.py defines PlayerController.
# player_controller.py
from gamengine3d import *
import math
class PlayerController:
def __init__(self, obj, context):
self.obj = obj
self.context = context
self.speed = 4
self.context.on_key_held("up", callback=self.move_forward, dt=True)
def update(self, dt):
pass # called every frame
def move_forward(self, dt):
yaw = math.radians(self.obj.rotation.z)
forward = vector3d(-math.sin(yaw), 0, math.cos(yaw))
self.obj.pos += forward * self.speed * dt
Scripts get everything through a shared Context:
on_key_press("e", fn),on_key_held(...),on_key_released(...)— input, with optionaldt.add_delay(seconds, fn)— schedule one-shot or repeating calls.runtime_vars— a serializable blackboard for cross-script state (e.g.coil_powered).send_message(name, "msg")→ object-to-object messaging between scripts.
Attach to an object with .attach(path, context), or to the whole engine with engine.attach(path) for scene-wide directors.
Save and load scenes
Any scene is a plain JSON file — objects, lights, scripts, and context included.
engine.save_scene("my_scene.json")
gamengine3d load my_scene.json 1280x800 60 --dynamic-view
Requirements & development
- Python 3.11+ and a working OpenGL driver.
- Runtime deps (pinned):
pygame,moderngl,numpy,pyrr. - On hybrid laptops, the engine auto-prefers the discrete GPU; force a choice with
gpu="nvidia" | "intel"onEngine(...)or theGAMENGINE3D_GPUenv var. - For development, use
uv:uv sync --extra devinstalls the runtime plus the release toolchain (build,twine).
Links
- Full documentation: GamEngine3D Package Docs
- The 2D sibling engine,
gamengine2d, is also on PyPI.
Release files for gamengine3d 1.22.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gamengine3d-1.22.0.tar.gz | 458.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gamengine3d-1.22.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 943.2 kB
Release files / gamengine3d-1.22.0.tar.gz
| Download URL | gamengine3d-1.22.0.tar.gz |
|---|---|
| Size | 458.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
97cc5cbe84b9a7c0ec8e8a7abb83fa7e2123ebdcb2e21fcd41bec4cba6ce9b7e
|
|
BLAKE2b-256 checksum How to use checksums |
9796ec0bbd63efd1dffaebb9e3550157f23f7b0e30843b68620a02388d0b0ab1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / gamengine3d-1.22.0-py3-none-any.whl
| Download URL | gamengine3d-1.22.0-py3-none-any.whl |
|---|---|
| Size | 485.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0491d866491f55f89959d12570efa4cc952f0d8901297e1c34e277e1398af9f3
|
|
BLAKE2b-256 checksum How to use checksums |
65c1ca3a4c854177cd08c5a8b8638ca6fa6dafeb55d84e4c3c490dee18a09a32
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|