Elden Ring Nightreign Recreation
Elden Ring Nightreign’s breakdown and prototyping in Unreal Engine 5.
Game Design Philosphy
The point of this game is to make everything modular. Modularity helps with expansion, design, and art. The goal here is to make and create a prototype to showcase.
Game made in Unreal Engine 5
Made for PC and (includes gameplay controller support)
Videos for Explanation
Modularity.
The first thing to keep in mind is the Modularity of everything. Calling everything in level design should be quick, streamlined, and simple. Creating new classes, assets, and more should not be a burden and take no more than 10 minutes.
Let’s Break it Down.
Elden Ring: Nightreign is a hit multiplayer third-person action game. It’s extremely fun and I love the systems in it. In this project, my main goal was to recreate the leveling up system. For this, I needed a couple things:
Player Stats
All ways to manipulate these
Status Effects
Healing Flasks
Sites of Grace
Interaction System
For me to do this, I have to break down the player stats. There are 8 main stats that the game calls “Attributes”. There are then several ssecondary stats that are derived from the 8 main stats. The secondary stats will include things like MaxHP, MaxFP, MaxStamina, and more. I can manipulate these by making a status system, quick ways to debug by putting this on keyboard events. Doing this will force me to make it as modular as possible so I can tweak every single setting that I can.
I will not be doing any of the actual scaling math as that comes under game balance and I also don’t know the exact numbers. However, I can still make it modular. That is my goal. To make everything as modular whenever I can. So, let’s get into it!
Where does it start?
The game first starts in the Main Menu. Here, there are two things to do: Start the game and play some music. For the Main Menu, I made a quick level and put the music actor there. There, it will play the soundtrack that is needed for the level. Once I have the music, I can then go into the level blueprint and make the main menu.
Once the main menu opens and the player presses to play the game, they will load into the Roundtable Hold. This is where a lot of different values and calculations will happen.
Player Stats
Main Stats: The game has the player have 8 main stats as shown here. The 8 main stats are the basis for the entire player’s stats. It determines all the values like the MaxHP, MaxFP, Max Stamina, and more. All of the scaling is made from these 8 main stats. Each class in the game have differetn values for scaling each one of these. Here’s the Wylder example. I got the values off the tables that I found online.
The main stats and the secondary stats are all in the blueprint as map variables. This holds the enum (the stat) and the struct (the values of the stat). The current values are all regular float values since I will be manipulating them quite a bit and also since there aren’t many (just 3 and 1 for the runes). This makes grabbing variables easy, streamlined, and efficient.
Here, the values are for each of the main stats that Wylder has whenever he levels up. To level up and give these values to the player, I made a simple level function, where the input is the number to give to the player.
Here, I am able to scale all the values of the player. This function is called at the end of the Update Player Level function, and is extremely modular. The reason why I made the damage scalings to also be there is because when dealing with the frost status effect, the player will get a debuff on those scalings. Hence, this function can be called with those values being inputted directly, allowing for modularity and conciseness in the function.
The player will go from the Roundtable Hold to the main level. So, since the variables all reset across levels, it’s important to make sure that they do not. Hence, I stored the player class in the Game Instance blueprint. Changing that in the project settings, it allows me to manipulate and do whever I need to.
This also includes the boss that is selected since the player will travel to a boss room dependent upon what boss was selected.
Player Class
The player class is first made in the Game Instance blueprint. This blueprint allows values to be stored and travel across levels. This is pretty vital when I need things like the player class and the boss selected.
In the Stats component of the player, I set that class and then get the first level. I am comfortable hardcoding this value in as the player class can only happen in the Roundtable Hold level. Once I have that, then I am able to take those values and also get the secondary stats for the maxHP, maxFP, and so on.
The player class can be selected in the Roundtable Hold level. Here, the player will go to the interaction in the back and select their player class. This layout is quite similar to the layout in the actual game. In this same level, the player will be able to interact with the Roundtable Hold and enter the actual game.
As the player will not be doing anything in the actual level, this is perfectly fine and does not require any performance boost or hinder gameplay at all. Class selection is modular, easy, and simple as placing down an actor in the editor.
Here is my class selection screen. Based on who I select, I can get the stats of that class and set that to be the player. I have a data table that holds all the information about the classes to display and set those when the mouse hovers over the button.
Once the player has selected a class (by validating the choice), then the player can close the menu.
Boss Selection
The boss selection is just a button to grab the boss and then commencing the expedition. The only code here is to make sure that the boss selected comes from the Game Instance. I have two examples here, but adding more and more is not difficult as it is simply is just a matter of copy, paste, and rename.
Status Effects
The function will do a check to see if the current value of the status effect should increase or not. Having this on each function allows the specifics of each function to be different. However, the modularity comes into the Handle Status Function. This allows any status effect to build up or cool down depending on the different rates.
The logic starts on the event tick, where there game checks if the player is in a zone to be affected by the status effect as seen below.
In the handle status, the status should only increase if the player is within the zone and does not have the status effect already. This is checked by using gameplay tags. I can add any at any time of development and check for whichever I need when I have to. This prototype is perfect for building up or cooling down any status effect I need.
Zones and Site of Grace
Status Build Up Zone
To make sure that the status can actually build up, we need to make a zone for it. The infamous Miyazaki Poison Swamps. For this, I made a quick actor that allows for it to build up any zone. Here, I essentially allow the zone type to be chosen and then set the text to find that in the specific zone in the map variable to allow the status to build up on the player.
The status is instance editable, so when placing it in the level, a designer can just choose what kind of status effect to build up, nothing more needs to be done!
The Site of Grace has to do a couple of things. All which it does. The first is to get rid of all status effects. This includes the build-up, the tags, and make sure that the player is no longer afflicted by them. The next thing is to make sure that the player stats are all reset properly. This means that the current stats are set again.
Upon interaction, the player is able to level up. So, using the interaction system that I made, the player will open up a widget that will allow them to level up. Upon leaving the interaction radius or pressing the interact button again, they will be able to close the menu.
I then added a VFX and a floating effect to the Site of Grace for that visualization based on how it looked like in the game. I’m not an artist at all, so this was my best shot at making it.
Storm Zone
The storm here is constantly closing in on the map. However, it closes in at specific points. When making the map, the designer will put down a few places where the storm will center to, making that the end boss fight for the night. In my research, I found no pattern to it, so I got a random point and made that the center for the storm, and then set the sphere radius from there.
If the player is in the storm, they will lose health pretty rapidly. I did notice while playing that it seemed to be based off the health scaling, vigor amount, and a couple of other attributes. To keep it all simple, I made a quick calculation function, made it pure, and put that in there. This way, all the calculations are modular and not just thrown in when needed and can be brought out any time it’s needed.
Having used the Ultra Dynamic Sky asset pack, I can also tune the storm to decrease at the same rate as the Ultra Dynamic Sky. This takes time to do as these values need to be refined and I’m still working on getting it perfectly synced up with the day/night cycle passing by quite quickly.
Site of Grace
Roundtable Hold
The Roundtable Hold is the exact same thing as the Site of Grace. Knowing that it exists in the Roundtable Hold level, there are no status effects, but knowing that it’s a Site of Grace, it would be the exact same functionality as a regular Site of Grace. The only other difference is that instead of being able to level up, the player will open up a menu to select which boss they want to play. This is again stored in the game instance, so that value is held across all levels.