Text Adventure Time! (Randomized Room and Creature Generation)

Some time ago, when I was brushing off my Java, I wanted to get my hands dirty while making something fun. I LOVE text adventure RPGs, so that’s what I attempted to build.

This is the seventh post documenting my single user dungeon development adventure.

In my last Java Text Aventure post, I left off at commit 783fa97, where I added a Gradle build to the project.

In this post, we take the game a little closer to procedural generation with automatic creature addition and randomized room layouts!

Here is the list of posts published on this project so far!

Check out the repo for this post and follow along!


Target commits:

Running the game:

Spawning creatures

Commands.java‘s changeRooms() method has been updated to call a new sub method checkRoomMonsters(). This sub method looks at the target room’s creatures ArrayList. If the list is empty, a new creature gets added.

The creature is generated from a list of creatures that gets loaded up at Application run time. The NonPlayerDefaults class randomly selects a creature from this list, then uses a constructor to set the various parameters to scale with the player’s current level. The NonPlayer class has a constructor that takes a NonPlayerDefaults object and sets the NonPlayer properties accordingly.

Getting a random creature:

Scaling the creature with player level:

The creature scaling is not very exciting, but we’re just laying the groundwork for dynamic generation at this point, so it’s OK to be boring.

Generating random room layouts

I had some fun with this one. World.connectTheRooms() randomly adds 1-4 exits to each room. It needs some refactoring: a while loop inside a for loop. Oh man.

First, we get a list of rooms. HashMap.values returns a Collection, but I want that stuff in a List, and casting is lame!

We want each room to have exits, so we loop through the rooms to add them. This approach doesn’t check to make sure every room is accessible, so it’s possible that multiple groups of rooms get created with no way for the player to go from one group to another. It’s a feature!

We generate a random number of required exits, then while the total number of exits is less than this number, we loop!

The method addSomeExits doesn’t exist, but it should. Instead, the code is all crammed inside the while loop.

We need two pieces: a direction, and a Room. Here, we get a direction:

We want to avoid adding the same direction to a room twice. Since the while loop continues until the quota of exits is met, we can just continue if we don’t like what we get:

Once we have an exit, we pick a room to connect to in a similar way we chose the exit, using random, but giving it an int that equals the roomList size:

We also don’t want to add an exit that connects to the current room, so we check that and continue if the Room we selected matches our current room (r is the current Room of the for loop):

Now we can add the exit, using our randomized direction and connecting room:

Of course, if Room1 exits to Room2, Room2 should exit to Room1 in the opposite direction, so we need to add the current room as an exit from the room we just added as an exit from the current room! Mind explosion! Here’s a horrible way to accomplish this (there’s way too much happening on this one line):

The whole potato:

Now every time the game is loaded, the room layout will be different! It’s far from perfect, and there are holes in the logic that adds the reciprocating exit, which results in one-way exits. This isn’t necessarily a bad thing, but it was unintended.

At least the platypus occasionally gets new scenery to look at, even if he can’t get back to the Study (it looks like the north exit from the Mess Hall to the Study got overridden with the Gatehouse!)

Matthew Odle

Indie dev, autodidactic polyglot, lover of programming, dad, musician, writer, mentor

One thought on “Text Adventure Time! (Randomized Room and Creature Generation)

Join the Discussion