Inspiration
We wanted to bring the addictive thrill of classic endless runners like Subway Surfers and Temple Run into the world of Augmented Reality. Most AR lenses are passive filters, but we wanted to build a fully interactive game that utilizes the user's physical movement. The goal was to create a hands-free gaming experience where your head becomes the controller.
What it does
Go Runner is a 3D endless runner game played entirely with face gestures.
Head Control: The player steers their avatar by physically moving their head left or right to switch lanes.
Procedural World: The road generates endlessly in front of the player, with obstacles (rocks, barriers) spawning randomly to create a unique path every run.
Dynamic Difficulty: The game speed gradually increases the longer you survive.
Collision System: If the player hits an obstacle, a physics-based collision system triggers a "Game Over" state, stopping the world and playing a dramatic death animation.
How we built it
We built this using Lens Studio 5.17+ and extensive JavaScript scripting.
Core Logic: We implemented a modular architecture. LevelGenerator.js handles the infinite scrolling and object pooling for performance. FaceGameController.js maps the user's nose position to the 3D character's X-axis using smooth linear interpolation (Lerp).
Physics: We utilized Lens Studio's Physics.BodyComponent to handle real-time collision detection between the player (Kinematic body) and obstacles (Static bodies).
Animation: We used the Component.AnimationPlayer to manage complex state transitions, ensuring the character blends smoothly between Running, Strafing, and Dying.
Inter-Script Communication: We built a custom API system using script.api to allow the Collision Detector to talk to the Level Generator and Player Controller simultaneously, ensuring the entire game state freezes instantly upon death.
Challenges we ran into
API Versioning: We faced significant issues with Lens Studio 5's namespace changes, specifically Component.PhysicsBody changing to Physics.BodyComponent, which broke our initial drag-and-drop references in the Inspector.
State Management: Preventing the "Run" animation from overriding the "Death" animation was tricky. We had to implement strict boolean flags (isGameOver) and clean up our update loops to ensure the character didn't accidentally "stand up" and keep running after crashing.
Performance: Ensuring the endless ground generation didn't lag the lens required implementing a "destroy" logic to clean up old chunks as they passed the camera.
Accomplishments that we're proud of
The Control System: We are proud of how responsive the head tracking feels. Using a "dead zone" and sensitivity thresholds prevents accidental movements, making the game feel fair and precise.
Modular Code: We successfully decoupled the game logic. The collision system doesn't need to know how the level moves; it just sends a "Stop" signal via the API. This makes the code very clean and scalable.
What we learned
We gained a deep understanding of Lens Studio's Scripting API, particularly how to expose public functions between different script components.
We learned how to implement Kinematic Physics for character controllers, avoiding the "floaty" feel of standard rigid bodies.
We learned the importance of Input sanitization, ensuring that once the game is over, all user inputs are immediately disabled to prevent glitches.
What's next for Go Runner
Power-ups: Implementing coins or shields that the player can collect.
Audio: Adding sound effects for jumping, crashing, and background music to enhance immersion.
More Obstacles: Adding dynamic obstacles like moving cars or falling objects to increase difficulty.
Built With
- javascript
- lens-studio


Log in or sign up for Devpost to join the conversation.