{"id":30002752,"url":"https://github.com/aram-ap/pyg-engine","last_synced_at":"2026-03-12T18:51:55.489Z","repository":{"id":307345961,"uuid":"1029203093","full_name":"aram-ap/pyg-engine","owner":"aram-ap","description":"A hardware accelerated 2D game engine built on Rust and WebGPU.","archived":false,"fork":false,"pushed_at":"2026-03-12T17:01:49.000Z","size":15799,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-12T17:48:40.440Z","etag":null,"topics":["game-development","game-engine","gpu-acceleration","physics-engine","python","python-library","rust","webgpu","wgpu"],"latest_commit_sha":null,"homepage":"http://pyg-engine.apra.dev/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aram-ap.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-30T17:14:40.000Z","updated_at":"2026-03-12T17:01:53.000Z","dependencies_parsed_at":"2025-07-30T20:36:20.049Z","dependency_job_id":"5f37d085-1bc8-4946-8e08-0f426a3705c3","html_url":"https://github.com/aram-ap/pyg-engine","commit_stats":null,"previous_names":["aram-ap/pyg-engine"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/aram-ap/pyg-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aram-ap%2Fpyg-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aram-ap%2Fpyg-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aram-ap%2Fpyg-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aram-ap%2Fpyg-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aram-ap","download_url":"https://codeload.github.com/aram-ap/pyg-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aram-ap%2Fpyg-engine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30438648,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T14:34:45.044Z","status":"ssl_error","status_checked_at":"2026-03-12T14:09:33.793Z","response_time":114,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["game-development","game-engine","gpu-acceleration","physics-engine","python","python-library","rust","webgpu","wgpu"],"created_at":"2025-08-05T06:37:34.754Z","updated_at":"2026-03-12T18:51:55.483Z","avatar_url":"https://github.com/aram-ap.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Logo](images/1_lower-res.png)\n\n# PyG Engine\n\nA Python game engine built on **Rust** and **WebGPU (wgpu)** with GPU rendering enabled \u003cu\u003e*by default*\u003c/u\u003e\n\nPyG Engine combines the ease of use of Python with the raw performance and safety of Rust. It leverages `wgpu` for modern, hardware-accelerated rendering across all major platforms (Vulkan, DirectX 12, Metal, OpenGL).\n\n\u003e **NOTE:** This project is currently in **Alpha**. Features are under active development.\n\n## :rocket: Key Features\n\n*   **Modern Rendering**: Powered by **wgpu** for cross-platform, high-performance graphics.\n*   **Rust Core**: The heavy lifting is done in Rust, ensuring speed and memory safety.\n*   **Measured Performance Gain**: In the fixed `1920x1080` benchmark workload, `pyg_engine` runs at about **2.26x** the FPS of `pygame` (see **Benchmarks** below).\n*   **Pythonic API**: Designed to feel natural for Python developers.\n*   **Flexible Drawing**: Easily draw lines, rectangles, circles, and pixels using pixel coordinates.\n*   **Mesh System**: Render textured quads and game objects with a component-based architecture (using normalized coordinates).\n*   **Thread Safety**: Safely issue rendering commands from background Python threads.\n*   **Robust Logging**: Integrated tracing-based logging system with file support and configurable levels.\n*   **UI Components**: Built in UI components built with extendability and custom styling. Easy callback function implementations included for buttons.\n*   **Unified Input System**: Easily implement controls with an Axis system, keyboard macros, and event-based callback functions.\n\n## :books: Documentation\n\n- **[API Reference](https://aram-ap.github.io/pyg-engine/)** - Complete Python API documentation\n\n## :eyes: Gallary\n\n- **[Snake](examples/snake_demo.py)**: One of the provided examples\n\n![snake](images/snake.gif)\n\n## :package: Installation\n\nRequires **Python 3.7+**.\n\n### From PyPI (Coming Soon)\n```bash\npip install pyg-engine\n```\n\n### From Source\n```bash\ngit clone https://github.com/aram-ap/pyg-engine.git\ncd pyg-engine\npip install -e .\n```\n\n## :zap: Quick Start\n\n### 1. Basic Window \u0026 Logging\n```python\nimport pyg_engine as pyg\n\n# Initialize the engine\nengine = pyg.Engine(log_level=\"INFO\")\nengine.log_info(\"Welcome to PyG Engine!\")\n\n# Run a window (blocks until closed)\nengine.run(title=\"My First Window\", width=800, height=600)\n```\n\n### 2. Drawing Primitives (Pixel Coordinates)\n```python\nimport pyg_engine as pyg\n\nengine = pyg.Engine()\n\n# Draw shape objects\nengine.draw([\n    pyg.Line(\n        start=pyg.Vec2(20, 20),\n        end=pyg.Vec2(220, 80),\n        color=pyg.Color.CYAN,\n        thickness=2.0,\n    ),\n    pyg.Rect(\n        position=pyg.Vec2(60, 120),\n        width=180,\n        height=90,\n        color=pyg.Color.ORANGE,\n        filled=False,\n        thickness=3.0,\n    ),\n    pyg.Arc(\n        position=pyg.Vec2(320, 180),\n        radius=42,\n        start_angle=0.0,\n        end_angle=3.8,\n        color=pyg.Color.YELLOW,\n        filled=False,\n        thickness=5.0,\n    ),\n])\n\n# Draw text as a shape object\nengine.draw(\n    pyg.Text(\n        \"Hello PyG\",\n        position=pyg.Vec2(32, 48),\n        color=pyg.Color.WHITE,\n        font_size=28.0,\n    )\n)\n\n# Start the application\nengine.run(title=\"Direct Draw Demo\", show_fps_in_title=True)\n```\n\n### 3. Font Families And Styled Text\n```python\nimport pyg_engine as pyg\n\nengine = pyg.Engine()\nengine.register_font_family(\n    \"inter\",\n    regular=\"assets/fonts/Inter-Regular.ttf\",\n    bold=\"assets/fonts/Inter-Bold.ttf\",\n    italic=\"assets/fonts/Inter-Italic.ttf\",\n    bold_italic=\"assets/fonts/Inter-BoldItalic.ttf\",\n)\n\nengine.draw(\n    pyg.Text(\n        \"Family font text\",\n        position=pyg.Vec2(32, 48),\n        color=pyg.Color.WHITE,\n        font_size=28.0,\n        font_family=\"inter\",\n        font_weight=\"bold\",\n    )\n)\n\nwidth, height = engine.measure_text(\n    \"Menu Title\",\n    font_size=32.0,\n    font_family=\"inter\",\n    font_weight=\"bold\",\n)\nengine.draw_text(\n    \"Italic caption\",\n    32,\n    96,\n    pyg.Color.WHITE,\n    font_size=20.0,\n    font_family=\"inter\",\n    font_style=\"italic\",\n    kerning=True,\n)\n\nengine.run(title=\"Font Family Demo\")\n```\n\n### 4. Using Game Objects \u0026 Meshes (World Coordinates)\n```python\nimport pyg_engine as pyg\n\nengine = pyg.Engine()\n\n# Create a GameObject\nplayer = pyg.GameObject(\"Player\")\n\n# Add components through the shared component API\nmesh = pyg.MeshComponent(\"PlayerSprite\")\nmesh.set_geometry(pyg.Mesh.Rect(1.0, 1.0))  # 1 world unit wide and tall\nmesh.set_fill_color(pyg.Color.RED)\nplayer.add_component(mesh)\n\n# Local transform (world-space while unparented)\nplayer.position = pyg.Vec2(0.0, 0.0)\nplayer.scale = pyg.Vec2(0.5, 0.5)\n\nplayer_id = engine.add_game_object(player)\n\n# Runtime lookup + lifecycle helpers\nruntime_player = engine.objects.get_id(player_id)\ncamera = engine.camera\ncamera.position = pyg.Vec2(0.0, 0.0)\ncamera.viewport_size = pyg.Vec2(8.0, 4.5)\nruntime_player.enabled = True\n# engine.destroy(runtime_player)\n\nengine.run(title=\"Game Object Demo\")\n```\n\n### 5. World Text Meshes And Camera Properties\n```python\nimport pyg_engine as pyg\n\nengine = pyg.Engine()\n\nlabel = pyg.GameObject(\"WorldLabel\")\nlabel.position = pyg.Vec2(0.0, 1.0)\nlabel.scale = pyg.Vec2(0.004, 0.004)\n\ntext_mesh = pyg.TextMeshComponent(\n    \"Hello from a GameObject\",\n    font_size=48.0,\n    font_family=\"inter\",\n    font_weight=\"bold\",\n)\ntext_mesh.color = pyg.Color.WHITE\nlabel.add_text_mesh_component(text_mesh)\n\nengine.add_game_object(label)\n\n# Camera behaves like an object-focused API\nengine.camera.position = pyg.Vec2(0.0, 0.0)\nengine.camera.position.x = 1.5\nengine.camera.viewport_size = pyg.Vec2(10.0, 5.625)\nengine.camera.aspect_mode = pyg.CameraAspectMode.FIT_BOTH\n\nengine.run(title=\"Text Mesh Demo\")\n```\n\n### 6. Function-Based Update Loop\n```python\nimport pyg_engine as pyg\n\nengine = pyg.Engine()\n\ndef update(dt, engine, frame):\n    if engine.input.key_down(pyg.Keys.ESCAPE):\n        engine.log(\"Exiting Pyg-Engine!\")\n        return False\n    engine.clear_draw_commands()\n    # draw/update game state...\n\nengine.run(\n    title=\"Callback Loop\",\n    show_fps_in_title=True,\n    update=update,\n    max_delta_time=0.1,\n)\n```\n\n`run(update=...)` supports callbacks with no arguments, a single\n`context` argument, or named argument injection (`dt`, `engine`, `input`,\n`elapsed_time`, `frame`, `user_data`).\n\nFor fully manual loop control, use `start_manual(...)` then drive\n`poll_events()`, `update()`, and `render()` yourself.\nThe callback acts as a global frame hook; planned per-GameObject scripts are\nintended to run in the engine update phase before this global callback.\nRuntime guard: calling `run(...)`/`start_manual(...)` while another loop is active\nraises `RuntimeError`.\n\n## :wrench: Architecture \u0026 Roadmap\n\n### Current Capabilities\n- **Window Management**: Resizable windows, VSync control, Fullscreen support.\n- **2D Rendering**:\n    - **Primitives**: Shape-first immediate drawing using pixel coordinates.\n    - **Text**: Built-in open-source font rendering with optional custom font files.\n    - **Meshes**: Component-based world-space rendering plus immediate mesh drawing.\n    - **Layers**: Float draw ordering for composition.\n- **Component System**: Basic `GameObject` with `TransformComponent` and `MeshComponent`.\n- **Input System**: Rust input manager (Keyboard, Mouse, Gamepad) to Python.\n- **Loop Control**: `run(...)` with optional callback and explicit `start_manual(...)` mode.\n- **Object Positioning System**: A straightforward method for moving and transforming your objects.\n- **Camera Controls**: Move your camera, customize backgrounds, set view area and fitment properties.\n- **UI System**: Built-in UI components.\n\n### Planned Features (Roadmap)\n- **Audio Manager**: Audio loading, playback, mixing, and timing.\n- **Engine Loop (Upgrade)**: Coroutines and global event systems.\n- **Physics Engine**: 2D rigid body physics and collision detection.\n- **Scripting**: Enhanced script attachment to GameObjects with frame-lifecycle hooks.\n- **Additional Primitives**: Added capabilities for more basic shapes, arcs, SVGs, and function-based shapes.\n- **Advanced Rendering**: Shaders, Particles, and Post-processing.\n\n## :open_file_folder: Examples\n\nCheck the [`examples/`](examples) directory for more complete demonstrations:\n\n- `direct_draw_demo.py`: Shows the new `engine.draw(...)` shape API.\n- `mesh_demo.py`: Demonstrates GameObjects, object-based mesh geometry, and world text meshes.\n- `threading_demo.py`: **Advanced**: Spawns a background thread that safely updates the UI using `engine.get_handle()`.\n- `manual_loop.py`: Shows how to control the game loop manually (`start_manual` -\u003e poll -\u003e update -\u003e render).\n- `function_update_demo.py`: Shows callback-based loop control via `engine.run(update=...)`.\n- `snake_demo.py`: Playable Snake game using immediate-mode drawing and keyboard input.\n- `camera_worldspace_demo.py`: Shows object-style camera control along with world-space objects and HUD text.\n- `ui_demo.py`: Demonstrates the UI system, button functions, and text label updates.\n\n## :bar_chart: Benchmarks\n\nPyG Engine includes a fixed, deterministic benchmark suite for 1:1 comparison with `pygame`:\n\n- `examples/pyg_engine_fixed_benchmark.py`\n- `examples/pygame_fixed_benchmark.py`\n- `examples/fixed_benchmark_side_by_side.py`\n- `examples/compare_benchmarks.py`\n\nAll benchmark runs use the same seeded scene configuration and workload:\n\n- Resolution: `1920x1080` (default)\n- Duration: `20s`\n- Objects: `2200` rects, `1800` circles, `1000` lines, `600` polygons\n- Motion: all objects continuously update and bounce in bounds\n- Caps: uncapped loops (`vsync=False` for `pyg_engine`, no `Clock.tick(...)` cap in `pygame`)\n- Logging: per-frame CSV + summary JSON\n\nQuick run:\n\n```bash\npython examples/fixed_benchmark_side_by_side.py\n```\n\nCompare latest pair:\n\n```bash\npython examples/compare_benchmarks.py\n```\n\nCompare all paired runs (grouped by resolution):\n\n```bash\npython examples/compare_benchmarks.py --all\n```\n\n### Current Findings (this repo, local machine)\n\nTest machine and display setup:\n\n- GPU: `NVIDIA RTX 3090`\n- CPU: `AMD Ryzen 7 7800X3D`\n- Memory: `64GB DDR5 6400`\n- Both benchmark windows displayed at `1920x1080`\n\nFrom 3 paired runs at `1920x1080` (`benchmark_logs/fixed_scene_v1`):\n\n- `pyg_engine` avg FPS: **166.51**\n- `pygame` avg FPS: **73.73**\n- Throughput gain: **~2.26x** (**+125.83% FPS**)\n- Avg frame time: **6.07 ms** vs **13.67 ms** (**55.62% lower**)\n- P95 frame time: **6.46 ms** vs **14.37 ms** (**55.02% lower**)\n- Draw submit time: **3.81 ms** vs **7.76 ms** (**50.95% lower**)\n- Present time: **1.01 ms** vs **4.55 ms** (**77.82% lower**)\n\nResults will vary by hardware/driver/OS, but the benchmark harness is fixed so repeated runs are directly comparable on the same machine.\n\n## :hammer_and_wrench: Development \u0026 Testing\n\nTo set up the development environment:\n\n```bash\n# Install in editable mode\npip install -e .\n\n# Run tests\npytest tests/ -v\n```\n\n## 📄 License\n\n[MIT License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faram-ap%2Fpyg-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faram-ap%2Fpyg-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faram-ap%2Fpyg-engine/lists"}