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.2

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.2
File Size Uploaded
gamengine3d-1.23.2.tar.gz 462.0 kB Details

Built distribution (wheel)

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

Total release size: 951.2 kB

Release files / gamengine3d-1.23.2.tar.gz

Download URL gamengine3d-1.23.2.tar.gz
Size 462.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b08776f9e160d5f11da428e80ac4453166cbcfdc5e8c57561c1748ec724a513d
BLAKE2b-256 checksum
How to use checksums
3f5db0fa36ad65a48e00cdef74c96faee64460aca46631cde061f9146bd70ffb
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.2-py3-none-any.whl

Download URL gamengine3d-1.23.2-py3-none-any.whl
Size 489.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5311d8b714f941a64456edb2cd9b6b2df0a57c89034db534c1ee7db7bddcb1ce
BLAKE2b-256 checksum
How to use checksums
56c4499ee8868b900b17bccf8f4002807a1b064fa109c923905fd301925a2d25
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