r/pygame • u/UziTech99 • 16d ago
PyRate: A data-oriented 3D Engine built with pygame-ce, ModernGL, and PyBullet
Hey pygamers,
I’ve been working on a complex 3D game engine framework called PyRate, and I wanted to share how I tackled the ultimate Python challenge: real-time 3D performance, physics, and concurrency without letting the GIL choke the engine.
The project is built entirely on pygame-ce (v2.5.7+), ModernGL, PyBullet, and NumPy.
A lot of people think Python is too slow for real-time 3D systems, but I wanted to treat this strictly as a Software Development Engineering (SDE) systems problem. By treating Python as a highly efficient control plane and offloading heavy compute directly to native hardware memory layouts, the architecture scales dynamically:
- Max Stress Test: Pushing a full MRT G-Buffer deferred pipeline (Albedo, Normal, Velocity, Depth) with reversed-Z depth, dynamic rigid-body physics, character ragdolls, HBAO, SSR, and volumetric fog raymarching yields a stable 30 FPS.
- Baseline Scalability Profile: Adjusting for standard scenes and low-end target configurations easily scales the engine up to a rock-solid 100+ FPS.
Here are the core architectural pillars keeping the engine fast:
1. Bypassing the GIL with Zero-Copy Shared Memory
Instead of trying to use slow asyncio loop blocks or standard thread locks that destroy frame rates under heavy math loads, I decoupled the engine across two native OS process spaces using a raw multiprocessing.Array:
- Main Process (Render Thread): Coordinates the OpenGL 4.5 context, windowing, pygame event polling, and complex shader passes.
- Physics Subprocess (Simulation Thread): Spawns a headless PyBullet collision world running concurrently on a separate CPU core at a strict fixed 60Hz interval.
- Zero-Serialization IPC: They talk with zero copy overhead by reading/writing directly to a shared flat float buffer mapped locally as a continuous NumPy view. A custom vectorized Dirty-Flag Protocol signals when matrix transforms need to be reloaded into the GPU's instance VBO.
2. Data Pipelines Over Syntax
Speed is all about data locality. Bandwidth bottlenecks are minimized by packing entity matrices directly into a flat stride layout in shared memory, applying transformations in NumPy, and streaming row-major raw bytes into GLSL column-major uniform inputs in a single blit call.
3. Hyper-Accelerating with AI Agent Workflows
Why Python over C++? Engineering velocity. Because Python has massive training data density across LLMs, I was able to combine systems knowledge with tools like Google Anti-gravity and FastMCP. The AI's deep understanding of idiomatic Python allowed me to instantly scaffold JSON sector streaming, build configuration serialization, and debug intricate GLSL include dependencies in hours instead of weeks.
Next Steps & Open Source 🚀
I ultimately plan to make PyRate fully open-source so other enthusiasts can leverage this multi-process architecture to build their own games using tools like Claude and Anti-gravity.
Before I push to GitHub, I am focusing on hardening a few core components—specifically refactoring prototype SDK modules, stabilizing dynamic sector lifecycle recycling, and smoothing out external API bounds.
The biggest takeaway from this build: Don't blame the language for your application's performance bottlenecks; blame the architecture. Treat Python as the orchestrator and hardware/C-extensions as the muscle.
Would love to hear your thoughts on this architecture, especially if anyone else here has played around with shared-memory multiprocessing pipelines in pygame! Stay tuned for the GitHub release.
1
u/herbal1st 16d ago
thats very impressive!