plutonium_engine
A pure-Rust 2D graphics engine built on wgpu. SVG-first,
DPI-aware, with font-atlas text, retained-mode widgets, animation, and a
WebAssembly target.

Every tile above is real engine output — see Examples.
Install
[]
= "0.8"
Hello, sprite
The frame callback runs every frame and receives the engine, a per-frame input
snapshot (FrameContext), and the app handle:
use ;
See docs/getting-started.md for a step-by-step
walk-through.
Features
| Area | What you get |
|---|---|
| SVG textures | Vector sprites rasterized via resvg/tiny-skia, DPI-aware. |
Raster textures (raster) |
PNG/JPEG loading with Contain/Cover/StretchFill fitting and logical insets. |
| Texture atlases | Per-tile UV addressing for sprite sheets and tilemaps. |
| Text | Font-atlas rendering with a raster path and an MSDF (crisp-at-any-scale) path, alignment, and auto-sizing. |
Widgets (widgets, default) |
Retained-mode Button, TextInput, Text2D, plus slider/toggle patterns, with hover/press/focus states. |
| Shapes | Shape vector primitives — rectangle, circle, polygon (via ShapeType). |
| Effects | Perimeter glow (draw_rect_glow) and tutorial halos (draw_halo, HaloPreset). |
| Camera | Follow-target with boundary clamping and frame-rate-independent smoothing. |
Layout (layout) |
Anchor/percent/margin helpers for building UIs. |
Animation (anim) |
Tween, Track::{Sequence,Parallel}, Timeline with labels/callbacks and CSS-like cubic-bezier easing. |
| Input | Per-frame key/mouse snapshots, held-key polling, action maps, and scroll deltas. |
| Determinism | Seedable RNG streams and per-frame input record/replay. |
WebAssembly (wasm) |
Runs on wasm32-unknown-unknown with a canvas backend and JS entropy. |
Two interchangeable rendering styles share one GPU pipeline:
- Immediate mode —
begin_frame(),draw_*(...),end_frame(). - Retained mode — hold objects (
create_texture_2d,create_button, …) and callobject.render(engine).
DrawParams carries z (layer), scale, rotation, and tint (RGBA).
Cargo features
= ["widgets"] # retained-mode widgets (Button, TextInput, ...)
= [] # PNG/JPEG texture + raster-font helpers (opt-in)
= [] # anchor/percent layout helpers (opt-in)
= [] # tweening/animation helpers (opt-in)
= ["dep:getrandom"] # wasm32-unknown-unknown support, JS entropy (opt-in)
RNG and record/replay are always available and are not behind a feature flag.
See docs/features-and-modules.md for the full
module and feature reference.
Coordinates
Logical pixels; origin top-left, +x right, +y down. DPI scaling is handled
internally. Engine objects are single-thread affine — create and use them on the
thread that owns the engine. See
docs/coordinates-and-dpi.md.
Examples
Run any example with cargo run --example <name>. Examples that use an optional
feature are marked; run those with the listed --features (or --all-features).
| Example | Shows | Features |
|---|---|---|
texture2d |
SVG sprite loading and movement | |
texture2d_raster |
PNG/raster sprites | raster |
texture_atlas2d |
Sprite sheets / tile UVs | |
grid |
Tilemap-style atlas grid | |
camera |
Camera follow, boundaries, smoothing | |
text2d / text_alignment / text_autosize_demo |
Text rendering, alignment, auto-size | |
msdf_visual_test |
Crisp MSDF text at scale | |
ui_primitives |
Buttons, labels, panels | |
button_debug / slider / toggle |
Widget states and interaction | |
text_input |
Focusable text field | |
actions_demo |
Action-map input (buttons/axes) | |
rect_glow_test |
Neon perimeter glow | |
halo_showcase / halo_text_container |
Tutorial halos/highlights | |
anim_demo |
Tweens and timelines | anim |
layout_basic / layout_percent_position / layout_top_bar |
Layout helpers | layout |
wasm_text_smoke |
Text rendering in the browser | wasm |
WebAssembly
Compile-check the whole workspace for wasm:
Runtime entrypoint (requires an existing #game-canvas canvas):
// cfg(target_arch = "wasm32")
run_app?;
For custom canvas ids or browser-debug tuning, use
run_app_wasm_with_options(config, canvas_id, WasmAppConfig { .. }, frame_callback).await.
wasm-safe loaders (load_font_from_bytes, create_texture_svg_from_str,
create_texture_raster_from_url, …) let you load assets without rebaking
bundles. A browser smoke test is provided:
Testing and snapshots
cargo test --all-features— unit tests (math, transforms, UVs, easing, RNG).cargo run --bin snapshots— headless golden-image tests; setUPDATE_SNAPSHOTS=1to refresh goldens.
Documentation
docs/getting-started.mddocs/features-and-modules.mddocs/api-styles.mddocs/coordinates-and-dpi.mddocs/layout.mddocs/textures.mddocs/instancing-and-batching.mddocs/layering.md
Full API docs: docs.rs/plutonium_engine.
Versioning and stability
The public API may still evolve ahead of 1.0; see
CHANGELOG.md. Low-level integration APIs intentionally expose
crate-pinned wgpu and winit types as part of the semver surface.
Contributing
Issues and PRs welcome — see CONTRIBUTING.md and
CODE_OF_CONDUCT.md.
Workspace note
plutonium_game/ is an in-repository companion workspace used to exercise engine
integrations. It is intentionally excluded from the published crate.
License
Licensed under the Apache License 2.0.