Welcome to Createrington, a full-stack community portal that unifies a Minecraft server, Discord community, and browser-based web client into one seamless experience. The project features real-time player tracking, a fully simulated in-game cryptocurrency market, a waitlist and application system, an extensive admin dashboard, and deep Discord bot integration — all built on a type-safe TypeScript monorepo with tRPC, Drizzle ORM, and React.
- Live: createrington.com
Createrington was designed to unify fragmented community platforms into a single portal. Instead of separate tools for Minecraft management, Discord automation, and user onboarding, this project merges everything into one cohesive ecosystem — with a novel in-game crypto economy layered on top to drive player engagement, retention, and community fun.
- Key Features
- Screenshots
- Architecture Overview
- Tech Stack
- Installation & Setup
- Running the Project
- Scripts
- API Overview
- WebSocket Events
- Services
- Crypto Market Module
- Admin Dashboard
- Discord Integration
- Contributing
- Related Projects
- Disclaimer
Createrington is a complete ecosystem linking Minecraft gameplay to Discord and a browser client. Highlights include:
Players log in via Discord OAuth. Account verification links a Discord identity to a Minecraft UUID, gating access to protected features like trading.
Two-way chat sync between Minecraft, Discord, and the web client using Socket.io and Discord webhooks. Messages appear across all three platforms in real time.
The server tracks per-player session time and aggregates it into daily, hourly, and lifetime summaries. Discord roles are automatically assigned based on playtime tiers. A daily "Top Player" role rewards the most active player.
A fully simulated exchange with three token tiers (memecoins, stablecoins, blue-chips), limit and stop-loss orders, real-time price ticks over WebSocket, OHLCV candlestick charts, price alerts, watchlists, portfolio snapshots, and AI-generated market news. See Crypto Market Module for details.
Prospective players apply via the website. Admins review, approve, or decline applications from the admin dashboard. Approved players receive Discord notifications and are automatically whitelisted.
BlueMap integration renders an interactive 3D Minecraft world map directly in the browser.
A dedicated admin panel covering player management, moderation, economy tools, Discord embed/message builders, server metrics, audit logs, and more. See Admin Dashboard for details.
Players can open support tickets from the web client. Tickets are managed by admins through the dashboard with full action history.
OpenAI generates in-character market news articles for the crypto economy, published to the news feed and Discord.
Three pnpm workspaces under packages/:
createrington/
├── packages/
│ ├── client/ # React 18 + Vite SPA (port 3000)
│ ├── server/ # Express 5 + tRPC backend (port 5001)
│ └── shared/ # Zod schemas + TypeScript types
├── db/
│ ├── docker-compose.yml
│ └── data/test-data.sql
└── scripts/ # Build helpers
- Express 5 with TypeScript — configures middleware, WebSockets, REST routes, tRPC, and Discord bots.
- tRPC v11 — type-safe API layer mounted at
/trpc, with three access levels:publicProcedure,userProcedure,adminProcedure. - Drizzle ORM — schema-first PostgreSQL access. All business logic lives in application code; no DB functions or triggers.
- Custom DI container (
services/container.ts) — services with async lifecycle are registered and resolved viagetService<T>(Services.KEY). - Two Discord bot instances — main bot (slash commands, events, leaderboards) and web bot (OAuth, role assignment).
- Socket.io — real-time events for player status, crypto prices, market events, and in-game chat.
- Winston — global structured logger with daily rotating log folders.
- React 18 + Vite — SPA with Vite dev proxy routing
/api,/trpc, and/socket.ioto the backend. - tRPC + React Query — data fetching with full type safety from server to client.
- Tailwind CSS v4 — dark theme using OkLCH color space.
- Shadcn/ui (new-york style) — component library built on Radix UI primitives.
- Socket.io-client — WebSocket connection with manual reconnection and exponential backoff.
- Zod schemas for input validation (shared between server and client).
- TypeScript types for auth roles, socket events, and DB entities (auto-generated from schema).
The server exports its AppRouter type via the @createrington/server/trpc package export. The client imports it as a type-only import, giving end-to-end type safety with zero runtime overhead.
// client
import type { AppRouter } from "@createrington/server/trpc";| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS v4, Shadcn/ui, Radix UI |
| Backend | Node.js 22, Express 5, TypeScript |
| API | tRPC v11, REST (Express routes) |
| Database | PostgreSQL 15 (Docker), Drizzle ORM, drizzle-kit |
| Real-time | Socket.io (server + client) |
| Auth | Discord OAuth, JWT (access token) + HTTP-only cookie (refresh) |
| Discord | Discord.js v14 (two bot instances) |
| Charts | Recharts, lightweight-charts (TradingView-style) |
| AI | OpenAI API (market news generation) |
| Nodemailer (SMTP) | |
| Rendering | Puppeteer + Canvas (image generation) |
| Maps | BlueMap (Minecraft world map) |
| Monorepo | pnpm workspaces |
| Testing | Vitest (unit + integration) |
- Node.js v22+
- pnpm v9+
- Docker (for PostgreSQL)
- Discord application with a bot token and OAuth2 credentials
- Minecraft server with RCON enabled
git clone https://gitea.matejhoz.com/Createrington/app.git createrington
cd createrington
pnpm installCopy .env.example to .env in packages/server/ and fill in the required values:
cp packages/server/.env.example packages/server/.envKey variables:
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string (e.g. postgres://user:pass@localhost:5433/createrington) |
JWT_SECRET |
Secret for signing access tokens |
JWT_REFRESH_SECRET |
Secret for signing refresh tokens |
DISCORD_MAIN_TOKEN |
Main bot token |
DISCORD_WEB_TOKEN |
Web/OAuth bot token |
DISCORD_CLIENT_ID |
Discord application client ID |
DISCORD_CLIENT_SECRET |
Discord application client secret |
DISCORD_GUILD_ID |
Your Discord server (guild) ID |
OPENAI_API_KEY |
OpenAI API key (for market news) |
RCON_HOST |
Minecraft server RCON host |
RCON_PORT |
Minecraft server RCON port |
RCON_PASSWORD |
Minecraft server RCON password |
SMTP_HOST |
SMTP server host |
SMTP_USER |
SMTP username |
SMTP_PASS |
SMTP password |
WEBSITE_URL |
Public website URL (e.g. https://createrington.com) |
Start the PostgreSQL Docker container, apply Drizzle migrations, and seed test data:
pnpm db:up # Start PostgreSQL container on port 5433
pnpm db:migrate # Apply Drizzle migrations to create all tables
pnpm db:seed # Load test dataOr reset everything in one command:
pnpm db:reset # Wipe DB, run migrations, seed test dataScrape your Discord server's roles and channels into the local config, then deploy slash commands:
pnpm scrape-discord # Sync Discord roles/channels to discord-entities.json
pnpm deploy-commands # Register slash commands with DiscordAfter any schema changes, regenerate TypeScript types and query classes:
pnpm generateRun the full development stack (server, client, and type watcher) in one command:
pnpm devOr start individual processes:
pnpm dev:server # Express + tRPC on port 5001 (tsx watch)
pnpm dev:client # Vite on port 3000 (with proxy to :5001)
pnpm dev:types # Watch mode tRPC type declarationspnpm build # Full pipeline: generate → shared → server → client → dist
pnpm start # Run production build (node dist/server/src/server.js)The build pipeline runs: tsc → tsc-alias (resolve path aliases) → post-build.ts (add .js extensions for ESM) → copyfiles (copy static assets) → Vite build for the client.
| Script | Description |
|---|---|
pnpm dev |
Start all dev processes concurrently |
pnpm build |
Full production build pipeline |
pnpm start |
Run the production server |
pnpm typecheck |
Type-check all workspaces |
pnpm lint |
Lint all workspaces |
pnpm generate |
Regenerate DB types + query classes, then typecheck |
pnpm generate:ci |
Same as generate but skips typecheck |
pnpm test |
Run server tests in watch mode |
pnpm test:unit |
Unit tests only |
pnpm test:integration |
Integration tests only |
| Script | Description |
|---|---|
pnpm db:up |
Start PostgreSQL Docker container (port 5433) |
pnpm db:down |
Stop the container |
pnpm db:reset |
Wipe DB, run migrations, seed test data |
pnpm db:seed |
Load test data only |
pnpm db:shell |
Open a psql shell inside the container |
pnpm db:generate |
Generate Drizzle migration SQL from schema changes |
pnpm db:migrate |
Apply pending migrations to the running database |
pnpm db:destroy |
Remove container, images, and volumes |
pnpm db:logs |
Tail PostgreSQL container logs |
pnpm pgadmin |
Start pgAdmin container |
| Script | Description |
|---|---|
pnpm scrape-discord |
Regenerate discord-entities.json (roles, channels, categories) |
pnpm deploy-commands |
Deploy Discord slash commands to the configured guild |
The API surface is split between tRPC procedures (primary, type-safe) and a thin layer of Express REST routes (webhooks, OAuth redirect, file uploads).
| Namespace | Procedures | Description |
|---|---|---|
servers |
list, get |
Server status, player counts |
players |
list, get, getByServer |
Player stats, online status, ranks |
waitlists |
apply |
Submit a join application |
metrics |
summary, activity |
Public community metrics |
crypto |
listTokens, getToken, getPriceHistory, getMarketEvents, getNews, getLeaderboard |
Market data, charts, news |
| Namespace | Procedures | Description |
|---|---|---|
account |
get, update, getPlaytime, getStats |
Profile, settings, playtime |
achievements |
list, get |
Achievement progress |
crypto |
getPortfolio, getHoldings, trade, placeOrder, cancelOrder, getOrders, getTransactions, getAlerts, createAlert, deleteAlert, getWatchlist, addToWatchlist, removeFromWatchlist |
Trading, orders, portfolio, alerts |
| Namespace | Procedures | Description |
|---|---|---|
dashboard |
getMetrics, getCharts |
KPIs, activity summaries |
players |
list, get, ban, unban, adjustBalance, issueStrike, getAuditLog |
Full player management |
servers |
list, get |
Server details |
waitlist |
list, approve, decline |
Application review |
crypto |
listTokens, createToken, updateToken, deleteToken, overridePrice, triggerEvent |
Token management |
embeds |
list, get, create, update, delete |
Discord embed presets |
autoMessages |
list, create, update, delete |
Scheduled Discord messages |
announcements |
send |
In-game broadcast announcements |
faq |
list, create, update, delete |
Knowledge base editor |
logs |
list |
Admin action audit trail |
discordCommands |
list |
Slash command introspection |
metrics |
growth, economy, moderation |
Advanced analytics |
| Method | Endpoint | Description |
|---|---|---|
| GET | /auth/discord |
Initiate Discord OAuth flow |
| GET | /auth/discord/callback |
OAuth callback, issues JWT |
| POST | /auth/refresh |
Refresh access token |
| GET | /api/players |
Live player list (used by Minecraft plugin) |
| POST | /api/verify |
Minecraft login token verification |
The server uses Socket.io with a subscription model. Clients subscribe to specific data streams.
| Type | Description |
|---|---|
SERVER_STATUS |
Server health and player counts |
PLAYERS |
Player online/offline status changes |
MESSAGES |
In-game chat relay |
CRYPTO_MARKET |
Price ticks, orders, market events, news |
ALL |
All streams |
| Event | Direction | Description |
|---|---|---|
SUBSCRIBE |
Client → Server | Subscribe to a data stream |
UNSUBSCRIBE |
Client → Server | Unsubscribe from a stream |
REQUEST_INITIAL_DATA |
Client → Server | Request bulk current state |
INITIAL_DATA |
Server → Client | Bulk state response |
UPDATE_SERVER_STATUS |
Server → Client | Server player count / health update |
UPDATE_PLAYERS |
Server → Client | Player list update |
UPDATE_MESSAGE |
Server → Client | New in-game/Discord chat message |
UPDATE_CRYPTO_PRICES |
Server → Client | Price tick for all tokens |
UPDATE_CRYPTO_ORDER |
Server → Client | Personal order fill or cancellation |
CRYPTO_MARKET_EVENT |
Server → Client | Major event (crash, IPO, new listing) |
CRYPTO_NEWS |
Server → Client | New AI-generated news article |
Key services registered in the DI container (packages/server/src/services/container.ts):
| Service Key | Description |
|---|---|
DATABASE |
Drizzle ORM connection pool |
HTTP_SERVER |
Express application instance |
DISCORD_MAIN_BOT |
Main Discord bot (commands, events, leaderboards) |
DISCORD_WEB_BOT |
Web Discord bot (OAuth, role assignments) |
WEBSOCKET_SERVICE |
Socket.io server + subscription room manager |
MESSAGE_CACHE |
Discord message cache for webhook deduplication |
PLAYTIME_MANAGER_SERVICE |
Session tracking and online status synchronization |
TICKET_SERVICE |
Support ticket lifecycle management |
LEADERBOARD_SERVICE |
Playtime and economy leaderboard aggregation |
PLAYER_BAN_SERVICE |
Temporary and permanent ban management |
CRYPTO_MARKET_SERVICE |
Price ticks, order matching, market events, IPOs |
Services with async lifecycle (Discord bots, WebSocket, etc.) are accessed via getService<T>(Services.KEY). Stateless singletons are imported directly.
The in-game economy is a fully simulated exchange with realistic market dynamics.
| Tier | Description |
|---|---|
| Memecoins | Highly volatile; periodically spawned and can crash to zero |
| Stablecoins | Pegged to €1, used as a base currency for the economy |
| Blue-chips | Mean-reverting, less volatile, behave like blue-chip stocks |
- Market orders — Immediate execution at current price
- Limit orders — Execute at a specified price or better
- Stop-loss orders — Auto-sell when price drops to a threshold
- Take-profit orders — Auto-sell when price reaches a target
- Partial fills — Large orders can be partially matched
- Order expiry — Stale orders are cancelled on a 5-minute cycle
- Real-time price ticks broadcast over WebSocket
- OHLCV candlestick history at 1m, 5m, 1h, and 1d aggregations (TradingView-style charts)
- 24h price change % and volume tracking per token
- Price alerts with WebSocket notifications
- Watchlist management per user
- Daily and weekly portfolio value snapshots
- Transaction history with full buy/sell audit trail
- Wealth and return % leaderboards
Random and scheduled events keep the market dynamic:
- Crash events — Sudden price collapses (removes tokens below a threshold)
- New listings — Fresh memecoins spawned with an initial price
- IPOs — Structured initial public offerings with a lock period and price discovery
- Seasonal events — Holiday or in-game seasonal modifiers
OpenAI generates in-character market news articles that are published to the web news feed and broadcast to a Discord channel, adding narrative depth to the economy.
The admin panel (accessible at /admin) provides complete control over the community.
- View full player profiles (Discord, Minecraft UUID, playtime, balance, bans, strikes)
- Issue temporary or permanent bans with a reason
- Apply strikes categorized by type (PvP, theft, griefing, harassment, etc.)
- Adjust player balances manually with logged audit entries
- View admin action audit logs per player
- Ban and strike history with searchable, filterable tables
- Full audit trail: who took the action, when, what changed, and why
- View and manage all crypto tokens (create, update, delete, override price)
- Trigger market events manually (crash, new listing, IPO)
- Embed Builder — WYSIWYG editor for Discord embed presets
- Auto-Messages — Schedule recurring or random messages to Discord channels
- Announcements — Broadcast messages to the Minecraft server in-game
- Command Docs — Introspect and browse registered slash commands
- FAQ Editor — Create and edit the public knowledge base
- Waitlist — Review, approve, or decline player applications
- Growth metrics (new players, active players, retention)
- Economy health (trading volume, market cap, balance distribution)
- Moderation stats (bans, strikes, ticket volume)
- Server metrics (player load per server, playtime distribution)
Two bot instances serve different roles:
- Handles slash commands (
/ban,/unban,/balance,/give, etc.) - Posts to Discord from web events (announcements, news, embeds)
- Manages automatic role assignments (playtime tiers, top player, supporter)
- Relays in-game Minecraft chat to a Discord channel
- Posts leaderboard embeds on a schedule
- Handles Discord OAuth flow for web login
- Assigns roles after successful account verification
Slash commands are defined in packages/server/src/discord/commands/ and deployed via pnpm deploy-commands.
- Format: Prettier (spaces, double quotes, semicolons, trailing commas)
- Commit format:
type(scope): description— e.g.feat(server): add player ban endpoint - Allowed types:
feat,fix,chore,refactor - Scopes:
server,client,shared(or omit if change spans multiple packages) - Tests: Vitest (
pnpm test:unit,pnpm test:integration) - PR base: always target
dev - Never push directly to
devormain
- Createrington Currency — Minecraft mod providing in-game currency integration with this platform
- Createrington: Cogs & Steam — The official Minecraft modpack
- mc-server — The original predecessor to this project; a single-package Node.js + React implementation of the Createrington portal before the rewrite into this TypeScript monorepo
Player skins shown on the Discord render cards (/profile, /top, /activity, /compare) and throughout the web portal are generated by free public Minecraft skin APIs:
- Starlight Skin API by Lunar Eclipse Studios — the full-body 3D poses on the render cards.
- MCHeads — avatar thumbnails in Discord embeds and the fallback body renderer when Starlight is unavailable.
- Crafatar — server-side skin download fallback.
Thanks to each of these services for keeping their APIs open for the Minecraft community.
Not affiliated with Mojang, Microsoft, or Discord.
The in-game cryptocurrency market is a simulated economy for entertainment purposes only and has no real-world monetary value.












