Leviathan is a simple game where you are in control of a boat. Your goal, to discover islands and collect treasure from them. The more treasure you find the better, right? Perhaps not. Legends tell of a treasure loving monstrosity skulking in the depths of the sea. Survive as long as you can and collect as much treasure as you can.
Hi there, I'm James! I've recently been developing this small game. Everything in this game, apart from the Unity 2D packages and the font, is made by me. I hope you like it!
I developed the game at varying speeds over the past month and I have greatly enjoyed working on it. I took this project as a chance to learn how to use several of the 2D packages provided by Unity. Since starting, I have learnt how to use the SpriteShape and Animation packages. Both are really awesome.
I should note, the lack of anti-aliasing is an art style choice because I like the pixel perfect style.
I wanted the game world to be predominantly water based with small generated islands making up the land mass. The islands are randomly generated at runtime from a SpriteShape asset. I change the Y position of points on the spline based on a noise curve. A number of other factors influence the amount of change in the Y value such as distance from the centre of the island to create a subtle falloff effect. I use the same noise curve for the surface of the water.
The water is comprised of two things; A SpriteShape and Line Renderer. Initially, I only had the line before I decided to fill in the space underneath it. I thought about using a shader but my shader skills are not at that level. I also considered generating a mesh and changing the vertex positions at runtime which I've done before. Then it hit me, why not use a SpriteShape? This solution was much easier for me to accomplish than the previous two options and it works really well! To prevent any rendering issues, I've encountered a few, I make sure the original shape fills the camera view. Then I add enough points to the spline at the start of the game to match the Line Renderer's position count. I then set all but two of the spline points and line positions to match the noise curve. It works great but there was an issue.
Rather than generating lots of islands, I decided it would be a good idea to teleport the player back to the first island they found when they find another one. I would set the first island's spline to be the same as the second one so the teleport is unnoticeable then regenerate the second one. This would have worked perfectly but the water SpriteShape would disappear after teleporting. I could not figure out what caused this because every time I went to the scene view the SpriteShape would reappear. So I limited the player's movement so they can't go back through islands and teleport the previous island to a position further on and regenerate it's spline curve.
To finish off the environment, I added several particle systems; One creates the effect of stormy clouds, one some water bubble things, another the stars in the background, and the last one is the fish. The fish shape is created with a curve in the trail module of the particle system and the movement is created by an orbital velocity over time. There are a few more particle systems triggered by various events like lightning and dropping treasure from the ship.
Originally, I wanted to have a focus on the exploring of these islands by disembarking the ship and locating the treasure. Due to time constraints I could not develop this mechanic. However, I don't think this negatively affects the game as it is now.
I wanted the game to revolve around a large sea based monster. This would be something the player should fear and panic upon sight of. I debated having more than one monster but I felt like having multiple would detract from the fear one should create. So I went with a single monster. I wasn't sure how to go about making it at first. I thought I might traditionally animate it but this would take a large amount of time that I probably couldn't afford. So I went with procedural animation. I'm no expert but I've attempt procedural animation in several projects previously. The next question was how to make such a large sprite look good when animated this way.
This was when I looked into the 2D Animation package. When I saw that I could rig and skin weight a sprite I knew I had to use it. Oh boy, did I find it fun to use. I went through several iterations of bones and sprite meshes because it took some experimenting to get something that could move in a smooth way. Next up was attaching the sprite to a simple worm like structure of linked rigidbodies I have used to create the leviathan. I thought maybe I could use the 2D IK package to help but this created more issues for me and I was running out of time. So I ended up setting the bones position and rotation based on the rigidbodies at runtime. While this is not perfect, it created the effect I wanted to achieve.
The art for the leviathan changed considerable over time. I originally had plans for it to be at least twice the size of what it is but in hindsight this would have been unreasonable. To begin with, I went straight into making an asset which was a mistake. I realised that I did not have a solid idea for the monster's form so I did what I should have done to start with and drew some concepts. This helped immensely but I still ended up changing things to add more interest in the final asset.
To make the game look more polished, I added a post processing stack and the 2D Pixel Perfect camera. I think this really helped the final look, especially looking at the game without it. The colour grading has improved the overall atmosphere as I think the colours were probably too warm before. The pixel perfect camera allows me to use my pixel art sprites without them looking odd.
I also made some music using Logic Pro X and a couple of sound effects using Audacity and my microphone in the last morning. The music and sounds aren't anything special but the addition of them really adds to the gameplay.
The End Result
I am pretty happy with how Leviathan turned out. There are a few things I would like to have added but for the most part the game plays well.