By: James Keats | 08 November 2017
The mid-year show and final presentations are coming up quick! It’s hard to believe, but we’re just under two weeks away from finding out if re[Mod] gets to go on to next semester!
Since we’re getting so close to the end, we’ve been settling into a slow code-freeze, and the number of new features we’ve selected for the past few sprints has gotten smaller and smaller as the deadline approaches. There is still plenty in our backlog should we go on to the next semester, but that hasn’t stopped us from adding a few cool new things. This week, we’ll be challenging Vertical Slice to get into Final Iteration, which means we’re guaranteed to present at the mid-year show; we’ve also already started that presentation as well. But let’s look at what’s new in the game this week!
One of the primary criticisms of our experience–and something we were well aware of, but had put off fixing–was the jarring transition after you died. The solution to this was a simple death cam, that rotates to where the character that killed you is, and waits 5 seconds before respawning you.
This was surprisingly easy to implement, and only ended up taking about an hour and a half. The Unity Post-Processing v2 stack made it incredibly easy to add the placeholder red vignette, and the rest of the effects are able to be done client-side, cleaning up the code on the server.
This sprint, we decided to test with 6 players instead of 4. This meant that it was finally time to sit down and optimize our network code as best I could. The networking for re[Mod] has been an adventure this entire time. At first, it was a mess of code slapped on top of our single-player experience just to get it testable as soon as possible. A few weeks ago I spent a mind-boggling number of hours rewriting and refactoring the networking code so that our synced data and RPCs made more sense and were handled properly. This week, I finally dug into the Unity Profiler for networking and started fixing a lot of code that had previously been sending an absurd amount of unneeded calls.
In order to just quickly get things like the guns and the magnet arm working, I threw a call in Update() for both of those scripts that set the data as dirty every single frame**, and then sent *all of the data for those classes. This was a fact that I had tucked into the back of my mind and refused to think about for a few weeks, because it was such a horrible decision driven purely by the need to get something testable. This week, I went in and completely rewrote those classes to use dirty bits properly; they now only send changed data, and only send it when it changes. The result was staggering:
|Class||OLD Updates/500 frames||NEW Updates/500 frames||OLD average size/update||NEW average size/update|
|CltBaseWeapon||150||16||60 bytes||14 bytes|
|PlayerMagnetArm||150||6||8 bytes + 1 bit||1 bit OR
4 bytes + 1 bit
In addition to all of this, I also reduced the send rate for a lot of the NetworkTransform objects in the game, including the player characters and the weapon parts scattered throughout the arena. Overall, it seems to have improved our network footprint significantly without any noticeable changes to gameplay, and the improvements should hopefully allow us to continue adding new players without an issue. Going forward, there are still some RPC calls that need to be worked on and optimized, but overall the results are promising. One important next step is adjusting our hitscan bullets so that they are no longer spawned on the network, but instead including the origin and direction of the shot in the RPC that is already sent to reflect muzzle-fire and the “shoot” animation locally.
I am currently struggling through an issue with Unity’s render pipeline that I have yet to solve. Check out these images, captured from Unity’s frame debugger:
The image series on the left, in the Unity Editor, is the expected behavior of the lighting and reflections in our scene. Unfortunately, the series on the left is how it currently looks in build. I am still investigating why this difference exists and why it is so significant. So far, all I’ve determined is that it’s related to the ambient light in our scene, and our work-around at the moment is to use a different color for the ambient lighting. Still, our reflection probes and geometry is set up in such a way that I wouldn’t expect this behavior regardless of the color of the lighting, and I especially wouldn’t expect such a difference between the two systems. Stay tuned for more.
Overall, the team is feeling confident about re[Mod]. Just a few more weeks until we know for sure!