Hi! I'm Noah. As a Technical Artist, I can wear a ton of hats: writing shaders, tools, tests, authoring vfx, run-time gameplay code, profiling and asset optimization, whatever the team needs. I feel most effective when I can create tools to increase velocity, prevent errors, and reduce the cognitive load of developing the game so my teammates can more easily achieve their vision. I hope you enjoy some of my work!


Niantic Launcher

When I was first hired at Niantic in 2018, almost all of their tools had to be run from command line. These commands and links to other project resources were loosely documented in a wiki. It was difficult to remember them, and tough to find them if you forgot. To solve this problem I created the Niantic Launcher (NLauncher).

NLauncher is a standalone application I built as a configurable, project agnostic tool hub with the intention of providing teams with a one-stop-shop collection of their tools and project resources.

NLauncher is built on the PyQt framework and packaged using pyinstaller. It's distributed to teams as a git submodule, allowing them to opt into tool updates as they please. The interface is configured using an XML file that defines all the tabs, buttons, and commands to run.

At present, the tool is deployed to three game teams and is widely praised by its users for making it easier to find tools.


Automated Addressables Tests

As Pokemon GO made a transition from using Unity's legacy asset bundles to Addressables, we found ourselves periodically fixing problems that arose from data being setup incorrectly. Or we might discover that someone had directly referenced one of these assets, completely negating the benefits of making them Addressable in the first place. To solve this I built a set of automated tests.

These test verify:
- There are no asset dependencies duplicated across our bundles
- There are no direct references to addressables
- Addressables are not assigned to a legacy bundle
- Remote Addressable groups are set to use the Asset Cache
- CRC Checks are disabled
- Bundle naming is set to Append Hash to Filename
- Groups have retry counts, request timeouts, and cache clear behavior set correctly

The tests are run automaticlaly every night, on every merge to trunk, and can be triggered manually on any of our Gitlab CI pipelines. They can also be run headless from NLauncher(see above) or individually in the Unity Editor. If run in Editor, some of the simpler tests will fix any validation errors they find.

The tests have been a great early warning system to alert us of problems and help fix them quickly.


Ingress Prime Kinetic Capsule

When the Ingress Prime team was planning the Kinetic Capusle feature, a crafting system that makes the player move to create the item, we wanted to release it to players as quickly as possible. Initially we discussed repurposing an existing UI context for the feature since engineering time was limited, but I was certain that I could deliver a new UI context made expressly for the feature in just a few weeks.

I created the entire front end experience including:
- A breadcrumb system to let players know they can claim a Capsule
- Feedback showing whether the player can craft the item
- A modal confirmation dialog
- A compartmentatlized version of our player energy meter that can be used in any UI context
- Progress bars that track how far the player has moved

I was able to complete the work in less than 3 weeks and we were able to really surprise players with how quickly this came together.


Ingress Prime Portal Shards

I was responsible for implementing the Portal Shards feature in Ingress Prime. Shards are objects that float above a portal during special events. Shards gameplay typically requires players to work together to collect as many of the shards above one portal as possible. The "prism" at the center displays the final shape the shards will take when they are all collected. I created 4 vfx transition sequences so players could see when shards arrived or departed a portal.

For any object on the Ingress Prime map, performance is a major concern. The shards themselves have some ambient movement which is driven by a vertex shader. Each shard is assigned a random vertex color which is used to offset the movement a bit. The prism uses a small cubemap to make it appear reflective. For very low end devices, the cubemap and vertex deformation are disabled. I ensured that the shards and prisms were simple enough to all be dynamically batched. Even with hundred of shards on screen, there might only be a handful of draw calls. Additionally the objects are all pooled.


Pokemon GO Source Asset Perforce Triggers

I helped facilitate the migration of Pokemon GO source assets from Google Drive to Perforce. As part of that effort, I created a suite of Perforce triggers to ensure this new repository would remain well organized, unlike its predecessor. I worked with Art, Production, and Tech Art stakeholders to come up with a set of rules, setup my own test server to develop the triggers, and worked with IT to deploy the triggers to the live Perforce server.

The triggers ensure:
- Users recieve a default changelist description template
- That defualt template is filled out correctly
- File and folder naming conventions are followed
- Only approved file formats can be submitted as the final source asset (.ma, .psd, etc)
- Artists can submit whatever they wish in user folders

Each of the triggers can be forced to succeed by adding a passphrase to the changelist description. A different passphrase will activate verbose logging to help debug any issues that might arise. And finally all the tiggers can be set to force failure at the trigger level to lock out submissions if necessary.


Pokemon GO Skin Colors

While not the most technically impressive, this one is really important to me. I tripled the number of skin color options in Pokemon GO to 12, adding many more options for dark skin tones.

When I started at Niantic, Pokemon GO had just 4 skin color options for its player avatar. While the team was very interested in adding more, it was seen as impossible becasue the current implementation required two new textures for each option, one for the male avatar and one for the female. The game was already struggling with asset size, but I knew I could make it work.

Instead of adding 16 new textures, I was able to halve the number of textures used to just 4. Two greyscale value textures for the male and female, and one 3-channel mask for each. I color the grey image by remapping the values to a Gradient and then with the masks, modulate some other colors on top to add back in some variety on the cheeks or lips.


Scorpion Game View

For Command & Conquer: Rivals, one of the biggest challenges in making our units was making sure they looked right from the game's camera, on device, and accomplished our design goals. With that in mind, I created this tool to allow artists to quickly preview and render how their 3d models might look in game.

The tool creates a new camera in the artist's scene that mirrors the perspective of the game and creates a plane, to which I assign a sceenshot from the game. The artist can then click "Arrange Unit" to instantiate 6 copies of their model rotated to the positions that units most often appear in game.

The tool was a huge boon to our concept artists who relished the game accurate starting point and it was an excellent tool for our outsourincing partners to communicate their progress as well.

- Easy switch between game view and perspective
- Quick render button to make sharing easy
- Support for multiple aspect ratios
- Tool automatically cleans up after itself

In game images are Pre-Alpha and are not representative of the final product.


Vertex Color Bench

VCB is a personal project I took on for scripting practice. It is a Maya tool that allows users to quickly assign vertex colors and alpha to a mesh.

Currently the tool supports:
- Standard single rgba color assignment to mesh components
- Option to replace, add, or multiply the colors
- Two color, rgba gradients
- Gradients along X, Y, and Z
- Gradients between 2 vertices

In future iterations of the tool, I'd like to give users the option of isolating the individual color channels, the option of using a ramp, and the option of baking vertex color from a texture.

Code on github.