For this project, after conducting some research, we decided to build the levels semi-procedurally.
To achieve this, we used different room/corridor patterns (with various shapes and sizes) and combined them to create beautiful and coherent levels. Additionally, when generating the levels, we needed to add another step to determine how many doors are locked by keys, how many are locked by mini-games, and how many are already open. We also had to make some keys accessible from non-locked doors (certain keys can be obtained by stealing guards or by solving mini-games). This part of the generation was a bit challenging to handle, and we had to anticipate every edge case that could result in blocking the player on an unsolvable level (for example: requiring a key to open a door, but the key can only be obtained in a mini-game that is inside a locked room).