Thursday, August 30, 2012

Dungeon Rendering

Since generating dungeons in Unity seems to work just fine, I started working on rendering the dungeon.

First, I added random colored lights, so each room would have its own feeling to it:

Random colored lights

The next thing I added was a basic character controller (the model is still a placeholder), so that I could walk around and see how everything looks.

I put in some walls and rendered it from an orthographic camera in 3D:

Orthographic perspective

At this point, you would be able to look into every room, even if its not in your line of sight. This is very boring from a gameplay perspective and it looks very strange, too. So I quickly programmed a "fog of war"-like visibility system. Due to the fact that this is just a test, I currently use ray casting for this. This will be replaced by a much more efficient approach later on.

This little video shows everything I mentioned so far:


I also started adding more parameters and randomness to the level generator to make the levels more interesting. Writing code to create random dungeons is not very hard, but doing so that you get predictable and consistent yet interesting results isn't that easy.

Sunday, August 26, 2012

Unity

I always wanted to try out the Unity Game Engine, but becoming acquainted with a new tool often takes a lot of time. This wasn't the case with Unity though.
I played around with Unity a little bit and I really like it. It is more suited for 3D games than it is for 2D though, but it makes things so much easier. Today I ported the dungeon generator to see how well that goes. I also made some bugfixes and did some code cleaning. So far everything seems to work pretty smoothly. The level generation seems to take some more time than on the Java implementation, but the rendering seems fast enough and should improve further as soon as I implement some optimizations.

Here is a screenshot of a generated dungeon layout in the editor (no textures yet):

Random Dungeon in Unity

I also made a very basic gameplay prototype that I will be integrating into this, so that I can try out some gameplay mechanics (I know it looks crappy :) ):

Very first gameplay testing prototype

Thursday, June 14, 2012

Something

There hasn't been much progress on the game lately, mainly due to the lack of time and also because of me having to study the gameplay mechanics of Diablo III :P.
I am currently considering some changes for the direction I am heading with this, because nothing is really worked out at the moment. There is a basic dungeon layout generator and some netcode and that's about it. There is an overall idea of the feel and the theme of the game, but I have a hard time figuring out how to make it interesting gameplay-wise. I first wanted to have point&click controls like in Diablo, but now I think I want it to be much more fast paced like an action adventure.

Because nothing happend on this blog for over a month now, I made this little rendering, showing the first "axe"-weapon for the game:


\m/

Friday, May 4, 2012

Faster Network and a Name

I am still working on the network code, which will now run on UDP instead of TCP. The decision was not an easy one, but I wanted network play to be as smooth as possible, so I chose UDP, because it doesn't have as much overhead as TCP does.
As mentioned in an earlier post, UDP has several issues. The first is that it is a connectionless protocol, which means that it is not defined wether a client is currently connected or not. The second is that UDP is unreliable. You don't know if packets will arrive and you can't be sure they arrive in the correct order. It is very likely that most packets will arrive in the correct order, but when packets get lost, you will run into serious problems.

So how do we tackle these problems? Solving the connectivity problem is pretty easy: Whenever a player attempts to join a game, the client will send a CHALLENGE_REQUEST message to the server. If the server has a free slot, it will respond with a CHALLENGE_ACCEPT message and add that player to the playerlist.

But what happens if either the request or the accept message get lost? There is a simple solution: the client will send requests until it receives an accept message. If the server already got an accept message and added that player to the playerlist, but receives another request, it will just send an accept message back to the client. This way, if a request gets lost, the client just sends another one. And in case the accept message gets lost, the server will know that, because it will receive multiple requests from the same ip.

A similar system is employed for regular game messages. All game messages are bundled into packets. Each packet has a consecutive sequence number. In every tick (e.g. every 50ms) one of those packets is send through the network. If the packet arrives, the receiver will send that sequence number back during the next tick. This way, the sender knows which packets got through and it can resend packets that got lost. This protocol is a bit more complicated in detail. If you want to learn more about it, you can find all information on this website.

There is still a lot to do in terms of network programming. Using this kind of reliability, packets can still arrive in the wrong order which leads to inconsistencies. How I am going to solve this will be a topic for a future blog post.

We've also decided on a better name than "Dungeon" for our game. The game will be called 

Einherjar 
- Requiem for the Metal Gods -

That's it for now. I hope I get finished will all this network stuff soon, so I can work on things that are more fun and metal-esque.

Rock on! \m/

Wednesday, April 18, 2012

Quick Update

I didn't do a lot of programming in the last weeks, because I was busy designing the network functionality and considering different techiques of lag compensation and stuff. I finally came up with a concept that I plan on implementing. If all goes well, the system will be very easy to expand, but I am still worried about performance issues.

What else happened? Creating and joining a game, as well as disconnecting seems to work pretty well now. A basic chat system with a very simple user interface is also in place. This allows me to enter commands without having to program a sophisticated ui. This will most likely look a lot better in the final game, but it does its job for the moment.

Here is a screenshot:
Basic chat interface with join/leave game messages
That's it for now. I will post about my plans for the more advanced network stuff as soon as I verified that it will work.

Thursday, April 5, 2012

Netcode

As mentioned in the last post, I started working on the netcode. It was a more difficult task than I thought initially. The problems weren't with the network itself, but how to structure the code and how to store data.

The netcode is based on the TCP/IP protocol. I did some research and there seem to be a lot of people who say that you have to use UDP, or it will be to slow to work for real-time purposes. In my opinion it really depends on the amount of data one wants to transmit and how frequently that data is sent. The reason I chose TCP is just because it is a lot easier to use. TCP makes sure that all packets will arrive and also that they arrive in the right order. To make UDP usable for such an application, you would need your own TCP-like protocol on top of UDP to make it reliable. The benefit of this approach is that you can decide which packages should be transmitted this way and which shouldn't. I just hope that TCP will be fast enough and I will try to only send data that is necessary to improve network performance.

The hard part was to program the network interface and I am still not very happy with it.
Data is being send in packets. Each packet starts with a packet identifier (e.g. 1 for the login packet), it is then followed by arbitrary data (like a name, a color, a position). The server has two threads for each client, one thread for sending packets and one for receiving. To avoid concurrency problems, the server stores every packet in a packet buffer which is processed and emptied in the server's main thread.

The next thing I am going to do is a basic login and player management system. Every player will need a unique identifier, so he can be referred to in the packet data. I am also going to start working on the class that will later represent the world. The server will modify this class using the information provided by the clients and send the resulting changes back to them. The right choice of what data is processed by the server or the clients is very important. For example if the client would send a position update and the server just takes the information as the player's new position, that would allow for all kinds of hacks like speed hacks or teleport hacks.
Though the game will allow for singleplayer, I do not plan on explicitly programming a singleplayer "mode". That means that if you start a singleplayer game, what happens essentially is that the game will start a local server and connect to that server. The benefit of that is that the code is the same and everything that will work in singleplayer will also work in multiplayer, so the experience will be the same. It is also easier to test the code.

I hope that for the next post I will have some images or videos. This one was rather dry, but I thought it was worth sharing.

Thursday, March 15, 2012

Random Dungeons

I scrapped the online algorithm and opted for an offline algorithm instead. I also got rid of the template system, because it is not very flexible. The new algorithm uses a room partitioning strategy to create a bunch of rooms first and then connects them with corridors. The dungeons created in this manner are a lot more interesting and unpredictable.

At first, I tried using a Quadtree to create the rooms. The problem with that was that if you increased the randomness, the algorithm would result in rather elongate rooms (see the example image below). This is due to the fact that when dividing a long rectangle into four, then one ends up with at least two smaller rectangles that are longish. I wanted to have rooms that are almost square, so I tried a different strategy.

Quadtree room partition, leading to elongate rooms
The next thing I tried was a BSP-like approach. Instead of splitting the rooms in four, I only split them in two. The axis was chosen depending on the ratio of the sides which leads to the kinds of rooms I wanted. To connect the rooms, the algorithm starts at the root of the tree and connects from its "splitpoint" (the center of the axis where the room was divided) to the splitpoint of its two children. These children will then connect to theirs and so on. Leaves (which don't have a splitpoint) are connected using their centers. This approach guarantees that every room will be connected. It also makes sure that there are no unwanted intersections between rooms and corridors or corridors and corridors. It didn't quite work for the example image below, but it has been fixed in the final version (see the last image).

Dungeon created using BSP
The BSP-approach worked pretty well, but due to its binary nature, it would only create one corridor per partition. From a gameplay perspective, this would lead to a lot of backtracking which is rather undesirable. To solve this problem, I tried to combine the benefits of both approaches using a hybrid tree. Rooms will usually be split in four, so you'd have many corridors to choose from. If the algorithm encounters an elongate room, it will use only one axis to split it in half. Connecting the rooms works the same as before.

Dungeon created using the Hybridtree

And here is a video of how it looks ingame:

The next step in terms of random dungeon generation would be an algorithm that fills the rooms with life. But before doing that, I might have a look at networking instead. It's always a good idea to incorporate network code at an early stage of development.

Saturday, March 10, 2012

Dungeon (working title)

In this Dev-blog, we will share the progress of our first game.
This game can be described as a cooperative real-time roguelike with rts elements. It's yet to be decided how much "roguelike" the game will be, but it will definitely be some sort of dungeon crawler. Imagine BrĂ¼tal Legend meets Diablo.

The "team" currently consists of two people, moppele and myself. I will do all the coding and moppele will provide ideas for gameplay mechanics and help with problem solving. Due to the absence of a decent artist, I will also be responsible for all the textures and animations. Here is a screenshot, of what the game could look like:

Mockup of a dungeon

Random levels are one of the most important parts of a dungeon crawler, especially in terms of replayability. That's why I started to develop algorithms for random level generation. The first thing I tried was using an online algorithm based on room templates. This algorithm has several advantages. For one, it is very easy to code, extensible and having room templates allows for a lot of artistic freedom. It also allows to have dynamically changing difficulty and stuff like that. But there are also downsides. It is very hard to control the behaviour of the algorithm and having different types of connections between the rooms is also not an easy thing to do. You also have to provide lots of templates to keep the levels interesting and non-repetitive.
I uploaded a short video, so you can see the algorithm in action. I made it so that you can see the rooms popping into existence whenever the player sees a new room. This is just a very first test of random dungeon generation. There are other techniques that I want to try out to see which one works best.



And here is an image of the room templates that were used for this level:

Room templates that were used to generate the dungeon in the video