For the slime, I wanted to create a design that was neutral so that if I end up adding a character customiser, there's enough space on the character to add parts and accessories. I originally had the character have a darker palette, but I gave them lighter colours since lighter blues have more calming themes. I added some light to make the slime look more reflective, and adding some lighter pixels to fill the empty space. When designing a face, I wanted a neutral expression so that the character could show more expression when jumping or getting hit, only adding some lines under the eyes in the final version.
For the walk cycle, I wanted something quick and fluid, making a 4 frame cycle with some squash and stretch to make the slime appear more liquid like. When I made the slime thinner, I also made it taller to keep the volume of pixels the same, applying the same logic to the stretch.
For the jump, I had a more exaggerated squash and stretch, and added some light pixels on the eyes so the slime can look as though it's looking up and down, giving it some hang time in the air to look down. While stretching, I made the lighter blue pixels dotted around the sprite stretch up and down depending on where the slime is in the animation.
With the hit animation, I moved the middle part inwards to illustrate the impact of taking damage. I created a closed eye expression to add more emotion to the hit, then making the character jump back, meaning in game the player will be knocked back, adding up to their time. This mechanic means players have to be precise and avoid getting hit to maintain control and get a fast time for each level.
For the crouch, I created two transition animations that play when the player starts playing crouch and lets go of crouch. For the walk itself, I shortened the animation to make sure the collision box size decreasing more believable. By adding an extra outline pixel on either side inside the slime, I intended to create the impression that the slime has squashed into itself, building up energy, and making the higher jump more convincing.
For the wall climb fall, I started by doing a layout of the first and last frame I wanted, which helped me to visualise where I wanted the animation to go by using the animation principles. I decided for the actual climb, it would be no different to the walk cycle except rotated to match which side of the wall the character is climbing. Initially, when adding frames, I had a sweat effect to indicate the player was about to fall and have each frame last longer so it was more visible. This ended up getting scrapped since the individual pixels moving around didn't look right, so I opted to show the fall differently.
I rearranged the sweat pixels a little, but I still couldn't get it to look right, so I instead had the slime strect out as if it was slipping, made more clear by the slime slowly peeling off of the wall. This will be the player's last chance to jump before they fall down, so I made the build up long enough for player's to recognise the anticipation and react to it.
I reused some frames from the fall of the jump animation and applied some more exaggerated squash and stretch for greater impact. Some of this animation's greatest challenges were positioning the frames, specifically getting the animation to flow smoothly from being on the wall to slipping off.
These were the initial silhouettes created in the early stage. Using the three ghosts that were the most popular from my Microsoft form, I started experimenting between colours players suggested.
I tried going for a primary colour theme, using colour theory to assign each ghost the colour that fits the most with their expression. I made the tail lighter like in the silhouette, along with any other features apart from the main body like the arms and eyes. While the blue worked with the second ghost, purple was also a popular choice from the form, leading me to choose it over a blue iteration.
I later added features in the animation stage, giving the red one more horns for more triangular shape language, making the mouth move with the up and down of the arms. For the purple one, I added a down to create some follow through on the hood, while also adding shading on the eyes for greater depth. To add more diversity, I used the mouth movement from the red version and instead had the mouth move against the up and down frames, making something unique about each ghost aside from their colour. Once I completed the frames for the red ghost, I recoloured segments of the animation that were the same and re used them for the other two to have more synchronisation.
I started by blocking out the basic shape and applying colour, then changing the outline to match the colour of each part, splitting up the main body and the spikes more clearly. I added some eyes and some dark green pixels to give the eyehole more depth, along with a leaf placed above the face to spread different shades of green across the design. To make the spikes appear pointy, I added some light at the end of each of them. To make the design more fluid and natural, I used more shades of green, making lines with different greens in between to create a layered effect.
When I added the extra texture and detail, the design became too crowded by visual noise, so I removed the leaf but kept the shape as it gave the eyes more expression. I tried out different eye shapes and decided to use a more neutral shape as I can make the eyes look angrier when the player gets close. This process allowed me to decide how the enemy could behave. By placing the enemy on mossy tiles, I could have it walk normally but when the player gets close, part of it rises from the floor and makes it harder to jump over. For this reason, I went back to shorten the spikes on each frame so the angry face had more impact when the spikes got bigger while it grew taller.
When animating the walk cycle, I used the arms to indicate movement since the legs are covered. I used the up and down to create some weight to the sprite, and had the right arm appear when the left arm was furthest away from the face for realistic motion. To make the spikes seem more connected to the body, I put some outline tiles below the spikes to cover them, giving the impression they are connected to the face inside the moss, by applying motion to the spikes on the frame after the up created some overlap in the animation for more movement.
Starting a new animation of Ambush with the same frame makes the transition more smooth. I used anticipation to make the spikes come in while the eyes close, then have the eyes have more of an angry expression when they are shown again, and have the spikes raise up immediately more rapid motion. Exaggeration was used to have the frame the big spikes appear have the spikes be taller than they're supposed to be, making them move down slightly to create some overlapping motion.
I altered the animation, instead of having the enemy grow larger to indicate the collision box size change more clearly in Unreal Engine. I used the same overlap and anticipation logic as before and had the enemy increase in size at an accelerating pace- achieved by having the enemy move up 5 pixels, then 10 on the next frame, and then 15. Adding detail underneath similar to the detail on the main body allowed me to carry the same texture throughout the entire sprite. To add some more detail on the lower half of the sprite, I added some additional spikes on the back and made the eyes move up and down on the rise and fall for some additional expression and follow-through.
When designing the enemy, I use the ideas from my research to make two different versions, deciding on a purple colour for the slow version. I add a face in the middle, separating it from the rest of the body as the inner part won't rotate. I put a darker purple around the outside but kept the spike one pixel inside so that it looks like the spike is rotating between two points. While building the animation, I found that the rotation wasn't perfectly clear, so I added some marks below each spike which help convey the message I'm trying to express. After going through some facial iterations, I found a combination I liked that looked like two eyes with tears coming from the side.
When designing the fast version, I first designed the face, then converted the purple palette to a red one since the colour has strong connotations with danger. Combined with the face change it's clear to the player that this enemy is more of a threat. The final addition was to speed up the frame duration of the angered version so it rotated faster, right clicking on the selected frames and going into Properties to change the millisecond values.
Using the same method I made the basic shape then added any limbs like the legs and arms. when designing the face I used lighter shades of the pixels that make up the eyes to create depth, making it look as though the eyes are hollow- I created the same effect with the mouth. I added sprinkles arranging them so that each of the colours where scattered, but the colours contrasted too much with each other. When I imagined the creature walking, I instead came up with the idea to make the legs melted ice cream, then I could animate it in waves as it moves across the floor. Changing the eye shape and facial expression, I quickly find an eye shape I'm more pleased with. I liked the width of the mouth but I also liked the shape of the previous version, so I combined them in the next design. The last thing I changed was the arms, as they looked better then they were longer.
I started adding some of the accessories peers who answered my form wanted to see, squashing the top middle pink pixels down so the cherry looks like it's stuck in. I made the arms longer and added a drip to the top tooth by making it stretch, aiming to illustrate this effect in the animation stage. I changed the pattern of the sludge at the bottom and made it lighter in colour, like how when ice cream melts, it gets thinner and more liquid like in property. I animated an up and down, focusing on the main body and face first for each frame, then the cherry, then the melted cream at the bottom. By splitting the animation up, the process was more manageable as I could focus on one aspect at a time.
I set the animation to be 8 frames, putting the cherry and the cream on a 4 frame loop so that they'll loop twice over the course of the walk cycle. I moved the sludge one pixel to the right each time, adding curves in different spots so that when strung together, it will move up and down, creating the wave effect I want. I opened the mouth to varying levels of exaggeration for more character, then moved the end pixel on the dribbly tooth to either side to make it look as though it's wobbling, creating an anticipation for when it falls off.
To get the three different flavoured variants, I copied the frames of the previous variant into each enemy file and used the Eyedropper Tool to get the hex code and then used Shift R to replace the colour in this example Vanilla < Chocolate. This way of converting the colour of the enemies avoided any inaccuracies if I were instead attempt to redo the animation.
I had to design an object that would function as the goal in the level, so I started by sketching out a diamond shape and using some darker pixels to add lines inside the sprite, recreating the geometry of traditional gemstones. I use the same outline method but make more of a contrast with the colour so there's more of a contrast between the lighter shades, using this effect to try to achieve a shinier texture on the sprite. For the last step, I gave it a simple animation similar to some other collectibles I have animated before, making the object stand out to players. I then went over each frame with a very bright blue shade and moved it closer to the right each time to make it look as if the object was a reflective surface like many other gems.
I had the idea to include a chest in the level, serving as an optional challenge. When designing the chest itself, I went for a classic style at first to align with the RPG theme I've been applying to my sprites so far, defining my demographic audience more clearly. After applying shade to a similar level of detail to the other sprites to mirror the same style, I changed the colour to make the object feel more distinct. I originally had the idea to open the chest when you collect it rather than it disappearing, so I designed a sprite to illustrate this, adding a range of gold pixels to resemble coins. However, through production, I realised that the collectables wouldn't fit with the game style, and it would be more fitting for the fast-paced levels to include no temptation on each split path to base players' decisions merely on their instincts.
When making the tileset, I started by making a black outline for each main piece, then put some tiles together and added the main character to the canvas to see how the scale would work. Once I had all the base tiles in mind, I began to add more detail to the design before colouring. Since one of my enemies was a creature made of moss, I wanted some mossy tiles for the enemy to walk on. I made a copy of the tiles and separated them into "Tower" and "Moss", this way I know which tiles I wanted to add the moss onto.
For background layer tiles like vines, I made a "t" shape out of one solid green colour and copied it to make four other versions. By giving each of these a different colour, they can be made to look like leaves, copying and arranging them to appear like spiralling vines.
Coming up with a colour palette was a straightforward process. I went for a dark purple to make the slime seem a lot brighter in contrast, having a standout colour making the character more definable, and reducing visual noise on the screen. For the background, I wanted to use bricks as it made sense to create an interior space for the tower.
For added detail, I refined the palette by adding texture, creating a cobbled effect for the main tiles by using blocks of varying sizes and copying over each tile to make them link smoothly. I added shading to the same degree of detail as the characters to make the world I'm creating feel more connected. I added some new background tiles like the flowering versions of the vines, making sure that the flowers don't overlap over one tile as this would result in an inconsistency when making the vines various sizes. I added two middle versions to switch between the ones I used for the longer vines, making the level less uniform and more natural. In the final version, I added some spikes in between tiles for walls and ceilings with moss only covering half of the tile. Later on, I changed the contrast of the flower colours so they stood out more against the dark green of the vines.
This segment covers all the processing of the blueprints required to obtain the final result. By the end, I had used "C" for comments to easily assign sections of code with a name for easier navigation.
The first thing to do when opening up Unreal engine was to import all of my sprites after exporting them from Aseprite.
By extracting the sprites I can select Apply Paper 2D Texture Settings and create flipbooks for each animation.
Since the Ambush will also move around, a parent function is created to prevent repeated blueprint nodes.
I gave the character a capsule collision accurate to the sprite shape, adjusting the half height to make a fair hitbox. For organisation purposes, I gave all the project related folders their own colour, making it easier to distinguish what was relevant between the base assets that I wouldn't need.
When importing my tileset, I create a folder for all the tiles that have unique functions like the one-way platforms and spikes. When extracting sprites, I set the Method to the grid and made the cell dimensions match that of the sprite size. Once I decided which of my sprites fitted into the first level, I put all the flipbooks in one place away from the others.
I added controls for each of the movements, adding two options for each input. I ended up not including the crouch as it didn't feel necessary for showcasing the main aspect of the game given the time constraint.
One optimization made was adjusting the player's movements, starting with how far away the camera was to make sure the player wasn't too big on the screen giving the player plenty of space to react.
These blueprints add the movement for the jump and walk, also preventing the player from jumping infinitely by doing a "Is On Ground" check.
This first sequence that uses the Event Tick node uses premade functions to allow the player to detect inputs and platforms. The blueprints to the right check that the motion is going forward or backward, and rotating accordingly to make it face the right.
These are all the animations I added into the game, repurposing the hit animation for when the player is defeated. After adding the jump and walk, I started working on the locomotion animation graph to incorporate the animations into the gameplay.
Once I connect all the animations to an Output Animation Node, I work on the different links made in the Locomotion. The first two setups on the right check to see if the player is walking or not, check if the velocity is 0, and execute the movement as a result. The same logic is applied to the damage in the Locomotion, making sure the animation plays in different instances such as when standing still, moving and in the air. The variables are used as a condition for each Result node so that the engine can play the animations correlating to the inputs.
Constraining the character to a plane means they are unaffected by the Z axis, stopping the player from falling off of the map when interacting with other assets like the enemies and spikes.
This logic for the enemy allows the box collision to check for any ledges. One the function is complete, the Rotate Char function will snap the character 180 degrees so they start moving back to the opposite way.
This is the Viewport for the Ambush character, showing the box detectors for the ledge and walls. Since the corner tiles are curved, I made the ledge detector further away to avoid some of the sprites hanging over the edge.
On Component Begin Overlap nodes for the Ambush enemy connect the functions for rotating the enemy when encountering a ledge. The bottom blueprint is how all of the hazards apply to damage to the player character and the blueprints to the right are used to multiply the defeat launch values together to launch the character once they have run out of HP.
These blueprints allow the player to be launched a certain distance based on the launch settings for the slime character. The code below prevents the character from moving after death by removing the context for the IMC after losing, making the player unable to control the player. Putting the camera shake up to 1000 allows for a more dramatic shake that gives the defeat more impact.
I started the one-way platforms by setting the sprite to the small one-tile version and applying some settings in the Project Settings to create a new function for the platform. After completing the blueprints, I copied them over to three other actors but replaced the sprites with the different tiles to ensure that all of the tiles had the correct collision properties.
The line tracer set up below detects the position of the bottom of the players collision box and makes the player land on the platform when then reach the top of the platform collision.
These blueprints show the nodes needed for the enemy to orbit around tiles. Each of the vectors allows it to change direction on a loop to make it move. It's important to layer the object on top of the starting point, in this case, Pos 2, or otherwise, the enemy will warp to wherever it is placed in the level after completing Pos 5, then make its way to Pos 2. After fixing this and making the enemy work, I added the red version and reused all the code to avoid any errors, only making the change of increasing the time it takes to complete the animation cycle and the overall speed of the enemy in the game, making a noticeable difference between the two variants.
With the spikes, I separate the blocks from the spikes themselves and make two different box collisions, one for the damage and one for the object itself.
The blueprints set each frame and add the collision types depending on what frame the animation is playing. I made it so that once the spikes go up, the SpikesUp variable adds the collision and the SpikesDown variable takes it away, also making sure that when the spikes are up, the player takes 1HP of damage.
Instead of a health bar, I wanted to use a hit point system so it wouldn't take up so much of the main HUD, putting the icon in the top left and putting the timer in the top middle of the screen. Instead of numbers, I used facial expressions, making the slime look more concerned with the lower the amount of hit points the player has. I decided on a neutral face for 2 HP and a more concerned face for 1 HP. This would give me a dead face for when the player runs out of health.
These final versions of the HP Bar. The biggest change I made was changing the colour of the health when the player gets to half their hit points. This is a more clear representation of danger by changing the colour of the health bar. This was more suitable than the first version when they were all blue since the visual cue is made more obvious.
Since I cut the health sprite into quarters, the first step to designing the health system was to create a variable named health and define the set value as 4. Then I wanted to make the player able to lose health and make a clear visual indication when they were hit. This is achieved by making a boolean variable and hooking it into a branch node, then using a Set Health and a subtract to take the health away. Using the same Boolean variable in a Set function, I ticked Has Taken Damage to true and put the sprite variable into a Set Colour node. To separate the next few nodes, I used a sequence, connecting a Health variable to an Equals which connects to a branch. This allows the player to be defeated when the player has lost 4 health, meaning their health would equal 0. Another thing that needed to happen was setting the character back to the original colour, using the same node as before along with a delay so that the colour change is still apparent. To implement invincibility frames, I added a third node from the sequence that for 1.5 seconds prevents the player from taking damage by setting the Has Taken Damage variable to false.
To allow the sprite for the HP to switch between each version, I use the Get Flipbook Length in Frames node to make the sprite change alongside getting hit.
To get the initial logic for a timer working, I make a variable for both seconds and minutes. Using branches and set variable nodes along with operators like "+" and ">" I can make so that if seconds reaches a value above 59, the seconds value will be reset back to 0 and the minute counter will be set to 1. The Can Count Down variable added to the beginning is part of a setup to make the timer stop when the player touches the goal.
For the timer and health to display, I needed a widget, adding a Canvas Panel I made a text box for both minutes and seconds so that they could count up independently. Creating a binding allows me to bind the widget properties to functions, also using anchors to fix the components in the same spot on the screen. The functions shown display the widget information on the screen, using the allocated variables created. Finally a Create "Widget Name" Widget and an Add to Viewport to place the widget in its spot on the screen.
The top image removes the gem from the screen when the player collides with it, and the bottom screenshot is the node required to make the text widget appear upon collection. The Can Count Down variable is set to off, acting as a parameter to stop the timer once the gem is obtained.
The level begins with a few safe jumps to get the player used to the slime's boundaries, the segment also shows off some spikes but they are impossible to reach to prevent danger, this helps players to assume that these spikes will appear later in the level and gets them used to their pattern.
I added moss tiles around and had the idea to only put the Ambush enemies on moss tiles for further indication of what to expect from players. They are presented with a choice to go past the spikes or take a risky jump to the right and climb up.
An Ambush enemy waits for them at the top, making more risk for the right path. Balancing this by putting the path to the next part on the right helps to make the the right path quicker, rewarding players who are aware of the wall climb mechanic.
Another optional path is presented to the player where a wall climb is required on the left path, a more complex move but the path up is shorter, making decisions where if players play later, they might take that path as it's closer to the entrance.
This section above is the first time the player is required to wall climb. By putting a lot of Ambush in this area, it makes them more common in the level and helps the players associate the enemy with the stage. The introduction to the Spikedisc enemy is on a large block to make it so the enemy takes longer to complete a lap, making the obstacle less challenging for the first level.
The player has the option to use the wall climb or run through the spikes when they're down. This gives the players a choice for a route containing a more advanced mechanic or risk losing time by waiting for an opportunity to run past the spike blocks. In the small opening between the row of spikes, I'll add a chest for players to collect as an optional bonus.
For the final challenge, the player uses what they learned about the wall climb and must scale a large tile with two moving Spikedisc running along it. This requires timing but the players must find an opportunity quickly to improve their time.
At the top, I'll add a gem so the player has a clear win condition. This will make it so there's always a clear visual object the player should look for at the end, like the flagpole in Super Mario Bros.
After adding all the collision tiles on one layer, I named this layer and created two new ones used for background assets. This is so that the brick background can be placed on Decor 0 as it has the lowest priority, and any additional pieces like vines or pillars on Decor +1, since it has increased priority over the brick background.
On the moss tiles I placed throughout, I included vines and used the different ones to create variety, making a left and right facing version of each vine type. This game the level more realism than if I were to put the vines below plain brick tiles as it makes more sense and gives the player a level of expectation.
Throughout the level, I focused the design on making the level short, while also making sure there were plenty of optional paths. This choice in structure aims to get players to try different routes on a second playthrough, allowing them to determine which path they like best and if it gives them a faster time. By adding multiple of these, some more advanced than others, there are plenty of combinations of different routes players can take to achieve a faster time, adding more appeal to speed runners that I set as my intended audience.
I only placed the Ambush enemy on moss covered tiles using the same design logic as when I placed the tiling for the vines. This is also because when the Ambush reaches its angered state and grows larger, it's made more believable by the floor tiles being made of moss.
When adding the background, I filled the level with the same brick tile to avoid any errors, and then placed different iterations where the bricks were missing to add a ruined effect.
Adding the gem at the top allows the level to be beaten, placing it in the many middle so it's more fair between which path you choose at the end.