Avatar: Rites of Passage

MAP | DEVELOPMENT | 2024

Designed and optimized a high-fidelity stamina wheel system for Avatar: Rites of Passage without sacrificing performance

THE PROBLEM

We had to design a stamina indicator that gives high-quality visual feedback without compromising performance through excessive rendering

THE SOLUTION

Compute the stamina wheel depletion server-side, then send the result to the client through glyphs

The team's initial goal for this feature was to display the player's remaining stamina visually. Instead of using numbers, we chose to base the stamina wheel in this DLC on the one from The Legend of Zelda: Breath of the Wild.

Now, this was an interesting challenge because in Zelda, the stamina wheel moves with the character, but always faces the camera.

Initially, I tried modifying the player model to include the stamina wheel and then rotating it so it faces the camera.

However, as you can see, the wheel appears to jitter. This jittering occurs because the variables that determine the wheel's rotation don't update fast enough to keep up with the real-time data. This desync causes the wheel to jitter.

At this point, I realized I had to pivot to a different system.

Implementing the stamina wheel as a static UI element

After realizing that the entity stamina wheel wouldn't be a viable solution, we decided to render it as a static UI element using JSON UI.

To render the wheel, each depletion stage and depletion delta of the stamina wheel were made into their own images.

The script would determine which wheel frames to show by sending the frame numbers to the Minecraft title. Then, the UI would select the correct image frames to display by reading the frame numbers from the title and displaying the corresponding images.

At a small scale, this system works. However, I still needed to add two more layers to the stamina wheel, which substantially increased the number of images.

Here's the performance impact of adding those two extra wheels:

Now, the lag wasn't caused by the number of images themselves, but by the constant calculations needed to decide which ones needed to be shown.

Since shipping a product with this amount of lag isn't feasible, I had to come up with a solution.

The glorious performance optimization fix to all of my problems

I knew the main performance issue was the number of bindings that were calculated on the client side to render the correct wheel state. Therefore, my goal was to reduce this number as much as possible.

I made a few cuts and optimizations to the rendering here and there, which did improve performance, but not enough to be considered a shippable product. Think of like borderline unplayable to merely unpleasant.

A bigger fix was yet to come.

"What if there was a way to not use bindings at all?" I thought to myself one day.

We could already send text directly to the UI without needing a ridiculous amount of calculations to display it. I just wished there was a way we could send images like text to gain all these performance benefits.

And that's when the realization hit.

Glyphs are custom text characters that you can modify to look like whatever you want.

In this sprite sheet, each square represents a frame index of the stamina wheel depletion or delta depletion.

Using it, I could send stamina wheel glyphs directly to the client, so they wouldn't need to do so many calculations to render the whole stamina wheel.

Seeing the performance improvements

Once I shifted the stamina wheel logic from the client to the server, I effectively offloaded the heavy calculations that were causing the UI to lag.

This one change effectively saved the stamina wheel feature. The game's frames per second soared from a measly average of <20 FPS to a commendable 200+ FPS.

Credits

Art Director: Wilson Viegas

Textures: Lenni Määttänen

Models: Oscar San Miguel

Particles and VFX: Matthew Blair

Animator: Alyssa Nicholas

Trailer and Keyart: Jos Vieveen

© Gamemode One Inc

© Lightstorm Entertainment Inc