Demonstrates running the Bevy game engine inside the RISC Zero zkVM to create verifiable, deterministic game simulations.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/risc0/risc0/llms.txt
Use this file to discover all available pages before exploring further.
What You’ll Learn
- Running game engines in the zkVM
- Using Bevy’s Entity Component System (ECS)
- Creating verifiable game states
- Proving game logic without revealing inputs
Overview
This minimal example shows how to:- Set up Bevy’s ECS in the zkVM
- Define components and systems
- Run deterministic game ticks
- Generate proofs of game state
Bevy is a powerful game engine. This example uses only the core ECS, but demonstrates the potential for complex game logic verification.
How It Works
use risc0_zkvm::guest::env;
use bevy_core::Outputs;
use bevy_ecs::{prelude::*, world::World};
#[derive(Component)]
struct Position {
x: f32,
y: f32,
}
#[derive(Component)]
struct Velocity {
x: f32,
y: f32,
}
#[derive(StageLabel)]
pub struct UpdateLabel;
// System that moves entities with Position and Velocity
fn movement(mut query: Query<(&mut Position, &Velocity)>) {
for (mut position, velocity) in &mut query {
position.x += velocity.x;
position.y += velocity.y;
}
}
fn main() {
let turns: u32 = env::read();
// Create Bevy world
let mut world = World::new();
// Spawn entity with position and velocity
let entity = world
.spawn((
Position { x: 0.0, y: 0.0 },
Velocity { x: 1.0, y: 0.0 },
))
.id();
// Create schedule with movement system
let mut schedule = Schedule::default();
schedule.add_stage(
UpdateLabel,
SystemStage::single_threaded().with_system(movement),
);
// Verify initial position
{
let entity_ref = world.entity(entity);
let position = entity_ref.get::<Position>().unwrap();
assert!(position.x == 0.0);
}
// Run timesteps
for _ in 0..turns {
env::log("running timestep...");
schedule.run(&mut world);
}
// Commit final position
{
let entity_ref = world.entity(entity);
let position = entity_ref.get::<Position>().unwrap();
let out = Outputs {
position: position.x,
};
env::commit(&out);
}
}
use bevy_methods::{BEVY_ELF, BEVY_ID};
use risc0_zkvm::{ExecutorEnv, default_prover};
fn main() {
let turns: u32 = 10;
let env = ExecutorEnv::builder()
.write(&turns)
.unwrap()
.build()
.unwrap();
let receipt = default_prover()
.prove(env, BEVY_ELF)
.unwrap()
.receipt;
receipt.verify(BEVY_ID).unwrap();
let output: Outputs = receipt.journal.decode().unwrap();
println!("After {} turns, position.x = {}", turns, output.position);
println!("Expected: {}", turns);
assert_eq!(output.position, turns as f32);
}
Running the Example
What Gets Proven?
The receipt proves:- Deterministic Execution: The game ran exactly N timesteps
- Valid Game Logic: Movement system applied correctly
- Final State: The entity is at the committed position
- No Tampering: Game state wasn’t manipulated
Bevy ECS Architecture
Entities
Unique identifiers for game objects:Components
Data structs attached to entities:Systems
Functions that query and modify components:Queries
Filter entities by component combinations:Schedules
Organize system execution order:Use Cases
Verifiable Game Outcomes
Prove game results without revealing player actions:Onchain Gaming
Generate proofs offchain, verify onchain:AI Training Verification
Prove AI trained with specific game outcomes:Tournaments
Verify tournament matches:Anti-Cheat
Prove legitimate gameplay:Extending the Example
Multiple Entities
Simulate multiple game objects:Collision Detection
Add collision system:Player Input
Process player actions:Resource Management
Add game resources:Performance
| Metric | Value (10 turns) |
|---|---|
| Cycles | ~2M |
| Proving time | ~2-5 seconds |
| Receipt size | ~128 KB |
| Memory usage | ~1 GB |
- Number of entities
- System complexity
- Number of timesteps
Bevy Feature Compatibility
This example usesbevy_ecs which works in zkVM:
Works in zkVM:
bevy_ecs: Entity Component Systembevy_core: Core functionalitybevy_math: Math utilitiesbevy_transform: Transforms (with limitations)
bevy_render: Graphics (requires GPU/system calls)bevy_window: Windowing (requires OS)bevy_input: Input handling (requires OS)bevy_audio: Audio (requires OS)
Use only the ECS and math components. Rendering and I/O systems require OS support not available in zkVM.
Determinism
Games in zkVM must be deterministic: Deterministic:Linking with Player Identities
Combine with signature verification:Bonsai Integration
For online games, use Bonsai:Game Development Tips
Keep It Simple
Start with minimal game logic:- Basic movement
- Simple interactions
- Clear win/loss conditions
- Deterministic state
Optimize for Cycles
Minimize computational cost:- Use integer math when possible
- Limit entity count
- Simplify physics
- Batch operations
Test Determinism
Verify games are deterministic:Separate Rendering
Keep game logic separate from presentation:Next Steps
- Build a complete game with Bevy
- Integrate player signatures
- Deploy on Bonsai
- Explore onchain gaming patterns
- Study Bevy documentation