Hey folks! This week I’ve been continuing on various bugfixes, and mostly polishing up a bit about how we handle death and connecting to the server. We weren’t handling some scenarios particularly well around this, so I’ve been streamlining those structures. While the current architecture does work with no super obvious downsides, it does lead to some confusing scenarios. For instance, if you disconnect from a server while dead, or someone kills your sleeper, you’ll actually respawn and die instantly. This feels like it’s the spawn that has killed you, when in reality it was something else. It also meant that there were some cases where you’d be spat out into a random spawn when you had a stake it was possible to spawn at. We don’t really communicate this particularly well, especially as we don’t store the reasons you died across server restarts. These are all very delicate structures, as bugs introduced can damage player progress, so I’ve been going slow, changing as little as possible, and doing a lot of testing.
There were a few places where you couldn’t interact with the player spawning system unless you had already spawned in the world, which hasn’t happened yet for players who are just connecting. This was because we were using the player entity as a keying object in a number of lookups. I changed the system to use the connected network session to key any data, which worked well. It also removed some coupling between the game mode object (which is an object that configures what game mode the game is currently using and the configuration of that mode) and the spawn window, which is always nice. As an added quick job, I moved the player customisation interface into it’s own little widget, as before it all just lived in the spawn window code. I also extended the game mode structure to allow game modes to write state into a savegame. In the case of the Survival game mode, we can write in stuff like how a player died when they were offline, so we can tell them when they log back in. We could also store things like leaderboards, teams, or other forms of game mode state with this in future.
So with these fixes you should have a much clearer experience when joining a server, as to what killed you when you were offline, as well as always giving you the choice where to spawn when there are multiple.
Mils Lord 5000
So I’ve finished the texturing on the second Riser for the Recurve Bow. This one is a re-purposed metal bar. So that the bow parts have a lot of variation, this one will be made from man made materials. There’s a steel bar, with a layer of yellow foam, wrapped in black rubber as the grip. This one contrasts nicely with the previous mostly wood version. I added a little rust near the welds to sell that it has seen some action. This came out just as I wanted it to.
I have also got the high poly done on the limbs for this set. These were going to be metal also, but the more I thought about it the less this made sense. I didn’t want the whole thing to be metal when combined with the new Riser. I have made the main flexy bit fibreglass (or as peeps from the elsewhere call it ‘glass wool’), and then galvanized sheet metal reinforcements where the limbs deviate. This should look pretty special when it’s done. 😀 😀
Hello, not much to show this week due to a short week and I’ve mainly been cleaning all the mess I made doing the particle stuff and getting the last little random jobs done. I did make a start on a new loot cache though, the original one had to be redone due to it being over the general poly budget but the one I did to replace it was just a place holder and looks very simple and average. So I’ve gone about it in a bit of an interesting way and instead of make a box then sculpting some wood grain and scratches into it, I’ve done the reverse and made all the different bits of a wooden crate separately and sculpted both sides of each bit of wood so that I can flip and position things in specific ways that don’t show any repeating details. Due to this being an item that you see a lot I’ve put a good amount of effort into the actual sculpt, once everything gets positioned and baked out it will be a very nice box with a nice solid feel.
This last week was a bit shorter than usual thanks to a public holiday so I don’t have heaps to share this week unfortunately.
I spent most of the week continuing on with bugfixes including a material sharing bug in the mesh caching system and a race condition that could occur with attachable vehicle seats for the roach.
The material bug was occurring because I had incorrectly assumed I could rely on the ordering of elements in a dictionary if GetHashCode() didn’t generate any hash collisions (where multiple objects share the same hash) between elements. Unfortunately it’s not quite that simple as elements get indexed internally as (hash/internal array size) meaning collisions can be much more frequent than I had assumed plus the removal of elements from the dictionary can change where the next entries will be placed (see https://www.red-gate.com/simple-talk/blogs/the-net-dictionary/ for a detailed explaination).
When retrieving a mesh from the bake cache I was assuming the collection of attachments would be in the same order and I could just iterate through getting the material for each and then assign this material list. Because the order had changed between the job that was entered into the cache and the current job we would end up with the wrong materials pointing at the wrong submesh (part of the mesh that is drawn by a single material). To fix this I added some extra data into the bake job cache to preserve the order of attachments, when retrieving from the cache we now use this list to resolve material assignments properly (by comparing old list to current).
I also fixed a nasty client side race condition with attachable vehicle seats like you see for the roach front and back seats. Basically what was happening here was that on spawn the vehicle was trying to place the passenger into the seat before the seat had initialized itself and the initialization was waiting on the equipment system to equip the attachment. This would cause the system to error and then on your client this passenger would appear running like a normal character but standing inside the car.
Rather than try to manage this order of execution across the client/server boundary I chose to refactor the initialization of the attachments to not depend on them being equipped first (they’ll initialize on entity creation instead). I also changed them so when the attachments are activated/deactivated they now run a list of actions serialized into the attachment itself rather than just activating/deactivating the game object, this gives us some performance benefits as well as configuration flexibility. In this instance we can now enable/disable the seat attachment by just enabling/disabling the box collider that is used to trigger the player to tell them they can use the seat. Disabling just the collider is much faster than disabling the whole game object.
This week I’ve been iterating on the random geography hotspot playtest. We had a bit of a play on Friday and came up with a big list of refinements that I’ve been working through today to ensure we get the value we expect out of the meteors and air drops. Getting the pacing right is a tricky one, as we want these events to be contested but not so frequent that you come across them without meaning to. The key here is balance between classic evenly spread resources, static hotspots and the new random location hotspots.
Hopefully tomorrows internal playtest will be better paced and we can work towards integrating it into the overall game by Friday for the experimental branch.