Skip to main content
GameDev.net gamedev.net

PRO Tired of ads? Read GameDev.net ad-free and help keep the community independent with GameDev Pro — $3/month.

PITVYPR Dev BLog #10: Level Generation Part 3: Simple Encounters, Prefabs, and Generalization

PITVYPR Dev BLog #10: Level Generation Part 3: Simple Encounters, Prefabs, and Generalization

BerneyTD
BerneyTD
PITVYPR Development · · 8 min read
1,281 0

Hello!

I have been dipping and diving into all aspects of PITVYPR with the upcoming Pre-Alpha Demo release (or, maybe it would be an actual Alpha release now?), I've been too all-over-the-place to properly sit down and write a cohesive blog. Especially in this ongoing series on Map Generation, a topic which I am still very much learning about and discovering new techniques for all the time. However, I am at a point where I believe I can discuss the simple encounter system that will be on display in the release build.

Dungeons as Trees

An important revelation that one should make in any Room-By-Room level generation is that you are creating a Tree. Not a literal tree, most likely, but a logical one.

Take our previously discussed BrogueLike Generation for example, we start with an initial room, and then mark it with exits. We make a new room, and attach it to one of these exits. Then, we mark some exits on that room, and continue.

Rooms are logically analagous to Nodes in a Tree Data Structure, with a determined maximum number of Edges available to connect with child Nodes.

Taking this Tree structure as a basis for dungeon analysis and design, you can really run to the hills with it:
Give some edges a direction, and you can then make the connecting doors Locked, with a required key found somewhere in the parent Rooms from that branching section.
Determine farthest and nearest Rooms from the spawn point (The Root Node), and fill them with better loot, or more dangerous enemies.
Identify disparate rooms that should have a connecting tunnel, and provide a back-route to make the dunegon feel more cohesive.

Now, these ideas are all REALLY cool, but I've yet to get around to a lot of what you can do with the Tree definition. I have done the 3rd one, and it works somewhat well, but that's a discussion for another time.

The basic focus I have for utilizing the Tree-wise Definition of our map is to localize our Encounters.

This means that, if we store each room as a separate object, we can place and create Encounters within those parameters.

This sounds kind of obvious, and it probably was for some of the other Roguelike Devs among you readers, but the use of this system becomes obvious when you consider Encounter design without it:

I want to place a goblin horder in this room. Wait, where is the room? I just have a lot of numbers in an array. Okay, I can find a room by looking for box-shaped areas. But, what about the Cellular Automata rooms? Okay, so I can find rooms using a FloodFill to get valid areas. But what about when a flood fill goes through our tunnels, and into other rooms? Okay, then a flood fill with a set radius.

For certain, this is a way to go about solving the problem, but it only works on a specific type of closed-room, tight-space map. Any more open maps, and encounters become more sparse.

Storing Room definitions makes Localized Encounters far simpler:

I want to place a goblin hoard in this room. Ok, find X many valid spots for goblins in that Room - they can be random. Done!

Indeed, this is how we implement most encounters in PITVYPR currently - even more simply than that, if I am being honest.

Encounters

Encounters come in 3 Flavours:

  1. Enemies
  2. Items
  3. Prefabs

The first two are the main types you'll come across in the demo.

Enemy encounters are made by placing a random number of enemies within a room. The type of enemy is semi-random, depending on the level parameters.

Item encounters are made by placing a random item within a room. The item is completely random.

These are REALLY basic encounters. So much so, that it almost seems frustrating. But, when put into the context of what the Demos goals are, I am more than happy with a simple system:

Understanding how different Items and Enemies work in a wide variety of contexts.

If PITVYPR's Demo had a lot of set-in-stone encounters, then that wide variety would be lost. I am focused on refining and exploring the barebones combat and Action systems in the game for now.

However, that doesn't mean that we can't have SOME consistency in the levels:

Prefabs

Prefabs are the true hero of any random generation. It's all well and good having some generated rooms and enemy encounters and random layouts, but a little human-made touch makes all the difference in giving any generated level some character.

Prefabs are defined in the pitvypr level generation as Rooms loaded from a JSON file and an image file, representing a layout of tiles: their types and positions. An example room, the Minotaur Arena, is shown below:

The information in the JSON should be self-explanatory: Dimensions, Special Entity Placements (Minotaur doesn't naturally spawn in, we manually add it), etc.

I hope that the image file is similarly simple to parse: Walls in White, Floors in Black, Doors in Red.

The special tiles are Pink for Spikes, Yellow for Locked Doors, Purple for Unbreakable Walls, and Magenta for Items.

This all gives the Minotaur Arena some very direct design:

  1. The Minotaur is an enemy that charges at you. Spacing and running away from it are important, but you must be careful of the spikes in the arena.
  2. The Minotaur can also walk through these spikes, though, so leading it to charge at you through them will make the fight easier!
  3. Minotaurs always drop Keys on death, so the locked room is a small reward for defeating the Minotaur.

Hey, look at that. A prefab in the game!

A little bit of direction and a more focused experience can go a long way in breaking up the pace of generated content. It allows you to more intentionally put players in interesting positions while still allowing for all of the emergent complexities and infinite fun that generation can provide.

Each level has its own set of Prefabs, and they help to give each level its own distinct character, along with the unique enemies and colour palettes that each level also has. All of this goes into making levels that are relatively unique for the Demo.

Room For Improvement

Horrendous pun aside, there actually is a LOT of “Room” to improve this BrogueLike Proc Gen. A few examples were listed above, with creating locked rooms and unique challenges/rewards based on different tree Nodes.

The biggest change I will be looking to implement in the future is a difficulty tag for levels.

Difficulty will be our metric for understanding how challenging a generated Room or Level is. A level might generate with 6 Item rooms and only ahandful of Enemy Encounters, or vice versa. This gives a wild difficulty variety to the game in its current state - which I am content with exploring, to try and find that fun balance. But, the ability to tweak it will be indispensible when that time comes.

Giving enemies a difficulty score, as well as prefabs and other types of generation (spike traps, hidden rooms, etc) will give a rough, ballpark measure of difficulty for levels, and allow us to deem them appropriate or not for use. If a level is too easy or too hard, we simply regenerate the random encounters until we reach a difficulty level more appropriate.

I will also be adding some small parameters that allow me to tweak room spawn rates, as well as some extra tunneling modifers that should allow my generated levels to feel wildly different even with the same generation algorithm in place.

Next Steps

So, Levels generate! Then, what's next? Well, not a lot, really.

In terms of the Demo I have a few enemies left to come up with (around half a dozen difficult enemies - the Demo's endgame), and a fun final boss for the third level (something that might be fun to discuss in another blog once the demo it out). A few unique prefabs for the two new levels: The Copper Chambers and The Underblood also need to be whipped up, to give them their own identity as levels.

Then, just some minor bug fixes and we should be ready to ship it out!

Yes, it is true that I say the Demo will be out soon in nearly every post, but I have channeled the ability to REMOVE features from my Demo Roadmap, as opposed to always adding more. So, no Shop, no Secret Levels, way less Bosses and Enemies, but we will have a good time regardless!

I constantly need to remind myself that this is not a full game demo, just an alpha playtest for the combat mechanics and general concept. Helping to refine the fun, and see if other people enjoy the game too.

Anyways, if that Demo doesn't get delayed a million times more, it will be up on the itch page for download whenever it comes out. I will probably make a retrospective blog on the road to making it, how that went, and what I look forward to adding in the future.

A fun screenshot I'd like to share is the Items page - an oh how it has baloon'd!

By my excel spreadsheet's count, we have 44 of these puppies fully implemented! Of course, they arent perfect, and the Demo is focused on refining them so that they can be even better! Keeping that in mind, I am doing my best to resist adding in or adjusting much on the Items before release. I just want to have some fun with what we have already, and make every item have a use-case.

Thank you for reading this posts, and again please do check out the PITVYPR itch page! Support really does mean a lot, and I'm super excited to get some feedback and actually make the game good when builds start becoming public.

Liam (BerneyTD)

Discussion

Loading comments...