An interactive web experience where players try to recognize Clash Royale cards from their artwork. You sign in, guess the card name, and see your score climb on a shared leaderboard. Think of it as a quick, competitive trivia game for Supercell fans that's built to be easy to host, play, and share.
I grew up grinding Clash Royale and always loved how instantly recognizable the cards are to me. I wanted a project that blended that nostalgia with a modern web stack so I could keep practicing full-stack skills. This app let me tackle:
- real user accounts and scores with a persistent database
- a live leaderboard that friends can actually compete on
- integrating an external API (Clash Royale) in a way that still works in a hosted environment
- my first time building a full-stack app from scratch
It also doubled as a playground for deployment to figure out how to keep API keys secure, handle a production database, and still ship something fun.
- Fast Onboarding: Lightweight registration and login with password hashing.
- Instant Feedback: Guess results update your score and show the correct answer when you miss.
- High Score Tracking: Session score plus persistent personal bests.
- Global Leaderboard: Everyone’s top scores ranked in one place.
- Stay Signed In: Cookie-based sessions keep you logged in while tracking your current run securely.
- Modern UI: Built with Bootstrap 5 and custom styling.
- Frontend: EJS templates rendered by Express, with Bootstrap for speedy layout tweaks.
- Backend: Node.js + Express.js for routes, Passport.js for authentication, bcrypt for hashing.
- Database: PostgreSQL stores user accounts and high scores.
- External Data: Card images and metadata pulled from the Clash Royale API via the RoyaleAPI proxy (so the app keeps a stable IP address).
└── RoyaleGuesser/
├── public/ # Fonts, images, and CSS
├── views/ # EJS templates (pages + shared partials)
├── apiService.js # Clash Royale API client
├── authService.js # Registration/login helpers
├── gameService.js # Scoring and leaderboard logic
├── database.js # PostgreSQL connection
├── index.js # Express app entry point
└── config.js # Centralized app settings
- Node.js 18.x or newer
- PostgreSQL 13+ running locally or remotely
- npm (ships with Node)
- A Supercell developer account (for the Clash Royale API key)
git clone <repository-url>
cd Project1npm installCreate a .env file in the project root. Everything is relative—no hard-coded paths needed:
# PostgreSQL connection
PG_USER=your_postgres_username
PG_HOST=localhost
PG_DATABASE=clash_guesser
PG_PASSWORD=your_postgres_password
PG_PORT=5432
# Session + API
SESSION_SECRET=replace_me_with_a_random_string
CR_API_KEY=your_supercell_developer_key
PORT=3000Create the database and required table (run this once in psql, DBeaver, or your tool of choice):
CREATE DATABASE clash_guesser;
\c clash_guesser
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL,
highscore INTEGER NOT NULL DEFAULT 0
);- Visit the Supercell developer portal.
- Create a key, ensure the
royalescope is enabled. - Add the RoyaleAPI proxy IP
45.79.218.79/32to the allow list (required for hosted environments). - Copy the key into the
.envfile asCR_API_KEY.
Want to use the official API endpoint instead of the proxy? Swap the URL in
apiService.jstohttps://api.clashroyale.com/v1/cardsand whitelist your hosting provider’s outbound IP when you deploy.
npm startVisit http://localhost:3000 and you’ll land on the login page.
- Create an Account: Quick form; credentials stored securely.
- Start Guessing: Each round shows a card image, so type your best guess.
- Score Updates: Correct answers bump your session score; miss and you restart from zero (but see what you missed).
- Leaderboard: Jump to the leaderboard to view top players and your own high score.
- Session Store: Currently uses Express’s in-memory store. Needs Redis or another persistent store for a production-grade deployment.
- Mobile Layout: Works on mobile but some spacing could be tighter and needs more responsive polish.
- Rate Limiting: API requests aren’t throttled yet. Add guards if opening to public traffic.
- Testing: No automated tests have been written; integration tests for auth and gameplay are on the roadmap.
- Card Pool Expansion: Right now it pulls from the default Clash Royale card list; adding filters (rarity, arena) would be a neat enhancement.