- Capuchin Caverns is a live multiplayer VR title on the Meta Horizon Store (15,000+ downloads, 2000+ Monthly Active Users at peak) which I built and shipped. View on Meta Horizon Store
- This codebase contains the entire version-controlled Unity Project for Capuchin Caverns, including C# scripts, prefabs, scenes, media, art assets, dependencies, project settings.
- The systems in this repository are all deployed to production and have proven their worth in live multiplayer conditions.
5,000-10,000 lines of original gameplay + systems code throughout project. This code has been refactored, optimized, and improved over and over again based on live user load.
⚪ Feature: Physics-based locomotion (Derived from an open-source gorilla-style locomotion project; reworked to fit my XR architecture)
This movement script is what I attach to an XR Origin component, which has the player's camera and hands; I've applied this base VR movement system in novel ways by varying constraints - creating new movement systems like slippery walls, flying, and zero gravity. All the while, I've made sure to reduce motion sickness by making momentum transfers feel self-controlled, mitigating a common problem many other VR apps face.
⚪ Feature: Real-time multiplayer
My Networking Controller Script (this talks directly to Photon PUN 2 API)
Multiplayer system is built on the Photon PUN 2 architecture with a client-authoritative model abstracted behind a reusable networking controller. Ultimately, it's a low overhead way to process network changes. Calls only happen explicitly, not at every frame. Each client owns a networking controller responsible for player instantiation, state synchronization, and RPC dispatch via the Photon Network.
Practical Example: Let's say one player wanted to change his color. Since this new color needs to be broadcasted to all other players, the networking controller script first changes the color locally, then dispatches an RPC targeting the entire room.
Here's the color-changing script, one of many scripts in the codebase that directly work with my networking controller script. Color Changing Script
⚪ Feature: Cosmetic Economy with real money payments system + virtual currency saved to game backend + shop with 63 distinct add-on items to purchase.
-
Each player gets a set amount of in-game currency each day they login (helps with retention). Daily Marbles Reward Script
-
This currency syncs to Azure PlayFab (my game's backend). Currency Manager Script
-
Cosmetic Shop has 63 Distinct Cosmetic SKUs that can be bought with in-game currency. About half of them are available year round and the other half is seasonal. You can find the year round ones as prefabs in this folder: Cosmetic Prefabs
-
Real Money Payment Systems (processed thousands of dollars). I implemented a VR storefront flow that launches the Oculus checkout for a specific SKU, consumes the purchase to prevent double-spends, then credits the player’s PlayFab currency balance. Purchases are initiated from in-world interactions (hand collider trigger) so the shop feels native to VR. Side Note: Meta's compliance process was a pain! In App Purchasing Script
-
The cosmetic shop has skins available for purchase: skin equiping syncs to all other players in the room. Network buffers allow new players who join late to an existing server to be “caught up” on game states such as who is "it" in the tag mode. NetworkSkin.cs is a script that is a reusable component doing the networking heavy lifting for all skins in the cosmetic shop.
⚪ Feature: Explore 3 levels of terrifying horror
The names of the horror monsters are Fluffy, Gruffy, and Scruffy. They roam different maps and are able to dynamically pathfind their way around obstacles to the nearest player to eat them alive. I used Unity's Navigation Mesh AI Agent because it's system can traverse environments aren't predictable or stable. In order for every player to see the monster in the exact same place, these monsters had to be networked too.
See this script for the implementation: Networked Enemy Follow Script
When the monster eats a player, they teleport back to the spawn through this script.
⚪ Feature: Jump on parkour obstacle courses and super bouncy trampolines
"Take a simple idea and take it seriously." - Charlie Munger. I've scattered trampolines across Capuchin Caverns - players shoot into the sky and come back down at 9.8 m/s^2. To achieve this, force is applied upward on the player's Rigid Body for a time - in other words, an impulse. I later learned the actual physics (impulse-momentum theorem: FΔt = Δp)in my AP Physics 1 class and it's helped me build bigger and better trampolines ever since then.
Trampoline Impulse Application Script:
⚪ Feature: Play tag inside an ever-changing forest and village
This script represents the pinnacle of my work with event-driven RPCS. It required me to understand in depth how to search through the multiplayer client list and manipulating data streams through the Photon Network. It now powers the "tag mode" in my game. It makes me proud that I followed through on it - considering it's difficulty - all the way to production.
⚪ Feature: Do an explosive, roller coaster train ride
The "train" is in essence a collection of objects that move along a path of waypoints. The waypoints are embedded into the track rails. The track rails are prefabs so that I could easily add custom routes for the train. I also had to implement networking logic for the train so that it appears in the same place for every single player. The MasterClient controls the train's movement. The train has a PhotonView component, which makes every other player see the train as the MasterClient sees it, thereby creating "syncing". For my use case, MasterClient (client-authoritative) is better than a server-authoritative model because it reduces CPU compute cost since less cloud processing as well as reducing the all-important latency because no roundtrip is needed between server and client.
Waypoint Train Controller Script
⚪ Feature: A trick glass bridge with glass stepping stones
Players must jump across a glass bridge suspended high into the air like Squid Game. Some stepping stones are fake; some are real. If they step on the wrong stone, they die and teleport back to the start. Initially, I approached this as a simple teleport. I soon found out that objects blocking the path would interfere with the player moving forward, which forced me to disable and reenable the map each time they fell with a coroutine.
Teleport Player If Fall Script
⚪ Feature: In Game "Computer"
I soon realized that I would need to add controls for players to join/create private rooms, change name, change color, etc. Controls are disguised as a 3D computer in game because 3D always feels more natural in VR than a 2D user interface screen. Controlling Scripts for the computer require being able to reason about servers, multiplayer, and user experience: Computer Scripts