A virtual tabletop tool for Daggerheart GMs featuring encounter management, battle maps, dice rolling, and player displays.
| Tier | Auth Required | Features |
|---|---|---|
| Demo | No | Full app functionality, no cloud persistence |
| Basic | Yes | Cloud save, campaigns, notes, 250MB storage |
| Premium | Yes | Basic + community battlemap repository (coming soon) |
| Component | Service | Notes |
|---|---|---|
| Static Frontend | Cloudflare Pages | Vanilla JS, no build step |
| Backend API | Cloudflare Workers | Serverless functions |
| Auth | Firebase Auth | Google OAuth |
| Database | Firestore | User data, campaigns, notes |
| Live Sync | Firebase Realtime DB | Room-based sync |
| File Storage | Cloudflare R2 | Battlemaps, images |
| CI/CD | GitHub Actions | Deploys Pages + Workers |
npm install -g wranglerpublic/js/lib/auth.jsworkers/.dev.vars.example to workers/.dev.varsFIREBASE_API_KEY=your-api-key
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_SERVICE_ACCOUNT={"type":"service_account",...}
cd workers
wrangler dev
npx serve public
Or run both together:
wrangler pages dev public --binding STORAGE=daggerheart-uploads
daggerheart-gm-management/
├── .github/
│ └── workflows/
│ └── deploy.yml # CI/CD pipeline
├── public/ # Static frontend
│ ├── index.html # Landing page
│ ├── gm-control-panel-simplified.html
│ ├── encounter-generator.html
│ ├── battle-map.html
│ ├── player-display.html
│ ├── daggerheart_creatures.json
│ ├── js/
│ │ ├── app.js # Cloud features integration
│ │ ├── lib/
│ │ │ ├── auth.js # Firebase auth wrapper
│ │ │ ├── api.js # API client
│ │ │ ├── entitlements.js # User entitlements
│ │ │ └── features.js # Feature flags
│ │ └── components/
│ │ └── notes.js # Notes component
│ └── assets/
│ └── images/
├── workers/ # Cloudflare Workers API
│ ├── src/
│ │ ├── index.js # Main router
│ │ ├── routes/
│ │ │ ├── auth.js # Auth endpoints
│ │ │ ├── campaigns.js # Campaign CRUD
│ │ │ └── upload.js # File uploads
│ │ └── lib/
│ │ └── firebase.js # Firebase Admin client
│ ├── wrangler.toml # Wrangler config
│ └── .dev.vars.example # Example secrets
├── firebase/
│ ├── firestore.rules # Firestore security rules
│ └── database.rules.json # Realtime DB rules
└── README.md
Push to main branch to trigger GitHub Actions deployment.
Set these in your repository settings:
CLOUDFLARE_API_TOKEN - API token with Workers and Pages permissionsCLOUDFLARE_ACCOUNT_ID - Your Cloudflare account IDSet these via wrangler secret put:
wrangler secret put FIREBASE_API_KEY
wrangler secret put FIREBASE_PROJECT_ID
wrangler secret put FIREBASE_SERVICE_ACCOUNT
Client-side code is public. Security is enforced by:
users/{userId}/
├── profile: {
│ email: string,
│ displayName: string,
│ createdAt: timestamp
│ }
├── entitlement: {
│ tier: 'basic' | 'premium',
│ grantedAt: timestamp,
│ expiresAt: timestamp | null
│ }
├── usage: {
│ storageBytes: number,
│ lastUpdated: timestamp
│ }
└── campaigns/{campaignId}/
├── name: string
├── createdAt: timestamp
├── updatedAt: timestamp
├── encounter: { ... }
└── notes/{noteId}: {
title: string,
content: string,
category: string,
createdAt: timestamp,
updatedAt: timestamp
}
| Method | Path | Description |
|---|---|---|
| POST | /api/auth/verify | Verify token and get user profile |
| GET | /api/campaigns | List user’s campaigns |
| POST | /api/campaigns | Create new campaign |
| GET | /api/campaigns/:id | Get campaign with notes |
| PUT | /api/campaigns/:id | Update campaign |
| DELETE | /api/campaigns/:id | Delete campaign |
| POST | /api/upload | Request file upload URL |
MIT