R-Typing is a terminal-based typing game built with Rust. It provides a TUI powered by ratatui and crossterm, real-time WPM feedback, optional audio, and multiple text generation sources.
The game starts from a title menu where you can choose a generation source and play mode. All settings are configured through the in-app Config screen and saved to disk.
- Terminal UI with title menu, config screen, typing screen, result screen, and stats screen
- Real-time WPM, timer, typed character count, and miss count
- Timed history with best WPM, average WPM, average accuracy, recent WPM trend, and frequent missed characters
- Practice mode (no time limit) via menu or by setting timeout to 0
- Optional BGM and typing feedback sound (configured in-app, saved to disk)
- Local text generation with a 4-gram Markov chain
- Remote text generation through Google AI Studio or Groq
- All settings and timed history saved under
~/.config/rtyping/
# Start normally and choose a provider from the title menu
cargo runcargo build
cargo build --release
cargo install --path .- Menu entries:
Start GamePractice ModeStart Game via Google AI Studio(shown only when Google AI StudioAPI URL,API Key, andModelare all configured)Start Game via GroqCloud(shown only when GroqAPI URL,API Key, andModelare all configured)StatsConfig
Up / Down: move between the visible menu entriesEnter: confirm selectionh: open or close helpEsc: quitCtrl+c: quit- The selected entry is marked with
▶︎
The Config screen lets you edit both Google AI Studio and Groq provider settings and game settings.
Each provider has these fields:
API URLAPI KeyModel
Game Settings:
Timeout– timer duration in seconds (0= no time limit / practice mode)TextScale– target text length scaleFreq– typing sound frequency in HzSoundEnabled–true/false
Controls:
Up / Down: move focusLeft / Right: move the input cursor inside the focused text field- Character keys: insert at the current cursor position
Backspace: delete the character before the cursorSpace: toggleSoundEnabledEnter: save configurationEsc: return to the title screen
API key fields stay masked while editing, with one mask character per stored character.
Saved files:
~/.config/rtyping/config.json~/.config/rtyping/config.key~/.config/rtyping/history.json
config.json stores encrypted API key data. The encryption key is stored separately in config.key.
history.json stores completed timed-session results. Practice Mode results are not saved to history.
The Target Text block keeps two blank lines above and two blank lines below the target text, including when the text wraps across multiple lines.
The typing cursor is hidden on the target text. The current target character is yellow and bold, future characters are gray, correct typed characters are green, and mistakes are shown as white text on a red background.
The WPM trend block uses a light yellow border while keeping the graph line colors unchanged.
The Result screen shows the current session summary:
- WPM
- Accuracy
- Miss count
- Elapsed input time
- Generation source
- Practice or timed mode
For timed sessions, the result is saved to ~/.config/rtyping/history.json.
The Result and Stats screens also show saved timed-history stats:
- Best WPM
- Average WPM
- Average accuracy
- Recent 10-run WPM trend
- Frequent missed characters, counted by the expected character
Controls on the Stats screen:
Enter / Esc: return to the title screen
- The final request URL is built as
API URL/+Model+:generateContent - The API key is appended as the
keyquery parameter - The prompt includes a per-request variation seed so repeated starts do not send identical instructions
Example:
API URL: https://generativelanguage.googleapis.com/v1beta/models
Model: gemini-2.0-flash
Final URL: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=YOUR_API_KEY
API URLshould be the full chat completions endpoint you want to callModelis sent in the request bodyAPI Keyis sent as a bearer token- The prompt includes a per-request variation seed so repeated starts do not send identical instructions
The generated target text length is controlled by TextScale in the Config screen. The current implementation uses roughly text_scale * 5 characters for both local and remote generation. Remote text is normalized and trimmed by the app, so the final target text does not exceed that character count.
make check
make buildCargo.toml の package version を更新して main に push すると、version-check.yml がリリース処理を実行します。
- Release tag は
v<version>形式です - Release 前に
make checkとmake buildを実行します - Linux と macOS の release build を GitHub Actions artifact として集約します
- GitHub Release は単一 job で1回だけ作成します
- リリースノートには version、変更履歴、配布成果物一覧を含めます
For Apple silicon macOS:
rustup target add aarch64-apple-darwin
cargo build --release --target=aarch64-apple-darwinFor Windows x86_64 GNU:
rustup target add x86_64-pc-windows-gnu
cargo build --release --target=x86_64-pc-windows-gnuCodex CLI と Copilot CLI 向けにハーネスを導入しました。GPT-5.4-Mini でも一定の品質が保てるようになりました。




