Community platform for sharing Unity game translation files with API for mod synchronization.
Live site: unitygametranslator.asymptomatikgames.com
- Browse translations by game, language, and popularity
- Upload translation files with automatic game detection (Steam, Epic, GOG)
- Fork translations to improve existing work
- Merge contributions — Main owners review and merge Branches
- Branch rating — Main owners rate contributor quality
- Inline editing — edit translations directly on the website with tag selection
- Merge preview — visual diff between local (mod) and server translations
- Vote system to highlight quality translations
- Report system for moderation
- Profile management with GDPR data export and account deletion
- Multi-language UI (19 languages)
- Admin dashboard with analytics, user management, and moderation
| Term | Description |
|---|---|
| Main | The original translation. First uploader becomes the owner. |
| Branch | A contributor's version, linked to the Main. One per user per UUID. |
| Fork | Copying a translation to create your own Branch. |
Workflow:
- User A uploads → becomes Main owner
- User B downloads, improves, uploads → creates a Branch
- User A reviews Branches, rates contributors, and merges contributions
Constraints:
- One Main per UUID (first uploader wins)
- One Branch per user per UUID (updating replaces your Branch)
- Languages locked after first upload (source/target immutable)
| Tag | Name | Score | Description |
|---|---|---|---|
| H | Human | 3 pts | Written by a human |
| V | Validated | 2 pts | AI translation approved by human |
| A | AI | 1 pt | Translated by AI |
| S | Skip | — | Intentionally not translated |
| M | Mod | — | Mod UI translations (internal) |
Quality Score (0-3): (H×3 + V×2 + A×1) / (H + V + A)
| Score | Label |
|---|---|
| 2.5+ | Excellent |
| 2.0+ | Good |
| 1.5+ | Fair |
| 1.0+ | Basic |
| <1.0 | Raw AI |
- Search translations by Steam ID, game name, or language
- Download translations with ETag caching
- Check for updates without downloading the full file
- Upload translations with gzip compression
- UUID check — detect if upload is New, Update, or Fork
- Branch listing — Main owners see all contributors
- Device Flow authentication — enter code on website to link mod
- Merge preview — mod sends local content, user resolves in browser
- Vote on translations
- Real-time sync via Server-Sent Events (SSE)
- Rate limiting per endpoint
OAuth providers: Google, GitHub, Discord, Twitch, Steam
Device Flow for Unity mod: mod displays a code, user enters it at /link, mod receives API token via SSE stream.
- Framework: Laravel 12 (PHP 8.2+)
- Real-time: Node.js SSE micro-server + Redis pub/sub
- Database: SQLite (dev) / MySQL (prod)
- Auth: Laravel Socialite (5 OAuth providers)
- Frontend: Tailwind CSS 4, Alpine.js (CSP build), Chart.js, Font Awesome, Flag-icons
- Analytics: Built-in event tracking with daily aggregation
Two processes communicating via Redis:
Unity Mod ──► Laravel API (PHP) ◄──► Redis pub/sub ◄──► SSE Server (Node.js) ◄── Unity Mod
(business logic, (signaling) (real-time streaming)
auth, DB, uploads)
- Laravel handles business logic, authentication, database, uploads, merges, API
- Node.js SSE server streams real-time events to connected clients (lightweight transport layer)
- Redis pub/sub bridges the two: Laravel publishes events, SSE server forwards to clients
| Endpoint | Auth | Purpose |
|---|---|---|
GET /auth/device/:code/stream |
None | Device Flow: streams auth result |
GET /sync/stream?uuid=xxx&hash=yyy |
Bearer | Multi-device sync: streams translation updates |
GET /merge-preview/:token/stream |
Token | Merge completion notification |
GET /health |
None | Health check |
- PHP 8.2+ with
phpredisextension - Composer
- Node.js 18+
- Redis 6+
- SQLite or MySQL
composer setupHandles everything: dependencies, environment file, database migration, and asset building.
# Laravel
composer install
npm install
cp .env.example .env
php artisan key:generate
touch database/database.sqlite
php artisan migrate
npm run build
# SSE Server
cd sse-server
npm installConfigure in .env:
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
TWITCH_CLIENT_ID=
TWITCH_CLIENT_SECRET=
STEAM_API_KEY=| Provider | Console |
|---|---|
| Google Cloud Console | |
| GitHub | GitHub Developer Settings |
| Discord | Discord Developer Portal |
| Twitch | Twitch Developer Console |
| Steam | Steam Web API Key |
Both Laravel and the SSE server need the same Redis instance:
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379For Unix socket: set REDIS_SOCKET=/path/to/redis.sock (overrides host/port).
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Listening port |
REDIS_URL |
redis://127.0.0.1:6379 |
Redis connection (TCP) |
REDIS_SOCKET |
— | Redis Unix socket (overrides URL) |
LARAVEL_API_URL |
http://localhost:8000/api/v1 |
Laravel API for token validation |
ALLOWED_ORIGIN |
— | CORS origin |
PER_IP_LIMIT |
10 |
Max SSE connections per IP |
MAX_CONNECTIONS |
1000 |
Global connection limit |
# Start Laravel dev server (runs server, queue, logs, and Vite)
composer dev
# Start SSE server (separate terminal)
cd sse-server
PORT=3001 REDIS_URL=redis://127.0.0.1:6379 LARAVEL_API_URL=http://localhost:8000/api/v1 node server.jscomposer test # Run tests
php artisan analytics:aggregate # Aggregate daily analytics
php artisan recalculate-hashes # Recalculate translation file hashesArabic, Chinese, Dutch, English, French, German, Hebrew, Hindi, Indonesian, Italian, Japanese, Korean, Polish, Portuguese, Russian, Spanish, Thai, Turkish, Vietnamese
- Unity Mod: github.com/djethino/UnityGameTranslator
- Laravel — PHP framework
- Laravel Socialite — OAuth authentication
- ioredis — Redis client for Node.js
- Tailwind CSS — Utility-first CSS
- Alpine.js — Lightweight JS framework (CSP build)
- Chart.js — Analytics charts
- Font Awesome — Icons
- Flag-icons — Language flags
Dual-licensed:
- Open Source: AGPL-3.0
- Commercial: Contact us for proprietary use
See LICENSING.md for details.