Archives

Categories

Meta

Hello, this is Alexander. One of the developer from the P219 development team. In this post I will talk about what I have been doing in the project, and what my experience with Unity, Source Tree and Mono developer.

In this game, I have been working with:

Animations

Enemies

Bosses

Xbox 360 controller mapping

Player’s attacks and abilities

Chest/health potions

Healing weld

Fog of War

Testing/debugging

Scripting

Optimization.

I have since the beginning of the project learned a lot. From before, I have never made a game or used Unity, so everything was new to me. It took a while to get started with Unity, but after I’ve used it some time it was really fun working with. I’ve definitely learned very must from this course/project, and it have also been very fun.

The Unity community it large, and I have found a lot of stuff and help online. If I have a question that none of my teammates know the answer of, it is most likely something someone else have asked about in the forums. With that being said, 3D games are way more popular to make then 2D, so everything I found is not relevant for 2D games.

What I didn’t liked about Unity, is Mono texteditor, which have poor functionality. No error/poor error detection. This means that after I have written some code, I have to save and go to Unity and wait for it to compile. This takes a lot of time.

Over to Source Tree, which is a graphical git client. This is a very powerful tool and let us merge our work, and roll back if there is any problems.

What I would do different if we started over with the project, would be not to use Tile2Unity. We started using this program to create maps and import it to Unity, but this did not work well with Source Tree/GIT. We would also have knowledge about how long time the different features takes, so we could do a better planning in forehand.

My conclusion after using Unity with this project is that it is easy and fun to work with. The requires little knowledge to start using it, and you will start seeing result early. After you have made some prefabs and scripts, you can quick make much of game very fast. My advantage is that I have programmed in java and C earlier, and C# which is used in Unity is not that far away these languages.

Coming into this project I had some experience with the Unity game engine, but not quite enough knowledge to sit down and make my own game. Through this project I wanted to get familiar with Unity so I felt comfortable taking on my own projects. I also wanted to become more comfortable when working in a development team. This is a skill which takes time to adapt to and I was eager to gain as much experience with it as possible.

I learned a lot about working together as a development team. To be more specific, I have become a lot more comfortable using Git. Having experience with fixing Git conflicts is definitely a skill I am glad to have more experience in, especially since these conflicts will occur when working on large projects, regardless of how careful your team is. I also feel more comfortable using the various Git tools, like branching, merging, stash, fetch, etc. Since Git is such a widely used tool within software development I am glad to have become more familiar with it.

If I had a bit more time with the project, I would have liked to make the game play out more smoothly. By adding a start to the game, and some clear end goal, the game would have a better flow to it and make the player feel more comfortable with what it is he or she is expected to do. At its present state, the game places the player in the world and the player just has to look around to figure out how to play the game. We have some NPCs (Non-Player Character) in the starting area who tell the players which buttons to press, and where to find the randomly generated dungeons, but this does not really solidify what the game expects of the player.

Other things like being able to enter buildings, or the ability to buy items from NPCs or stores, or being able to equip items, were things we discussed together and wanted to implement into the game. Sadly these things became stretch goals which we didn’t manage to complete in time. After all, the goal of our project wasn’t to make a complete game, but to work together on a project to get a better understanding of what it was like to work together as a team of developers using tools such as Git and SCRUM. From this, I can safely claim that time and task management is very difficult and hard to predict when working on a project like this.

Throughout this project I learned a lot of interesting things about game development. I think one of the things that sticks out most for me is that setting up the control scheme and logic for the controls of a game is a lot harder than you would originally expect. It is difficult to get controls to feel natural and to respond correctly to what the player is thinking. I wanted to avoid a situation where the player is fighting the controls, rather than the game, but this turned out to be challenging.

I really enjoyed working on this project. Game development is something I have always been interested in and understanding Git and SCRUM are skills which I believe will be very valuable. Over all I am very glad that the project turned out the way it did.

I’m one of the developers of p219, my responsibilities where mostly GUI and dungeon. I’m here to speak about my experience with Unity.

First of all, I worked with Unity on windows. There is a GNU/Linux build, but it’s experimental and still in it’s early days. I didn’t want to take the risk of programming with bugs so I went for the more mature windows port.

For git we used Source Tree. A graphical git client which has been a fantastic tool in helping us both understand git better and get to work. Though we still managed to get conflicts and some problems with git, at some point things clicked and source control became a very natural thing.

Here is what Source Tree looks like.

Now to Unity. I just want to put this out there, but the amount of documentation, tutorials, presentations, live sessions and other resources for understanding Unity better is outstanding. I really want to commend the Unity team for the fantastic work they’ve done in providing the developers all they need in order to learn Unity. The API is also very well documented.

On the other hand the text editor provided by Unity isn’t all that spectacular. I mean it’s functional, it even has a “vi mode” which you definitely shouldn’t use unless your understanding of vi/vim doesn’t exceed hjkl(basic navigation). It’s not awful, I mean it has auto complete and syntax highlighting, but that’s pretty much all of the features it has.

I tried using Visual Studio with Unity. Now that’s a fantastic IDE, but it was too much. The start up times of VS are slow and it’s a resource hog. At some point I tried vim. It’s light and it has the greatest control scheme known to man. However the lack of auto complete killed it for me. During my time with Unity I was very dependent on auto complete scrolling through it in order to find the functions I needed. So in the end I kept at it with the default text editor which isn’t particularly light or good but it’s functional.

Text Editor aside Unity is a really impressive piece of technology. The way you’d go about programming in Unity is through components. Think of it as using small lego bits to make something greater. You create small components and attach them to objects. For instance our main player has scripts and other components in order to define it’s behavior.

Working with this Component based programming was fairly difficult to get used to at the start. I didn’t know the components, I had no idea how to make them behave how I wanted. That was however, part of the learning experience. The more time You spent on Unity the more things felt natural and that hurdle was quickly overcome. Honestly I was a bit surprised the short time it took for me to get accustomed to Unity.

It didn’t take long before you started to manage to get things done, however a lot of what we did at the start was scratched as it was made in a poor manner. For instance the way I had programmed NPC dialog was clunky. I put every moving object under a parent object and everything under that parent object would be locked if the dialog object was in use.

The problem was that I deactivated the NPC object each time It wasn’t in use which sent a null object to every object using it. Another annoyance was that it locked everyone in place, yet the animations was not stopped so every character would be locked yet their animations was active.

I’m fully aware that it was a logic error on my part, however I didn’t know that deactivating an object changes the state of said object to null. That sort of knowledge, knowing the minor issues would have saved me such a long time and such a hassle. However I only had a semester to do this project and as such had to jump straight at production of the game rather than taking some time to learn more about Unity. At the same time I don’t think I’d learn things as fast as I did without having a project of this size and the pressure of the University. You usually work more efficiently when something in the back of your head keeps nagging you about progress.

Unity is a huge tool and throughout this semester from the start till the very end I kept learning things, and I will probably still keep learning things as I don’t think I’ll stop making games with Unity in my free time. Also working with Unity as frustrating as it may be at times, has a certain charm to it. I can not remember how many times I thought to myself “I’ll just fix this bug, it’ll take half an hour” and then ended up spending an entire day in front of the computer working with it. It really helped to that you see the results of your work quite quickly.

If you ask me “What would you do different with your current knowledge of Unity” I’d answer that I’d put much more emphasis in generalizing my components and the way I make things. The preferable way of programming in Unity is to make general components and then reuse them for different objects, making mass production that much easier. It’s much like the “don’t repeat yourself” rule in programming. About Dungeon I’m quite satisfied with how it turned out.Though I’d like to do it in a different way. Perhaps a room based generator to the dungeon would be interesting.

I’m also quite satisfied with GUI as it works as intended and looks pretty good. Honestly it was quite difficult to find decent GUI assets, however we did end up with some decent ones. And the GUI works as intended. However I’d like to know more about the GUI components IO never got to try to use. I mostly used panels, images and buttons.

My conclusion after a semester with Unity is that it was a fun project. I enjoyed working with it. However like all other programming projects it had it’s fair share of frustrations, bugs, and attempts at tracing said bugs. This project taught me a lot about Unity, Git, C# (I never got to use it, but C# actually has lambda functions!), licenses and general teamwork in such a project.

Today I will show you how Fog of war, gamepause, bosses and healing weld is implementet.

First, Fog of war:

We have made a prefab FOW which is a sprite renderer with a black square and a box collider. Next, we create a new prefab, called FOWManager which have a script that takes FOW as input. This script runs though a 2D for-loop and create new gameobjects of the black square.

We have recently added functionality for pausing the game. This is actually very simple. First, I went to “mspaint” and paintet a pause symbol. Then I created a prefab(gameobject with paintet image in a sprite renderer). Next, I created a script in “MoveableCharacters” with these lines:

We have created a healing weld. If the player stands in the weld, it will slowly heal, 1 health per 0.1 second. This is just a sprite renderer (the blue one in the picture above), a polygon collider and a small script which add 1 health to the player if Time.time > time + cooldowntime.

Today, I will write a little post about chests that you can find around in the maps and in the caves. When you open the chest, you will find a health potion that you can take with you and use whenever you want.

First, we need to create the health potion prefab which is a Gameobject with a Sprite Renderer, a Box collider and a script which gives the player an health potion.

Next, we need to create the Chest prefab. To create the Chest, we start with an empty GameObject, and add Sprite Renderer, Box collider and one script. The script takes two sprites, one for un-open and one for open chest which changes after you have opened the chest. The script also takes the health potion prefab which it spawns upon the chest when opened.

To begin creating our player we first start with some very basic logic. We apply a sprite to our player object and add some simple code to make our character move along the x and y axis in the game world. This is done quite simple in Monodevelope (Unity’s C# scripting language) with the call to Input.GetAxisRaw(“Horizontal”) and Input.GetAxisRaw(“Vertical”). This sets up a vector for us which we call “movement vector”.

We want the player game object to play an animation while moving, so that it looks more natural. Since our game is a 2d sprite based game, our walking animation includes 4 sprites for each direction (up, down, left, right). We can set up this animation through Unity’s animator controller, where we just apply the sprites we want in the order they should play in, and set up a transition. This transition is a Boolean (true, false) which we call isWalking. In order to decide whether our player is moving or not, is a simple matter of asking whether or not our “movement vector” (which we set up earlier) is equal to a zero vector or not. If it is not a zero vector, we can set isWalking to true, and the animator will play the animation. In order for the animator to know whether the player is moving up, down, left or right, we also send the x and y directions to the animator controller. If the player is not moving (movement vector is a zero vector) then the animator receives a command tell it that isWalking is now false, and the animator plays an idle animation, which is just a single sprite showing our player standing still, but pointing the direction we last moved in.

The final code looks like this.

So at this point we have a character which can be moved around in our world along the x and y axis, and when the character is moving, the appropriate animations are played. It is worth noting that when using Input.GetAxisRaw(), Unity knows that you are referring to the arrow keys or the WASD keys on a keyboard, or the joysticks of a controller.

Abilities

So we plan on having enemies in our game, which means that our player is going to have to defend itself. We originally planned on introducing four abilities which the player would be able to use, two offensive and two defensive and then expand upon the ability arsenal from there. Each ability has a cooldown, which prevents the player from using the abilities too often. This is an ideal way of balancing the game and making sure our player does not become too powerful.

The first ability we gave our character was a fireball. This is a long range spell which shoots fire in a straight line. This is done rather easily via a script which our player game object has. If we press the fireball button on our keyboard, or gamepad, then a fireball prefab is spawned and is given a direction and force. This moves the fireball across the map depending on the direction the player is facing when he/she pressed the fireball button. The force applied to the fireball game object is applied by a number given to the script from Unity’s inspector. This will dictate how fast the fireball can travel.

If the fireball comes in contact with an enemy or an object in the environment, the fireball game object is destroyed. If the fireball came in contact with an enemy, then it deals damage to that enemy by calling on the enemy stats script and calling the function ‘DoDamage’.

Our next ability is called “Ice Shield”. This is a shield the player can put on themselves which will reduce incoming damage. Much of the code is the same as fireball. At least when we want to spawn the ice shield. We have a script connected to the player game object. If the designated ice shield button is pressed, then we spawn a new game object. The difference from fireball is that we do not apply any force to the ice shield, since we want it to remain on top of the player, and the ice shield has no physical presence in the game, unlike fireball. It presents is only visual. When the ice shield is applied, a boolean value is set to true, which is then sent to the PlayerStats scripts. In the PlayerStats script, if iceShieldOn is set to true, it means the ice shield is active and the TakeDamage script will run a different formula to calculate the amount of damage the player will take if injured.

The third ability is also a defensive ability. It is called teleport. It will teleport the player a short distance in the current direction the player is facing. When activating teleport we spawn the animations in exactly the same way we spawn the ice shield animation, only this time we spawn two versions of it. One where the player was, and one where the player ends up. This animation helps give the player a visual indication of what has happened.

One problem we had to be a bit cautious of was that we can now teleport into walls and other objects in the world. This wasn’t ideal, so we used an inbuilt Unity function called RayCastHit2D. What this does is it creates a vector from one point to another and then it finds the first object it collides with. We can then use RayCastHit2D.point to get the location of the closest object it hit, and then tell our teleport script to teleport the player to that point rather than through it or into it.

Our forth ability is called Nuke. This is an AOE (area of effect) ability, which spawns eight big fireballs around the player and causes damage to all enemies around the player. We decided to have an ability like this because we realised that our player was easily getting swamped by enemies with little means to dispose of them. Some of our enemies are fast moving, which makes them hard to hit with a basic fireball, but if you wait for them to get close then you can easily dispose of them with Nuke.
How this ability works is that when activated, it finds all enemies within a certain area around the player and then adds them to a list. We then go through the list and deal the damage to each enemy.

We also added an ability which we called Haste. This ability adds movement speed to our character for a short time. This is more often used as a sprint button to get around the world quicker but can also be used if running away from scary monsters in dungeons.

Scaling and RPG elements

We are trying to create a RPG (role-playing game) style game, with that there are some expectations that a player would expect from the game. Some of these expectations are that there should be some kind of levelling system, the player should have stats, and these stats should be changed or improved as the player progresses through the game.

So we decided to start off simple and add some basic stats to our character. Our character has health and damage stats. The health stat simply increases the maximum amount of health the player can have, and the damage stats increase the amount of damage each ability the player has can do.

The health stat was quite easy to implement. Based on the level of the player, a formula calculates how much health the player should be allowed to have. Each time the player gains another level, some amount of health is added to the player’s health pool (maximum health).

The damage stat is the one which is a little harder to add and keep track of. Basically each abilities script fetches the player’s damage from the PlayerStats script. With this variable, each ability calculates the amount of damage it should do. Again this variable from the PlayerStats script is based on the current level of the player.

The math behind the health and damage calculations is still something which is not solidly decided yet, as we have to go through balancing the game when more elements are in place and the game is closer to completion. The calculations of these stats will also have to be balanced based on the enemy’s stats, which also are based on the player’s level.

A stretch goal which we have at the moment is to implement randomly generated items which the player can equip. If this is implemented then this will affect how much the health and damage should increase with each level since the items themselves will have health and damage on them.

Now, we need a levelling system in place for our player. This is where the math gets quite scary. Basically we want the player to earn experience for doing things in the world, when something in the world yields experience, it calls the function in the PlayerStats script to increase the experience by X amount. The PlayerStats script has two variables, “needed experience” and “current experience”. “Needed experience” is how much experience the player needs before he or she can gain another level, “current experience” is how much experience the player has currently got. If “current experience” exceeds “needed experience” then the script calls the LevelUp function.

The level up function does a series of tasks. First, it increases the level of the player by one. Then it calls on a function which increases the stats, which does what we talked about earlier with increasing the amount of health and damage the player has. It then sets the current experience to be the excess amount of experience left after exceeded the needed amount. (This is so that no experience is lost, if current experience is set to zero, the player may lose out on some experience).

The function then calculates the needed experience for the next level. This is done via a scary mathematical formula. I would love to say that I came up with this formula all by myself, but the truth is that I used this formula because it is a proven formula used to calculating experience for RPG games based on how much experience is needed for the first level and how much is needed for the maximum level the player can achieve. This formula gives a nice, balanced amount of experience needed for each level between level 1 and the maximum level the player can achieve.

A representation of what the formula will return for each level if the max level is 40, and the experience needed for the first level is 1000 and the experience needed for the last level is 1000000.

The code and formula to calculate these numbers.

With these aspects of the player in place, what is left is to balance the game and make sure that these numbers are appropriate throughout all the levels. This is something that will be done right at the end of the game development when we can play through the game multiple times and make small adjustments until everything feels comfortable, meaning the game is not too hard and it is also not too easy.

That concludes the most important aspects of our player game object in our game.

An ongoing process throughout this project has been to create a world in which our character will explore and exist in. From early stages in development we decided that there will be one large hub filled with a town, various points of interest and treasure. Also, within this hub there will be entrances spread around the map which will teleport our protagonist into randomly generated caverns or dungeons. These entrances are depicted as cave entrances in mountain sides or holes in the ground which our character can climb down. Other types of entrances might be implemented later depending on how the map develops.

So this task was given to me, and ever since we started on this project, I have worked on this every now and then when inspiration strikes. Luckily I am given this freedom on this portion of the project because it isn’t as strongly tied to what everyone else is doing, unlike my other major task, creating our player character. This is due to the fact that everyone has their own test scene. So the majority of the logic based testing and game balance is done in the developers test scene, rather than in the main world where the game will primarily take place.

So how is our world created? I’m glad you asked!

We took some time deciding how this world would be created. Our first attempt at getting started was to use a program called Tiled Map Editor. This is a program designed specifically for making 2D maps for games. To import the maps into Unity we were going to use a plugin called Tiled 2 Unity, which imports maps made in Tiled Map Editor, to Unity. As the name suggests.

At first this method worked great. Tiled Map Editor is an amazing tool and makes map editing very easy and the maps you create look great with minimal effort. Importing to Unity using the plugin was also easy and painless. The problems started when we tried to share our maps with each other over git. When another group member tried viewing the map which was created and imported to Unity and then sent over git, pieces of the map and textures were missing and it just looked terrible. After researching the problem and finding no solution, or solutions which didn’t fix the issue for us. We decided that we may in fact have to use the standard map editing tools in Unity.

The map editing tools in Unity are in fact quite powerful, if you are working with 3D games, which we are not. Unity is known for being quite terrible for working with 2D maps and it feels like all the tools available were implemented by the Unity team as an afterthought. This may be directly linked to the fact that Unity is in fact called “Unity 3D”. But I powered through and eventually got used to using it, and when I got used to it, it wasn’t so painful to work with.

Moving on to how I actually created a map, or world, if you will.

So we first got lots of sprite sheets from the Open Game Art website. These sprite sheets are free for everyone to use, as long as we give the correct recognition. We decided to try and stick to the sprites created for The Liberated Pixel Cup (LPC) since they all had the same art style and worked well together.

Most of the sprite sheets were created so you could slice them up into 32 by 32 pixel squares. Once that was done it was simply a matter of placing the squares which matched next to each other to create what you wanted. If you look at the picture below you can see that it has been cut into squares (32×32 pixels). This sheet is the sheet I used to create some of the paths in our game. The sheet is set up nicely so you have everything you require to make whatever size dirt path or area you wish.

The sprite editor shown above is the Unity tool for cutting up sprite sheets, and is quick and painless to use. The painful part starts when you have to start positioning them and lining them up besides each other. Unity has a pivot for the sprites, as you can see on the picture above, the pivot is set to the center on this sprite. The pivot is used when you want to snap the sprites together (line up the sprites pixel perfect). This makes it much easier to align sprites and make everything pixel perfect. This sounds amazing in theory, but in practice it wasn’t as easy to use. Each individual sprites needs to be given its own pivot position, and even when clicking apply, the pivot position didn’t always apply. A lot of the time I just relied on zooming in really far and manually placing the sprites so they aligned.

When I have created a collection of sprites which depict something, which I hope looks reasonable. I save it as a prefab in our project. A prefab is basically a finished product which we want to use in our game. A good example of a prefab would be a tree. The idea is that, if we have one hundred trees in this world I have want to create, instead of me making one hundred separate trees, with an ordering layer, and its own box collider. I can instead make one tree, save it as a prefab, and then I can basically click and drag it into our world to add it. Every tree of this type will then have its own ordering layer and box collider so I don’t have to set it one hundred times. Instead, just to add some variation, I can change the scale of each tree, so each tree looks independent from each other and creates a more dynamic world.

So coming back to creating a world as a whole. The main idea with the world is to give the player a playground to explore in. We decided early on that our world will have a main town where the player can interact with other non-player controlled characters (NPCs), to learn about the world and perhaps buy and sell items. From the town there would be paths leading north, east, south and west which the player can follow to be guided to various points of interest. Out in the world the player will encounter entrances which will teleport the player into randomly generated dungeons filled to the brim with enemies and wonderful loot (If we have time to implement items). This is where the main gameplay will take place and the player will be forced to fight for their lives.

As of right now while I’m writing this, our world has a basic layout. There is a town in the middle, a mountainous area off to the west, a river and lake down to the south and a farm area to east. And of course there is The Dark Forest to the north, which I have named such for ominous and adventurous reasons. We still haven’t decided on any name for the world yet, but I’m almost positive that we will come up with something colourful and original like Wondershire, or Fantopia.

Before I am happy with the world I am creating I still have a bit more work to do. I want to have more dungeon entrances spread all around the map. I would also like to fill the map up enough so that you never have your character in a screen which only shows grass. As this gives you little sense of where you are on the map and is just plain boring to look at. I also need to enclose the map so our player doesn’t just wonder off into the abyss that is a world with no textures.

Otherwise the world creation is an ongoing process which can always be worked and improved upon, as well as just generally adding more things to it. Atleast until the final build of the project.