Divine Awakening involves a lot of tentacles, tails, and other wriggling things. So far I've been animating the majority of these by hand, or if it's an integral part of an enemy's movement AI, I program the animation/movement from scratch. As of writing, there are 4 different systems in the game, for segmented creatures and their movement. It was getting out of hand. This led me to work on a single node type, which I could tack on to enemies wherever they needed a tentacle, tail, or similar.
The obvious choice for tentacles is to base the motion on a sine function, and building the tentacle from different segments with different offsets along the function. It's not that simple however, since the motion can be done using rotation, translation, or both, and involving the x and/or y axes. There are also choices for what numbers to use with a sine function, including the position on one axis, the angle, a timer, or another number variable. For my system, I chose to use a float variable - a "counter" that increases with each frame, wrapped between -PI and PI. Then, for each segment, the angle is set based on [sin(counter-segment no.)]. This does not yet produce a curve, which must be done by changing the position of each segment. The position needed to be set such that each segment was attached at the end of the previous segment (base to tip), which is done by setting each segment's position to that of the previous segment, plus length of that segment, in the direction it was pointing.
The segments themselves were ordered so that their scale was reduced based on [total no. - segment no.], resulting in the smallest segment being #0 in the list of segments. In order to respect the layering of the segments at the same time as respecting the scale, the positions had to be set from base to tip. This meant that segment #11 (pictured) had to be positioned before segment #10, and so on until segment #0. The reverse order (largest to smallest) caused major problems with the angles, although I won't even attempt to explain exactly what or why (it involved predictions). The solution in the end was to set angles from tip to base and then positions from base to tip.
Overall this is the most visually pleasing method I've found so far, since positioning is not independent of angle (if it was, segments would not seem truly connected), and there is no need for each segment to run its own script each frame (as would be necessary if they were children of each other). With the basics working, I've now added a set of options controlling the tentacle's movement speed, direction, shape (amplitude and frequency), and sprite textures - from either a predefined set, or using custom textures with their own segment lengths and sprite offsets. This allows for a really incredible variety of applications and is going to save a lot of work in future. I have already used the system for the skeletal enemy shown above, which actually limits the tentacle to run on every other frame and match the framerate of the animated sprite. There are some limitations of course, such as not being able to customise individual segments, or scale them on the y-axis as well as the x-axis. There's also something odd going on if I set the "fps divisor" (a sort of frameskip) too high, resulting in a straight edged "V" shape. But aside from that, this is probably my favourite part of the whole game, apart from perhaps the map loading process I spent three months working on.
Interpolating animations with DAIN
I am not an animator, however it is something I have to do to make my game. This animation in particular, seemed to be too much work, so I decided to try out a software called DAIN.
DAIN is a software which uses AI to interpolate animations, which means adding more frames in-between the existing frames for a more fluid and detailed animation. Previously I'd seen video demonstrations using old game sprites which looked pretty good. Above you can see the results I had with the software. The blurry frame in the middle was produced by the software, and then restricted to the original pallette (by the software) in the final animation.
I am almost happy with it, but there are a few problems. First of all, the software has to interpret the movement correctly, and for my animation, it did not. You can see the neck seems to be morphing into the right shoulder, is if it is spitting them out. The other problem is that the outline isn't preserved - there are a lot of bright pixels at the edges, which I need to clean up (not saving work there). And finally, the interpolated frames are more or less smear frames, which changes the style of animation compared to my hand drawn animations. The software is still quite impressive of course, and if you'd like to try it yourself, it can be found here.
Divine Awakening: Overkill
Development is in a bit of a rut at the moment...I'm not sure how to go about making the level layout. I have been gradually making progress though...the biggest leap in the past week has been finally figuring out a way to use paths drawn in the Godot editor for enemy movement. Guess and check with mathematical functions wasn't working out. But that's not what this update is about. This update is about overkill! Or in other words, what happens when you don't limit the use of special attacks. The screenshots here are what currently happens if the 'bomb' button is spammed. Ordinarily, there should only be 4 of the plasma beams. Oddly enough, while it instantly kills weaker enemies on contact, the boss and some of the tougher enemies still take a while to go down.
The green effect is overkill all on its own. I was hoping it would be nice for the acid's special mode, something like the AT Fields in Neon Genesis Evangelion, but it's a bit ugly and glaring. It can be stacked with the other two special attacks though, making for an even more over the top screenshot. Nice.
I will keep at it. These larger attacks have been pretty challenging to make. It's hard to make them look impressive with only a few seconds to work with. The next update will probably be about level 2. I'm working on the tileset again.
Divine Awakening: AI
AI is by far my favourite thing to program. I use the term "AI" somewhat loosely though. What I'm doing is quite primitive. The boss for the first level has a simple but fairly effective AI. Unseen in the screenshot, are 5 different collision areas, laid out in front of the enemy. When the player enters one of these areas, it is added to a list of active areas. The enemy then picks a random area from the list, and executes an attack specific to that area (as long as it has the limbs left to perform it). At this point in time, it's not too effective trying to swipe or punch the player with its hands, but the plasma attack shown, is tough to beat. The attack is aimed at the player's position, added to an estimation of their velocity. This means that it will tend to start off right in front of where the player is moving. The attack then charges up, and then the plasma sweeps across the screen. To avoid the attack, the player can of course change direction, however the sweeping is not affected by the player's velocity, reducing the usefulness of such a move. The player can also try dashing out of the path of, or through the beam, but when the player is naturally moving in all different directions, it can be hard for them to predict where the beam is going to be. Overall this doesn't seem to be too unreasonable, and I hope it will work well with players who don't yet know how it works.
Divine Awakening: 2D graphics from 3D renders
2D graphics made from 3D renders are pretty cool, especially in old games where 3d was not really an option. I couldn't resist trying out a rotating globe for the level select screen, and I think it turned out to be quite nice. The globe was made using a photo of the sky I had from a few months ago, edited to reduce the colour count and then mapped onto a sphere. Then the animation was rendered in Blender, exported as a set of images, which were then reduced in colour again. I didn't bother using any fancy filters this time around, just a bucket tool and a palette. There is a small issue in that this planet doesn't appear to have any land on it...but maybe I'll put that down to it's really thick atmosphere? It was painstaking enough just recolouring clouds frame by frame.
Divine Awakening: Large Decorations
The problem with working with a tile map is trying to get large details that stand out. Unfortunately that is easiest with large objects composed of multiple tiles, which take a lot more work to create and have limited use compared to tiles for smaller details (eg: a single dirt tile). Since the rainforest tilemap is almost complete, I've been adding a few of these in, where there is space left over, so that I can create memorable locations within the level. The screenshot shows a carving I made for the stone cliffs. I have to say, these larger decorations help a lot with setting the vibe/tone of the game, so I won't neglect them for future tile sets. This month will be primarily spent working on Divine Awakening, so hopefully this is only the first update of many. Ideally I would like to have the first level finished by the end of the month.
Divine Awakening: Caves
I've begun work on the second level - the caves. For now that just means making the tilemap though, since I still haven't finished the first level. The idea is that the player flies down deeper into the planet, so all the decorations must be upside down. You can see this in the screenshot above, where I made the tiny forklift and truck. It's quite difficult to maintain scale in these maps, I think it won't matter too much if I don't keep it too consistent. But there's a definite improvement between this tileset and the jungle level, the details are larger and the small tiles are more useful for making large objects. I've also improved my method for faking a printed paper texture on the screenshots..still needs work though. Now I have to go to work, more updates soon.
Divine Awakening: Introduction
Divine Awakening is my first original game project, created using the Godot engine. The original concept is based off an atrocious old game which I won't name, but has a really unusual exotic vibe that I wanted to recapture in a better game. Divine Awakening is a vertical scrolling shmup, with an emphasis on being fun to play rather than difficult. The game takes place across several planets, which the player must free from evils in order to "awaken" the hidden powers of 5 priestesses. It is now in it's third (possibly fourth?) year of development, and will soon have the first level and a demo.