Extinguish

 May 02, 2017 - Game

 

Extinguish

Extinguish is a 2D platformer in which you take control of a Capitalist Firefighter.

In reality a water simulation technical showcase, Extinguish is a game in which players have a choice: save buildings and be a hero…. or let them blow up and grab money! Along the way there will be puzzles, solve them if you can!


 

 

Work Completed

Programming

Scripting

Visual Effects

 


Overview

For our final project for the trimester we were given a brief: we were to create a physics-driven platforming game with one catch; you are only allowed on main “verb”. Along with this verb, we were allowed one analogue stick for movement mechanics. This means that we had one core mechanic that would be the focus of our game. There were no restrictions on genre or theme or other requirements. We had creative freedom with this one technical limitation.

After some though I decided to work on something I’ve always wanted to work on: water simulation. I began thinking of fun ways to implement it while following the task of only having one “verb”. I had a bit of a flashback to the flash-game era – where things like Miniclip and such were massive. I thought of a fairly simple but fun system: a firefighter who solves platforming problems in order to get to a building on fire, with the goal to save the building.
My water mechanic took the verb “Extinguish”. The act of extinguishing would be a spray of water from a turret-mode where the player was able to freely aim the direction.

I added some fun puzzles that revolved around this water, such as filling a cavity with water and floating objects in order to get over a gap that would otherwise have been much too far to jump normally. Players could shoot environment sections to provide buoyant objects to stand on, and another was to fill a counter-weight with water in order to raise your platform. All in all, a fun little game that required a decent amount of programming.

 

The Issue

I wanted to achieve water that sprayed out like a hose, had physical interaction via collision with objects but then also provided buoyancy as a non-solid object as it pooled together. This issue with this I essentially had two different water simulations for a single action. Initially, I just used the colliders as a “the object just sits on it” but was not comfortable with how fake it looks. I tried making my collider a trigger – but the lack of collision with my environment objects felt wrong. Initially, I tried to add a percentage of the velocity of the colliding water to the environment object – but it didn’t seem “real”.

Approach

Visuals (Metaballs)

I initially created a screenspace metaball environment in which a C# script was used to achieve the visual effect. It provided a lot of customisation and engine-level changes to shaders.

The issue was that I simply did not have time to get it working properly before our initial playtests. Then, my water was having so many issues regarding efficiency and player experience that I didn’t have time to properly implement it. Instead, I used a method that relied basically on in-engine components with minimum outside change.

It works like this:

What happens is the RenderTexture culls anything that doesn’t meet a certain opacity threshold, set via the RenderTexture settings. The Water Camera sets a blur to the water particles, adjusting the amount of opacity edge. When the object is drawn and the opacities overlap, it gives the illusion that water particles are “grabbing” each other.

It worked well for such a small object, scaling the Quad correctly was a giant pain in the ass. It works by being an aspect ratio equal to that of the RenderTexture size. So for our project settings of 16:9 we had to work out the mathematical ratio we’d need our quad to be to correctly render each particle in the proper world-space. This. Sucked. It’s why a scripted version that adjusted to the current screen size is preferable – especially when most games tend to offer various screen sizes and aspect ratios.

Instead, I would continue to work on the C# version of metaball screenspace rendering.

Water Physics

I began translating my research into SPH and Eulerian water simulation to the Unity3D environment. Many of the issues and hard math was resolved by the fact that Unity3D has such a powerful physics system already built into it. As above, my water was going to be rather simple – just circle colliders and a bunch of math to make them actually act like water.

 

There were a number of pros and cons involved with my water.

Pros

Cons

At the end of the day my water looked good and worked as intended mechanically – but I still feel like there is a universe of improvements to be made.

 

Broad-phase Collision Detection

I researched a number of broad-phase collision detection methods thanks to a friend, Eli Piilonen, who worked on the Newgrounds game Spewer alongside well-known developer Edmund McMillan of Binding of Isaac fame. The two I focused on were:

To keep it simple:

Spatial Hashing was fast to implement and easy to understand.
Sweep and Prune was clever and cool but required more time investment to understand and implement.

 

At the end of the day I trialed spatial hashing – but after working on it, it became apparent that my game didn’t actually need this implementation of broad-phase collision as I was already cheating when it came to my water simulation. It would have provided an excellent boost to efficiency and such – but it just so happened that I didn’t have enough time. If I had the time, I would have used Sweep and Prune anyway.

Iteration and Solutions

How the first iteration was that of friction-less circle colliders that had an oversized sprite with decaying opacity the further it was from the centre of the circle.

Conversion to a metaball like solution with no friction.

We now had a few issues:

My water took a number of iterations to reach the final product.

  1. Circle colliders with a Rigidbody2D and a sprite that was over-sized and had opacity that faded out from it’s centre.
  2. As above with  the addition of low or no friction. Metaball rendering was added.
  3. Circle colliders are now triggers with an additional collider for interacting with base environment (floor, walls, etc).
  4. Reverted to normal colliders for interact-able objects.
  5. Colliders turn off after collision with an interact-able object or after a short amount of time. This provided a system where an object could be moved around world space via collision but upon falling into a cavity filled with water would provide a non-solid buoyancy. It looked better and felt better.

With the exception of the metaball rendering, all of the above practices were done through physics adjustments through inspector and scripts. The final change to my water was the addition of some “chaos” to water particles that were on top of other water particles but not covered themselves. This was to adjust the water level and stop my water particles clumping to one side. Basically. I wanted my water to actually act like water and not dollar-store jello.

 

Result

The water in Extinguish wasn’t as amazing as you’d see in larger projects – but for the time I had to work on it, it turned out fairly well! My water was a little bit more akin to an “extinguishing gel” but it still looked good and was mechanically sound in the way that it met all of my simulation requirements. While inefficient under certain circumstances, performance as a whole was quite good. The only issue was that if people wanted to actively break the game they were able to do so and I simply didn’t have enough time or knowledge to implement safety measures.

The Future

Changes and Methodology

Water Simulation

I would take an entirely new approach to my water system in future projects. The current physics engine has a world of issues regarding efficiency. I would like to take a look at different approaches and “real” implementation of SPH elements to the Unity3D environement. For such a task I would like to trial the particle system.

With the addition of the particle system and it’s unique physics elements, while still relying on base physics, I believe I could achieve a much more realistic system. I’d also like to continue work on the current circle based system I have now with a large number of adjustments:

A number of scripts could be added, following a better programming pattern:

BoundingVolumes:

An example of the OBB script:

 

Particles:

SmoothingKernels:

An example of the SmoothingKernel script:

 

Solvers:

An example of the Solver script:

 

 

Meta-Ball Rendering

Overall, my metaball rendering worked well for such a small object… but scaling the Quad correctly was a giant pain in the ass. It works by being an aspect ratio equal to that of the RenderTexture size. So for our project settings of 16:9 we had to work out the mathematical ratio we’d need our quad to be to correctly render each particle in the proper world-space. This. Sucked. It’s why a scripted version that adjusted to the current screen size is preferable – especially when most games tend to offer various screen sizes and aspect ratios.

Instead, I would continue to work on the C# version of metaball screenspace rendering:

The above, along with additional script and tweaking, would provide a much better environment that is more modular than what I currently have. I’d be able to add additional sections for things like having transparency and many other adjustments that simply don’t work with my current implementation. For Extinguish, it was preferable that my water was a solid – just because of the way my background environment and such looked. For most other projects, this transparent water will look much, much better.

To achieve a more realistic system I would also work on removing collider based physics interactions and work more mathematically towards having some kind of offset for when water collides with a physical object (thus moving it). I would probably set the object to receive a physical force equal to an algorithm that calculates the mass of the current pool of water colliding with the object. A percentage of water would continue to pass through/under the object while the greater (denser) body of water would slow or cease based on the mass of the object it has “collided” with.

 

 

A Passion For The Gaming Industry.

Contact Me!