Announcement

Collapse
No announcement yet.

Titan Keep - A procedurally generated ARPG roguelike

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Titan Keep - A procedurally generated ARPG roguelike

    So I had some spare time in the holidays so I thought why not try to make a really quick ARGP rogue like with procedurally generated levels. Here's a little blog about my progress. If the project seems to be going well, it could become a real project ... but we'll see.

    Feel free to post to ask questions on how I do things.

    Day 1 (28 Dec 2013)



    After purchasing a character pack and a dungeon environment pack from 3DRT.com; I spent half the day prepping the content for import into UDK. This mostly consisted of just messing around with Blender to get the correct FBX export parameters I needed for skeletal meshes and static meshes. It was also really handy to export at a much bigger scale than Blender (32 times) as the original meshes were really tiny. I then spent the other half writing up the basic game info and room generation. Right now the room generation is super simple in that it just picks a random room and lays it out in a grid. Over time, I plan for it to do more complex things but right now I just want something up and running. My past experiments with procedurally generated levels were too complicated. They were complicated because I tried to do everything randomly. The rooms were randomly sized and the room contents were randomly generated. This lead to really unpredictable results most of the time. Sometimes it'd generate awesome levels but most of the time they were pretty boring / garbage. The levels were also not really that interesting. This time around, I made things super simple by writing a template system using the configuration files. The mark up for it is pretty simplistic. Here's an example:

    Code:
    ########
    #......#
    #......#
    ########
    This would generate an 8 by 4 room with nothing inside it. The #'s are walls and the .'s is empty floors. So what I plan to do overall, is to have a lot of these premade rooms and the level generator really just places them in a random fashion. To add some randomness to the mix, the templates can also include random elements. For example a # could be replaced by a + which would randomly place a door or a wall. This gives the templates some randomness, but not enough to really muck things up.

    At the end of day one, I managed to get the wall generation code for the room templating just about right. Walls in corners correctly generate and inner walls correctly generate with caps at the end too.

    #2
    Day 2 (29 Dec 2013)



    Today I added a little wizard for the player to control. Shadow generation from the single directional light source didn't look that appealing and performance was pretty horrible. Taking a lesson learnt from my past project, Derelict 9, I am going to ditch the single directional light with an ambient light attached to the character. Shadows were still pretty expensive, so I decided to just remove them all together. To get some grounding for the characters, I will probably just add a blob shadow ... but there are more important things to do right now. I attached a camera to the wizard as well.

    I had a lot of trouble exporting animations from Blender as the animations came as a single file. It kept exporting it with the entire animation track, but it was fixed by setting the start and end frames and ensuring not to export with everything. Scale also had to be kept consistent or the animations would export with the incorrect translations.

    I improved the wall generation a bit more, and I also decided that wall caps would extend to the next floor over rather than in the grid space it was allocated at. This ensured that single walls weren't just two wall caps next to each other. You can see that in the previous day's screen shot.

    Lastly I added passage ways so that it was possible to go from room to room.

    Comment


      #3
      Day 3 (30 Dec 2013)



      Today I mostly spent a few hours adding in the collision to the static meshes that are used to create the level. Prior to this you could just walk where ever you liked.

      I also added a staff for the wizard to carry around.

      Lastly I improved the wall generation logic a bit more to handle more wall placement situations in the template.

      Comment


        #4
        Day 4 (31 Dec 2013)



        To improve the visuals of the game, I decided to experiment with a sky light to provide some ambient color. I ended up with an very dim orange ambient color which seems to suit the dungeon theme at the moment. It also seemed to compliment well with the player's ambient light spot. It also helped to give the world a bit of depth and ambient moodiness.

        To make the levels seem more random, I also added randomly chosen wall meshes. It seems with only four variations, it is enough to make levels feel more random.

        I also have a fire ball spell for the player. Pretty simple at this stage, press fire and the wizard will perform a casting animation and out comes a fire ball! Paired with a simple particle effect while it is flight and a point light and it seems to do the trick. An explosion particle effect at the end when it hits something and its complete.

        I added a simple zombie monster that just chases the player when he gets too close. The player can blast him away with his fire balls.

        Comment


          #5
          awesome work there
          im really fond of procedural stuff and this is looking quite nice

          could we maybe get a screenshot with a wider angle? your progress from day 1 to day 2 in regard to the rooms seemed quite much more than what you described

          Comment


            #6
            Looks really nice Especially because we aren't getting much procedurally generated stuff with udk. Keep it up!
            Did you think of making something, which is often used in such view games, that all rooms your not in, are black, I mean, no light in them at all, or just a plane over them. So the player can only see the room he is currently in.

            Comment


              #7
              This is really nice looking, keep it up!

              Comment


                #8
                awesome work there. im really fond of procedural stuff and this is looking quite nice
                Thanks!

                could we maybe get a screenshot with a wider angle? your progress from day 1 to day 2 in regard to the rooms seemed quite much more than what you described
                Sure, but nothing huge changed between Day 1 and Day 2. A difference in light and better wall generation.

                Looks really nice Especially because we aren't getting much procedurally generated stuff with udk. Keep it up!
                Thanks!

                Did you think of making something, which is often used in such view games, that all rooms your not in, are black, I mean, no light in them at all, or just a plane over them. So the player can only see the room he is currently in.
                I had some thoughts about using a texture to cover bits of the screen. It just depends whether or not it is worth doing or not, mostly because for game play purposes it can be enticing to see something that you can't reach. But not sure, I'd prefer not to wrestle with technical issues too much as it can be a rabbit hole where I spend too much time tackling small problems.

                This is really nice looking, keep it up!
                Thanks!

                Comment


                  #9
                  Jeez Snake, you make it all look so easy! I'm doing procedural generation but the way I've approached some of it is with prefabs. I've become stuck on getting triggers and the like (anything that isn't a mesh) to spawn properly as part of the prefab so how do you plan on doing say, doors, gates etc.? Is there a better method to doing things like that without using prefabs?

                  Comment


                    #10
                    In terms of doors / gates and other things like that they will just be actors that perform a specific task.

                    Right now the world generation is done as a single pass. It simply lays down the rooms expecting them to all be exactly the same size. The rooms themselves already define where doors and pass ways are. In time, I'd like to improve the world generation to have a range of room sizes (probably not too many, perhaps from 7x7 to 9x9 at the most). So ideally the world generators select a number of rooms, spaces them out and then creates corridors to join them. The corridors themselves aren't particularly interesting, so they can be generated on the fly.

                    The next type of puzzles I'd like to do are ones involving key(s) and locked door(s). The trick with this one is that I have to ensure that the key(s) and door(s) are reachable from each other. Thus I need to keep track of how rooms are joined together and this can be done in the first pass as I'm generating the layout. I could make a lot of variants of the key(s) and locked door(s) ... for example I could replace the key(s) with switch(es).

                    Another type of puzzle I'd like to do is where you have to find an item and bring it to the stairs to go down to the next dungeon.

                    The rooms themselves are chosen at random right now, but I do imagine over time that the rooms will be chosen based on particular facets such as having the right amount of doors / passage ways and so forth.

                    I checked out your blog and I think your world generator is going to be a lot more complex than mine. I purposely chosen a top down view as you can't scrutinize the graphics too much. I also made it grid based as that just makes it a lot easier when it comes to aligning everything up. What you've got looks really awesome though, keep up the great work on your end!

                    I don't use prefabs because I know that they can be quite buggy.

                    Comment


                      #11
                      Day 5 (01 Jan 2014)



                      Today I added a random floor tiles to be used as well as randomized rotation. Makes the world seem a little bit more interesting. I lowered the randomness of these so that they aren't overused. I may use the same level of randomness with walls as well.

                      I removed a bad hack where I just had a blocking volume to handle the collision of the floor. I redid all of the collision of the static meshes and also added them to the door / passage ways. The reason why I did this was because I wanted to add fosses / pits into the level to add a little bit of Z depth to the world. Redoing all of the collision took a lot of time, but it was worth it in the end as these fosses / pits added some complexity to the world.

                      Comment


                        #12
                        Day 6 (02 Jan 2014)



                        For screenshot purposes I adjusted the FOV so you can see more of the level.

                        Today I worked on the world generator. I created a starting room which is always placed. It starts by having a few doors that will always be generated. From the those doors other rooms are generated randomly. I decided that a starting room was going to be needed because you always want to ensure that the starting room has no enemies in it and has enough room for other players to spawn into as well. I could possibly make starting rooms different based on mission objectives or something ... but maybe more on that later.

                        For now I've modified the other random rooms so that they never have passage ways but rather just empty spots where other rooms could be connected.

                        As you can see, I haven't quite fixed the problem where you can see through the back facing walls. The way I plan to fix this is by always generating the back facing walls and then having a tiny corridor between two rooms that is generated on the fly. While I could have looked up all of the information required on the near by rooms, I think it would get too complicated too fast and the benefits of having a tiny room in between two rooms is that it is just simpler to do. Occam's Razor as always.

                        To add a little more life to the level, I also randomly generate a point light and a particle system for the wall torches in the world. Makes the world seem a bit more interesting to have lights in places that make sense.

                        Comment


                          #13
                          Day 7 (03 Jan 2014) [Titan Keep is now a week old!]



                          For screenshot purposes I adjusted the FOV so you can see more of the level.

                          Today I continued work on the room generator and the world generator. Room generator now always creates the back facing walls so you can never see into the rooms from the outside. Rooms now have sections of the walls marked as joins. When the world generator generates a room (in this case the landing pad) it will iterate through all of the joins and spawns a corridor of a random length at each one. The corridors snap into place where the join is (prior to that the join is just empty space). Once the corridor has been generated, it will then generate a random room attached to it. When the room is generated, it is aligned to the corridor.

                          Corridors also randomly place a door arch way to make it appear as a separate room or as if the other room is attached by a seamless corridor. This helps improve the "room" like look. What I also hope to do is to have rooms that are capable of joining directly to other rooms without needing a corridor. This is probably going to be a feature for later though. In future, I also plan to allow corridors to be a bit more windy too. Some corridors might also branch and split off into multiple directions or just bend to create a more interesting look.

                          Because rooms now generate and align themselves afterwards (I can't predict what's going to be generated), I had to add a deferred pass to the entities within the room. Entities thus far are the zombie wizards, additional wall torch lights and particle effects. When these are requested to be generated, they get put into an array and then when the world geometry has finished generating it will then instance all of the entities requested.

                          You can see empty spaces in the end rooms right now. These are designated joins and what these will do soon is either be blocked off with a wall or a corridor is attached to it.

                          Comment


                            #14
                            Nice system keep working! this can become very cool!

                            Comment


                              #15
                              Thanks zibipod. Still got a while to go.

                              Comment

                              Working...
                              X