RPG encounter's goal is to bring real-time voice NPCs to in-person tabletop sessions. It's designed to replace encounters where the DM - you - does not want to impersonate characters and instead introduce some variability, and free-form role play in a non-obtrusive way. You can choose to only setup one important character with plot hooks or important items and keep all other interactions in-person. Or fill your scenarios with as many characters as you want.
- Read the game instructions and features, and watch the demo videos to understand the mechanics.
- Follow the setup guide and usage instructions.
- Talk to some characters in the default scenario!
- Follow
backendsetup guide - Follow
frontendsetup guide
You must decide how you want players to interact with characters. Locally, you are restricted to the shared microphone option unless you setup a local LAN configuration. In the hosted version, you can choose between:
- 🎤 Shared Mic - DM Controlled - Something that you can pass around or conference speaker works best. This allows the table to share in the experience. The DM initiates and stops dialogue from the
/encountersscreen. - 📱 Mobile Phone - Player Controlled - You can generate player login codes from the
/playersscreen, such that players can use their mobile devices as their microphones.
Because the application uses magic links in production, locally you need to:
- Set
LOG_MAGIC_LINK=trueinbackend/.env - Seed the database with a user and email
- Request login link
- Copy login link from backend service logs, which looks something like:
test1@example.com login link: http://localhost:3001/auth?token=e-e6Cs6paxa6H0fmC0gYfrwfLElxWwkeSF0Jb6ck-XY - Paste login link into the same browser used to request it
You can avoid token billing checks by either:
- Setting
BILLING_IGNORE_BALANCE_CHECK=trueinbackend/.env. - Adjusting token balances with the script in
backend/tests/scripts/set_billing_state.py:
docker exec rpg-encounters-backend /app/.venv/bin/python tests/scripts/set_billing_state.py --email test1@example.com --available 1000000 --last-used 0You can skip moderation by setting SKIP_MODERATION=true in backend/.env.
You can switch models by setting the appropriate API keys in your backend/.env and adjusting src/core/backend/app/agents/base_agent.py following the Pydantic docs.
Provider availability is based on which API keys are set in backend/.env:
- ElevenLabs
ELEVENLABS_TTS_API_KEY - Google
GOOGLE_CLOUD_TTS_API_KEY
The default provider is set by DEFAULT_TTS_PROVIDER.
If you want players to speak through their own devices locally, you need to setup the LAN configuration.
WARNING: This only works if each player uses Chrome desktop. Mobile browsers block microphones on insecure origins.
- Get IP address
ipconfig getifaddr en0 - Set
LAN_PUBLIC_URLinbackend/.envlikehttp://<IP_ADDRESS>:3001 - Set
VITE_BACKEND_URLinfrontend/.envlikehttp://<IP_ADDRESS>:8000/api - Set
VITE_WEBSOCKET_URLinfrontend/.envlikews://<IP_ADDRESS>:8000 - Launch backend and frontend services
- Login and generate player links from the
/playersscreen. Automatic copying to clipboard will fail because of restrictions to Clipboard API locally. - Each player launches Chrome with
open -n -a "Google Chrome" --args --unsafely-treat-insecure-origin-as-secure=http://<IP_ADDRESS>:3001 - Players login with the previously generated login link
Start frontend
npm run devEnsure you have set all the required backend/.env variables in setup and start backend services
docker compose -f backend/docker-compose.yml -f backend/docker-compose.dev.yml upNavigate to the login page and generate a magic link
open -a "Google Chrome" "http://localhost:3001/login"There are many ways to support:
- Use it! Write about it! Star it!
- Sponsor my work at https://www.buymeacoffee.com/carlrcr






