Going Under

 

The First Pirate

With the setting, perspective, and gameplay mechanics, it can sometimes be difficult to come up with unique enemies with unique behaviors. There are only so many things you can get a fish to do that makes hopping up and down on the ocean interesting. This is where more fantastical elements come in.

The pirates in Sailbound are going to be a recurring faction of mobs that will pilot steampunk-style machines and drones to attack the player. These give me more opportunities to use things like projectiles, or movement styles that aren't stuck to just swimming.

With that said, the first pirate craft I decided to approach was the submarine. Because this is similar to other existing mobs - an enemy that inhabits the water - it could help keep me grounded in the mechanics I was familiar with while adding a little bit more vocabulary to my gameplay vernacular.

Movement and Mechanics

Development for the pirate sub began directly after I created the ghost enemy. For that one, I had created a movement system whereby the ghost would "drift" towards a target point with momentum, but without using the physics system. I decided that this would be a very useful mechanic to have as a reusable piece. I abstracted it out into functions, gave it some variable arguments, and voila! We have a submarine moving under water.

Movement code done with no extra work. So what does the submarine do? I decided it would fire a torpedo up out of the water three times, then rise to the surface to expose a weak point, allowing the player to jump on it. The sub will also be vulnerable to items and weapons once I add those into the game, but it is important for an enemy like this that targets and harasses the player to be vulnerable even if the player has no items, as it would be somewhat difficult to guarantee the player is armed consistently when they need to face a particular mob without some contrivance.

The explosion asset and code already existed, so no need to do any extra coding around collisions / damage.

Initial Design

I tend to rush into creating "final art" assets without having any design work prior. Sometimes this works out for me on smaller pieces, but on larger pieces I'm rarely (if ever) satisfied with the result. So I decided to go through a more fleshed out design process with this mob as an experiment.

Stage 1: The Mood Board

I've somehow gotten it into my head that I "cannot copy" existing work. But real artists do this all the time! So for the first time, I gathered a number of images into a mood board over on Miro to have in front of me while I did the initial design work.

I gathered a collection of both early real-world submarines (which were basically wood barrels with propellers) and fantasy steampunk-style submarines. Images were picked for shapes, mood, textures, specific mechanical devices - literally anything that might help me.


Stage 2: First Concepts

This submarine was built by scrappy pirates roving a junk filled ocean, so their machines ought to feel cobbled together. The first concept was too simple, the second was too elegantly shaped. The third one kept some design language from the second, but made it feel a little rougher. This is the one I decided to go with.

Stage 3: Pixel Art

Now on to the pixel art! I tend to like my line work but not my actual fleshed out drawings. So I decided to start with the line work in the pixel art and try to built up from there, rather than starting with flat shapes like I normally do. This would allow me to focus on proportion without worrying about pixel precision, colors, or anything else.

After that I colored it in and tried to give it some texture and lighting. Lighting my pixel art is the most difficult thing for me, and I'm not sure I entirely succeeded. But it was good enough.


How did it go?

Before animating, I just wanted to put it in the game to see how it felt. Aaaaaaand... it looked far too serious.

You are playing as a monkey with a bean mouth. This sub was too angry and technical looking! It feels like it has no personality and contributes nothing to the "vibe" of the game. So time to go back to the drawing board.

The Redesign

I was redesigning from the ground up, but was not starting from 0. I had learned lessons about texture and shape and certain parts of the design language I wanted to use.

In the game, I have a type of fish I call a chomper. Chompers are very basic enemies that mimic the shape and behavior of classic Pac-Man - they chomp their way across the water surface.

I decided to base the design of the sub on the chompers. Not only for a big boost of whimsy, but also to tie it visually to some kind of design language already in the game.

Much better!

Now for the same process of pixel art...


A much better fit for the vibe of the game! So now on to the fun part: animation.

Animating the Chomper Sub

Doing hand animation pixel-by-pixel is fun, but for larger - especially mechanical - characters, it can look stiff. So I wanted to animate this sub entirely through code. I call these kinds of animated objects "puppets". First I had to split the sub into individual images, each one being exported to their own file.

A Bit About Puppets

For characters animated in a traditional frame-by-frame pixel art style, I usually have a target sprite and draw the frames at some frame rate. This can all happen internally on the same object with no complication.

For characters like this sub, however, it isn't that simple. They require a lot of code in the constructor and step events, and all that code layered on top of the logic for gameplay mechanics can make things quite cluttered. That's where I use a puppet.

A puppet is basically all of the animation and drawing code for these kinds of characters that abstracts all of the visual parts of a character into a single object. The "gameplay-character" can then create the puppet and call animation scripts on that puppet to sync with certain actions, even providing callback functions to animations to help sync gameplay actions with animation triggers.

This makes it easier to animate and test the animation, because it can be created in a separate space from other gameplay elements. But it also makes coding the character simpler, because I can write the gameplay mechanics without worrying about how I'm going to integrate animation code inside the gameplay code, and I can prototype behavior much earlier in the process.

Animating the Jaw

I wanted the jaw to be vibrating as if the machine is just cobbled together and barely functional, like a used lawnmower or something. That could be done by just giving the jaws a random angle offset every frame.

With the inclusion of the jaw, that sort of implies that this submarine can bite stuff. So time to animate that! The sub was not originally going to have any kind of secondary attack, but the design with the jaw sort of implied that it could do that. So this is sort of a case of gameplay mechanics emerging from design, rather than the other way around.

The bounce animations at the start and end were accomplished using an easing library that simplifies the use of animation curves, allowing me to lerp through that curve from 0 to 1 with no other complications.

Animating the Engine

Before I get to the engine, I want the ship to sort of "wobble" in the water as if it is floating. This will help it feel less stiff. That can be done with a sine wave on the angle of the sub.

With that in mind, the engine needs to try to stay aligned to be "level with the ground", because it should be trying to push the sub forward. The engine doesn't stay fixed at 0 degrees angle (that would look unnatural), but it is always trying to move to counteract the motion of the sub to remain level.

Now for those pesky propellers. Posting every part of the process would be tedious. But basically there are two propellers to draw: front and back. They scale from 1 to -1 on the y axis and blend their colors so it is brightest at the front and darkest in the back. Once they reach the end (so the top blade reaches the bottom, bottom reaches the top) it resets back to starting position, so it looks like a continual loop, but in reality it is just snapping back to the starting position repeatedly.

The hardest part of all of this was positioning the engine and propellers in space based on the "wobble" angle. So it is just pointed at an approximate position based on a vector, but is not precisely placed. There is no science to this, it's just trial and error of guessing angles and distances, from the origin point of the sub to the joint of the engine and from the joint of the engine to the center of the propeller blades.

Animating the Other Propeller

Propeller round two, but much easier! I just copied my homework from the previous propeller blade and, since it is directly back from the center of the sub, no complicated vector guessing either. So, voila!

Honestly, should have done this one first instead of the harder one. You live and you learn.

Animating the Cannon

The cannon on top needs to always be facing upwards, because the torpedo is always firing straight up. Since the engine already has some organic "stabilizing" code on it, I can just have the cannon aim in the same direction of the engine.


Perfect! No extra work, always the best.

The cannon has two parts: an outer shell, and an inner tube. The idea is that the inner tube "overheats" after three shots, so they have to return to the surface to cool it off, leaving them vulnerable. To communicate this, the inner part will spring out once it reaches the surface of the water and vent steam out the sides and cool off from hot red to cool metal.

So first we can animate the cannon firing.


Very easy, they just retract a bit and then return to their start position. And honestly, springing it out for cooling isn't much harder.


Once we take damage, it needs to retract and show that it has received damage somehow.

And there you have it, base animations done!

Finé

And with that, the sub is mostly done. There is still work to be done - like particle effects, some lighting, effect animations like the smoke trail on the torpedo. But the base puppet is complete. 

When we play a video game, it's very easy to take many of the things we see for granted without thinking about how much thought has to go into every detail. Even writing this out was an exercise in realizing the scope of work I put into this - I wasn't even aware of it while I was in the trenches. But the end result is worth it, and hopefully the culmination in care on every detail will make for a better experience overall.



Comments