Python SDK for GoudEngine. Build 2D and 3D games powered by a Rust core.
Project description
GoudEngine Python SDK
Alpha — This SDK is under active development. APIs change frequently. Report issues · Contact
Python SDK for GoudEngine. Build 2D and 3D games powered by a Rust core.
Install
pip install goudengine
Quick Start
from goud_engine import GoudGame, Key
game = GoudGame(800, 600, "My Game")
player_tex = game.load_texture("assets/player.png")
while not game.should_close():
game.begin_frame()
dt = game.delta_time
if game.is_key_just_pressed(Key.ESCAPE):
game.close()
game.draw_sprite(player_tex, 400, 300, 64, 64)
game.end_frame()
game.destroy()
Networking
Use NetworkManager(game_or_context) to create wrapper endpoints. host() and connect() return NetworkEndpoint. connect() stores the connected peer ID, so clients can call send(...). Host endpoints reply with send_to(...).
from goud_engine import GoudContext, NetworkManager, NetworkProtocol
host_context = GoudContext()
client_context = GoudContext()
host = NetworkManager(host_context).host(NetworkProtocol.TCP, 9000)
client = NetworkManager(client_context).connect(NetworkProtocol.TCP, "127.0.0.1", 9000)
client.send(b"ping")
while True:
host.poll()
client.poll()
packet = host.receive()
if packet is None:
continue
host.send_to(packet.peer_id, b"pong")
break
Networking Wrapper API
The wrapper API is constructor-based and works with GoudGame or GoudContext:
from goud_engine import GoudContext, NetworkManager, NetworkProtocol
host_ctx = GoudContext()
client_ctx = GoudContext()
host_net = NetworkManager(host_ctx)
client_net = NetworkManager(client_ctx)
host = host_net.host(NetworkProtocol.TCP, 40000) # no default peer ID
client = client_net.connect(NetworkProtocol.TCP, "127.0.0.1", 40000) # default peer ID is set
client.send(b"hello") # uses default peer ID from connect()
packet = host.receive() # Optional[NetworkPacket]
if packet is not None:
host.send_to(packet.peer_id, b"world")
host.disconnect()
client.disconnect()
host_ctx.destroy()
client_ctx.destroy()
Debugger Runtime
The Python desktop bindings can enable the shared debugger runtime through pre-init config on GoudContext, then read JSON snapshots, pause or step the route, inject input, capture a frame, export metrics, or run replay through thin helpers.
from goud_engine import (
ContextConfig,
DebuggerConfig,
GoudContext,
parse_debugger_snapshot,
)
ctx = GoudContext(
ContextConfig(
debugger=DebuggerConfig(
enabled=True,
publish_local_attach=True,
route_label="python-demo",
)
)
)
ctx.set_debugger_profiling_enabled(True)
snapshot = parse_debugger_snapshot(ctx)
manifest_json = ctx.get_debugger_manifest_json()
memory = ctx.get_memory_summary()
ctx.set_debugger_selected_entity(42)
ctx.clear_debugger_selected_entity()
ctx.destroy()
Capture, replay, and metrics stay Rust-owned. capture_debugger_frame() returns PNG bytes plus JSON attachments. stop_debugger_recording() returns a replay envelope. get_debugger_metrics_trace_json() returns the versioned trace JSON directly.
See docs/src/guides/debugger-runtime.md for desktop-only scope, determinism limits, and the goudengine-mcp bridge workflow.
Features
- 2D and 3D rendering with runtime renderer selection
- Entity Component System (ECS) with Transform2D, Sprite, and more
- Physics simulation (Rapier2D/3D): rigid bodies, colliders, raycasting, collision events
- Audio playback with per-channel volume (Music, SFX, Ambience, UI, Voice) and spatial audio
- Text rendering with TrueType/bitmap fonts, alignment, and word-wrapping
- Sprite animation with state machine controller, multi-layer blending, and tweening
- Scene management with transitions (instant, fade, custom)
- UI component system with hierarchical node tree
- Tiled map support for 2D worlds
- Input handling (keyboard, mouse)
- Asset hot-reloading during development
- Structured error diagnostics with error codes and recovery hints
Flappy Bird Example
Here's a condensed version of the complete Flappy Bird example:
import math
import random
from goud_engine import GoudGame, Key, MouseButton
# Constants
SCREEN_W, SCREEN_H = 288, 512
GRAVITY = 9.8
JUMP_STRENGTH = -3.5
PIPE_SPEED = 1.0
PIPE_SPAWN_INTERVAL = 1.5
PIPE_GAP = 100
TARGET_FPS = 120
game = GoudGame(SCREEN_W, SCREEN_H + 112, "Flappy Bird")
# Load textures
bg_tex = game.load_texture("assets/sprites/background-day.png")
bird_frames = [
game.load_texture("assets/sprites/bluebird-downflap.png"),
game.load_texture("assets/sprites/bluebird-midflap.png"),
game.load_texture("assets/sprites/bluebird-upflap.png"),
]
pipe_tex = game.load_texture("assets/sprites/pipe-green.png")
base_tex = game.load_texture("assets/sprites/base.png")
digit_tex = [game.load_texture(f"assets/sprites/{i}.png") for i in range(10)]
# Bird state
bird_x, bird_y = SCREEN_W / 4, SCREEN_H / 2
velocity = 0.0
rotation = 0.0
frame_idx = 0
frame_timer = 0.0
jump_cooldown = 0.0
# Pipe state
pipes = [] # list of dicts: {x, top_y, bottom_y, counted}
pipe_timer = 0.0
score = 0
def reset():
global bird_x, bird_y, velocity, rotation, frame_idx, frame_timer
global jump_cooldown, pipes, pipe_timer, score
bird_x, bird_y = SCREEN_W / 4, SCREEN_H / 2
velocity = rotation = frame_idx = frame_timer = jump_cooldown = 0.0
pipes.clear()
pipe_timer = score = 0
def spawn_pipe():
gap_y = random.randint(PIPE_GAP, SCREEN_H - PIPE_GAP)
pipes.append({
"x": SCREEN_W,
"top_y": gap_y - PIPE_GAP - 320, # 320 = pipe image height
"bottom_y": gap_y + PIPE_GAP,
"counted": False,
})
def aabb(ax, ay, aw, ah, bx, by, bw, bh):
return ax < bx + bw and ax + aw > bx and ay < by + bh and ay + ah > by
reset()
while not game.should_close():
game.begin_frame()
dt = game.delta_time
# --- Input ---
if game.is_key_just_pressed(Key.ESCAPE):
game.close()
if game.is_key_just_pressed(Key.R):
reset()
jump = (game.is_key_just_pressed(Key.SPACE) or
game.is_mouse_button_just_pressed(MouseButton.LEFT))
if jump and jump_cooldown <= 0:
velocity = JUMP_STRENGTH * TARGET_FPS
jump_cooldown = 0.30
jump_cooldown = max(0.0, jump_cooldown - dt)
# --- Physics ---
velocity += GRAVITY * dt * TARGET_FPS
bird_y += velocity * dt
target_rot = max(-45, min(45, velocity * 3))
rotation += (target_rot - rotation) * 0.03
# --- Bird animation ---
frame_timer += dt
if frame_timer >= 0.1:
frame_idx = (frame_idx + 1) % 3
frame_timer = 0.0
# --- Pipes ---
pipe_timer += dt
if pipe_timer >= PIPE_SPAWN_INTERVAL:
spawn_pipe()
pipe_timer = 0.0
survived = []
for p in pipes:
p["x"] -= PIPE_SPEED * dt * TARGET_FPS
if p["x"] + 52 < 0: # pipe scrolled off screen
score += 1
continue
if (aabb(bird_x, bird_y, 34, 24, p["x"], p["top_y"], 52, 320) or
aabb(bird_x, bird_y, 34, 24, p["x"], p["bottom_y"], 52, 320) or
bird_y < 0 or bird_y > SCREEN_H):
reset()
break
survived.append(p)
else:
pipes = survived
# --- Draw ---
game.draw_sprite(bg_tex, SCREEN_W / 2, SCREEN_H / 2, SCREEN_W, SCREEN_H)
for p in pipes:
game.draw_sprite(pipe_tex, p["x"] + 26, p["top_y"] + 160, 52, 320, math.pi)
game.draw_sprite(pipe_tex, p["x"] + 26, p["bottom_y"] + 160, 52, 320)
game.draw_sprite(
bird_frames[frame_idx],
bird_x + 17, bird_y + 12, 34, 24,
math.radians(rotation)
)
# Score digits
digits = [int(d) for d in str(max(score, 0))]
start_x = (SCREEN_W - len(digits) * 24) / 2 + 12
for i, d in enumerate(digits):
game.draw_sprite(digit_tex[d], start_x + i * 24, 50, 24, 36)
game.draw_sprite(base_tex, SCREEN_W / 2, SCREEN_H + 56, SCREEN_W, 112)
game.end_frame()
game.destroy()
API Overview
Types
| Type | Description |
|---|---|
GoudContext |
Engine context managing an ECS world |
GoudResult |
FFI result type for operations that can fail |
GoudEntityId |
FFI entity identifier |
Vec2 |
2D vector |
Color |
RGBA color |
Rect |
2D rectangle |
Transform2D |
2D transformation component |
Sprite |
2D sprite rendering component |
Entity |
High-level entity wrapper |
GoudGame |
High-level game abstraction |
GoudContext Methods
| Method | Description |
|---|---|
create() |
Creates a new context |
destroy() |
Destroys the context |
is_valid() |
Checks if context is valid |
spawn_entity() |
Spawns an empty entity |
spawn_entities(count) |
Spawns multiple entities |
despawn_entity(id) |
Despawns an entity |
is_entity_alive(id) |
Checks if entity is alive |
entity_count() |
Returns alive entity count |
Transform2D Methods
| Method | Description |
|---|---|
from_position(x, y) |
Factory: position |
from_rotation(radians) |
Factory: rotation |
from_scale(sx, sy) |
Factory: scale |
look_at(px, py, tx, ty) |
Factory: look at target |
translate(dx, dy) |
Translate in world space |
translate_local(dx, dy) |
Translate in local space |
rotate(radians) |
Rotate by angle |
scale_by(fx, fy) |
Multiply scale |
forward() |
Get forward direction |
right() |
Get right direction |
transform_point(x, y) |
Local to world |
inverse_transform_point(x, y) |
World to local |
lerp(other, t) |
Interpolate |
Sprite Methods
| Method | Description |
|---|---|
with_color(r, g, b, a) |
Builder: color tint |
with_flip_x(flip) |
Builder: horizontal flip |
with_flip_y(flip) |
Builder: vertical flip |
with_anchor(x, y) |
Builder: anchor point |
with_source_rect(x, y, w, h) |
Builder: sprite sheet rect |
with_custom_size(w, h) |
Builder: render size |
set_source_rect(...) |
Mutate source rect |
clear_source_rect() |
Clear source rect |
set_custom_size(...) |
Mutate size |
clear_custom_size() |
Clear size |
Platform Support
| OS | Architecture | Status |
|---|---|---|
| Windows | x64 | Supported |
| macOS | x64 | Supported |
| macOS | ARM64 (Apple Silicon) | Supported |
| Linux | x64 | Supported |
Native libraries are bundled in the PyPI package.
Development
For contributors building from source:
cargo build --release
python3 sdks/python/test_bindings.py
python3 sdks/python/test_network_loopback.py
python3 -m coverage erase
python3 -m coverage run --source=sdks/python/goud_engine sdks/python/test_bindings.py
python3 -m coverage run --append --source=sdks/python/goud_engine sdks/python/test_network_loopback.py
python3 -m coverage report
python3 -m coverage xml -o sdks/python/coverage.xml
The Python SDK CI gate expects at least 80% line coverage across
sdks/python/goud_engine.
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file goudengine-0.0.831.tar.gz.
File metadata
- Download URL: goudengine-0.0.831.tar.gz
- Upload date:
- Size: 49.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
448200754e5ea6748076506f96efd235e72f122a45cfeed6457b8481bef014e4
|
|
| MD5 |
9ac3a44e1b2cbc2c15adf82ab54fe7ba
|
|
| BLAKE2b-256 |
d8aaa1b1741adfabf5b33fa696764e95017583e96ffdaf16119812b67a3b67e5
|
Provenance
The following attestation bundles were made for goudengine-0.0.831.tar.gz:
Publisher:
release.yml on aram-devdocs/GoudEngine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
goudengine-0.0.831.tar.gz -
Subject digest:
448200754e5ea6748076506f96efd235e72f122a45cfeed6457b8481bef014e4 - Sigstore transparency entry: 1099376007
- Sigstore integration time:
-
Permalink:
aram-devdocs/GoudEngine@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aram-devdocs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Trigger Event:
push
-
Statement type:
File details
Details for the file goudengine-0.0.831-py3-none-win_amd64.whl.
File metadata
- Download URL: goudengine-0.0.831-py3-none-win_amd64.whl
- Upload date:
- Size: 7.9 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f315fc6da868a5c2cbc4b05900f228ae74f3e5efbcf1f920057f65a38d5a5843
|
|
| MD5 |
15634c0de28de66bb4fe554634e72d9b
|
|
| BLAKE2b-256 |
da69ee416f1236990cd572253a6bdf26c3820eb7d0e47e4187f0afe8795246e3
|
Provenance
The following attestation bundles were made for goudengine-0.0.831-py3-none-win_amd64.whl:
Publisher:
release.yml on aram-devdocs/GoudEngine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
goudengine-0.0.831-py3-none-win_amd64.whl -
Subject digest:
f315fc6da868a5c2cbc4b05900f228ae74f3e5efbcf1f920057f65a38d5a5843 - Sigstore transparency entry: 1099376011
- Sigstore integration time:
-
Permalink:
aram-devdocs/GoudEngine@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aram-devdocs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Trigger Event:
push
-
Statement type:
File details
Details for the file goudengine-0.0.831-py3-none-manylinux2014_x86_64.whl.
File metadata
- Download URL: goudengine-0.0.831-py3-none-manylinux2014_x86_64.whl
- Upload date:
- Size: 12.5 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a117ffdb85ef8afb3d51e81bb7d76024666e4b1180c6419f1221ec2e6633d15
|
|
| MD5 |
6eea905dbcd899c15b41d5b7ebcd26e4
|
|
| BLAKE2b-256 |
0e0e195c50af3ba33b6218eabed86c7cdf9c79ac86e0f3961ba25f694e117879
|
Provenance
The following attestation bundles were made for goudengine-0.0.831-py3-none-manylinux2014_x86_64.whl:
Publisher:
release.yml on aram-devdocs/GoudEngine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
goudengine-0.0.831-py3-none-manylinux2014_x86_64.whl -
Subject digest:
2a117ffdb85ef8afb3d51e81bb7d76024666e4b1180c6419f1221ec2e6633d15 - Sigstore transparency entry: 1099376008
- Sigstore integration time:
-
Permalink:
aram-devdocs/GoudEngine@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aram-devdocs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Trigger Event:
push
-
Statement type:
File details
Details for the file goudengine-0.0.831-py3-none-macosx_14_0_arm64.whl.
File metadata
- Download URL: goudengine-0.0.831-py3-none-macosx_14_0_arm64.whl
- Upload date:
- Size: 12.3 MB
- Tags: Python 3, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf2ad738ef614257477766293a1725f39f44d6d652860557ac8c62726ca0f446
|
|
| MD5 |
637376f6453344833545f9114be35084
|
|
| BLAKE2b-256 |
883e163d7117f8b2e5c87541670f52600b9a939e80ac928ddf225b0765616a43
|
Provenance
The following attestation bundles were made for goudengine-0.0.831-py3-none-macosx_14_0_arm64.whl:
Publisher:
release.yml on aram-devdocs/GoudEngine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
goudengine-0.0.831-py3-none-macosx_14_0_arm64.whl -
Subject digest:
bf2ad738ef614257477766293a1725f39f44d6d652860557ac8c62726ca0f446 - Sigstore transparency entry: 1099376013
- Sigstore integration time:
-
Permalink:
aram-devdocs/GoudEngine@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aram-devdocs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Trigger Event:
push
-
Statement type:
File details
Details for the file goudengine-0.0.831-py3-none-macosx_13_0_x86_64.whl.
File metadata
- Download URL: goudengine-0.0.831-py3-none-macosx_13_0_x86_64.whl
- Upload date:
- Size: 4.2 MB
- Tags: Python 3, macOS 13.0+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a98023c62aff6dba990cb75b6acc5fc6c7fab1fc4656618c0d027c19d33ca3b
|
|
| MD5 |
277d4ac72736e2a4f3d383c6774e39f8
|
|
| BLAKE2b-256 |
2aae16a20ec883bd23a8a3d8a29d15c731f7b6018d3498d79ce2b527fab98588
|
Provenance
The following attestation bundles were made for goudengine-0.0.831-py3-none-macosx_13_0_x86_64.whl:
Publisher:
release.yml on aram-devdocs/GoudEngine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
goudengine-0.0.831-py3-none-macosx_13_0_x86_64.whl -
Subject digest:
8a98023c62aff6dba990cb75b6acc5fc6c7fab1fc4656618c0d027c19d33ca3b - Sigstore transparency entry: 1099376017
- Sigstore integration time:
-
Permalink:
aram-devdocs/GoudEngine@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aram-devdocs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ebf6c72795fed43e6a0aa556b9b1ed1573877757 -
Trigger Event:
push
-
Statement type: