Phase 1 — Setup & Foundations
Version: v0.1.0 Status: ✅ Complete
Goal
Get a working Rust server and Miyoo SDL2 client that can connect over WiFi and exchange basic data. No gameplay yet — just a solid, deployable foundation everything else will build on.
Deliverable
A Miyoo binary that connects to the Rust server over WiFi and renders a player sprite that can move around a static test room.
Planned
Tech Stack
- Server: Rust + Tokio (async TCP + UDP), running on Raspberry Pi 5 (LAN) for development
- Client: Rust + SDL2, cross-compiled for ARM (Miyoo Mini Plus)
- Shared: A
sharedRust crate imported by both server and client — the single source of truth for all network messages and game types - Persistence: SQLite via
rusqlite(server-side only) - Cross-compile target:
armv7-unknown-linux-musleabihf(statically linked musl — avoids glibc version issues on Onion OS) - Linker:
armv7l-linux-musleabihf-gccfrom~/armv7l-linux-musleabihf-cross/bin/
Workspace Structure
rpg98/
├── Cargo.toml # workspace root
├── server/ # Tokio TCP server
├── client/ # SDL2 client (cross-compiled)
└── shared/ # shared types (Tile, DungeonMap, ClientMessage, ServerMessage)
Shared Crate — Core Types
These live in shared/src/lib.rs and must match exactly on both sides:
pub enum ClientMessage {
Connect { username: String },
}
pub enum ServerMessage {
Connected { welcome: String, map: DungeonMap },
}
Serialization: bincode 1.x (length-prefixed, over TCP). Note: bincode 2.x / 3.x have breaking changes — pin to "1".
Networking Pattern
All TCP messages are length-prefixed:
- Write 4-byte big-endian length
- Write bincode-serialized payload
Both client and server use the same read_message / write_message helper pair.
Cross-Compile Notes
- Target:
armv7-unknown-linux-musleabihf - Linker config in
~/.cargo/config.toml:[target.armv7-unknown-linux-musleabihf] linker = "armv7l-linux-musleabihf-gcc" - Always build with musl — the Miyoo's glibc is too old for dynamically linked Rust binaries
- SDL2 on Miyoo: the device ships
libSDL2-2.0.so.0at/mnt/SDCARD/.tmp_update/lib/parasyte/— it depends on SigmaStar MI libs present on the device
Deploy & Test Loop
# Build for Miyoo
cargo build -p client --target armv7-unknown-linux-musleabihf
# Copy to Miyoo over WiFi (replace 192.0.0.1 with your Miyoo's local IP; SSH password is blank)
scp target/armv7-unknown-linux-musleabihf/debug/client root@192.0.0.1:/tmp/rpg98_client
# Run on Miyoo via SSH
ssh root@192.0.0.1 "/tmp/rpg98_client"
# Run server (dev machine or Pi)
cargo run -p server
Completion Checklist (Planned)
- Rust workspace with
server,client,sharedcrates -
sharedcrate definesClientMessage,ServerMessage,Tile,DungeonMap - Server accepts TCP connections, sends a
Connectedmessage - Client connects, receives message, prints confirmation
- Client cross-compiles for
armv7-unknown-linux-musleabihfwithout errors - Binary runs on real Miyoo hardware over WiFi
- Player sprite renders on screen
Actual
What Was Built
Everything in the plan was implemented. The workspace, shared crate, TCP networking, and cross-compile pipeline all work as described.
Deviations & discoveries:
bincode 3.0.0has a deliberatecompile_error!protest — pinned to"1"(resolves to 1.3.3)- Dynamically linked binary failed on Miyoo with missing
GLIBC_2.30/2.32/2.33/2.34— fixed by switching toarmv7-unknown-linux-musleabihf(musl) scpmust be run from the project root directory, not home directorylibsdl2-image-devwas missing on the dev machine —sudo apt install libsdl2-image-devrequired- Render scale confirmed as 2× (320×240 logical resolution on 640×480 physical screen) after comparing sprites at 1× vs 2×
- Corridors were initially 1-tile wide (16px) — too narrow for the 32×32 player sprite; fixed by making corridors 2 tiles wide in dungeon generation
What Was Deferred
- Smooth player animation (walk cycles) — currently uses a static idle frame
- SDL2 cross-compile for Miyoo with full SDL2 image support (partially blocked; using host dev build for now)
Completion Checklist (Actual)
- Rust workspace with
server,client,sharedcrates -
sharedcrate definesClientMessage,ServerMessage,Tile,DungeonMap - Server generates procedural dungeon and sends
Connected { map, welcome }on connection - Client connects, receives map, renders dungeon with contextual tile selection
- Client cross-compiles for
armv7-unknown-linux-musleabihf - Binary connects to server over WiFi from Miyoo
- Player sprite renders and moves with D-pad / WASD
- Contextual tile rendering fully correct — in progress (debug tooling built, tile coords being refined)
Next: Phase 2 — World & Movement