WASM-Native Universal Game Engine
Mobile-first to 49" ultrawide - Pure WASM, Zero JavaScript
Jugar (Spanish: "to play") is a WASM-native game engine built on the Batuta Sovereign AI Stack. It compiles to a single .wasm binary with ABSOLUTE ZERO JavaScript dependencies, making it ideal for secure, deterministic game development.
use jugar::prelude::*;
fn main() {
let mut engine = JugarEngine::new(JugarConfig::default());
engine.run(|ctx| {
// Your game logic here
if ctx.input().key_pressed(KeyCode::Escape) {
return LoopControl::Exit;
}
LoopControl::Continue
});
}- Pure WASM - Compiles to
wasm32-unknown-unknownwith zero JavaScript - ECS Architecture - High-performance Entity-Component-System using hecs
- Fixed Timestep - Deterministic physics via Heijunka (leveling) principle
- Responsive Design - Scales from mobile portrait to 32:9 ultrawide monitors
- Tiered Backends - WebGPU → WASM-SIMD → Scalar automatic fallback
- Rigid Bodies - Static and dynamic body simulation
- Collision Detection - Spatial hashing for efficient broad-phase
- GOAP Planner - Goal-Oriented Action Planning for emergent behavior
- Behavior Trees - Modular, composable AI decision making
- Steering Behaviors - Reynolds-style autonomous agent movement
- Viewport Management - Safe area calculation for all aspect ratios
- Anchor System - UI positioning that adapts to screen dimensions
- Resolution Independence - Pixel-perfect scaling across devices
- Spatial 2D Audio - Distance-based attenuation and stereo panning
- Channel Mixing - Master, Music, Effects, Voice, Ambient channels
- Listener System - Player-relative audio positioning
- Value Noise - Configurable octaves, persistence, lacunarity
- Dungeon Generation - BSP-based room placement with corridors
- Wave Function Collapse - Constraint-based procedural generation
Add Jugar to your Cargo.toml:
[dependencies]
jugar = "0.1"use jugar::prelude::*;
fn main() {
// Create engine with default 1920x1080 configuration
let mut engine = JugarEngine::new(JugarConfig::default());
// Spawn a player entity
let player = engine.world_mut().spawn();
engine.world_mut().add_component(player, Position::new(100.0, 100.0));
engine.world_mut().add_component(player, Velocity::new(0.0, 0.0));
// Run the game loop
engine.run(|ctx| {
// Handle input
let input = ctx.input();
let mut vel = Vec2::ZERO;
if input.key_held(KeyCode::W) { vel.y -= 1.0; }
if input.key_held(KeyCode::S) { vel.y += 1.0; }
if input.key_held(KeyCode::A) { vel.x -= 1.0; }
if input.key_held(KeyCode::D) { vel.x += 1.0; }
// Update velocity component
// ... game logic
LoopControl::Continue
});
}# Build for WASM target
cargo build --target wasm32-unknown-unknown --release
# Verify no JavaScript in output (PMAT compliance)
ls target/wasm32-unknown-unknown/release/*.wasm┌─────────────────────────────────────────────────────────────────────────┐
│ JUGAR WASM BUNDLE (Single .wasm file) │
│ NO JAVASCRIPT WHATSOEVER │
├─────────────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Game Loop │ │ AI Agents │ │ Render │ │ Responsive │ │
│ │ (ECS) │ │ (GOAP/BT) │ │ (Viewport) │ │ UI Layout │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ ┌──────┴────────────────┴────────────────┴────────────────┴──────┐ │
│ │ jugar (entry) │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ jugar-core │ jugar-physics │ jugar-ai │ jugar-render │ │
│ │ jugar-input │ jugar-audio │ jugar-ui │ jugar-procgen │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ BATUTA ECOSYSTEM │
│ (trueno v0.7+ / aprender v0.14+) │
└─────────────────────────────────────────────────────────────────────────┘
| Crate | Description | Tests |
|---|---|---|
jugar |
Main entry point, JugarEngine | 17 |
jugar-core |
ECS, Game Loop, Components | 52 |
jugar-physics |
Rigid body simulation | 7 |
jugar-ai |
GOAP, Behavior Trees | 17 |
jugar-render |
Viewport, Anchors | 10 |
jugar-ui |
Widget system | 10 |
jugar-input |
Touch/Mouse/KB/Gamepad | 10 |
jugar-audio |
Spatial 2D audio | 21 |
jugar-procgen |
Noise, Dungeons, WFC | 18 |
jugar-yaml |
ELI5 YAML-First declarative games | 334 |
jugar-probar |
Rust-native WASM game testing | 128 |
jugar-web |
WASM Web platform | 95 |
Total: 1500+ tests
A responsive Pong implementation that works from mobile to 32:9 ultrawide:
# Run the Pong web demo
make build-web && make serve-web
# Open http://localhost:8080Features:
- Touch controls (mobile)
- Keyboard (W/S, Up/Down)
- Gamepad support
- Responsive paddle positioning
- AI opponent with .apr ML model (Dynamic Difficulty Adjustment)
- SHAP-like explainability widgets
# Deterministic simulation with replay verification
cargo run --example pong_simulation -p jugar-probar
# Playwright-style locator API demo
cargo run --example locator_demo -p jugar-probar
# WCAG accessibility checking
cargo run --example accessibility_demo -p jugar-probarJugar uses Probar (Spanish: "to test/prove") - a pure Rust testing framework that replaces Playwright for E2E testing. Unlike Playwright, Probar can directly inspect game state without browser automation overhead.
# Run all E2E tests (39 tests, ~3 seconds)
make test-e2e
# Run with verbose output
make test-e2e-verbose
# Or directly via cargo
cargo test -p jugar-web --test probar_pong| Aspect | Playwright | Probar |
|---|---|---|
| Language | TypeScript | Pure Rust |
| Browser | Required (Chromium) | Not needed |
| Game State | Black box (DOM only) | Direct API access |
| CI Setup | Node.js + browser | Just cargo test |
| Zero JS | ❌ Violates constraint | ✅ Pure Rust |
# Unit tests (fast, <2 min)
make test-fast
# All tests with coverage
make coverage
# Property-based tests (QuickCheck-style)
make test-property
# Chaos engineering tests
cargo test -p jugar-web --test chaosJugar follows PMAT (Pragmatic Metrics for Agile Teams) quality methodology:
| Metric | Target | Status |
|---|---|---|
| Test Coverage | ≥95% | ✅ |
| Mutation Score | ≥80% | ✅ |
| TDG Grade | A+ | ✅ |
| SATD Comments | 0 | ✅ |
| Unsafe Code | 0 blocks | ✅ |
| JavaScript | 0 bytes | ✅ |
| Principle | Application |
|---|---|
| Mieruka (Visual Control) | Telemetry overlays in dev builds |
| Poka-Yoke (Error Proofing) | Type-safe APIs with Result<T, E> |
| Jidoka (Autonomation) | Fail-fast on invalid state |
| Heijunka (Leveling) | Fixed timestep game loop |
| Genchi Genbutsu (Go & See) | Examples as source of truth |
- The Jugar Book - Comprehensive guide and tutorials
- API Documentation - Complete API reference
- Specification - Full engine specification
- Examples - Runnable example games
We welcome contributions! Please see our Contributing Guide for details.
# Clone the repository
git clone https://github.com/paiml/jugar.git
cd jugar
# Run tier 1 (sub-second feedback)
make tier1
# Run tier 2 (full validation)
make tier2
# Run tier 3 (mutation testing)
make tier3All PRs must pass:
cargo fmt -- --checkcargo clippy --all-targets -- -D warningscargo test --all-featurespmat analyze tdg --min-grade B+
This project is licensed under the MIT License - see the LICENSE file for details.
- Batuta Sovereign AI Stack - Core compute and AI layers
- hecs - ECS implementation
- glam - Math library
Built with the Batuta Sovereign AI Stack