spottedcat
A simple, clean 2D/3D graphics library for drawing images and 3D models using Rust and wgpu.
[!WARNING] ALPHA VERSION: This library is currently in an alpha state. The API is subject to frequent breaking changes and significant refactoring. Use with caution in production environments.
Stability
- Stable-ish core direction:
Context,Spot,Image,Model,Text, andrunare the primary surfaces the crate is trying to converge around. - Still volatile: scene payload internals, shader extension points, platform-specific behavior, audio internals, and lower-level rendering details may change between minor releases.
- Release expectation: until
1.0, minor versions may include breaking API changes, behavior fixes, and platform-specific adjustments. - Production guidance: pin an exact crate version if you ship with
spottedcattoday, and review changelogs before upgrading.
Why spottedcat?
The library is named after the Rusty-spotted cat (Prionailurus rubiginosus), the world's smallest wild cat. Just like its namesake, this library aims to be tiny, agile, and remarkably efficient.
Features
- Simple API: Minimal core types to learn:
Context,Spot,Image,Model,Text, andrun. - GPU-accelerated: Built on wgpu for high-performance rendering.
- 2D & 3D Support: Draw 2D UI and images, or load and render 3D models with PBR materials and skeletal animation.
- 3D Billboards: Easily render 2D textures as 3D billboards that properly depth-sort with 3D objects.
- Instanced Rendering: Draw thousands of identical 3D models (grass, particles, crowds) natively in a single CPU draw call via
draw_instanced. - Custom Shaders: Inject custom WGSL code into the rendering pipeline for both 2D and 3D.
- Image operations: Load from files, create from raw data, extract sub-images.
- Text rendering: Custom font support, text wrapping, and styling (color, stroke).
- Audio support: Play sounds, sine waves, and handle fades/volume.
- Input management: High-level API for Keyboard, Mouse, and Touch events.
- Scene management: Easy switching between game scenes with payload support.
- Resource management: Built-in dependency injection for shared resources.
- Cross-platform: Support for Desktop, Web (WASM), iOS, and Android.
Quick Start
Add to your Cargo.toml:
[]
= "0.6.0"
Basic Example
use ;
use Duration;
AI Assistant Guide
For comprehensive guidance on generating games and working with the spottedcat engine, please refer to the dedicated AI Game Generation Guide.
API Overview
Core Components
Context: Central state for managing draw commands, input, audio, and resources.Spot: Trait defining application lifecycle (initialize,update,draw,remove).Image: GPU texture handle for 2D drawing. Supports sub-images and raw data creation.Model: 3D model handle for rendering meshes, PBR materials, and skeletal animations. Supports extreme performance Instanced Rendering (draw_instanced).Text: High-level text rendering with font registration and layout.DrawOption: Unified configuration for position, rotation, scale, and clipping in 2D.DrawOption3D: Configuration for 3D model placement (position, rotation, scale).
Key Systems
- Input: Check keys with
key_down(ctx, ...), mouse withmouse_button_pressed(ctx, ...), or gettouches(ctx). - Audio: Load and play sounds with
play_sound(ctx, ...), or generate tones withplay_sine(ctx, ...). - Scenes: Transition between states using
switch_scene::<NewScene>(). - Resources: Share data between systems via
ctx.get_resource::<T>().
Custom Shaders
You can inject custom WGSL code into the fragment shader using register_image_shader (2D) and register_model_shader (3D).
3D Shader Exposed Variables
When using custom shaders for 3D models, your code is injected at USER_FS_HOOK at the end of the fragment shader. The following variables are available to read or modify:
final_color: vec4<f32>: The computed PBR color (RGB) and opacity (A). You can modify this to change the final output.in: VertexOutput: Containsin.uv,in.normal,in.world_pos, andin.clip_position.user_globals: array<vec4<f32>, 16>: Custom uniform data passed from your Rust code viaShaderOpts.scene: SceneGlobals: Containsscene.camera_pos,scene.ambient_color, andscene.lights.model_globals: ModelGlobals: Containsmodel_globals.mvp,model_globals.model,model_globals.extra(x: opacity), and UV transforms.- Textures (with
s_sampler):t_albedo,t_pbr,t_normal,t_ao,t_emissive.
Example 3D shader hook:
// Make the model pulse based on the extra opacity parameter
let pulse = (sin(model_globals.extra.x * 10.0) + 1.0) * 0.5;
final_color = vec4<f32>(final_color.rgb * pulse, final_color.a);
Platform Support
Declared support:
-
Desktop: Windows, macOS, Linux.
-
Web: Compile to WASM with
wasm-pack. Seecanvas_idinWindowConfig. -
Android: Integrated with
winit's android-activity. -
iOS: Support for UIKit and native sensor access.
-
WASM example:
examples/wasm/webandexamples/wasm/wasm_demo -
Android example:
examples/android/GameActivityExampleandexamples/android/spottedcat_android_wrapper -
iOS example:
examples/ios/SpottedcatIosSimulatorExampleandexamples/ios/spottedcat_ios_wrapper
Generated outputs for these examples such as target/, .gradle/, pkg/, .xcframework/, and IDE caches are intentionally excluded from version control.
License
This project is licensed under either of:
- Apache License, Version 2.0
- MIT license
at your option.