A Diablo-like RPG
Let me proudly present my own take on the top-down RPG genre, combined with features from my favourite game-series Dark Souls!
What started as a small free-time project evolved into four months of dedication, refining gameplay mechanics and mastering the implementation of Diablo-like features. However, this isn't just another mob-grinding RPG. My goal was to create a challenging and punishing experience inspired by Dark Souls, where strategy and precision are key. By incorporating a rolling mechanic, players must carefully plan their moves and dodge enemies to survive, making every encounter a test of skill and reflexes.
The name of the game is temporary, I borrowed it from the band: "King Gizzard and The Lizard Wizard"
Point to click
Hold or click the mouse button to move the character to that position.
Move() runs while isMoving is true
In case mouse hit is Interactable
Buffered input
To make the game more responsive, I have implemented a "buffered input"-system. While doing an attack or performing a roll, the player can hit a key which performs another action during the current one, and when the current action is finished it queues the action the player has pressed.
Roll mechanic
When pressing space, the player performs a roll.
RollStart:
RollEnd and OnAnimatorMove:
RollUpdate:
IsCollidingWithWall
Event handler
For the Enemy AI, I used something called Event Handler. Every event has an OnBegin, OnUpdate and OnEnd function, and a bool that returns if event is done. The enemy has a List (that acts as a stack) where it keeps track off which current event is active, when when the current event is done it removes it from the list and proceeds with the previous event. Some examples of events are:
Enemy base script
This is the script that all enemies use as a base. The scripts consists of:
Enemy Event
This is the script I have used for the base of all the other event scripts. Every enemy-event like Idle or Attack inherits from this.
Some other functions that are inherited from Character script:
Three different attacks
For this section, I want to show the three unique attacks that the boss has, since the boss otherwise share the same base behaviour as the other enemies do. The boss attacks consists of a combo attack, a jump attack and a ranged attack that makes it rain rocks from the sky.
Combo attack
This attack script does all melee enemies share in common. I have made a attack combo-system that is easily expandable upon, where you can just add more animations in queue and the enemy will play them in order unless he is too far from the player. In that case he will go back to its "FollowPlayer"-state.
Jump attack
The JumpAttack script works in a similar way that the roll mechanic for the player does. It lets the animation handle the movement. In the previous state/event, it checks if the boss is within a certain distance of the player, and in that case it either performs a jump attack or a ranged attack depending on the RNG.
float jumpAttackDistance = 4f;
float comboAttackDistance = 2f;
These two floats are used to decide if the enemy should do a combo attack (the previous one) or a jump/ranged distance.
Now onto the script itself:
Ranged attack
In this attack, the boss makes it rain rocks from the sky. Before the rocks hit the ground, it shows indicators of where the rocks are going to land, so that the player has some time to dodge them. The first rock will always be above the player, so that the player has to move either way to not get hit.
It has three variables:
Boss projectile script
Choose your path
At the skill tree's current state, it only has five different types of passive skills in total. The skill types consists of damage increase, health increase, defense increase, mana increase and attack speed increase. Despite that, I have big plans for the skill tree in the future, and it is going to play a large part in what makes the game enjoyable. There will be a lot more stats that will be affected by different skills, and the player will be able to choose a lot more paths in what way he/she wants to take the character. Here is a list of skills that I plan to add in the future:
Currently added skills:
Future skills:
(Inspiration from Path of Exile)
Get skill points by leveling up
I have made a level system that applies for all characters in game (both player and enemies). Each time the player levels up he gets a skill point that he can spend to achieve a passive skill. For the enemies it works a little different though. For each level the enemy has, it multiplies all its stats by 1.2. That makes it easily scalable for future levels where the enemies should be harder, and it's easy to reuse already existing enemies and just increase their level to match the level's difficulty which will save a lot of time during development. With that said, I will of course introduce new enemies as the game goes on.
ItemSO
Every single item in the game has a scriptable object called ItemSO as a parent. The ItemSO script stores some important variables that will apply for all children, like a item name, item description, item icon and a bool that is called "isStackable" which determines if you can stack multiple items of a specific type in the same inventory frame.
ActionItemSO
This is a child of the ItemSO that can be equipped in the action slots and used by the player. It stores two floats, one for a cooldown and one for a timer that starts at the moment the player uses the item. It also has an abstract function called "PerformAction", which is called when the player presses the key that matches the number of the action slot the item is in.
AttackTypeSO
This is a child of ActionItemSO, and is a parent to all the different abilities the player can do. It consists of:
PotionSO
This is a child of ActionItemSO, and is a parent to all the different potions the player can drink in game. It consists of:
EquipmentSO
This is a child of the ItemSO script and is used for equipment and weapons. The player can put them in the Equipment Slots. Each equipment item has an enum for what type it is, and all the equipment slots has its own specific type as well. The type consists of Helmet, Boots, FirstHandWeapon, etc. This is because the player is not going to be able to equip a helmet in the boots slot, or a sword in the helmet slot. The equipment type of the item and the slots has to match for the player to equip it.
The Stat class consists of:
__________________________________________________
Inventory screen
The inventory screen consists of 30 inventory slots, 5 equipment slots and 5 action slots. InventorySlot is the parent script of all the other slot types, and is where most of the inventory logic is handled. Each of the inventory slots stores an ItemSO, and the player is limited to place item's in different slot types depending on what item type it is. For example, you can not put an action item in an equipment slot, and you can't put a non-action item in an action slot.
To move around item's, I've implemented a drag and drop-mechanic. The InventorySlot script has three inferfaces included: IBeginDragHandler, IDragHandler and IEndDragHandler. Each of these has a function for when the player is beginning to drag, during drag and end of the drag. To make the item icon follow the mouse when dragging, I have removed the sprite from its parent and placed at the mouse position during drag, and when dropped, it shoots a raycast from the mouse position and depending on what inventory slot it hits, it is placed in that slot by setting the current inventory slot to null, and the targeted inventory slot to this inventory slot. The sprite becomes a child of the previous slot again, but is set to null, and the sprite of the new inventory slot is changed to the new one.
I also have implemented a mechanic to easily switch items with each other. This was the trickiest part in the whole game to get right, in my opinion. There was a thousand stuff to keep track off, since a lot of bugs occured where you could for example switch an item from the equipment slot with an item in the normal inventory slots. That made the player being able to equip a health potion for example, if he switched it with an armour piece. So, I had to set a lot of restrictions to in what moments the switch was going to be successful, or where the item's should go back to their original places. On top of that, I also had to keep track of when the stats of the armour pieces should be applied and when they should be removed.
__________________________________________________
Tooltip window
The Tooltip window shows up when you hover the mouse over an item or a skill to see more information about it. The information it displays depends on what type of item or skill it is, and the window scales depending on how much text is inside the box.
For an armour piece, it displays the title at the top, then below that there is a short description and what the main stat of the item is. Below the description it shows what level is required to equip the item, and at the bottom it shows all the bonus stats (if it has any at all).
Every time you hover over an item, it takes all the information from the ItemSO that item slot holds.
Fire Attack
The Fire Attack is the most straight forward attack I have implemented, you simply shoot a fireball and when it hits an enemy or an object it causes an explosion. The explosion has a sphere collider, and it takes the radius of that sphere and deals damage to all the enemies that are within the distance of that radius.
FireAttackSO
Explosion
__________________________________________________
ProjectileSpawner
Lightning Attack
The Lightning Attack causes a chain effect between up to five enemies if they are close enough to each other, and deals electric damage to those enemies. The player also has to be close enough to an enemy for the effect to deal any damage at all, otherwise nothing will happen.
FindClosestEnemy
__________________________________________________
ChainToClosestEnemy
Earth Shatter Attack
The Earth Shatter attack causes rocks and fire to come out of the floor, and deals great continuous damage to whatever enemy steps inside of it. Even though this attack is overpowered, the mana cost and cooldown is very high. So the player has to consider in what moment it is best to use it.
Rock script
I have made a script for the rocks of the particle effect as well, where it checks if the rocks are colliding with an enemy.