DevLog: Cygluln Chamber Wave Dungeon
Following we wanted to write up a bit on our wave dungeon we implemented over the last few months. We hope you enjoy the read :)
For our final level 10 patch in stein we wanted to give the players some content which they could enjoy, while we are working on some upcoming bigger content patches. For that we had to find something which should probably give more playtime to the player than we take to implement it.
And that is how we came up with the idea of putting together a wave dungeon were waves of enemies should come at the players which they have to defeat to gear up and compete in a ranking to show who manged to get the furthest.
As we are planning to create some classical dungeons, where you fight through with friends, we thought this should be a great fit and step in the right direction.
The basic concept
We wanted to put a system in place where we could easily create wave dungeon which followed some basic rules and requirements we wanted to put in place. Those where along the lines as:
- most of the parts must be configurable in our editor
- we must be able to set requirements for entering the dungeon
- we must be able to specify rewards
- we must be able to specify how the the difficulty increases
- we must be able to specify enemies which can be scaled with the current wave difficulty
- enemies should increase in quality and not quantity per wave
- we wanted boss waves
- waves should be random
- the dungeon should end when every player is dead or left the dungeon on his own
- the same system should be usable to make future wave dungeons without any additions
So we started out with using an existing part of our map to draft some basic things.
On the image you can see we identified we needed things like:
- a position where the players spawns in the dungeon (Entrance)
- a position through which the players can leave the dungeon without dying (Exit)
- some kind of entity where you can start the waves (QG Start)
- multiple points where enemies can spawn with some special positions to test out path finding (the blue area/points)
We already knew that we have to consider a lot of edge cases which can occur or are different to how we handle things in the "over world". Examples for this would be:
- player should not be able to respawn at the graveyard/on their own
- enemies should always try to kill the players and not get out of range
- players must be auto resurrected when they died during a wave and there are still other players alive
Making our systems more versatile
To achieve the above goals we had to make some greater changes to our game systems. Things we had to add or adjust where:
- we needed instances of our game world where only one or a few eligible player should be able to join
- players must be able to switch between those instances seamlessly
- the instances and over world should share basic functionality so that the world/instance the player or an entity is in is abstracted away from them (that enables to have multiple over worlds, instances and makes creating new types of instances easier)
- we had to extend our loot table system so that it can be used for dungeon rewards too
Our old system consisted of entities (including players) which were hardwired to our over world. And we had to change this so we can wire entities to what ever we want. To give you a better view of how our systems work and how our changes solved the problem, following a quick overview how the old system worked:
The whole system on the server side works of parts which only communicate through messages with each another. So every entity, player, party and the over world itself consists of such communicating parts. And every part informs other parts of changes they could be interested in or they should distribute to parts which could be interested. For an simple example when a part which represents a player changes his life it sends a message to the part which represents the world which consists of "hey i changed my life to 50 of 100" which the world distributes further to other parts of the system which he knows are other entities which could be interested in the life change.
To make the hole over world system a bit more complicated it is divided into chunks, so that not everything gets information about every other thing which is to far away.
The first Image shows again how the system roughly worked. To get entities to interact with something else than an world object, we had to extract everything the world object provided to interact with itself into an interface which we could reuse for other "WorldLike" objects. This were things like determining if players can walk on certain tiles or where the player should respawn after death. Now the only thing we had to do was derive our old World from our new WorldLike and substitute the reference type in our entities. After that we were able to start to create a new type of world which was our wave dungeon, which introduced its own rules how the world behaves.
After creating the WorldLike for the dungeon, we where only left with getting some logic into our entities which let them transition from one WorldLike object to another which was provided to him. Now we were ready to let players and enemies join/spawn or leave/die our dungeon!
Loot table extension
To be able to reuse our loot tables which currently only find use for item drops of enemies, we decided to improve of them a lot and make some configurations more easy.
The base we worked on was a simple construct where you could define a loot table which was linked to some items and a respective chance the item was retrieved from it, so that none or if you are extremely lucky all of the items would drop.
For example we had a loot table "gimme stuff" with following chances
- 0.05 (for 5%) Some Item 1
- 0.03 (for 3%) Some Item 2
- 0.1 (for 10%) Some Item 3
As we needed a loot table which gave us always an item back we introduced a new property for loot tables which defined the type of it. So we could still have our old system which we called "individual chance" and a new type we called "ensured single loot". When we encounter now a loot table of the new type, the chances no longer define what chance the item has the be retrieved instead it tells how likely it is to be retrieved compared to the others while giving you exactly one of the items. So the list above would translate to something like:
- 0.05/0.18 = 28% Some Item 1
- 0.03/0.18 = 17% Some Item 2
- 0.10/0.18 = 55% Some Item 3
To make everything a bit more easy to configure we also added the ability to link other loot tables with respective chances to one loot table, additional to items. Where the linked loot tables follow their own configured rule set. So we could configure multiple loot tables for the different item types we wanted to be able to be rewarded in wave dungeon, give them there the chances of they should have to one another (typical all should be retrieved with the same chance) and combine them in a single loot table which splits the chances for the given item type. So we can easily configure something like "drop one of the head items with a 10% chance, one of the chest items with 30% chance, .. ".
As a nice side effect we now can configure our loot tables for enemies with this way more easy too.
Coming up with a good balancing was harder that we initially thought. We wanted to get some key things right:
- it should feel right in the ranking, so when you have better equipment you manage to get further in a visible amount
- the rewards should be appropriate for the reached difficulty in the dungeon
- there should be depending on your equip a definite wall you hit when you manage to play the system
For the first point we experimented with some exponential increases of the dungeon where we weren't so happy at the start with. For the beginning we started with a fairly low start difficulty and an increase of 5% per wave compared to the previous one. After we extracted some key values (like difficulties we failed at with some specific equipment) from our experimenting, we were able to come up with some values we thought should feel more right, after a lot of trying out numbers in a spreadsheet.
While our starting values were so low we managed to get pretty high wave counts while failing at very similar difficulties while having equip which should not feel similar at all. So we adjusted our values so that for low equip the difficulty is very high from the start and our increase is considerably lower with 2% per wave, so that better equipped players hit their maximum later. We think this values greatly depend on our item design so could be very different in future wave dungeons. As a side effect this made our wave dungeon more challenging right from the start, which is way more fun to play.
The second point is pretty straight forward. So that someone playing the dungeon feels rewarded we have to start to give him better equipment at the points where he starts to fail, while he should not be getting to many of those items so that the challenge is over to quickly. To achieve that the dungeon rewards with items which increase in quality the higher the reached difficulty is. And to ensure that the player is rewarded correctly we increase the quality by difficulty so that it reaches sweet spots in its drop chances at the key values we determined at the point before.
Besides all the spreadsheet calculations, we found out that some enemies could be "gamed", especially in groups. Through that you were able to dodge attacks forever and kill some enemies independent of its difficulty. To counter that we had to put some special mechanics in place so that it is guaranteed that players always take some damage, which should increase over time to inflict enough damage that they cant heal back up fast enough or maybe kill them instantly. To ensure that the enemies get their free guaranteed hit we put a charge mechanic in place, which triggers after the enemy has not dealt any damage over a period of time. This means that melee ranged enemies charge to the player and stun them and ranged enemies snare the player so he just can not move. Through both the player can not move for a short period of time and the enemy can land a safe hit on them.
It was a lot of fun building the system for the wave dungeons, even while encountering a lot of problems on the way we have not been anticipating. For example we learned that it is not always enough to know that some entities (de)spawn at all, instead it is imported why they did that (like did they despawn because they died or because they left the world). In the end we are very proud of our first wave dungeon, even when it took us longer than expected, which we shouldn't be surprised about at all while working in software development. For finishing up we want to leave you with an overview the dungeon in the editor and one where we are playing:
Leave a comment
Log in with itch.io to leave a comment.