Introduction
My goal for this project were to create a biome set in the Returnal universe. I focused a lot on prototyping the games main mechanics, set up enemies that synergies well together and design combat arenas that felt fair but challenging.
Project details
-
Made during the Portfolio Course at The Game Assembly
-
Developed over 7 weeks, half time
-
UE5
-
Refined blockout
-
Technical design and performance
-
AI and mechanics scripting
-
Assets used: Weapon models and dash animation from Lyra, Animation Starter Pack from Epic
The process
Pre-Production
I started by gathering the information I needed from the game by playing it to get a feel for the player movement and sense of space. I frequently used the in game photo mode to get as many references as possible to be able to determine the metrics of the game.
At the same time I wrote an LDD with pointers and things to have in mind which I picked up from several dev talks and Combat Arena analyses.
I also set up a board with tasks to have a better overview of my project and to make it easier for myself to plan ahead.
Getting started
I needed a good place to start so I made a first draft of a bubble design to give me a solid springboard into blocking out each segment and to control the flow of the level.
The final version of my project strayed quite a bit away from the initial bubble draft but I believe that this workflow enabled me to iterate the level more easily.
Player gym and metrics
The first thing I did in Unreal was to set up a player gym with the metrics I gathered and measured based on the photos taken in game. I made sure to cover everything from the longest gap the player can jump over to the smallest covers and the max ceiliing height.
Blocking out test spaces
After setting the metrics I started blocking out a bunch of different action blocks to get a feel for the scale, architecture and gameplay. At the same time I made the first iterations on the player movement and enemies to test the flow of each block. I scrapped a bunch of different blocks, but quite a few of them became the foundation of the final map.
Prototyping gameplay mechanics
Roguelite mechanics
I wanted to try and prototype close to a complete gameplay experience. So I made a Game Instance and stored the necessary data like current health and equipped/stowed weapons to develop a roguelite experience in a struct. I wanted to build a biome with a lot of verticality, so in order to make that fair with roguelite mechanics I scripted a fast respawn system, storing the players last safe location and spawning the character there if the player fell to her death while having more than 20 health remaining.
The player
One of my goals for this project was to design a biome after the players movement mechanics. So I spent a week trying to recreate the player movement from Returnal that could elevate my level design.
I lowered the gravity to match the otherworldly planets, I scripted a grapple so the player could easily reach higher points and I took assets from Lyra for a dash that complemented the design of the map. I put a lot of love into the camera so that the player could see as much as possible of the complex design that a bullet hell is.
Weapon system
In order to give the gameplay more depth I scripted a system that allowed the player to pick up rewared weapons which improved the sense of progression of the game, cycle through equipped and stowed weapons to increase the player agency by utilize what would be most efficient for the different scenarios ahead and how each of the diffrent weapons behaved. How and when the player used each weapon also affected player movement behavior such as locking the player forward orientation when aiming down sight and switching between different states of movement depending on which weapon that's equipped.
Room objectives
I made a function that could be applied to several actors such as reward chests and progression gates. The script checked if the player had met the requirements needed in order to progress or receive their rewards. It was quick and easy to use in the editor by mouse picking actors to the choosen array. When selected enemies health were less/equal to 0, the requirements were met. The script made it very efficient for me to quickly playtest these sections and easily iterate if needed.
Enemy and combat design
Details
I wanted to have complete control over every aspect of the enemies, so I made them all from scratch. Including different projectile patterns and custom perception logic. It was important for the project due to how much they would influence the level and combat design. I tried to follow a few sets of goals I set up beforehand for the best possible result.
Goals
-
Create an optimized bullet hell system
-
Prevent a cluttered screen space
-
A mix of static and dynamic enemies
-
Force the player to move around
-
Distinct enemy design
-
Orthogonal Unit Differentiation
-
-
Consistent behavior
-
Easy to grasp projectile patterns
-
-
Give life without having to animate
Here is my first draft of the five different enemies I planned on creating. Since I didn't plan on rigging and animating my enemies, but still needed them the be easy to differentiate I designed them based on primitive shapes. I went with a sphere, a set of rectangles, a cube tower, a flying cone and a cloud of smaller cubes. Two of the above (tier 2 and 5) I later on cut from the project because I felt like they didn't fit the level design.
Tier 1 - The Sphere
The most common of the enemies. The sphere slightly moves around just to keep the player alert. It's main purpose is to serve as a turret with area denial capabilities. This enemy is very one dimensional so the design needs more dynamic enemies, but it works great in tandem with the others. After cutting away 50% of it's health it goes into an unstable state and doubles it's rate of fire.
To give the sphere a bit of life, I made a material in which I offset the vertex positions along the world normals to create the animated effect.
Tier 3 - The Cube Tower
The pylons main purpose is to protect nearby allies. It's static and rooted to where it spawns. Due to where in the arena the pylon is placed, it makes each arena a puzzle in which the player has to find a way to reach it without loosing too much health.
In addition, the pylon will also shield itself, forcing the player to actively switch weapons (see: Synergizing enemies) since the shield can only be destroyed by the close range shotgun.
The animations are made by adding a relative location to childed meshes.
Tier 4 - The Flying Cone
The most dynamic out of the three. It plays a huge part in preventing the player from exploiting the more advantageous parts of the arenas due to the other two enemies being fairly one dimensional. This enemy was particulary hard to balance properly since it's by far the most lethal one. Due to that fact it has the lowest amount of health. It constantly tracks the players movement and can both follow a set path or roam more freely.
The tentacles are made in niagra and are childed to the main mesh.
Synergizing enemies
Since I early on wanted the player to have to make an active decision on how to approach each arena, some of the enemies needed to interact with eachother. This tied well together with my plans of making the pylon enemy serve as a support. I made a function attaching a beam from the pylon to allies which the pylon continuously tracked. In order to be able to damage the protected enemies the player would have to get close to the pylon, actively decide which weapons to use along the way and equip the close range shotgun to take out the pylons shield. This combat loop helped further emphasize on the 30 seconds of fun, which I made sure to keep in mind alot along the process.
Overview
1
2
3
4
5
6
7
8
9
Level design highlights
The High Cliffs
After the player leaves the central piece for the first time, the level becomes more open. A lot of verticality is presentet to the player. I use these areas with platforming as a means to control the overall pacing. I subtely guide the player through the environment with clear buffer zones of when to dash, jump or grapple. While traversing the cliffs a soft reveal of the first arena is presented to the player, this enables her to make inform decisions later on. This sections ends with a good vantage point before the combat arena. When the player decides that she's ready there's a point of no return right before the action begins.
Guiding with enemies
I carefully placed a few enemies across the platforming section. I subtely utilize implicit information by using the Tier 4 enemies movement to lead the players eyes . Having a few enemies across the more slow paces sections of the level also helped with maintaining a good balance to the 10 second rule and lower the gameplay fatigue.
Things I kept in mind
-
Use arenas as a mean to control pacing
-
Room to evade
-
Mindful utilzation of vertical space
-
Quick instant reads
-
Player positioning
-
Think critically about which weapon to use and when
-
Build up a difficulty curve
-
Enemy placement must complement the level design
-
Keep things from becoming repetitive (30 sec of fun)
The third combat arena
This is the most narrow out of the 4 arenas, but at the same time the one with the most verticality as it consists of 4 floors on top of eachoter that loops well together to create a fluid combat experience . The goal of the arena is to reach the top in order to progress further. At the decompression zone the player has a great opportunity of planning how to approach the arena. The sightblocker hides a good portion of the first floor but since it's not the first time the player encounters a protective pylon she understands that the first visible enemy can't be taken down without tracking the source of the protective beam first. Using the verticality of the stairs as cover against the first enemys one dimensional attack will be prove useful. I mix in environmental traps into this arena to raise the perceived complexity.
The multi purpose piece
This is the most important section of the level. And the part I spent the most time iterating on. It serves as both a node and as the boss arena. When the player first steps foot in here, the level opens up after a funnel before reveal. I use this area to teach the important affordances so the player understands the rules. The player enters the oval node slightly higher than the dormant boss making her feel powerful and in control. It's easy to read where to go everytime the player returns to the node since the verticality of each progression gates prevents the player from going back. The first time the player returns she gets another point of view over the arena and can build a good mental map for what to come. The last time the player returns to the arena she enters at a much lower position than compared to the first time invoking distress from the awoken och unstable boss. The power dynamic has changed and the tension is increased. Since this isn't the first time the player has been in the boss arena she is now familiar with the obstacles ahead and cover provided during the encounter.
Technical Level Design
Utilizing my own plugin for Unreal
Since the start of the autumn semester of 2022 I've used and continuously improved my own plugin for Unreal called Under Construction. It contains several procedural meshes of primitive shapes that can be manipulated in different ways.
The main reason I started working on it were to make blockouts faster and easier for Level Designers to iterate on.
In the video below I showcase the revolve cylinder I frequently used during this project. Instead of rotating cubes I can set the exact degrees needed. I really like using this non-destructive way of working. And I think it could be quite useful even for a larger team, for example - the modelling team can get the exact dimensions from the designers if used in the intended way. After working on several group projects at The Game Assembly and seeing how easy numbers can get lost along the way, I believe this could really help.
After blocking out with the dynamic meshes, I've scripted a function in the parent class that bakes the dynamic meshes into static meshes. If needed, the static mesh can be updated while maintining its world position.
Full level playthrough
Reflections
This was a huge experience for me, I have never taken a project this far by myself before. I learned a ton about organizing bigger projects and keeping everything easily accesable. I had a very ambitious plan from the beggining which involved hand crafting larger segments of a level and then run them in a procedural level generating script. Unfortuntely I wasn't able to finish that plan but since I took a smart decision in pre production to build the tile sets so they could both work alone and together in a larger level I had a solid plan b to fall back on. I would love to keep working on the procedural level generator in the future and I believe that could still work well due to the tile sets being designed this way.
Another thing I didn't anticipate but really appreciate happening were all the small things I needed to fix in order for the whole project to work. For example activation timers between vantage points and enemies so that the player could not shoot the enemies from a safe spot miles away. I'm very proud of the solutions I came up with and they worked very well, but obviously took some time away from things I've would have liked to include in this project.
Thank you for reading!
/Christoffer