The Problem
Gamers who play nonâEnglish titles often have to pause or switch to external translation tools, breaking immersion and slowing progress. The pain point is a lack of an inâgame, lowâlatency solution that can capture screen text, run OCR, and feed the result to an LLMâbased translator without leaving the game window.
What This Does
RSTGameTranslation is a Windowsâonly WPF application that captures a userâselected window region, runs OCR (OneOCR, Windows OCR, EasyOCR, PaddleOCR, or RapidOCR) and passes the extracted text to a configurable translation backend (Google, Gemini, Groq, ChatGPT, Ollama, Mistral, LMâŻStudio, etc.).
Key files:
src/App.xaml.csâ boots the WPF app and registers services.src/MainWindow.xaml.csâ UI entry point; handles hotâkey shortcuts, starts OCR, and displays overlay windows.src/OcrServerManager.csâ launches the selected Python OCR server (app/webserver/*/server_*.py) as a child process and communicates via HTTP.src/TranslationServiceFactory.cs&src/ITranslationService.csâ resolve the concrete translator (e.g.,src/GoogleTranslateService.cs,src/GeminiTranslationService.cs).src/ConfigManager.csâ persists user selections (OCR engine, language pairs, API keys) in JSON files underapp/Languages/.
The Python side (app/webserver/EasyOCR/process_image_easyocr.py, .../PaddleOCR/*.py, .../RapidOCR/*.py) each expose a tiny Flaskâstyle HTTP endpoint that receives an image, runs the respective OCR library, and returns plain text.
How It Is Wired
Execution begins in the compiled binary generated from RST.csproj; the WPF runtime loads src/App.xaml.cs, which creates the DI container and opens src/MainWindow.xaml. When the user presses AltâŻ+âŻQ the MainWindow calls OcrServerManager.StartServer() (see src/OcrServerManager.cs). This method selects the configured OCR type and launches the matching script, e.g.:
app/webserver/EasyOCR/server_easy.py â started via Process.Start
The server listens on a hardâcoded local port; MainWindow then captures the selected screen rectangle (via src/WindowSelectorPopup.xaml.cs) and sends the bitmap to the server using HttpClient (inside src/OneOCRManager.cs). The server returns raw text, which MainWindow forwards to TranslationServiceFactory.Create() to obtain an ITranslationService implementation. The chosen service (e.g., src/GoogleTranslateService.cs) performs an HTTP request to the external API, receives the translated string, and the UI displays it in the overlay (src/OverlayOptionsWindow.xaml.cs).
All sideâeffects (file writes, network calls) are confined to:
src/ConfigManager.csâ reads/writes JSON config.src/*TranslationService.csâ external HTTP APIs.src/OcrServerManager.csâ spawns/terminates Python processes.
No circular imports were detected; each module is isolated, which limits blast radius but also means duplicated logic across the OCR scripts (see measured findings).
How To Use It
- Clone and build
git clone https://github.com/moses-y/RSTGameTranslation
cd RSTGameTranslation
dotnet build RST.sln -c Release
- Install OCR backâends (optional for nonâOneOCR). Run the provided batch files, e.g.:
app\webserver\EasyOCR\SetupServerCondaEnvNVidiaEasyOCR.bat
These scripts create a Conda environment with the required Python packages and place the server executable in the same folder.
- Configure - Edit
app/Languages/*.jsonto add or modify language codes. - Place API keys in the UI under Settings â Translation (the app stores them encrypted viasrc/ConfigManager.cs).
- Run
dotnet run --project RST.csproj # or execute the built rst.exe
Press AltâŻ+âŻQ to select the game window, AltâŻ+âŻF to toggle the overlay, and AltâŻ+âŻG to start/stop translation.
RealâWorld Use
A streamer runs rst.exe alongside Elden Ring (windowed mode). The overlay shows translated dialogue in real time, letting the audience follow the story without subtitles. The streamer configures PaddleOCR for Japanese text and Gemini for translation, achieving subâsecond latency thanks to the local GPUâaccelerated OCR server.
Code Health & Issues
- HIGH â Pin thirdâparty GitHub Actions to commit SHA (
.github/workflows/*). - HIGH â No test suite; 55 source files lack automated verification.
- HIGH â Workflow pushes directly to default branch (
update-readme-version.yml). - MEDIUM â Large binaries (
app/AudioModel/ggml-tiny.bin,oneocr.onemodel,oneocr.dll) should be stored with GitâŻLFS or external storage. - LOW â Add job timeouts in CI (
release.yml). - LOW â Add convention files (
.editorconfig,.gitattributes, formatter config).
Measured static analysis also reports 48 instances of deep nesting, duplicated OCRâserver code, and 11 oversized C# files (e.g., src/ConfigManager.cs, src/Logic.cs, src/MainWindow.xaml.cs). Refactoring these would improve readability and reduce change impact.
The Bottom Line
RSTGameTranslation delivers a functional, extensible pipeline for realâtime game text translation on Windows, with clear separation between UI, OCR servers, and translation services. However, the codebase suffers from duplication, deep nesting, and a lack of automated tests, which raises maintenance risk for any custom extensions. It is suitable for teams comfortable with C# and Python who need a quick, locallyârun translation overlay and are prepared to address the identified health concerns.