Well hello there! And welcome to this new installment of your favourite Weekly Update blog!
I won't lie: this week wasn't as productive as I wanted.
Although I was able to still add some new things in the game taking care of my niece and nephew took most of my time (especially earlier this week).
Nevertheless, there's still new stuff to talk about, so let's get right to it.
New gun animations
First thing first, let's talk about the gun.
For those who didn't know there's a gun in the game. With it, the player can have a ranged weapon that doesn't need to charge to the expends of having limited ammo compared to the bow.
Previously the gun was completely static: it didn't move at all.
Now there are new animations for it.
When the player reloads the gun you can now see the actual reloading.
Here's a video of it:
Another big thing is that now the game occludes obstructed rooms.
Previously when the player clears a room the next one is activated and fully rendered. It was fine at the beginning of the level, as there were only a few geometries to render.
However, as the player advanced the number of geometries got progressively bigger and bigger, to the point where the framerates were taking a noticeable hit.
Unity themselves recommends to keep the vertices count below 200k, but with all the geometries rendered at once (even for a low poly game) I actually was well above 200k. This meant FPS that got below 25 (yikes!).
Of course, it was unacceptable. The game needed to be able to hide unseen geometries. Here comes our hero: Occlusion Culling.
The idea is quite simple really: hide geometries that are occluded by others.
Unity actually got their own Occlusion system, however, to function properly it requires baking. Needless to say that for a procedurally generated roguelite baking was out of the question. In order to fix this, I needed to implement my own occlusion algorithm (or at least integrate one).
I've may or may not mentioned this before but I used to makeTF2 maps in my spare time. It was fun and all.
The Source engine can look quite archaic on the surface, but there's a lot of interesting technologies here too.
One of them was the use of Area Portal. These were specially marked brush that indicates some type of opening (a window, door. hole and whatnot).
The idea is that when the player is inside a completely closed area it skips rendering any other area. This is effectively some kind of occlusion by itself.
This applies to properly closed areas. If the area isn't properly closed (AKA there's a leak) then that functionality is not applied, meaning that everything will be rendered at once.
In some area (like a house for example) there are actual openings like doors and windows. On the surface, you might think that once in the house the engine got to render everything as it isn't a sealed space. But we can do better...
This is where the area portal brush gets quite useful. With it, the mapper can tell the game that this whole is a portal to the outside. Once this is said the engine can now shut it close and open at will.
Once closed, every geometry outside the sealed area will be skipped. If it's open then the engine will only show the geometries in the direct line of sight of the camera.
This is quite useful. By doing this we can hide unseen geometries and save ourselves some frames.
Because I already knew about Area Portals I knew that this was the way to go with the game as well.
To be frank, I didn't come up with the implementation myself, but I did get the main gist of it.
(To illustrate this I'm taking a top-down view but you'll get the idea)
The idea with portals is that each portal describes a connection between two areas.
If the camera is in a given area then we check each of its linked portals and do a bit of testing.
Fist, we need to find the actual visible part of that portal. To do this we simply need to protect the camera's frustum onto them (essentially taking a slice of the viewing pyramid)
If the camera is in full view of the portal then its B area is activated.
We then recursively test the other visible areas by getting each point of the projected camera frustum and creating another frustum from which we basically do the exact thing until there are no more visible portals.
And voilà! All our visible rooms are rendered!
In essence, we're basically checking whenever or not two portals overlap each other. If it is them we render the connected room.
With this, depending on the level I can get the vertice count below 100k. This effectively means glorious 60 FPS!
I won't lie though: there's still a bit of bug here and there but nothing that a nice debugging session can't solve...
I would show you this but, well, it's occluded...
Added a grass density calculation.
Previously every room got a set amount of grass strains.
- This meant that small grass patches were densely populated with strains
- This wasn't really good on the CPU and on the aesthetics
- To remedy this I've simply added a density function that calculates the number of strains a room need based on the amount of grass square it got.
- Previously every room got a set amount of grass strains.
- Added even more LOD models (I'm on a roll bae)
Changed the appearance of liquids
- Now the liquid floor looks a lot deeper.
- There are also new SFX playing when a collectable items fall in a liquid floor.
- Changed steps SFX so it sounds like the player is swimming through it rather than walking on it shallow depts.
- Fixed bugs with the ammo counter not being displayed when picking up a gun.
- Fixed a bug with gun reserves not getting loaded in the gun properly.
- Remodelled the mall models to patch up any holes in the geometry.
Next week is probably going to be me finishing up LODs and whatnot. I also need to fix bugs with the occlusion algorithm.
Other than that I really want to touch-up enemies. Probably add another one or changing that behaviour tree altogether...
Otherwise, it's the usual suspect if I have time.
I'm trying as much as I can to get that demo up, although for some it might be too early yet (It's only been technically like about 7 months in development so yeah)