- About Galfus
- Design Philosophy
- Architecture
- Key Concepts
- Quick Start
- Main Features
- Development
- Project Structure
- Documentation
- Contributing
- License
- About Vulppi
Galfus is a rendering and systems core written in Rust and exposed as a dynamic library. The name combines "Vulppi" (derived from Vulpes, the scientific name for fox) and "Frame", representing our mission to create perfect frames for incredible interactive experiences.
Galfus is designed to be host-agnostic and driven by external runtimes via FFI or WASM:
- 🟢 Node.js (N-API)
- 🌙 Lua (via
mlua) - 🐍 Python (via
PyO3) - 🔧 Any environment capable of calling C-ABI functions
- 🌐 Browser runtimes via WASM (WebGPU + DOM canvas)
- 🚀 High Performance: GPU-accelerated rendering with WGPU (WebGPU)
- 🔄 Cross-Platform: Native support for Windows, macOS, and Linux
- 🎮 Complete Input System: Keyboard, mouse, touch, and gamepads (via Gilrs)
- 🪟 Advanced Window Management: Full control over multiple windows (via Winit) or a DOM canvas (WASM)
- 💡 Lighting & Shadows: Support for various light types and shadow mapping
- 🎨 Materials & Textures: Flexible resource management for rendering
- 🔌 Language Bindings: N-API (Node.js), Lua, Python, and more. With C-ABI,
bun:ffiis also possible. - ⚡ MessagePack Communication: Fast binary serialization for commands and events
- 🎯 Host-Agnostic Design: No assumptions about ECS, OOP, or game framework
Galfus follows a black box approach where:
The host controls the engine only through:
- A small set of C functions (
galfus_*)- Binary buffers serialized with MessagePack
Design Goals:
- Host-agnostic: Works with any game framework or architecture
- Minimal public surface: Only essential C-ABI functions exposed
- Binary and fast: MessagePack for structured data, raw bytes for heavy assets
- Clear separation: Host manages logic and IDs, Core manages GPU and rendering
- Async linking: Components/resources can be created in any order, using fallbacks until data is available
Galfus uses a queue-based architecture that enables efficient communication between the host and the Rust core:
## Workspace Layout
The monorepo is split by ecosystem:
- `crates/`
Rust workspace crates for runtime, render, realms, bindings and demos
- `packages/`
Bun/TypeScript workspace packages for transports and host-facing JS runtimes
- `scripts/`
repository automation executed through Bun
### Repository Scripts
- `bun run check`
runs the standard Rust/WGSL validation pipeline
- `bun run artifacts -- --skip-download`
skips artifact download explicitly via CLI flag
- `bun run artifacts -- --base-url <url>`
overrides the artifact source URL without environment variables
- `bun run version -- <semver>`
updates Cargo workspace version and transport package versions, except
`transport-types`
- `bun run release-meta -- --ref <channel>/vX.Y.Z`
resolves the package version, artifact version, npm dist-tag, and GitHub release tag
┌─────────────────────────────────────┐
│ Host Layer │
│ (JS/TS, Lua, Python, etc.) │
│ • Game Logic │
│ • Entity Management │
│ • ID Generation │
└────────┬────────────┬───────────────┘
│ │
│ Commands │ Events
│ (MsgPack) │ (MsgPack)
▼ ▲
┌────────────────────────────┐
│ galfus_send_queue() │
│ galfus_receive_queue() │
│ galfus_receive_events() │
│ galfus_upload_buffer() │
│ galfus_tick() │
└──────────┬─────────────────┘
│
┌──────────────▼───────────────────────┐
│ Galfus Core (Rust) │
│ • Resource Management │
│ • Component Instances │
│ • Platform Proxy (Desktop/Browser) │
│ • GPU Rendering (WGPU) │
│ • Input Processing (Gilrs/Web) │
└──────────────┬───────────────────────┘
│
┌──────────────▼───────────────────────┐
│ GPU Layer │
│ Vulkan / Metal / DirectX 12 │
└──────────────────────────────────────┘
Host (Your Game/App):
- Manage game logic and world state
- Generate logical IDs (entities, resources, buffers)
- Build MessagePack command batches
- Drive the main loop with
galfus_tick() - Process events and responses
Galfus Core:
- Abstract window, input, and rendering systems via platform proxies
- Manage GPU resources and pipelines using WGPU
- Track component instances (cameras, models, etc.)
- Translate commands into internal state changes
- Render frames efficiently
Galfus distinguishes between two fundamental types:
Components - High-level structures describing scene participation:
- Always attached to a host-chosen ID (e.g.
camera_id,model_id,light_id) - Examples:
Camera,Model,Light - Can contain static data (local colors, matrices)
- Reference sharable resources by logical ID
- Created/updated via MessagePack commands
Resources - Reusable assets used by components:
- Identified by logical IDs:
GeometryId,MaterialId,TextureId - Sharable across multiple components/entities
- Have internal GPU handles (buffers, textures, pipelines)
- Examples: geometries, textures, materials
The host manages all logical identifiers:
WindowId- Window instancesRealmId- Realm instancesTargetId- Logical composition targetsCameraId- Camera instancesModelId- Model instancesLightId- Light instancesGeometryId- Mesh/geometry assetsMaterialId- Material configurationsTextureId- Texture assetsBufferId- Upload blob identifiers
These are opaque integers to the core. The host ensures uniqueness and consistency.
The core derives and owns these runtime tables internally:
SurfacePresentConnector
The host composes output through Realm, Target, and TargetLayer commands
instead of managing these internal tables directly.
Galfus allows resources to be created out of order:
- Models can reference geometry or material IDs that do not exist yet.
- Materials can reference texture IDs that do not exist yet.
In these cases, Galfus renders using fallback resources until the real resources are created later with the same IDs. When a referenced resource appears, it is picked up automatically on the next frame without recreating the model or material.
This enables async streaming and decouples creation order.
Galfus uses u32 bitmasks for visibility control:
layerMaskCamera- Specifies which layers a camera can seelayerMaskComponent- Specifies which layers a model belongs tolayerMaskLight- (Future) Which layers a light affects
Visibility Rule:
Visible if: (layerMaskCamera & layerMaskComponent) > 0
This enables:
- World-only or UI-only cameras
- Team-based rendering
- Debug geometry filtering
- Multi-pass rendering strategies
- A single geometry can be referenced by many models.
- A single material can be referenced by many models.
- A single texture can be referenced by many materials.
There is no ownership tracking. If a resource is disposed while still referenced, rendering falls back gracefully.
Per camera:
- Opaque/masked objects are sorted by
material_idthengeometry_idto reduce state changes and batch draw calls. - Transparent objects are sorted by depth for correct blending.
Draw calls are batched by runs of (material_id, geometry_id) after sorting.
Heavy data uses one-shot uploads:
- Host calls
galfusUploadBuffer(bufferId, type, data) - Core stores blob in internal upload table
Create*commands referencebufferIdto consume data- Entry is marked as used and can be removed
CmdUploadBufferDiscardAllcommand clears all pending uploads
Uploads are independent of model/material creation, so you can create components first and upload data later.
- Rust 1.70+ (rustup.rs)
- Vulkan, Metal, or DirectX 12 updated drivers
# Clone the repository
git clone https://github.com/vulppi-dev/galfus.git
cd galfus
# Build and run the first demo
cargo run -p galfus-demo -- 1The demo harness lives in crates/galfus-demo and exercises:
- window creation
- primitive geometry creation
- camera + model setup
- basic rendering loop
- Multiple window creation and management
- Window state control (normal, minimized, maximized, fullscreen)
- Position and size configuration
- Borderless and resizable options
- Custom window icons and cursors
- Drag-and-drop file support
- Window events (resize, move, focus, close)
- Keyboard: Physical key events with modifiers and IME support
- Mouse: Movement, buttons, scroll wheel
- Touch: Multi-touch support with gestures (pinch, pan, rotate) on native
- Pointer: Unified API for mouse/touch/pen via
PointerEvent - Gamepad: Automatic detection, buttons, analog sticks, triggers (Gilrs on native, Gamepad API on web)
- Standard mapping with dead zones
- Change threshold filtering for efficient event generation
- GPU-accelerated rendering via WebGPU
- Cross-platform support (Vulkan, Metal, DirectX 12)
- Buffer upload for textures and meshes
- Efficient CPU-GPU synchronization
- Component-based rendering system
- Layer-based visibility control
- MessagePack serialization for fast binary communication
- Separate queues for:
- Commands (host → core)
- Responses (core → host)
- Events (core → host)
- Profiling data export for performance analysis
- Event caching: Filters duplicate events to reduce overhead
- Redraw optimization: Dirty flag system for selective rendering
- Dead zone filtering: Reduces gamepad noise
- Batch processing: Commands processed in bulk for efficiency
# Build the workspace
cargo build --workspace --release
# Run tests
cargo test
# Check code with Clippy
cargo clippy
# Format code
cargo fmt1. Update host-side logic (game state, entities)
2. Upload heavy data (optional) via `galfus_upload_buffer()`
3. Send command batch via `galfus_send_queue()`
4. Advance the core via `galfus_tick(time, delta_time)`
5. Receive responses via `galfus_receive_queue()`
6. Receive events via `galfus_receive_events()`
7. Read profiling data (optional) via `galfus_get_profiling()`
galfus_receive_queue() consumes and clears the internal response queue.
galfus/
├── crates/
│ ├── galfus-runtime/ # Integration root, ABI re-exports and frame orchestration
│ ├── galfus-types/ # Shared logical/base types
│ ├── galfus-protocol/ # Host/runtime contracts + MsgPack codec
│ ├── galfus-realm-core/ # Realm composition semantics and graph/report DTOs
│ ├── galfus-input/ # Normalized input semantics
│ ├── galfus-render/ # WGPU-facing render policy, graphs and planning helpers
│ ├── galfus-audio/ # Audio domain + backends
│ ├── galfus-platform/ # Desktop/browser integration
│ ├── galfus-realm-3d/ # 3D realm semantics + sync plans
│ ├── galfus-realm-2d/ # 2D realm placeholder/contracts
│ ├── galfus-bindings-ffi/ # C ABI host binding
│ ├── galfus-bindings-wasm/ # wasm-bindgen host binding
│ ├── galfus-bindings-napi/ # Node.js binding
│ ├── galfus-bindings-python/ # Python binding
│ ├── galfus-bindings-lua/ # Lua binding
│ └── galfus-demo/ # Visual/manual validation demos
├── docs/
├── assets/
├── scripts/
├── Cargo.toml
└── README.md
Comprehensive documentation is available in the docs/ folder.
Not sure where to start? Check our complete documentation index for guided navigation based on your role and needs.
For Engine Users (Binding Authors):
- OVERVIEW.md - Start here! High-level concepts and design philosophy
- ABI.md - C-ABI functions, usage contract, and calling conventions
- ARCH.md - Architecture, lifecycle, and main loop patterns
- REALM-ARCH.md - Realm composition architecture and refactor direction
- GLOSSARY.md - Terminology and naming conventions
For Core Contributors (Rust Developers):
- OVERVIEW.md - Core concepts and design
- ARCH.md - System architecture
- API.md - Internal Rust API, crates, and data structures
- GLOSSARY.md - Internal terminology
Additional Resources:
- PLATFORM-PROXIES.md - Platform proxy architecture
- Copilot Instructions - Development patterns and memory
Automated tests do not fully cover perceptual/platform-dependent flows (window lifecycle details, audio audibility, visual quality). Validate those manually by running demo scenarios.
Contributions are welcome! Please follow these guidelines:
- Rust code: Minimal comments, self-descriptive names
- All code: English for variables, functions, types, and comments
- Documentation: English for all docs (README, API docs)
- Communication: Brazilian Portuguese for discussions and issues
- Fork the project
- Create a feature branch (
git checkout -b feature/MyFeature) - Follow the project's coding conventions (see
.github/copilot-instructions.md) - Write tests for your changes
- Ensure all tests pass (
cargo test) - Format your code (
cargo fmt) - Check for issues (
cargo clippy) - Commit your changes (
git commit -m 'Add MyFeature') - Push to your branch (
git push origin feature/MyFeature) - Open a Pull Request
- Keep the C-ABI surface minimal
- Use MessagePack for all structured data crossing the ABI
- Maintain clear separation between host and core responsibilities
- Follow the component/resource model
- Ensure thread safety (all functions are main-thread only)
wgpu- GPU abstraction layer (WebGPU implementation)winit- Cross-platform windowinggilrs- Gamepad inputnapi- Node.js N-API bindings (optional)serde- Serialization frameworkrmp-serde- MessagePack serializationglam- Vector and matrix mathbytemuck- Safe type conversions for GPU dataimage- Image loading and decoding
Bindings now live in dedicated workspace crates:
galfus-bindings-ffi, galfus-bindings-wasm, galfus-bindings-napi,
galfus-bindings-lua, and galfus-bindings-python.
This project is licensed under the MIT License. See the LICENSE.md file for details.
Vulppi is a company focused on creating cutting-edge technologies for game development and interactive applications. Our name comes from Vulpes, the scientific name for fox, symbolizing agility, intelligence, and adaptability.
