RustShips v1.0
A two-player Battleship game running on devices having a 4" touchscreen display and wireless peer-to-peer communication.
Author: Mîrza Daniel
GitHub Project Link: https://github.com/UPB-PMRust-Students/fils-project-2026-Danum1z
Description
RustShips is a fully embedded, wireless two-player Battleship game. Each player owns a dedicated device consisting of an STM32U545RE Nucleo-64 board connected to a 4" TFT touchscreen (ST7796S, 320×480) wtih action buttons and a passive buzzer. The two devices communicate wirelessly via NRF24L01+ radio modules over SPI.
Each player places a fleet of 5 ships on a 10×10 grid, then takes turns firing at the opponent's grid. The game tracks two matrices per device: my_fleet (own ships and incoming hits) and enemy_radar (shots fired and confirmed results). A dedicated button toggles between the two views.
The game features three special mechanics, each usable once per game:
- Sonar Scan: hold the action button for 3 seconds to reveal a 3×3 area of the enemy grid for 2 seconds
- Airstrike: double-press the action button to instantly sink an entire enemy ship
- Ferris Repair: named after Ferris the Rust mascot — fully repair a damaged ship and move it to a new position
The entire game logic is written as a no_std Rust library (game-core) that compiles for both the real MCU and a desktop simulator built with embedded-graphics-simulator.
Motivation
The choice of this project comes from a long-standing interest in classical strategy games like Battleships and a desire to translate tactile, paper-based mechanics into a robust digital embedded system. Beyond the childhood nostalgia, this project serves as a comprehensive learning platform for several reasons:
- Software Complexity: Developing a full-featured game from scratch in Rust requires mastering state machines and no_std logic.
- Hardware Integration: The project offers hands-on experience with SPI bus sharing between high-resolution displays, touch controllers, and wireless radio modules.
- Future Potential: This handheld terminal is designed as a versatile gaming platform. Its low energy consumption and independent peer-to-peer wireless link make it ideal for offline use (trains, planes, or remote trips). It establishes a foundation for a suite of offline multiplayer games like or Connect 4, Tic-Tac-Toe, or even singleplayer Sudoku.
Architecture
The project is split into three crates inside a Cargo workspace:
game-core — no_std pure logic library, no hardware dependencies. Compiles for both x86_64 (simulator) and thumbv8m.main-none-eabihf (MCU). Contains the grid, ship fleet, game state machine, special mechanics, and network message types.
simulator — std desktop application. Uses embedded-graphics-simulator (SDL2) to render the game in a window on the development laptop. Uses the exact same game-core types as the real hardware. Used for developing and testing all game logic before using hardware.
embassy-app — no_std Embassy application for the real hardware. Spawns independent async tasks that communicate via Embassy channels and signals.
Game State Machine (per device):
Placement ──► WaitingForOpponent ──► Battle ──► GameOver
├── Aiming
├── WaitingForResult
├── OpponentTurn
└── FerrisRepair
Communication protocol (NRF24L01+, peer-to-peer, no server):
Each game action is serialized into a NetworkMessage and sent to the opponent. Message types include FireShot, ShotResult, SonarRequest/Response, AirstrikeResult, FerrisRepairUpdate, and GameOver.
Log
Week 5 - 7
- Searched for a suitable project idea
- Adopted the BattleShips game concept
- Defined the project logic and workflow
Week 8 - 9
- Chose STM32U545RE + Embassy async Rust stack
- Ordered two 4.0"SPI TFT Modules
- Set up the Cargo workspace with
game-core,simulator, andembassy-appcrates - Implemented the
grid.rs,ship.rs, andstate.rs(ingame-core) - Received the ordered TFT modules
- Ordered two NUCLEO-U545RE-Q boards
- Passed the Documentation Milestone
Week 10 - 11
- to be continued...
Week 12 - 13
- to be continued...
Hardware
Each player's device consists of:
- STM32U545RE-Q Nucleo-64: Arm Cortex-M33 microcontroller running at up to 160 MHz, 512 KB flash, 274 KB SRAM. Runs the Embassy async runtime with multiple concurrent tasks.
- 4.0" TFT LCD (ST7796S, 320×480): Connected via SPI. Displays both game grids, ship positions, hit/miss markers, and special ability highlights. Driven by the
mipidsicrate withembedded-graphics. - XPT2046 resistive touch controller: Shares the SPI bus with the display (separate CS pin). Used for cell selection on the touchscreen.
- NRF24L01+ radio module: Connected via SPI. Provides 2.4 GHz peer-to-peer wireless communication between the two devices. No server or router required.
- Passive buzzer: Driven via PWM. Provides audio feedback for shots, hits, sinks, special abilities, and win/lose outcomes.
- Navigation buttons: Arrow buttons (up/down/left/right) for cursor movement and ship placement, plus Action, View-Toggle, and Rotate buttons.
Schematics
KiCAD schematic to be uploaded later...
Bill of Materials
| Device | Usage | Price |
|---|---|---|
| STM32U545RE Nucleo-64 | Main microcontroller board (×2) | 130 RON × 2 |
| 4.0" TFT LCD ST7796S 320×480 | Touchscreen display (×2) | 130 RON × 2 |
| NRF24L01+ module* | 2.4GHz wireless link (×2) | __ RON × 2 |
| Passive buzzer* | Audio feedback (×2) | __ RON × 2 |
| Tactile push buttons* | Navigation + action input (×2 sets) | __ RON × 2 |
| Jumper wires + breadboard | Prototyping connections | ~30 RON |
| Total (estimated) | ~~ 550 RON |
*to be ordered...
Software
| Library | Description | Usage |
|---|---|---|
| embassy | Async embedded framework | Task scheduler, async SPI/GPIO/PWM drivers for STM32U5 |
| mipidsi | MIPI display driver | Drives the ST7796S TFT display over SPI |
| embedded-graphics | 2D graphics library | Draws grids, ships, cursors, highlights, text |
| embedded-graphics-simulator | SDL2-based simulator | Runs the full game on laptop for logic testing |
| xpt2046 | Resistive touch driver | Reads touch coordinates from XPT2046 controller |
| heapless | Fixed-size collections | Stack-allocated Vec/Queue replacements for no_std |
| defmt | Embedded logging | RTT-based debug logging via probe-rs |
Links
- Battleship - Wikipedia: General rules and history of the classic board game.
- Sea Battle (App Store): A popular mobile version that inspired the digital UI and special mechanics.
- Embassy - Async Rust for Embedded: Documentation for the framework powering the game's concurrency.