Polish Pass – Dev Update 3

Lighting Polish – Shempi

This week I’ve been working a lot with lighting in Unreal. Good lighting can add significant polish to any game. Lighting is a challenge because every use case requires a different lighting setup. One thing I’ve noticed is that many users find nice lighting through fakery of sorts, by using many lights of varying intensity. As a lighting beginner in Unreal, I’ve decided to start by putting the lights in that make sense, then tweaking from there. After much tweaking, the tentative lighting setup consists of 1 Skylight, 1 Directional Light, and 1 Exponential Height Fog. The skylight is a stationary light, which is the middle ground between static and movable lights. Stationary lights are not as costly as moveable lights while allowing baked lighting and dynamic shadows. Since a directional light would be necessary for believable lighting, I decided that the skylight will be used for the general “filler” lighting and therefore would not need to be movable. The Directional Light is what gives the scene shadows and depth. By making the directional light movable, and setting a variable in the engine config file (for some reason it’s disabled by default), we allow for Global Illumination through UE4’s Light Propagation Volumes. More on Global Illumination later. Finally, to soften up the scene we have Exponential Height Fog (EHF). EHF is most easily compared to plain old fog, but it’s useful for more than simply making a foggy scene. In UE4, EHF is customizable by density, starting distance (from the camera), opacity, falloff, color, and much more. Even the slightest use of EHF gives a scene depth, so it is normally recommended to use it. Don’t be deterred by the word “fog” though, because probably the most common use is producing an aerial perspective effect in scenes that have no fog at all. For both lights and the EHF, I use a very light blue color in order to lower the temperature of the scene for more believable lighting in a snowy environment.

Quick note on Global Illumination. Global Illumination is one of the most realistic lighting schemes in which each object being lit by a light source projects it’s own light onto the rest of the scene. Global Illumination allows for even a single light to produce a much more rich scene with realistic lighting and color bleeding. For example, if light were shining on a red box sitting near a white box, the white box would catch red light emitting from the red box. These details may seem small but they end up making a big difference in the lighting of a scene. Global Illumination helps realistically light BCE largely because of the snow that covers the battlefield. The snow, which is largely white, helps light the rest of the scene through the indirect lighting of global illumination. This gives our scene a richer, more vibrant look.

A big challenge for us is to have believable outdoor lighting, while also being able to have a nice transition to the darker indoor lighting of the cave. I’m currently experimenting with different methods to produce a dark, firelit cave that is largely unaffected by the outdoor lighting. While perusing the internet I found a method using reflection captures and the console command “r.DiffuseFromCaptures 1.” The basic workflow for this method is as follows:

1. Place reflection captures in the area that should be dark (house with windows, cave, etc)
2. Turn off the light source (this will only work for static or stationary lights)
3. Enter “r.DiffuseFromCaptures 1” into the console (this step might not be strictly necessary…still experimenting)
4. Update Captures on your reflection captures
5. Turn the light back on (don’t recapture!)

This method essentially preserves “out-of-date” lighting within the reflection capture volumes. This little trick is sort of a hack, so I’m hesitant to use it. One thing I have yet to determine is whether or not this method requires the ONLY reflection captures in your scene to be the ones that are used to fake darken a room. The reason this might be the case is because, as far as I know, you can’t individually update reflection captures. It’s all or none. I will continue to research that but if that’s true, then we wouldn’t be able to use this method because there are reflection captures all over our scene. Either way, my attempts at using this method have failed so far, so I must either be doing something wrong or this hack has been made obsolete by a new version of Unreal. The other method that I found involved decreasing global illumination through a post process volume. I suspect that a combination of both methods will produce the best result.

OldLighting

Old lighting

Reaching polish on lighting

Current WIP lighting

Lighting is still very much a work in progress, but it’s getting more and more polish with each iteration.

New HUD, Grass, and Fading Scenery – Kig

The last two weeks I’ve been hopping around a number of polish tasks but today it’s all coming together and things are starting to look good. After creating a behemoth of a landscape material I mentioned in my last post, I started looking into some grass materials on the Unreal Marketplace. The one I settled on looks pretty nice and it allowed me to edit the materials to add some snow effects, wind, and play around with the spawning of each individual type of grass and flower. Right now the grass doesn’t react to player movement and does not have any collisions so it looks static when they player moves through it. This is something I’d like to change when walking through a patch of grass but that will be a lot of work which I’ll have to focus on another time.

The grass is not optimized yet so it has an impact on the FPS. I'll be fixing that next week.

The grass is not optimized yet so it has a slight impact on the FPS. I’ll be fixing that next week too.

Another big change to the game is the new and improved HUD. Up until this point the HUD has been a mess of mismatching art styles and odd placements. This update moves all the relevant HUD information to the top of the screen and accomplishes two things. It makes the information more readable to the player and the bar at the top slightly mitigates the problem of having an extended line of sight as a result of our 60 degree camera angle. The style of the new HUD is meant to resemble cave paintings so the colors and geometry will be simple and it will match the style that all of the upcoming UI elements will incorporate.

Still on the way: Animated fires, new font, and cleaner spacing.

Still on the way: Animated fires, new font, and cleaner spacing.

The last thing I just got finished this week was fading scenery which was a really crucial feature. Once this is implemented, we’ll be able to bring in our cave asset which will add lots of polish. I started work on fading scenery about a month ago when I created a fade component. Unreal allows you to create new component actor classes so I wrote a simple fade actor in C++ that I could attach to any static mesh which would allow it to become translucent when the player was in front of it. This worked for a single player but caused issues on the network because the texture would fade for everyone on the server. After struggling with it for a few days I left it alone and finally picked the ticket back up this week. I scrapped the C++ component actor I had written and instead made a new blueprint for a parent fading object. This parent object does almost everything the fade component did but it does it at the replicated actor level instead of the static mesh actor level. This is an important distinction because when Unreal generates the map for the server and clients, static mesh actors only exist on the server. A replicated actor exists once on the server, and once for each client. This allows me to edit the translucency of a static mesh but only for the person who needs to see that change. This does mean however that the Game Mode must spawn the caves at runtime so that they are replicated to clients. The solution I came up with ended up being pretty elegant and easy so I think I’ll make a tutorial for it in the coming weeks. When I was working on this I spent a lot of time looking for tutorials and found nothing about networked fading scenery so it should save some people from the struggle I went through to get it working!

Now only one person will see faded scenery.

Now only one person will see faded scenery.

That’s all from me for this week. Next week I’ll be continuing to polish the HUD and map and doing a pretty deep QA pass on the game for the upcoming trailer.

BCE Netcode 2: Replicated Variables and Combat State – Toffee

Hi everyone, this is the second post in a series regarding BCE’s netcode, and how we handled network replication within the Unreal 4 Engine. Previously, I discussed on a basic level how the Unreal 4 Engine handles network replication. This time, I’m going to delve into a bit of our own netcode, beginning with the Caveman and the Weapons.

For those who haven’t seen or played the game yet, the core combat revolves around cavemen picking up and choosing their own weapons. Weapons have a melee and ranged attack, and their damage and effects depend on the weapon. For example, hitting someone with a club melee deals flat damage, but throwing the club stuns the recipient. In order for combat functionality to flow effectively, it was imperative that we categorize each potential state the caveman can be in. His holding stance, animations, and movement are dependent on the weapon held, and must be updated accordingly. We’ve deemed this state as the “Combat State.”

Combat State

Above is the logic flow of our Combat State switching. If you’ve seen the previous post, this might look familiar, as it’s an extended snippet of the same code. The caveman picks up a weapon, triggering this state switch: if they are not the server, they request the server to run the following functions on their behalf. Any changed information that other players need to be aware of is stored as a replicated variable.

When a variable is replicated, all currently connected players are aware of that variable’s value. This is useful for keeping track of things like player health, or in our case, Combat State. It’s crucial that all connected players are aware of each other’s states when in combat. The key to properly utilizing replicated variables is understanding that only the server can broadcast a change to that variable. Like the example above, this means that if the client were to update his Combat State variable locally from Unarmed to Club, his version of the variable would be updated, but no one else’s would. But should he request it be updated by the server, all connected players will see that his Combat State variable has been set to Club. Ensuring that the server handles the updating of these variables keeps everyone synchronized.

What occurs following the Switch has Authority node is as follows: set the calling caveman’s speed appropriately (cavemen move slower when holding a weapon or a bundle of weapons), destroy the rock in the caveman’s hand unless he is switching to unarmed, then perform a weapon-specific attachment. The implementations of these functions is irrelevant at the moment, but what’s important is that all of this is run on the server, allowing all connected players to see what happens to both the calling caveman and his weapon.

That about wraps it up for this post. Going forward I’ll be going into more detail on other areas of UE4 netcode and BCE’s usage in particular, as well as some insight into what worked and what didn’t during our development process. Thanks for reading, and I’ll see you next time. 

Greenlight – Dev Update 2

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.

soundfiles

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.

The Blue Drop Games crew at the recording studio!

The Blue Drop Games crew at the recording studio!

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.

Here's the map with the only the lighting showing.

Here’s the map with the only the lighting showing. The new landscapes are far less expensive on our build.

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.

The sphere reflection captures make the ice look a lot better.

The sphere reflection captures make the ice look a lot better.

The blueprint for our landscape material is kind of a mess right now.

The blueprint for our landscape material is kind of a mess right now.

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.

The new map is coming along nicely for Greenlight!

The new map is coming along nicely!

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.  

clientserverFor 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.

UdateCombatState Example

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.

 

Fresh Start – Dev Update 1

Fresh Start

For those of you familiar with the old site you might have noticed things have changed. Our old site had some memory leaks and issues with hosting so we’ve migrated and we have a fresh start focusing on building the press platform for our game. This is still the place to find development updates but we’ve also added a press page for media outlets and potential customers to learn more about the game in a concise manner. The press page will also be how we distribute beta access to the game as we move forward.

The press page is still under construction and I’m in the process of importing posts from the legacy website to a separate page on this new site so that they aren’t lost forever. Expect frequent and detailed updates posted here every Thursday.

Development Update

The team is currently pushing towards the next milestone which is our Steam Greenlight debut. With that comes a lot of visual improvements to the game, a new map specifically designed for our game mode, much more visual and audio feedback, voice over work, new animations and models, and a host of networking and performance improvements.

Until now, the game had the working title of “Project Ice.” From this point forward the title is “BCE”.

Better Code

This week we’re working on fixing a lot of old netcode and re-doing the character class. The netcode has been unstable up until this point because when we started building the core systems of the game we didn’t have a very deep understanding of replication in Unreal 4. The same goes for the character and projectile movement classes. The last week has been spent diving back into old code, making it more functional and robust.

fresh start on caveman

Say goodbye to the red and blue UE4 models!

In the past we had a blueprint for two different character classes, one for each team. This was a bad practice because it added complexity, made our code difficult to follow, and made it difficult to move forward with planned features like cosmetics. We re-parented the caveman class with a newly design C++ parent class which contains an ENum that determines what team the caveman is on. The ENum initializes based on the player state when the server auto-assigns the client to a team. This improvement allows us to update the skeletal mesh of the player every time a change is made to the player state. These changes will come in handy down the line, when we implement cosmetic items.

New Map

We’ve also been working on a new map specifically designed with the data we gathered from early playtests. Our first map was completely procedurally generated but lacked any real level geometry. It was essentially a football field with trees in the middle. It was uninteresting to navigate and difficult to mentally map. We experimented with map hazards, procedurally generated landmarks and ice patches, but finally came to the conclusion that we would need to hand-craft a map so that it would have more character.

Another challenge that we identified came with the semi-top-down perspective in BCE. The camera is angled in such a way that players who are “south” of other players have the distinct advantage of being able to see and attack enemies without the threat of being seen. We have chosen to remedy this imbalance through level design. The new Gorge map features three organic lanes which laterally split the battlefield, removing much of the advantage that approaching from the bottom once afforded.

Gorge Level update

Here’s a sneak peek at the new map which is still going through its art-pass stage.

The new map is a little smaller, and has a second higher layer along a cliffside that offers an entry-only choke point into each cave. In the middle there are rivers of ice that will break over the course of the game, shrinking the mid choke point to make flanking opportunities more attractive. Along the bottom of the map there is a plane of slippery ice which, although difficult to traverse, leads straight to the enemy cave. We hope that with a map that helps encourage tactics and team work players will start getting the point of the game a lot quicker. It also looks way better thanks to our artists!

Going forward

We are scheduled to debut on Steam Greenlight by the end of June or early July. That update will include a newer more stable build of the game, a gameplay trailer, and a new song! As mentioned before we’re going to start posting an update every Thursday with possibly some more content in-between, so if you’re interested in the process check our Twitter!