Sharlock Hub
Students walk a 3D harbour town as a capybara detective and enter buildings to play short security games; instructors run classes and see results. I built the platform (accounts, classes, scoring), the 3D hub with its 2D fallback, and two of the games, and integrated the rest. I wrote 407 of about 524 commits.
What it is
A cybersecurity learning web app for the SMU course IS216, built by a team of six (me, Keane, Eric, Russell, Xin Lei and Athithya) between 16 September and 6 November 2026. Each building in the town is a short game on one security topic.
What I built
I was platform and integration lead.
- Accounts and classes. Argon2id password hashing, HttpOnly session cookies, CSRF checks, rate limiting, and one active session per account. Institutions contain classes, and instructors see only their own. Password recovery is staff-run: staff verify the student out of band and issue a single-use, expiring link.
- Server-side scoring. The server creates each attempt, checks every action and computes the score, because a security app should not trust browser scores. Every scored game saves through this one contract, which also feeds the leaderboards.
- The 3D hub and 2D town. A walkable Babylon.js harbour town is the home page. Phones, browsers without WebGL2 and slow laptops fall back to a 2D town automatically. The hub supports reduced motion and keyboard controls.
- Live presence. Classmates in the same class see each other on the town over WebSockets, in both 2D and 3D.
- The Sharlock Times. A news reader over the town, fed by a Guardian API proxy with an allowlist and a 30-minute cache.
- Botnet Tag. A multiplayer game about how worms spread and why patching stops them. The server owns positions, tags and puzzles.
- Integration. I wired Xin Lei’s CLI Cyber Defender, Athithya’s Phishing Post-Mortem, Eric’s Social Engineering Simulator, Russell’s Clearance Tower and Keane’s SQL Injection Arcade into the shared scoring contract, game catalogue and router.
The course exercises stored tokens in localStorage. We chose HttpOnly cookies instead, to avoid token theft through XSS. The cost was that we needed CSRF protection.
AI use
As declared in the project README, we used Codex and Claude Code as planner and tutor, and wrote first versions and bug fixes by hand. AI generated most tests, the 3D models (from our Photoshop references), the NPC dialogue and the code and security reviews. With six people running agents in one repository, I wrote the rules file every agent had to follow: read context first, plan before coding, ask before editing, stay out of other contributors’ modules, and check for collisions before starting a feature.
Scale
| Measure | Count |
|---|---|
| Commits (mine, of about 524) | 407 |
| Vitest test files (team) | 262 |
| Playwright end-to-end journeys (team) | 36 |
I set up the team’s testing tools: Vitest for unit, component and API integration tests, Playwright for end-to-end journeys, and disposable test databases so integration and end-to-end runs never touch real data.
Limits
- Not publicly hosted. Botnet Tag and live presence need a long-running WebSocket server, which free serverless hosting cannot provide. The Social Engineering Simulator calls Gemini through one shared free key that could run out during grading. We demoed from localhost and spent the time on usability and testing; the video is the way to see it.
- Interiors are still images. Each game room started as a live 3D scene. Two 3D scenes per game were too slow on laptops, so I replaced the interiors with WebP stills to improve load time, at the cost of less immersive rooms.
- The fallback is a different experience. The 2D town keeps every game reachable but lacks the walkable 3D world.