Skip to main content

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).
  • ObjectsCuboid, Sphere, Cylinder, ObjModel (load .obj files), 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 like Color.light_blue.
  • LightsLight (point) and DirectionalLight, 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 optional dt.
  • 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" on Engine(...) or the GAMENGINE3D_GPU env var.
  • For development, use uv: uv sync --extra dev installs the runtime plus the release toolchain (build, twine).

Links

Release files for gamengine3d 1.23.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gamengine3d 1.23.1
File Size Uploaded
gamengine3d-1.23.1.tar.gz 461.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gamengine3d 1.23.1
File Interpreter ABI Platform
gamengine3d-1.23.1-py3-none-any.whl Python 3 none any Details

Total release size: 949.5 kB

Release files / gamengine3d-1.23.1.tar.gz

Download URL gamengine3d-1.23.1.tar.gz
Size 461.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c10c876e6b930a2eb0d6bdec608212f8771c7c5a40ea6888372d933a68b60424
BLAKE2b-256 checksum
How to use checksums
89aeb45d99aadd1628db1e91ecf61ae34fbc47d88cf0bd70bedbe40d536b9cb2
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.23.1-py3-none-any.whl

Download URL gamengine3d-1.23.1-py3-none-any.whl
Size 488.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7e0d39cba3bfd6064420553bad2eb6ddb90d548fd12687996c75d0327acaa4d6
BLAKE2b-256 checksum
How to use checksums
ea1972fff9a28a4a54b35d031b0ad353b2ae29f1398f73d29218b51657fc2e0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page