Roadmap

RPG98 Roadmap Phase 1 — Setup & Foundations

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 shared Rust 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-gcc from ~/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:

  1. Write 4-byte big-endian length
  2. 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.0 at /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, shared crates
  • shared crate defines ClientMessage, ServerMessage, Tile, DungeonMap
  • Server accepts TCP connections, sends a Connected message
  • Client connects, receives message, prints confirmation
  • Client cross-compiles for armv7-unknown-linux-musleabihf without 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.0 has a deliberate compile_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 to armv7-unknown-linux-musleabihf (musl)
  • scp must be run from the project root directory, not home directory
  • libsdl2-image-dev was missing on the dev machine — sudo apt install libsdl2-image-dev required
  • Render scale confirmed as (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, shared crates
  • shared crate defines ClientMessage, 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