A browser escape-room game in which players solve image puzzles from the Banana API to crack each room's code. The server keeps the answers, validates every attempt and owns the leaderboard.
Project media coming soon
Screenshots and demo videos for this case study will appear here.
Banana Cave embeds a Phaser 3 game inside a React 19 application. Each room hides three puzzles, and each solved puzzle reveals one digit of the door code. Five rooms make a level. An Express and MongoDB backend handles accounts, puzzle sessions, progress and a persistent leaderboard.
If the browser ever knew a puzzle's answer, a player could read it from the network tab. The game also depends on a third-party puzzle API that can be slow or unavailable.
I kept the Phaser scenes (boot, preload, game) separate from the React interface and put every rule on the server. The server fetches each puzzle, sends only its image to the client and stores the solution in memory, keyed by user, level, room and slot. Answers are checked on the server, and every final-code attempt is recorded as a game session.
The project shows how to combine a game engine with a conventional full-stack app without giving the browser any authority over answers or progress.
Boot, preload and game scenes with player, door and bomb components, inside a React shell for authentication and menus.
Auth, game and leaderboard routes, with request validation and auth middleware.
Users with current level and room, game sessions with every attempt, and a leaderboard collection.
Fetched on the server with a 5-second timeout and a generated fallback puzzle if the API fails.
The puzzle endpoint returns only the image URL and coordinates. The solution stays in a server-side map keyed by user, level, room and slot. Single digits and the final three-digit code are both checked against that map, and correct codes clear it, so the same answers can't be replayed.
Progress advances only if the new position is beyond the stored one. The leaderboard is updated with MongoDB's $max operator, so a replayed or out-of-order request can never lower a player's best result.
If the Banana API times out or returns a malformed payload, the server generates a fallback puzzle and flags it, so the game stays playable when the third-party service is down.