
Rec Room hired me to scale their UGC platform by leading the development of the next generation of their in-game scripting system, Circuits, and building a team around it.
At Rec Room, my responsibilities evolved across three roles: as a Senior Software Engineer, I built the core technology and team; as a Software Architect, I scaled that technology across a 300-person company; and as an Organization Technical Lead, I brought the same engineering discipline to every team in our UGC org.
This page focuses on the first part of that journey: building the core technology for Circuits.
Table of Contents:
Circuits was Rec Room's in-game scripting system for building interactive, multiplayer experiences. When I joined, Circuits V1 was already in production and widely used. Unfortunately, the Circuits V1 architecture synchronized only numeric values across the network every 100 ms, forcing creators to encode all objects, strings, and state as numbers and capping the system at a 10 FPS tick rate. These constraints limited expressiveness, performance, and usability, motivating the design and implementation of Circuits V2: a ground-up re-architecture that removed these limitations while preserving the accessibility that made Circuits successful.
For Circuits V2, we modeled our approach on Unreal's Blueprint System with two key differences: we designed it as a fully physicalized experience using 3D interaction principles rather than 2D menus, and we supported real-time, multiplayer-synchronized editing.
The system was designed for 13-year-olds. At that age, logical reasoning is still developing, so we aimed to make the system accessible to everyone. An engineer might implement a delay by accumulating delta time across frames and comparing it against a constant; a kid might drop a ball onto a button and let gravity do the work: higher for more delay; lower for less. Starting physicalized was critical to how our audience thought about the world.
With all that in mind, I worked with the design team to put principles in place to govern the system:
Circuits empowers by being:
It didn't feel like much in the moment. If you were doing it right, it just felt like doing your job. Putting those principles in place was an ordinary day at the office but it was the start of something big. Those principles would later be repeated at the start of meetings, printed on T-shirts and coffee cups, spread across a 300-person company and tens of millions of players: an ordinary day ended up being a magical moment, crystallized forever in Rec Room lore.

With the principals established, we moved into implementation. Jamie McDuffee really led the first six-months of development. Although I assumed ownership after this period, Jamie was our first engineering hire; three years at the company gave her deep knowledge of the existing systems we needed to integrate. Jamie's partnership through this period was critical.
Our responsibilities naturally divided: Jamie focused on the system's dynamic execution, while I defined its static structure. We came to describe these as Dynamic Circuits--the runtime and gameplay behavior experienced by players in a room--and Static Circuits--the tools and workflows used by creators when building with Circuits.
We ran the project in three phases, each starting with a two-week planning period followed by a two-month development cycle. The first phase established Circuits as a standalone system by building a dedicated simulator and unit tests outside the core Rec Room project. The second phase integrated Circuits into in-game creation tools, including the palette and Maker Pen. The final phase focused on polish and restoring essential Circuits V1 features that creators depended on.
Circuits V2 was developed alongside Circuits V1 rather than as a drop-in replacement. At launch, creators could use either system independently, or both simultaneously. Our goal was for Circuits V2 to succeed because creators chose it, not because we artificially hobbled Circuits V1.

After eight months of development, we released Circuits into beta in August 2020. I published a blog post explaining how to enable the beta and get started. We gained traction instantly. Since players could continue using Circuits V1 with Circuits V2, they were able to migrate at their own pace. We closely tracked V1, V2 and mixed usage ensuring that V2 adoption increased week-over-week, and we provided weekly status reports to the rest of the company.

To accelerate adoption, I built a simple GitHub pages site that consolidated key resources in one place. I also created a tool that exported Rec Room creation information to JSON, enabling Creators to build their own documentation and websites around Circuits. In parallel, I embedded myself deeply in the community, emerging as the most active participant in the Circuits Discord and sending thousands of messages in a single year.

During the beta, I formed a dedicated Circuits team: the Logic Team. I drew on lessons from leading the robotics team at The Ohio State University and managing contractors at Turn 10. We applied the same bug-week strategy I developed at Turn 10, maintained detailed plans a quarter out, and published a longer-term public roadmap. We shared our work openly with creators: design docs, short and long-term plans, and internal playtest videos. We also helped organize creators into teaching and beta-testing groups: teachers collaborated with staff to produce YouTube content and in-game classes, while beta tester received weekly builds to provide feedback and identify issues.

As the team matured, adoption continued to grow. Circuits V2 exited beta after surpassing Circuits V1 in usage, and the Logic Team became a model for building teams at Rec Room. As the company scaled through subsequent fundraising rounds, managers regularly sought my advice on how to grow and organize their teams. A presentation I gave on Circuits technology also launched our internal Dev Talks lunch series, where engineers shared lessons learned from their projects. I was honored that our VP of Engineering selected my work to pilot the program.
While building Circuits, I pursued several additional initiatives aimed at improving the company. Although these efforts were outside my formal responsibilities, I focused on outcomes and seized opportunities as they arose.
When I arrived at Rec Room, the palette already contained hundreds of items. These were the atomic building blocks for creating games and experiences: trigger zones, lights, buttons, spawn points, and more. Having previously worked on Forza, which shipped with over 700 cars, I knew firsthand how painful it can be to navigate large content libraries with a controller.
For Forza, I had long wanted to build a car search feature, but institutional inertia made it difficult to prototype in a large organization. When I encountered the same problem at Rec Room, I could move quickly, building a search interface for the existing content in a month. I wrote a custom algorithm that could reliably surface relevant results from just three characters, even across thousands of items.
The algorithm proved so effective that it was eventually extracted into a shared module and adopted across the app for all search experiences. It later became the basis for another Dev Talk I gave in our lunch series.
I built our debugging module after investigating reports of stuttering in retail builds. I traced the issue to excessive log spam causing I/O stalls. I didn't initially set out to build a full debugging system, my goal was simply to create a custom logger that deduplicated repeated messages.
Over time, the system grew organically as I addressed real problems and incorporated team requests:

I used the Harmony Harmony .NET patching library to extend our debugging module in ways that are worth calling out separately. One recurring problem was helping developers understand why an object's position was changing. A single movement could be influenced by hundreds of call sites, making the source of a position change effectively a needle-in-a-haystack problem.
Using Harmony, I injected code into the Transform.position setter to log whenever an object's position was modified. This dramatically improved our ability to trace movement issues. The patching foundation I built was then extended to hook into many other Unity systems.
We combined this with our existing log-flag system so that enabling a flag would dynamically inject targeted logging into compiled Unity code that would normally require recompiling the editor to diagnose. The entire system was only a few hundred lines of code, but it proved to be enormously valuable across the company.
Code to create one of these patchers looked like this:
1234567891011121314151617181920
private sealed class LogSetPositionPatch : LogFlagsPatch{protected override ref readonly LogFlags ActiveFlags =>ref LogFlags.LogTransformSetPositionPatch;protected override AccessInfo OriginalMethod =>AccessInfo.ClassProperty<Transform>(nameof(Transform.position));protected override Expression<Action> Prefix =>() => PrefixMethod(default, default);private static void PrefixMethod(UnityObject __instance,Vector3 value) => DebugUtil.LogDbg((in (UnityObject Instance, Vector3 Value) o) =>$"{o.Instance.name}.position = {o.Value.ToString("F6")}.",(__instance, value),LogFlags.LogTransformSetPositionPatch);}
UGC Watchdog was a system I built to diagnose live UGC issues using analytics. It ran locally on every client, continuously sampling key game-state metrics. When anomalous measurements were detected, they were uploaded to our analytics provider (Amplitude), allowing us to understand their impact at ecosystem scale.
For example, one Watchdog plugin tracked anomalous load times, while another hashed the full Circuits state and compared it across players in the same instance. Any mismatch immediately signaled a state desynchronization. Tools like these helped us catch large-scale issues early and keep the experience stable.

I designed and rolled out the system which organized our branches. Previously, developers could use any branch name. We added a few common-sense rules to bring some order to the chaos. For example, developer branches were prefixed with users/{name}/{branch} and team branches were prefixed with teams/{team-name}/{branch}. In addition to building the tech, I helped champion the change across the company and organized the transition from the rules-free world.
I also built the system which tagged our releases in git. This allowed us to access any given release by date. This was useful for understanding which builds shipped major defects to production when we were doing root cause analyses.
