Steam Greenlight Update Week 2
We’re in the second week of our push to Steam Greenlight. This week we heavily optimized the netcode and lighting build. The map is starting to come together with new landscapes and textures, and we’re adding lots of new audio and visuals making the game feel more polished and fun. The format of the update posts from now on will be that every Thursday we each have a few paragraphs to talk about what we worked on during the week.
Audio/Visual Feedback – Shempi
Audio/visual feedback has been a focus lately as we push towards a Steam Greenlight debut. We’re trying to put as much polish on the game as possible, and that means ensuring that players are constantly being given sensory feedback that’s both entertaining and informative. Every input and every action a player takes should be coupled with appropriate animations, sound effects, and particle effects. Animations are a tough one because we don’t have an animator just yet (well we do but he’s hard at work on our Caveman), so in certain places we have placeholder poses that help get the point across until we do.
Since sound and particle effects require much less training than animations, I’ve been implementing as many as I can. Audio feedback includes has been added for footsteps, attacks, impacts, picking up, dropping, lighting on fire, fueling fire, attacking fire, healing, and many more that I don’t dare list them all. Individually these sound effects don’t mean much, but the culmination of them all during gameplay increases immersion and helps new and experienced players comprehend different gameplay situations. SoundSnap has come in handy for cheap, high quality sound effects since we lack the resources to record our own.
We’re currently missing models and animations for our Cavemen but other than that, the biggest thing that our character has been missing is a voice. At the beginning of the week we had the chance to visit a recording studio to do some voice-over work for the various cavemen of BCE. We hope that in addition to providing auditory feedback, the grunts and howls that we recorded will be funny and entertaining. The list of voice lines that we recorded cover injuries, attacks, exerting forces, callouts (attack, defend, follow, etc), emotions, and more. I’m excited for players to hear them in-game.
Lighting/Map Fixes – Kig
This week, outside of recording voice lines and tweaking our web page a bit more, I’ve been working on our map. As mentioned in last week’s post the new level, titled Gorge, is a departure from the procedurally generated map we used in the past. It is completely done by hand which makes it a lot more interesting from a visual and gameplay perspective. We hope to showcase the Gorge map in our Greenlight trailer.
At the beginning of the week I started by trying to reduce the footprint our lighting build had on our game. Before I made optimization changes the lighting build was on pace to take about 100 hours. I was never patient enough to let one finish so we’ll never truly know how long it would have taken. I spent some time digging into optimization documentation to figure out how to reduce the time it takes to build lighting but couldn’t really find a solution. After some trial and error I finally realized that the cave model we had been using was the problem. The static mesh for the cave pieces were so big and complex that having them inside the lightmass importance volume was causing the light calculation to be far too expensive. I removed the cave pieces and the lighting build went from potentially 100 hours and 500+mb to taking about 60 seconds and 73mb.
After the lighting build was manageable I started tweaking the lighting settings until I found some values I was happy with. Outdoor lighting in Unreal is actually a little bit harder than I assumed because the really beautiful set pieces that you see in made in the engine take advantage of multiple light sources. In the case of our map because of its primitive setting we basically only have the sun and the fires contributing to the lighting. This makes it difficult to make the lighting interesting because it’s all coming from one direction. I’m still experimenting with ways to make the lighting look nice but a lot of that comes down to also having good textures and art assets which we don’t have much of yet.
Another significant change for Gorge compared to our older maps is that we’re no longer using BSPs. BSPs were crucial for a procedurally generated map because we had to generate subtractive volumes via Blueprint for ice lakes that could spawn anywhere on the map. The disadvantage with BSPs is that they are harder to texture and shape and therefore are a lot less appealing compared to a landscape map. Now that we’re back on landscapes I’ve spent a lot of time working on our landscape material so that we have more interesting ground textures. They are blended so that the snow covered rock texture is at the bottom layer and the other layers like grass, snow, and weeds are on top of those layers. The landscape process is tedious however because every time I add a new texture to our landscape I have to wait for all the shaders to recompile in each component.
By the end of the week I’ll the map looking a lot more complete and polished while we wait on the new art assets to be integrated. Next week I’ll be making some big changes to the HUD and UI which are really going to add a big layer of polish on our current product!
BCE Netcode – Toffee
Hi everyone, this will be the first in a series of posts regarding BCE’s netcode, and how we handled network replication within the Unreal 4 Engine. It’s been quite the experience; netcode is a beast to tackle. As hard as we tried, we definitely did not get it right the first time, and it’s taken multiple iterations to ensure actors replicate properly over the network. But with each pass, we’ve grown more confident in BCE’s network functionality, and are proud of the progress we’ve made.
For those unfamiliar with networking, or UE4’s networking specifically, I’ll quickly go over a simple description of the basics. UE4 uses the Client – Server model to transmit data over the network. The Server is the “master” of the network, and all gameplay crucial information must come from him and be sent to all clients. Examples of crucial information would be things like player health, player locations, or dealing damage. We want these variables and functions to be updated and called only by the server, to prevent unauthorized clients from modifying critical values.
For the sake of simplicity I’m choosing to ignore cases where clients are given authority.
For example, based on this diagram above, let’s say Client A attacks Client B. The network situation would be as follows: Client A attacks client B in-game with a club. A hit is registered, and client A sends a request to the server in the form of a function called DealDamage. The Server sees the request, validates its authenticity, and then calls DealDamage on client B. Since the server processes the request and updates client B’s health, all connected clients are aware that this damage was dealt, and therefore stay synchronized with the game’s current state. As only the Server has authority over the network, clients are unable to modify gameplay crucial values, preventing them from cheating or causing desynchronization.
Below is a snippet of our Caveman Blueprint. For those unfamiliar, Blueprint is UE4’s visual scripting tool, which allows quick and easy functionality implementation without having to write any code. It’s incredibly helpful when using state machines, as it allows us as developers to clearly see how each state changes the player.
This snippet is an example of the Client – Server model in use within our game. Calling this function would proceed as follows: a Caveman calls the function to update their combat state (This occurs when a weapon is picked up, like a club or spear). They then set their combat state variable to be the new state. But the next node, Switch Has Authority, is crucial to the networking process. When this node is called, it checks if the caller is either Authority (Server), or Remote (Client). In this example, let’s say the caller was a Client: the node returns Remote, and we proceed to call the function RequestUpdateCombatState, which is marked as Run on Server. Simply put, when this function is called by a Client, they are requesting that the Server runs the following code and update all clients of the information change. The following code happens to re-call the UpdateCombatState function, but this time, run the following code sequence on the Server. Which means when we reach the Switch Has Authority node this time, we pass through the Authority output instead, and reach the Combat State switch case. The code following this switch is irrelevant, but it’s important to understand that the all information changes happen on the Server, and all connected clients become aware of the change.
Sidenote for those that are familiar with Unreal networking, this example assumes the actor is replicated, and the code following the switch case is also modifying replicated variables/actors.
I hope this post served as a basic introduction to the Client – Server model, and how we’ve utilized it and UE4’s blueprint system to construct BCE’s netcode. I will be continuing this series of netcode posts, with a post detailing UE4’s networking system coming next. This will include replicated and repnotify variables, Run on Server, Multicast, and Run on Owning Client functions, and how they fit together in an online multiplayer game.