
Maze


Following the chaos of Thunder Mode, our 7th update focused on structure, persistence, and UX refinement. We introduced a Procedural Maze System, extended our Ghost Persistence to 24 hours, and performed “UX Subtraction” to ensure mobile controls don’t get in the way of gameplay.
1. Procedural Architecture: The Recursive Labyrinth
Instead of static maps, we implemented a Recursive Backtracking Algorithm to generate a unique 25×25 grid every time a session begins. To make it a true challenge, we punched only two exits (North and South), forcing players to navigate deep into the core before finding a way out.
The “No-Jump” Constraint:
To prevent players from simply hopping over the challenge, we dynamically disabled the Jump logic whenever Maze Mode is active. This forces a grounded, tactical experience where movement speed and memory are the only tools for survival.
2. UX Subtraction: Fixing Mobile Friction
One of the biggest issues in Round 6 was “Control Interference.” On mobile, players frequently swiped down while trying to turn, accidentally triggering the Camera Flip, which inverted their controls and caused them to run directly into lightning bolts.
The Solution:
- Removed Swipe-Down Flip: We completely stripped the camera-flip gesture from mobile and the ‘V’ key from the maze. In a high-stakes maze or storm, the player needs a consistent perspective.
- The 45px Centering: We refined the landing page UI by calculating a precise dual-toggle layout. By offsetting the Thunder and Maze buttons by 45px from the center, we created a balanced, professional “Game Mode” selector that disappears once the player enters the world.
3. Camera Engineering: Preventing “Wall Cheating”
In early testing, the camera was too far back, allowing players to see over the walls and easily locate the exit. We re-engineered the camera for a “Close-In” feel.
code JavaScript
// Optimized Maze Perspective
const mazeOn = maze && maze.enabled;
const h = mazeOn ? 4 : 6; // Lower height to stay inside the hallways
const d = mazeOn ? 6 : 12; // Shorter distance to block the "long view"
const camOffset = new THREE.Vector3(0, h, -d).applyQuaternion(localPlayer.quaternion);
camera.position.lerp(localPlayer.position.clone().add(camOffset), 0.1);To balance this difficulty, we added the ‘M’ Map Cheat. Pressing ‘M’ flies the camera 180 units into the sky. To prevent a “white-out” from the scene fog, we implemented a Dynamic Fog Override:
- Normal: Fog end = 150 (Atmospheric).
- Map View: Fog end = 2000 (Clear overview).
4. Persistence: The 24-Hour Ghost System
A world feels empty if you only see who is currently online. We updated the Node.js server to transform every disconnected player into a Persistent Ghost.
These ghosts stay at their last known coordinate for 24 hours. They are rendered with 50% opacity and marked as “(OFFLINE),” serving as a historical record of who has visited the world. If a player rejoins with the same name, the server automatically “cleans” their old ghost to prevent duplicates.
5. The Victory Loop: High-Precision Timers
Competitive play requires data. We integrated a millisecond-accurate timer that triggers the moment “START” is clicked.
code JavaScript
// Victory Logic in maze.js
const timeTaken = ((Date.now() - this.startTime) / 1000).toFixed(2);
const name = player.userData.name || "Explorer";
this.ui.msg.innerHTML = `
<div style="font-size:24px;">🏆 ${name} ESCAPED!</div>
<div style="font-size:18px;">TIME: ${timeTaken}s</div>
`;When a player crosses the maze boundary, the system automatically clears the geometry, displays a victory card, and logs the time, creating a “speed-run” meta-game within the social space.
The Result
Round 7 turned our world from a simple “look and see” experience into a “do and survive” platform. By tightening the camera, removing confusing mobile gestures, and adding persistent history through ghosts, we’ve created a world that feels lived-in and challenging.
The walls are up, and the clock is ticking—can you find the exit in under 60 seconds?