System Architecture
The platform follows a client-server architecture with three main components:
- Backend Server: A Rust-based server handling WebSocket connections with a custom binary protocol for efficient communication
- Hardware Controller: Raspberry Pi Zero with two buttons and an MPU6050 accelerometer/gyroscope that connects to the server as a WebSocket client.
- Web Frontend: WebAssembly-compiled games using the Bevy game engine that receive controller data via WebSocket and updates its game state
Hardware Controller
The physical controller is built around a Raspberry Pi Zero with the following components:
- Two pushbuttons (A and B) for primary inputs
- Accelerometer for motion detection and tilt sensing
- Gyroscope for precise rotation tracking
- Portable power bank for wireless operation (it was quick and easy)
The firmware uses asynchronous interrupts for button presses and sensor data collection. All inputs are piped into a single consumer channel that batches and sends data packets to the server in sequential order, ensuring consistent input timing and reducing network overhead.
Game Engine and Bowling Implementation
The bowling game was developed using the Bevy game engine, compiled to WebAssembly for browser execution. The implementation includes:
- Physics-based bowling ball mechanics with proper collision detection
- 2.5D sprite rendering with custom-drawn assets
- Real-time controller input processing for aiming and power calculation
- Pass-and-play multiplayer support
- JavaScript-to-WASM communication bridge for game configuration
The game uses two axes of rotation from the controller for aiming and calculates throw speed based on the acceleration data. The physics simulation handles pin collisions and scoring automatically based on standard bowling rules.
Overall, I'm super happy with how my little game architecture turned out, it was a rewarding project that was super fun to play with some of my friends. I'm looking forward to using the system I already have in place to add more games and functionality in the future :)