RepoPilotOpen in app →

not-fl3/macroquad

Cross-platform game engine in Rust.

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 5w ago
  • 34+ active contributors
  • Distributed ownership (top contributor 25% of recent commits)
Show all 6 evidence items →
  • Apache-2.0 licensed
  • CI configured
  • Tests present

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/not-fl3/macroquad)](https://repopilot.app/r/not-fl3/macroquad)

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/not-fl3/macroquad on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: not-fl3/macroquad

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/not-fl3/macroquad 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 5w ago
  • 34+ active contributors
  • Distributed ownership (top contributor 25% of recent commits)
  • Apache-2.0 licensed
  • CI configured
  • Tests present

<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 not-fl3/macroquad repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/not-fl3/macroquad.

What it runs against: a local clone of not-fl3/macroquad — 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 not-fl3/macroquad | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | 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 ≤ 67 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>not-fl3/macroquad</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of not-fl3/macroquad. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/not-fl3/macroquad.git
#   cd macroquad
#
# 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 not-fl3/macroquad and re-run."
  exit 2
fi

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

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 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 "Cargo.toml" \\
  && ok "Cargo.toml" \\
  || miss "missing critical file: Cargo.toml"
test -f "src/exec.rs" \\
  && ok "src/exec.rs" \\
  || miss "missing critical file: src/exec.rs"
test -f "src/camera.rs" \\
  && ok "src/camera.rs" \\
  || miss "missing critical file: src/camera.rs"
test -f "macroquad_macro/src/lib.rs" \\
  && ok "macroquad_macro/src/lib.rs" \\
  || miss "missing critical file: macroquad_macro/src/lib.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 67 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~37d)"
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/not-fl3/macroquad"
  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

Macroquad is a Rust game engine that provides cross-platform 2D/3D rendering, immediate-mode UI, and audio handling with a single codebase that compiles to Windows/Linux/macOS/HTML5/Android/iOS. It wraps miniquad (a low-level graphics abstraction) and adds high-level game development primitives like draw_circle(), draw_rectangle(), UI widgets, and particle systems—all inspired by raylib's simplicity but implemented in Rust. Monorepo structure: src/ contains the core engine API (prelude module, drawing primitives, input handling), examples/ holds 45+ runnable demos (basic_shapes.rs, 3d.rs, audio.rs, ui.rs, etc.), and dev-dependencies point to specialized subpackages (particles/, tiled/, profiler/, physics-platformer/) that extend core functionality. The macroquad_macro crate (path dependency) handles the #[macroquad::main] async entry-point macro.

👥Who it's for

Game developers and hobbyists who want to write games in Rust without platform-specific boilerplate, targeting both native desktop and web (WASM) platforms. Contributors are Rust developers interested in graphics abstractions, cross-platform tooling, and game engine architecture.

🌱Maturity & risk

Actively maintained and production-ready: at version 0.4.14 with CI/CD via GitHub Actions (rust.yml workflow), pinned dependency on miniquad 0.4.8, and extensive examples covering 3D, audio, UI, and physics. The codebase is substantial (565k lines of Rust) and stable enough for small-to-medium game projects, though still pre-1.0 and subject to API changes.

Standard open source risks apply.

Active areas of work

Recent stable activity: v0.4.14 released with pinned miniquad 0.4.8, GitHub Actions CI validates Rust builds, examples remain current. No visible breaking API churn. The repo appears in steady maintenance mode rather than rapid feature development—focus is on stability and bug fixes rather than new major features.

🚀Get running

cargo init --bin my-game
cd my-game
echo '[dependencies]
macroquad = "0.4"' >> Cargo.toml
cat > src/main.rs << 'EOF'
use macroquad::prelude::*;
#[macroquad::main("MyGame")]
async fn main() {
    loop {
        clear_background(BLACK);
        draw_circle(screen_width() / 2.0, screen_height() / 2.0, 50.0, RED);
        next_frame().await
    }
}
EOF
cargo run

Daily commands:

cargo run --example basic_shapes
cargo run --example 3d
cargo run --example ui
# For WASM:
rustup target add wasm32-unknown-unknown
cargo build --target wasm32-unknown-unknown --release
# Output: target/wasm32-unknown-unknown/release/CRATENAME.wasm (then serve via HTML loader)
# For Android:
cargo apk --example basic_shapes

🗺️Map of the codebase

  • src/lib.rs — Main library entry point and public API surface for macroquad; all public functions and module definitions originate here
  • Cargo.toml — Defines core dependencies (miniquad, glam, image) and feature flags (audio, log-rs) that shape the entire architecture
  • src/exec.rs — Event loop and execution model; critical for understanding how macroquad runs on all platforms
  • src/camera.rs — Camera abstraction layer; foundational for 2D/3D rendering coordinate transforms across all examples
  • macroquad_macro/src/lib.rs — Procedural macro implementation for main() annotation; required to understand platform-specific build mechanics
  • src/color.rs — Core color type definition used throughout rendering and UI systems
  • src/audio.rs — Audio subsystem integration with quad-snd; handles cross-platform sound/music playback

🛠️How to make changes

Add a new 2D game example

  1. Create a new .rs file in examples/ directory following the pattern of arkanoid.rs or snake.rs (examples/your_game.rs)
  2. Use #[macroquad::main("Title")] macro as entry point and call next_frame().await in main loop (examples/your_game.rs)
  3. Import drawing functions from macroquad (draw_rectangle, draw_circle, draw_text, etc.) (examples/your_game.rs)
  4. Add input handling via is_key_pressed(), is_mouse_button_pressed() from input module (examples/your_game.rs)
  5. Run with: cargo run --example your_game (examples/your_game.rs)

Add a custom shader/material

  1. Create a .glsl file with vertex and fragment shaders (reference: examples/custom_material.rs uses inline shader strings) (examples/your_shader.glsl)
  2. In your code, load the shader using load_material() and pass GLSL source code (examples/your_material.rs)
  3. Bind uniforms via set_uniform() with appropriate types (vec2, vec3, mat4, etc.) (examples/your_material.rs)
  4. Call gl_use_material() before draw calls to apply custom shader (examples/your_material.rs)

Create a new particle effect

  1. Reference particles/src/lib.rs for EmitterConfig and Emitter API (particles/src/lib.rs)
  2. In your game, create Emitter with custom EmitterConfig (lifetime, emission_rate, velocity_curve) (examples/particles_example.rs)
  3. Call emitter.draw() each frame in the render loop with an optional texture (examples/particles_example.rs)
  4. Refer to particles/src/particles.glsl for low-level particle shader behavior (particles/src/particles.glsl)

Add UI components to a game

  1. Reference examples/ui.rs and examples/ui_skins.rs for widget patterns (buttons, windows, checkboxes) (examples/ui.rs)
  2. Place macroquad_widgets::root_ui() or root_ui().with_skin() block around UI code (examples/ui.rs)
  3. Add widgets via root_ui().button(), root_ui().label(), root_ui().window() calls (examples/ui.rs)
  4. Optionally load custom fonts from examples/ui_assets/ and apply skins for theming (examples/ui_skins.rs)

🔧Why these technologies

  • miniquad (v0.4.8) — Low-level graphics abstraction that handles windowing, OpenGL/WebGL context management, and input across PC, Web, Android, and iOS with minimal dependencies
  • glam (v0.27) — Pure Rust SIMD-optimized math library for Vec2/Vec3/Mat4 operations; scalar-math feature ensures WASM compatibility
  • image crate (PNG/TGA support) — Standard cross-platform image loading without additional native dependencies; supports core game asset formats
  • quad-rand (PRNG) — Lightweight deterministic random number generation suitable for games without std::rand overhead
  • Procedural macros (macroquad_macro) — Platform-specific #[macroquad::main] macro abstracts away entry point differences (wasm-bindgen vs native, Android JNI, etc.)

⚖️Trade-offs already made

  • Immediate-mode UI instead of retained-mode

    • Why: Simpler API for game developers, easier state management in game loops, minimal overhead per-frame
    • Consequence: UI state must be recomputed every frame; not ideal for complex data-bound UIs but perfect for game menus/HUDs
  • Single monolithic library with all-in-one rendering/audio/UI instead of micro-library ecosystem

    • Why: Zero setup friction: one cargo add macroquad and you can draw. Fast compile times (16s from scratch).
    • Consequence: Less modularity; audio/particles are included features not standalone; harder to replace individual subsystems
  • Automatic geometry batching for 2D rendering

    • Why: Transparent performance: developers don't manually manage draw order or batches
    • Consequence: Less control over rendering order; tricky to debug performance; some advanced techniques (custom depth testing) harder to implement
  • Async/await event loop model via macroquad_macro

    • Why: Natural Rust pattern; game loop reads linearly as imperative code instead of callback spaghetti
    • Consequence: Requires platform-specific runtime shims; WASM version uses requestAnimationFrame polling which may differ from native vsync behavior

🚫Non-goals (don't propose these)

  • Does not provide ECS framework; users must implement their own entity/component systems
  • Does not include advanced physics (only lightweight platformer plugin available); no Rapier/Bevy Physics integration
  • Does not handle networking; designed for single-player or local multiplayer only
  • Does not include scene graph or hierarchical object management

🪤Traps & gotchas

Platform-specific system dependencies required on Linux (libX11-dev, libGL1-mesa-dev, libasound2-dev on Ubuntu; listed in README but easy to miss). WASM target requires explicit rustup target install before cargo build. The #[macroquad::main] macro rewrites main() as async and handles event-loop setup—developers must use await on next_frame() or the game will hang. Dev-dependencies use path dependencies (particles, tiled, profiler, physics-platformer) that must be cloned alongside the monorepo; these are not published to crates.io. Miniquad version is pinned to exactly 0.4.8 (using =), so updating it requires coordinated changes across multiple files.

🏗️Architecture

💡Concepts to learn

  • Immediate Mode Rendering — Macroquad's drawing API (draw_circle, draw_rectangle, etc.) uses immediate-mode semantics where each call adds to a batch that's flushed per frame—understanding this prevents performance surprises and explains why next_frame().await is required
  • Graphics API Abstraction Layer — Miniquad abstracts OpenGL/Metal/WebGPU behind a unified interface, allowing macroquad to compile identically to 5+ platforms—a key design win for portability without platform-specific #[cfg] blocks
  • WebAssembly (WASM) Compilation Target — Macroquad can compile Rust game code to WASM (rustup target add wasm32-unknown-unknown) and run in browsers without modification—critical for web game distribution and why next_frame().await uses async/await (integrates with JS event loop)
  • Cross-Platform Marshaling (Touch/Keyboard/Mouse) — Input events (examples/input_keys.rs, examples/input_touch.rs) are normalized across desktop, web, Android, and iOS—macroquad handles platform differences in event representation so game code doesn't need platform-specific input handling
  • Procedural Macros for Async Entry Point — The #[macroquad::main("title")] macro (in macroquad_macro) wraps user code and handles platform-specific event loop setup (especially critical for WASM which requires integration with JavaScript promises)—understanding macro expansion helps debug startup issues
  • Font Rasterization (Signed Distance Field / Bitmap) — Fontdue (0.9) rasterizes TTF fonts to bitmaps at runtime—knowing this explains text rendering performance, font size limitations, and why examples load fonts at startup (examples/text.rs, examples/default_font.rs)
  • Automatic Geometry Batching — Macroquad batches draw calls internally (mentioned in README as 'efficient 2D rendering with automatic geometry batching') to minimize GPU submissions—developers don't manage batches explicitly, but understanding this prevents naive patterns like drawing text every frame without caching
  • not-fl3/miniquad — The low-level graphics abstraction that macroquad wraps—pinned at 0.4.8 in Cargo.toml, provides the WebGPU/Metal/OpenGL backend
  • raysan5/raylib — The original C library that macroquad's API design is heavily inspired by (same function naming, immediate-mode philosophy, cross-platform goals)
  • bevyengine/bevy — Alternative Rust game engine with more features and a larger community, but heavier dependencies and steeper learning curve than macroquad's simplicity-first approach
  • ggez/ggez — Lightweight Rust 2D game library with similar goals (simplicity, cross-platform) but uses a different graphics backend (glium then wgpu) and less WASM support
  • not-fl3/macroquad-particles — Official particle system extension shipped as a dev-dependency in this repo, demonstrates how to build macroquad plugins

🪄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 integration tests for audio feature flag

The audio feature is optional (quad-snd dependency) but there are no automated tests verifying that examples/audio.rs compiles and runs correctly with/without the 'audio' feature. This prevents regressions when dependencies are updated. A GitHub Actions workflow step testing both cargo build --no-default-features and cargo build --features audio would catch breaking changes early.

  • [ ] Create .github/workflows/feature-tests.yml with steps to test: cargo build --example audio && cargo build --example audio --no-default-features
  • [ ] Verify examples/audio.rs compiles in both feature configurations
  • [ ] Add feature-specific compilation check to CI pipeline

Add Android build verification to CI/CD

The Cargo.toml has [package.metadata.android] configured with examples/ as assets, and the README mentions 'Single command deploy for both WASM and Android', yet .github/workflows/rust.yml likely doesn't test Android builds. Adding Android target compilation verification would prevent native build regressions.

  • [ ] Review current .github/workflows/rust.yml to confirm android-aarch64 target is not tested
  • [ ] Add cargo check --target aarch64-linux-android step to CI workflow
  • [ ] Document Android build requirements in README.md's setup section if missing

Add unit tests for text measurement utilities

There are examples for text features (examples/text.rs, examples/text_measures.rs, examples/text_wrap.rs) but likely no unit tests in src/ validating text layout calculations. The fontdue dependency is used for font rendering, but its integration deserves test coverage to prevent layout regressions.

  • [ ] Create tests/text_layout_tests.rs with test cases for text_measures functionality
  • [ ] Add tests for text wrapping edge cases (empty strings, very long words, unicode)
  • [ ] Include tests verifying font metrics calculations match expected values
  • [ ] Run cargo test --test text_layout_tests in CI pipeline

🌿Good first issues

  • Add comprehensive doc comments and examples to drawing functions in src/ that lack them (e.g., draw_poly, draw_texture_ex) and generate docs with cargo doc --open to verify rendering
  • Create a beginners' troubleshooting guide documenting the Linux system dependencies per distro (ubuntu vs fedora vs arch), platform-specific build failures, and WASM target setup in a TROUBLESHOOTING.md file
  • Expand examples/text_wrap.rs or create examples/text_measurement_guide.rs with detailed comments on text_dimension(), measure_text_dimensions(), font loading, and Unicode handling edge cases

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 87f2b0e — Don't allocate a Vec per pixel in Font::cache_glyph (Rust >= 1.53.0) (yuryshulaev)
  • 6b0de95 — Linux: fix enter/leave mouse state handling (Jose Luis Parrilla Fuentes)
  • 9db1345 — README: fix target dir mentions and some other inconsistencies (mochou-p)
  • 4283931 — doc: clarify Color::from_hex didn't contains alpha (YuevUwU)
  • 87541ba — Fix Camera3D aspect when using render target (ingobeans)
  • aec10b2 — Fix world_to_screen to handle viewport correctly (ESBL-Erik)
  • 748a79a — Added is_any_key_down (Quan1umMango)
  • a78f842 — add normalized function for rect (michaelcortese)
  • 23b8bc3 — schedule deferred drop for render passes to avoid dropping before frame is over (jonatino)
  • d8d6141 — add measure_multiline_text (JaniM)

🔒Security observations

The macroquad repository demonstrates a generally secure posture with minimal external dependencies and clear separation of optional features. The primary concerns are: (1) the exact version pinning of the critical miniquad dependency which should be verified for known vulnerabilities, (2) lack of visible security policy and vulnerability disclosure documentation, and (3) absence of a CHANGELOG to track security-related updates. The codebase itself shows no evidence of hardcoded secrets, SQL injection risks, XSS vulnerabilities, or exposed credentials in the analyzed files. As a game engine library with cross-platform support, the attack surface is relatively controlled. Recommended improvements focus on dependency management transparency and security communication practices.

  • Medium · Pinned Dependency Version - miniquad — Cargo.toml - dependencies section. The miniquad dependency is pinned to an exact version (=0.4.8) with the 'log-impl' feature enabled. While pinning can prevent unexpected breaking changes, it may also prevent receiving critical security updates. The exact version constraint should be reviewed to ensure no known vulnerabilities exist in miniquad 0.4.8. Fix: Review the security advisory database for miniquad 0.4.8 (https://rustsec.org/). Consider using a caret constraint (^0.4.8) to allow patch updates, or maintain a process for regularly reviewing and updating pinned dependencies.
  • Low · Optional Audio Feature Not Enabled by Default — Cargo.toml - features section. The 'audio' feature (quad-snd) is optional and not included in the default features set. While this reduces the default attack surface, users may not realize they need to explicitly enable audio support, potentially leading to incomplete feature usage. Fix: Document the audio feature clearly in README.md. Consider if audio should be in default features based on typical use cases. Ensure users are aware of optional features and their security implications.
  • Low · Missing CHANGELOG and Security Policy — Root directory. The repository structure shows no visible CHANGELOG.md, SECURITY.md, or security.txt file. This makes it difficult for users to identify when security fixes are released or how to report security vulnerabilities responsibly. Fix: Create a SECURITY.md file documenting the vulnerability disclosure process and supported versions. Maintain a CHANGELOG.md with security-related notes. Consider adding a .well-known/security.txt file.
  • Low · Backtrace Feature Optional and Conditional — Cargo.toml - dependencies section. The backtrace dependency (0.3.60) is optional and may not always be enabled. While this is reasonable, it should be clearly documented as it affects error reporting and debugging capabilities. Fix: Document when backtrace is needed and ensure it's enabled in production builds if error tracking is critical. Review backtrace 0.3.60 for known vulnerabilities.
  • Low · Development Dependency on Local Paths — Cargo.toml - dev-dependencies section. Dev dependencies reference local paths (./particles, ./tiled, ./profiler, ./physics-platformer) without version constraints. This is appropriate for dev dependencies but could mask issues if those subdirectories are modified. Fix: Ensure all local path dependencies are version-controlled and reviewed before publishing. Document the local development setup clearly.

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 · not-fl3/macroquad — RepoPilot