First or Third, It's All The Same Person.
Tim Lochner, tool and game systems programmer, reveals technical secrets in the making of H1Z1.
Hey everyone. Welcome to another installment of “SOE Devs talk about the nerdy things we do.” I’m Timothy Lochner, tool and game systems programmer for H1Z1. While the large chunk of my work is done in our tools, tools are really difficult to talk about in an exciting and interesting way. So instead, today I’ll be writing about the changes we’ve made to what we call the Proxied Character.
Essentially, the Proxied Character is the client’s representation of objects that are controlled by the server and replicated to the clients. The Proxied Character acts kind of like a marionette handle where the Actor (or collection of Actors in some cases) that it controls are the puppet. The Proxied Character has to receive information from the server and then control and command the Actor so that what you see on your screen is exactly what everybody else sees. For this Dev blog, I’ll be talking about one particularly unique responsibility of your own local Proxied Character – making sure the local character’s first person and third person actors stay in sync.
We’re building H1Z1 on the ForgeLight engine, which is the same engine used for PlanetSide 2. One of the things about H1Z1 that PlanetSide 2 never dealt with was switching between first and third person. Because we need this for H1Z1, initially, our first and third person actors simply did not stay in sync and sometimes did not animate the same at all.
In PlanetSide2, the player never saw their own character in third person (with a few exceptions, such as the death cam). So when a lot of our code played animations in first person and not in third or vice-versa, the player would never know. If you looked closely enough at another player (a player who sees you in third person) and then at your own animations, you might be able to identify the oddities, but by and large this would go entirely unnoticed.
Enter H1Z1 with the ability to change between first and third person camera at any moment, and suddenly this becomes a really big deal. You can even go back and watch some of our livestreams and see this de-sync happening (until recently, when we fixed it).
Unfortunately, it wasn’t a really simple fix, but we could at least hit some of the big offenders first and work our way through the issues from there.
The first thing we did was change every place that raises an animation request on either the first or third person character to raise that request on both actors if both actors were present (other players don’t have a first person representation on your client). In addition, any time we assign an animation variable (inverse kinematic locations, locomotion animation speeds, weapon type states), that also had to be set on both actors.
Doing this took care of a large portion of the problems, but didn’t solve everything. Because both actors were receiving animation requests, both actors were now firing off animation events. We use animation events to trigger stuff like footstep sounds, muzzle flashes, other particle effects, and even to manage some state controls. Suddenly, we were hearing double sounds. The particle effects wouldn’t show double, because one would be hidden (a result of its parent, the actor for that particular view being hidden), but they were a problem still because we would be running those particle effects twice for no visual benefit. The performance gods simply wouldn’t allow that.
After weighing our options, we decided to suppress all events getting fired from the first person actor. This had some surprising benefits. Now, our animators and sound engineers would only have to add animation events to one skeleton which meant they could get work done faster. It also blatantly exposed places where our animators didn’t match up the first person and third person animations. We would see cases where a sound would play well before punch would make contact when viewing in first person. With these bugs being so obvious, our animators were able to track them down quickly and sync them back up.
Another side effect of this was that our third person actor became a sort of source of truth, while the first person actor became mostly a façade that just piggy-backed on what the third person actor was doing. While it may seem like a “so what” statement, from the development side, having roles and responsibilities clearly laid out makes it easier, faster, and cleaner to develop. A good example of this is how Greg Spence (who wrote about some of our audio changes last week) had put in some code so that first-person sound events would get piped into the third person actor for the sake of consistency in our audio engine. After this change was made, that special case code could be taken out, as the first person actor is now always silent and all sounds come from the third person actor, regardless of which view the player is in.
After all this was done, it was a matter of hunting down small bugs. At one point lights were emitting lights from hidden actors, giving players doubled up flashlight beams. Another part of this undertaking was making sure your first and third person attachments (read: equipment) matched up (there’s more to talk about with attachments, but that’s for another day).
Before I wrap things up, I bet many of you are wondering why we didn’t just make the first and third person actors be exactly the same actor and not have to worry about any of this at all. The reason we couldn’t do that is because then our first person view wouldn’t look very good. Our first person arms have much higher texture resolution and polygon density than the third person arm models because we know that they are going to be right in front of the camera. The third person models is often viewed from quite a bit farther away, so they have a lower polygon density and texture resolution. And then, we sometimes want the first person arms to animate slightly differently in first than when you’re in third. If they were the same actor, we wouldn’t be able to accomplish this.
So check out our earlier livestreams and compare them to livestreams we’ve done more recently and see the difference yourself. And when you’re all playing the game, “kick the tires” so to speak and test it yourself. Changing back and forth from first to third while in a long reload animation loop (rifle is a pretty long one) is a good way to see the results shine.