A comprehensive D&D campaign management platform for Dungeon Masters
Dragonroll is a powerful web application designed to streamline campaign preparation and enhance your D&D gaming experience. Generate AI-powered NPCs, manage campaigns, and access a suite of tools to make your DM life easier.
Dragonroll empowers Dungeon Masters of all experience levels with intelligent tools to create compelling campaigns. By leveraging AI assistance and intuitive design, we reduce preparation time while enhancing creative possibilities, making it easier than ever to run memorable D&D sessions.
Frontend:
- βοΈ React + TypeScript + Vite
- π¨ Tailwind CSS + ShadCN/UI components
- π Firebase Authentication
- π± Responsive design with dark/light mode
Backend:
- π₯ Hono API framework (Node.js)
- ποΈ PostgreSQL with Drizzle ORM
- π€ OpenAI GPT-4 & DALL-E integration
- π Firebase Admin SDK for auth
Infrastructure:
- π Local Development: Embedded PostgreSQL + Firebase emulator
- π Production: Cloudflare Workers + Pages
- π Database: Supabase PostgreSQL (production) / Embedded PG (local)
- π§ Package Management: pnpm workspace
- π€ AI-Powered Creation: Generate detailed NPCs using OpenAI GPT-4
- π¨ Character Images: Automatic character portraits with DALL-E 3
- πΎ Personal Collection: Save and organize your generated NPCs
- π Custom Prompts: Tailor generation with specific requirements
- π Secure Storage: User-specific collections with Firebase authentication
- π Rich Details: Names, descriptions, backgrounds, and motivations
- πΊοΈ Map Generator: AI-powered dungeon and world maps
- βοΈ Encounter Builder: Balanced combat encounters
- π° Loot Generator: Treasure and magic item creation
- π Story Prompts: Campaign and plot hook generators
- π° Campaign Hub: Centralized campaign management
β οΈ Important: NPC Generator requires an OpenAI API key. AddOPENAI_API_KEY=your_key_hereto yourserver/.envfile.
- Node.js 20+
- pnpm 8+ (
npm install -g pnpm) - OpenAI API Key (for NPC generation)
- Clone and install dependencies:
git clone https://github.com/yourusername/dragonroll.git
cd dragonroll
pnpm install- Set up environment variables:
# Copy template and add your OpenAI API key
cp server/.env.template server/.env
# Edit server/.env and add: OPENAI_API_KEY=your_key_here- Start development servers:
pnpm run devThis starts:
- Frontend:
http://localhost:5173(or next available) - Backend API:
http://localhost:8787(or next available) - PostgreSQL: Embedded database (dynamic port from 5433)
- Firebase Emulator: Authentication emulator
# Frontend only
cd ui && pnpm dev
# Backend only
cd server && pnpm dev
# Build for production
pnpm run build
# Run tests
cd server && pnpm test- Access the app at
http://localhost:5173 - Sign in with any email/password (Firebase emulator mode)
- Generate NPCs - Go to the NPC Generator page
- Test API directly:
curl http://localhost:8787/api/v1/helloYour app defaults to everything running locally. Connect to production services when you're ready:
# Choose from available providers
pnpm connect:database
# Or connect to specific provider
pnpm connect:database:neon # Neon PostgreSQL
pnpm connect:database:supabase # Supabase PostgreSQL
pnpm connect:database:custom # Custom PostgreSQL# Set up production Firebase Auth
pnpm connect:auth# Set up Cloudflare Workers + Pages deployment
pnpm connect:deploy# See what's connected to production vs local
pnpm connection:statusWhat happens when you connect services:
- Your
.envfiles are automatically updated - A backup of your current config is created
- You can always revert to local development by restoring the backup
dragonroll/
βββ ui/ # React frontend (Vite + TypeScript)
β βββ src/
β β βββ components/ # ShadCN/UI components + custom components
β β β βββ ui/ # Base ShadCN components
β β β βββ npc-generator.tsx # NPC generation component
β β βββ pages/ # Application pages/routes
β β β βββ NPCGenerator.tsx # Main NPC generator page
β β βββ lib/ # Utilities, Firebase config, API communication
β β βββ types/ # TypeScript type definitions
β β βββ hooks/ # React custom hooks
β βββ package.json
βββ server/ # Hono API backend
β βββ src/
β β βββ controllers/ # API route controllers
β β β βββ npcs.ts # NPC-related endpoints
β β βββ lib/ # Server utilities
β β β βββ openai.ts # OpenAI integration
β β β βββ db.ts # Database connection
β β β βββ env.ts # Environment configuration
β β βββ middleware/ # Auth & other middleware
β β βββ schema/ # Database schema (Drizzle ORM)
β β β βββ users.ts # User table schema
β β β βββ npcs.ts # NPC table schema
β β βββ api.ts # API routes & server setup
β βββ drizzle/ # Database migrations
β βββ .env # Environment variables (create from template)
β βββ package.json
βββ database-server/ # Embedded PostgreSQL for local development
βββ data/ # Local development data (auto-generated)
β βββ postgres/ # PostgreSQL data files
β βββ firebase-emulator/ # Firebase emulator data (auto-backed up)
βββ docs/ # Documentation
β βββ PRODUCT_BRIEF.md # Project overview and goals
β βββ features/ # Feature documentation and planning
βββ scripts/ # Development and utility scripts
βββ run-dev.js # Development server orchestration
βββ periodic-emulator-backup.js # Auto-backup Firebase data
Edit server/src/index.ts:
// Add to the existing api router
api.get('/your-route', (c) => {
return c.json({ message: 'Hello!' });
});
// For protected routes, add to protectedRoutes:
protectedRoutes.get('/private-route', (c) => {
const user = c.get('user'); // Get authenticated user
return c.json({ user });
});- Edit schema in
server/src/schema/ - Push changes:
cd server && pnpm db:push
- Add components in
ui/src/components/ - Use ShadCN/UI: Browse components at ui.shadcn.com
- Install new components:
cd ui && npx shadcn-ui@latest add [component]
- Modify
ui/tailwind.config.jsfor custom themes - Global styles in
ui/src/index.css - Use Tailwind utility classes throughout
Note: Embedded PostgreSQL is for local development only. Production deployments require an external database (configured during setup).
cd server
pnpm run deployYour API will be available at: https://your-worker-name.your-subdomain.workers.dev
- Connect to Git: Link your repository to Cloudflare Pages
- Build Settings:
- Build command:
pnpm run build - Build output:
ui/dist
- Build command:
- Deploy: Automatic on every git push
Set these in Cloudflare dashboards:
Worker Environment Variables:
DATABASE_URL- Your database connection stringFIREBASE_PROJECT_ID- Firebase project IDOPENAI_API_KEY- OpenAI API key for NPC generation (required for AI features)
Pages Environment Variables (if needed):
VITE_API_URL- Your deployed worker URL (optional, defaults work)
-
Update Firebase authorized domains:
- Go to Firebase Console > Authentication > Settings
- Add your Pages domain (e.g.,
your-app.pages.dev)
-
Test your deployment:
curl https://your-worker-name.your-subdomain.workers.dev/api/v1/hello
Your app includes a complete authentication system that works in both local and production modes:
- Sign in: Use any email/password combination in the UI
- Storage: User data stored in local Firebase emulator
- API calls: Authenticated requests work normally
- Development: No external accounts needed
- Login: Users sign in with Google (or other configured providers)
- Token: Frontend gets Firebase ID token
- API calls: Token sent in
Authorization: Bearer <token>header - Verification: Backend verifies token and creates/finds user in database
- Protection: Protected routes automatically have user context
// Frontend (already implemented in lib/serverComm.ts)
const response = await api.getCurrentUser();
console.log(response.user);Your database is set up with Drizzle ORM and works the same whether local or production:
// server/src/schema/users.ts
export const users = pgTable('users', {
id: text('id').primaryKey(),
email: text('email').unique().notNull(),
display_name: text('display_name'),
photo_url: text('photo_url'),
created_at: timestamp('created_at').defaultNow(),
updated_at: timestamp('updated_at').defaultNow(),
});- Create schema file in
server/src/schema/ - Export from main schema file
- Push to database:
cd server && pnpm db:push
- React: react.dev
- Hono: hono.dev
- Drizzle ORM: orm.drizzle.team
- Tailwind CSS: tailwindcss.com
- ShadCN/UI: ui.shadcn.com
- Cloudflare Workers: developers.cloudflare.com/workers
- Firebase Auth: firebase.google.com/docs/auth
Backend won't start:
cd server
# Check environment variables
cat .env
# Reinstall dependencies
pnpm installDatabase connection errors:
cd server
# Test database connection
pnpm db:pushFrontend build errors:
cd ui
# Clear cache and reinstall
rm -rf node_modules .vite dist
pnpm installLocal Development:
- Firebase emulator should start automatically with
pnpm dev - Try signing in with any email/password combination
- Check
data/firebase-emulator/for persisted data - Data Protection: Emulator data is automatically backed up every 60 seconds and on clean shutdown to prevent data loss during crashes
Production Mode:
- Check Firebase config:
ui/src/lib/firebase-config.json - Verify environment variables:
server/.env - Check authorized domains in Firebase Console
- Verify build succeeds locally
- Check environment variables in Cloudflare dashboards
- Review logs in Cloudflare Workers/Pages dashboards
- Explore the code: Start with
ui/src/App.tsxandserver/src/index.ts - Customize the UI: Modify components and styling
- Add features: Build your app logic in both frontend and backend
- Deploy: Push to git for automatic deployment
Happy coding! π
Need help? Check the detailed documentation in each workspace (server/README.md, ui/README.md) or visit the community discussions.