RepoPilotOpen in app →

ggez/ggez

Rust library to create a Good Game Easily

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 4d ago
  • 13 active contributors
  • MIT licensed
Show all 6 evidence items →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 74% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/ggez/ggez)](https://repopilot.app/r/ggez/ggez)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/ggez/ggez on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: ggez/ggez

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ggez/ggez shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 4d ago
  • 13 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 74% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live ggez/ggez repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/ggez/ggez.

What it runs against: a local clone of ggez/ggez — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in ggez/ggez | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 34 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>ggez/ggez</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ggez/ggez. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/ggez/ggez.git
#   cd ggez
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of ggez/ggez and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ggez/ggez(\\.git)?\\b" \\
  && ok "origin remote is ggez/ggez" \\
  || miss "origin remote is not ggez/ggez (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "src/lib.rs" \\
  && ok "src/lib.rs" \\
  || miss "missing critical file: src/lib.rs"
test -f "src/context.rs" \\
  && ok "src/context.rs" \\
  || miss "missing critical file: src/context.rs"
test -f "src/graphics/draw.rs" \\
  && ok "src/graphics/draw.rs" \\
  || miss "missing critical file: src/graphics/draw.rs"
test -f "src/graphics/gpu/mod.rs" \\
  && ok "src/graphics/gpu/mod.rs" \\
  || miss "missing critical file: src/graphics/gpu/mod.rs"
test -f "src/event.rs" \\
  && ok "src/event.rs" \\
  || miss "missing critical file: src/event.rs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 34 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~4d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ggez/ggez"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

ggez is a lightweight, cross-platform Rust game framework for building 2D and 3D games with minimal friction, inspired by LÖVE. It wraps wgpu for hardware-accelerated rendering, rodio for audio (OGG/WAV/FLAC), glyph_brush for TTF fonts, and provides filesystem abstraction (zip/folder-based resource loading), input handling via winit, and an event-driven API—aiming to be a batteries-included foundation without dictating physics engines, ECS, or other high-level systems. Single-crate structure: src/lib.rs is the main entry point with organized module organization (graphics, audio, filesystem, event handling). examples/ contains 50+ runnable demos from trivial (01_super_simple.rs) to complex (3d rendering, bunnymark benchmarking). doc_tests/ holds doctests via skeptic. Shaders are in WGSL (19KB). Modular features: audio, gamepad, 3d, gltf, obj are optional Cargo features.

👥Who it's for

Game developers building 2D/3D indie and hobby games in Rust who want immediate productivity without learning a heavy engine, and contributors looking to maintain or extend a community game framework with a LÖVE-compatible API.

🌱Maturity & risk

Actively developed (v0.10.0-rc0, approaching 1.0). The project has CI/CD via GitHub Actions (rust.yml), comprehensive examples (50+ files in examples/), detailed docs, and a Discord community, but is still pre-1.0 and may have breaking changes. The codebase is substantial (506KB Rust) with established patterns, making it production-ready for indie projects but not yet API-stable.

Dependency surface is moderate but complex: wgpu (GPU abstraction), rodio (audio), gilrs (gamepad), glyph_brush (font), winit (windowing), and image format decoders. Pre-1.0 release status means breaking changes are expected. Single maintainer risk is mitigated by the community and GitHub organization structure, but commit recency and open-issue backlog would need inspection. Platform support is advertised as 'fully supported: Windows, Linux, macOS' with Android/iOS/Web as experimental.

Active areas of work

The project is working toward v1.0 (current: 0.10.0-rc0). Development targets wgpu 29, Rust 2021 edition, and improved 3D support (gltf, obj loaders available). Active additions include 3D features (see 3d.rs, cube.rs examples) and modernization of rendering pipeline. The CHANGELOG.md and RELEASE_PROCEDURES.md indicate organized release management.

🚀Get running

git clone https://github.com/ggez/ggez
cd ggez
cargo build
cargo run --example 02_hello_world

For development: cargo test runs tests, cargo doc --open builds docs locally.

Daily commands:

cargo run --example 02_hello_world

Or build and run any example in examples/. For 3D: cargo run --example 3d --features=3d. For GLTF loading: cargo run --features=gltf,3d.

🗺️Map of the codebase

  • src/lib.rs — Library root and public API surface; defines what ggez exports to users
  • src/context.rs — Core Context struct managing game state, graphics, audio, and filesystem; required by nearly all game loops
  • src/graphics/draw.rs — 2D drawing API implementation; the primary interface for rendering in most games
  • src/graphics/gpu/mod.rs — GPU abstraction layer using WGPU; bridges drawing calls to graphics hardware
  • src/event.rs — Event system and game loop dispatcher; controls input handling and frame timing
  • src/conf.rs — Configuration struct defining window, graphics, and feature settings at startup
  • Cargo.toml — Defines dependencies (wgpu, rodio, gilrs) and feature flags (audio, gamepad, 3d)

🛠️How to make changes

Add a new 2D drawing primitive

  1. Define the shape struct in a new submodule (src/graphics/draw.rs)
  2. Implement mesh generation (vertices/indices) for the shape (src/graphics/draw.rs)
  3. Add a public draw_* method to DrawContext trait (src/graphics/context.rs)
  4. Add example demonstrating the new primitive (examples/03_drawing.rs)

Add a custom shader effect

  1. Write WGSL shader file in resources/ directory (resources/fancy.wgsl)
  2. Create pipeline definition in gpu/pipeline.rs (src/graphics/gpu/pipeline.rs)
  3. Add bind group layout in gpu/bind_group.rs (src/graphics/gpu/bind_group.rs)
  4. Expose drawing function in graphics/draw.rs or graphics/draw3d.rs (src/graphics/draw.rs)
  5. Create example in examples/shader.rs or similar (examples/shader.rs)

Add a new audio feature (conditional on 'audio' feature)

  1. Extend audio playback API in src/audio.rs (src/audio.rs)
  2. Update Context to expose new audio methods (src/context.rs)
  3. Add example demonstrating the feature (examples/sounds.rs)
  4. Ensure feature gate: #[cfg(feature = "audio")] in context.rs (src/context.rs)

Add support for a new file format (via filesystem)

  1. Update filesystem.rs to recognize the new extension (src/filesystem.rs)
  2. Implement decoder using appropriate crate (e.g., image crate for images) (src/graphics/image.rs)
  3. Add public loading method to Context (src/context.rs)
  4. Add test file in resources/ and example usage (examples/files.rs)

🔧Why these technologies

  • WGPU — Cross-platform GPU abstraction (Vulkan/Metal/DX12); supports WebGPU; enables native + web build parity
  • Rust & tokio async — Memory safety without GC; enables low-latency game loop; coroutine support for async game logic
  • rodio — Pure Rust audio library; cross-platform; no external dependency bloat; optional feature
  • gilrs — Gamepad input library; cross-platform; optional feature flag allows games without gamepad support to skip it
  • image crate — Unified image loading (PNG, JPEG, etc.); optional rayon feature for parallel decoding

⚖️Trade-offs already made

  • Immediate-mode rendering API (stateless draw calls) vs. retained-mode scene graph

    • Why: Simplicity and predictability for small-to-medium games; matches LÖVE API; less abstraction overhead
    • Consequence: Games must manage their own state; no automatic culling or optimization; suitable for 2D games with <1000 draw calls
  • Single Context as god object vs. dependency injection or ECS

    • Why: Easier API surface and learning curve; matches LÖVE; all subsystems accessible from one handle
    • Consequence: Context becomes a bottleneck for large projects; encourages mutable borrow; teams may move to bevy/specs for larger games
  • Optional features (audio, gamepad, 3d) via Cargo features

    • Why: Reduce binary size and compile time for games that don't need them; web targets may not support all features
    • Consequence: Feature-gated APIs require #[cfg] checks; documentation must clarify which features enable what
  • 2D and 3D APIs coexist (no separate 3D engine)

    • Why: Allows hybrid 2D+3D games; no need to learn a different framework; LÖVE doesn't have 3D so this extends it
    • Consequence: 3D support is less mature than 2D; no full scene graph; games needing heavy 3D should use bevy or glium

🚫Non-goals (don't propose these)

  • Not a full-featured game engine (e.g., no physics engine, particle system, audio mixer in core; those are add-ons)
  • Not intended for AAA-scale games (recommend bevy, Godot, or Unreal for large teams)
  • Does not provide an editor or visual tools (ggez is code-first)
  • No built-in networking or multiplayer framework (developers integrate external crates)
  • Does not abstract over platform differences comprehensively (some OS-specific code required for edge cases)

🪤Traps & gotchas

Feature gates: 3D, audio, gamepad, and model loaders (gltf, obj) are optional; code that uses them must enable features. wgpu initialization: requires async runtime (uses pollster for blocking); Context initialization may fail on headless systems. Resource paths: loaded via filesystem abstraction which searches specific directories (see Filesystem API docs); relative paths are context-dependent. Shader compilation: WGSL shaders are compiled at runtime; syntax errors only surface during draw calls. Platform differences: Web/Android/iOS are experimental; some features (gamepad, certain audio formats) vary by platform. Mint version pinning: must be 0.5.9 to match glam; mismatches break math type conversions.

🏗️Architecture

💡Concepts to learn

  • Immediate-Mode Graphics (IMG) — ggez uses an immediate-mode API (Draw builder, draw calls per frame) rather than retained-mode; understanding this shapes how you structure rendering code
  • GPU Abstraction via wgpu — ggez abstracts hardware acceleration through wgpu (WebGPU equivalent), which handles device creation, command buffers, and shader compilation; understanding the boundary helps debug rendering issues
  • Filesystem Virtualization (VFS) — ggez's Filesystem module mounts resources from zip archives or folders transparently; critical for cross-platform asset distribution and testing
  • GameState Trait Pattern — The core GameState trait (update/draw/event_handler callbacks) defines ggez's event loop; this inversion-of-control pattern is fundamental to the API design
  • Lyon Path Tessellation — ggez uses lyon to convert vector paths into GPU-ready triangle meshes; understanding tessellation helps with custom shape rendering
  • Glyph Rasterization & Caching — TTF text rendering via glyph_brush pre-rasterizes and caches glyphs; affects text performance and memory; understanding batch rendering is key
  • Async Runtime (Pollster) — ggez uses pollster to block on async GPU operations (context init, device creation); important for understanding initialization and debugging async-related hangs
  • gfx-rs/wgpu — The underlying GPU abstraction layer that ggez wraps; essential for understanding rendering internals
  • PistonDevelopers/piston — Alternative Rust game engine with similar scope; design inspiration and ecosystem companion
  • bevyengine/bevy — Heavier-weight Rust game engine with ECS and advanced features; target users often migrate from ggez when needing more structure
  • love2d/love — Original LÖVE framework that ggez's API is based on; design philosophy and API reference
  • glam-rs/glam — The linear algebra library ggez relies on for Vec, Mat, Quat types; required for game math

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for graphics module (wgpu integration)

The repo has extensive examples but lacks unit tests for core graphics functionality. Given that ggez is a graphics-heavy game framework using wgpu 29, adding tests for the graphics module would catch regressions in rendering, mesh creation, and shader compilation. This is critical for a graphics library where subtle bugs can go unnoticed.

  • [ ] Create tests/graphics_tests.rs for core graphics module functionality
  • [ ] Add tests for mesh creation and batching (examples/meshbatch.rs exists but no unit tests)
  • [ ] Add tests for transform operations (examples/transforms.rs exists but no unit tests)
  • [ ] Add tests for canvas/framebuffer operations (examples/hello_canvas.rs and examples/canvas_subframe.rs have examples but no tests)
  • [ ] Integrate into CI workflow (.github/workflows/rust.yml to run cargo test --lib graphics)

Add GitHub Actions workflow for cross-platform build validation

The repo claims to be 'lightweight cross-platform' and has docs/BuildingForEveryPlatform.md, but the CI workflow (.github/workflows/rust.yml) likely only tests on Linux. Adding explicit macOS and Windows CI jobs would catch platform-specific issues early and verify the cross-platform claims.

  • [ ] Examine current .github/workflows/rust.yml to identify what platforms are tested
  • [ ] Add macOS runner job matrix to rust.yml (GitHub Actions 'macos-latest')
  • [ ] Add Windows runner job matrix to rust.yml (GitHub Actions 'windows-latest')
  • [ ] Test at least one example per platform (e.g., examples/01_super_simple.rs) to verify build success
  • [ ] Document results in docs/BuildingForEveryPlatform.md if needed

Add integration tests for optional features (audio, gamepad, 3d, gltf, obj)

The Cargo.toml defines 6 optional features but there are no feature-gated integration tests. This risks silent breakage when dependencies update. Creating tests for each feature flag combination would ensure optional features remain functional.

  • [ ] Create tests/feature_audio.rs to test audio playback with rodio (examples/sounds.rs exists)
  • [ ] Create tests/feature_3d.rs to test 3D rendering with basic shapes (examples/3d.rs, examples/3dshapes.rs exist)
  • [ ] Create tests/feature_gamepad.rs to validate gamepad input parsing (examples/input_test.rs exists)
  • [ ] Add .cargo/config.toml or update rust.yml to test feature combinations: --features audio, --features 3d, --features gltf, --features obj
  • [ ] Ensure doc_tests/src/lib.rs is updated to cover feature-gated code paths

🌿Good first issues

  • Add doctests to src/graphics/mod.rs for Drawable trait and Draw builder pattern with concrete mesh/shape examples—currently documented but untested.
  • Expand examples/ with a dedicated 'input_advanced.rs' showing keyboard/mouse state queries and gamepad rumble (gilrs integration)—input_test.rs exists but lacks structured examples.
  • Write integration tests in a tests/ directory covering Context initialization, basic draw/update cycle, and filesystem asset loading (zip and folder modes)—currently only doctests and examples exist.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • f066eec — Merge pull request #1341 from damian-giebas-solidstudio/fix/1273-drop-suboptimal-texture (sampullman)
  • 403dc5a — Drop SurfaceTexture before reconfiguring surface (Draqun)
  • b43e673 — Remove unused EventHandler::text_input_event (a1phyr)
  • 8f079f7 — Improve cargo features (a1phyr)
  • f84aff9 — Fix compilation without feature gamepad (a1phyr)
  • a8450b4 — Update dependencies (a1phyr)
  • c46bf21 — Continue development on master (#1339) (a1phyr)
  • 07f8b02 — Merge pull request #1330 from ggez/release (a1phyr)
  • b24947c — Release 0.10.0-rc0 (a1phyr)
  • 0277065 — Merge pull request #1329 from a1phyr/improve_audio (a1phyr)

🔒Security observations

The ggez project shows generally good security practices as a Rust-based game framework. Key strengths include use of memory-safe Rust, no apparent hardcoded credentials, and active maintenance. Primary concerns are: (1) incomplete Cargo.toml content visible in the analysis, (2) several dependencies enabled by default that could be optional, increasing attack surface, and (3) lack of visible automated dependency vulnerability scanning in CI/CD. The dependency choices are reasonable for a game framework, though image processing and audio libraries should be monitored for security updates. No SQL injection, XSS, or major infrastructure issues are apparent given the project's nature as a game library rather than a web service.

  • Medium · Incomplete Dependency Declaration in Cargo.toml — Cargo.toml - [dependencies] section, obj-rs entry. The obj-rs dependency declaration appears to be cut off in the provided Cargo.toml content. The line reads 'obj-rs = { version = "0.7.1",' without closing braces, which indicates either a malformed configuration or incomplete file content. This could lead to build failures or unexpected dependency versions being used. Fix: Complete the obj-rs dependency declaration with proper version constraints and features. Ensure all dependencies have complete and valid specifications.
  • Low · Optional Audio Dependency Without Default Disablement — Cargo.toml - [features] section, 'audio' in default. The 'audio' feature is included in the default features list and depends on the 'rodio' crate. While rodio is a legitimate audio library, including audio capabilities by default increases the attack surface. Audio processing libraries can have buffer overflow or parsing vulnerabilities. Fix: Consider removing 'audio' from default features if it's not essential for all use cases. Users can explicitly enable it when needed via feature flags.
  • Low · Gamepad Feature Enabled by Default — Cargo.toml - [features] section, 'gamepad' in default. The 'gamepad' feature is included in default features and pulls in the 'gilrs' dependency. While gilrs is a legitimate gamepad library, enabling this by default increases dependencies and potential attack surface for users who don't need gamepad support. Fix: Consider making 'gamepad' an optional feature that users explicitly enable if needed, similar to 3d features. This follows the principle of minimal default dependencies.
  • Low · Missing WGPU Security Configuration Details — Cargo.toml - wgpu dependency and src/lib.rs (not fully visible). The codebase uses wgpu 29 for graphics rendering. While wgpu is a well-maintained library, there's no visible security configuration for GPU resource limits, shader compilation sandboxing, or validation in the provided file structure. Untrusted shader code or GPU memory exhaustion could be concerns. Fix: Review wgpu initialization code to ensure proper validation layers are enabled in development, GPU resource limits are enforced, and any user-provided shaders are validated before compilation.
  • Low · Dependency on Numerous Image Format Parsers — Cargo.toml - image dependency with ['png', 'webp', 'bmp', 'jpeg'] features. The image crate is configured with multiple format support (png, webp, bmp, jpeg). While these are standard formats, each parser adds complexity and potential parsing vulnerabilities. Image format parsers have historically been sources of security issues. Fix: Document which image formats are actually required by the application. Consider disabling unused formats to reduce attack surface. Ensure the image crate is kept up-to-date as image processing libraries receive frequent security updates.
  • Low · No Visible Dependency Audit Mechanism — .github/workflows/rust.yml (content not provided). The file structure does not show evidence of cargo-audit, cargo-deny, or other dependency vulnerability scanning tools being integrated into the CI/CD pipeline, though CI workflow exists at .github/workflows/rust.yml. Fix: Integrate cargo-audit or cargo-deny into the GitHub Actions CI pipeline to automatically detect known vulnerabilities in dependencies. Add a check that fails the build if critical vulnerabilities are found.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · ggez/ggez — RepoPilot