Game Design, Programming

Week 7: Scrap Pirates, one week left before GGC!

Hello! Week 7 has just passed and Gotland Game Conference is in just one week. A couple of weeks back we decided to cut back on a couple of features like upgrade system, some enemies, multiple levels, among other things, and I feel like that was a good decision because otherwise we would be up to our necks in half-done things and nothing would probably feel finished for GGC.

As I mentioned the last time I had one bigger problem to try and solve, it was the parallaxing windows into other rooms. After a lot of testing with placeholder graphics and a lot of discussions we have decided to put those parallexes on hold until after GGC because of two reasons: first, the graphical artists are already up to their necks with stuff to get done before the conference, and secondly because it does not feel good with our placeholder graphics. I think that the programming part of the parallexes is done, only variable changes so they scroll the right speed, but it is hard to test without the right textures to test with. Anyway, as I said, we have put those windows on ice and will just keep us to scrolling space parallexes instead.

So, what do I have left to do this week? I will need to make a couple of different TriggerZones for different actions. One of them will be that when a player enters it, it will light the lamps in the room and remove the shadowsprite over time. Another zone will be that when both players have entered it, it will close the doors behind. I do not foresee any difficulty in making those two scripts. I will also implement a highscore list so that those that come and test our game at GGC can compete with each other trying to get as high as possible. I have not done a save system before, but I do not think it will be so hard, should be plenty of guides out there.

Other than that, I only think it is bug-fixes and polishing left for my part.

I hope I will see you guys at GGC this year! (Free entrance for the public on Monday and Tuesday!)

Standard
Game Design, Programming

Scrap Pirates – Ranting about Physics

I think it is time for a status update on what I am working on.

 

I have had two bigger problems thus far in this project. The first one is about our physic. It was apparent early that Unity’s own 2D physic did not work so well for us. Because of how we want the magnetism to work and that things in the environment should be able to knock you around a bit, we could not just set the players and the objects velocity directly. So instead we tried to add a force instead, but the problem with that approach was that it felt that the player was gliding around on ice; it took a while before the character came to a stop. Neither of those approaches seemed to work so well for us.

I tried to change the physics material on the players and on the ground, changing its friction to try and work it out. If I had low friction the “ice-skating” was horrible. If I turned it up it felt sluggish to get momentum, it took too long before the character got up to its maximum speed.

When I could not get it to work with the Unity’s own physics I decided to try to write my own simple physics. After some trial and error I thought I had gotten in as we wanted it. There was almost no more sluggishness or slipping around.

Now, the only problem was the boxes the players could throw around were behaving very strange if thrown into the air. They lost all their momentum on the x-axis after just half a second even if it took it more than a second to get back to the ground. This meant that if anyone threw a box in a 45 degrees angle it would, almost instantaneous move to a much steeper angle and going almost straight up before losing y-axis momentum and coming straight down again.

To do this I made a couple of exceptions in the physics. Instead of treating everything the same, no matter what was happening I changed so that if something did not touch anything else, it would not lose any x-momentum. This gave the box-throwing a much nicer arc while still making sure that they came to a quick stop when they touch ground.

Another exception I had to do, in response to the exception above was to only apply that exception on the object if it was not a player. Otherwise the player would have a hard time controlling its character in air, and that would make it very frustrating for the player because we want the player to have much control while in the air.


 

Alpha version of Scrap Pirates, some placeholders still there, most notably the doors and the healthbars

Alpha version of Scrap Pirates. Some placeholders still there, most notably the doors and the healthbars

 


The second big problem I have had is something else entirely. It has to do with “parallaxing” the content of windows on the ship. It is very frustrating and hopefully I will find a solution soon, or else we will have to go with something easier.

The window problem has to do with that we want to give a depth to a room seen through one of the ships indoor windows by having multiple parallaxes. For example: We want a window where the back wall is slowly scrolling, then a couple of pipes scrolling in another speed and yet another layer with more pipes or something else, everything scrolling when the camera moves and at different speeds. I have tried to only scroll the Texture and not having to use multiple Quads, but so far I have not been able to make it look good. Hopefully I will come up with a solution soon; otherwise we will have to rethink if we can do it without having multiple layers of parallaxes.

 

Bye. It is back to work for me now.

Standard
Programming

Game Programming 3 week 1

So, a new course has begun. Game Programming 3. This course focuses on 3D programming, with some networking too. This first week was about templates, linked lists and binary search trees.

Templates were something I had not worked with before and I must say that I start to like them. Instead of having to create a new function for each of type of parameters (int, float, double, etc) it should be able to take, I could just make a template function. The compiler takes care of the rest, creating multiple functions from that one template. The drawback with this is that the time it takes to compile the code can increase drastically.

We also got an assignment in three parts to do before this course is over. Part one is to create a linked list and a binary search tree. Part two is to create a web server using bsd sockets Application Protocol Interface (API) and Transmission Control Protocol (TCP). Finally, we are to create a 3D game. Part one and two are individual work while part three is to be done either alone or in a small group of up to three persons.

So, this week I have begun on the first part. The linked list is done and the work with the binary search tree is about halfway done and I will finish it this weekend.

How does the linked list work, or rather, a double linked list? It consists of nodes. Each node holds data together with two pointers, one pointing to the next node in the list, and the other pointing to the previous one. This means that if one node would be lost, the list after that node would also be lost. It also means that the list can grow and shrink without moving the entire list. All that is needed to insert a node in the middle is to redirect the next pointer of the one before, and the previous pointer of the next one. Instead of them pointing at each other they will instead point to the new node and the new nodes pointers pointing at the old ones. So, the only thing the list has to know is where the list begins and from there it can access the other nodes by going through nodes, one by one.

The binary search tree is similar to a linked list with nodes and pointers. The difference is that instead of one pointer to the next node, it has two, one pointing to a higher value node and the other pointing to a lower value node. So, to find the node you are searching for you start at the beginning of the tree, the node that was added first. You check to see if it is the value you are looking for. If it is the right one, you are done with the search and you now know that it exists. If it was not the right one, you check to see if the value you are searching for it higher or lower than that node and follow the right pointer to the next node where you repeat the same process until you find the node you are searching for, or ends up at a null pointer, a pointer that does not points to another node. In that case you know that the value you are searching for does not exist in this tree.

Next week we will start with network programming and the second part of the assignment.

Standard
Game Design, Programming

Nemesis – Level Generating

So, I have been doing some initial work on my dungeon generation this week. It is not quite as I want it yet, but it is getting there.

As it is now, it tries to spawning a random number of rooms between 20 and 39. The world is 100 times 100 tiles and each room is between 5×5 and 9×9. Each room gets 10 tries to find a suitable. A suitable spot is somewhere where it will not put any of its floor-tiles on a wall- or floor-tile of another room. When the room is placed its coordinates and size is saved and stuffed into a container where all the rooms are saved.

When all rooms have been spawned it is time to connect them with corridors. I pick the first room and say that it is connected. Then, while there are still rooms not connected, I loop through them and create corridors between them. As it is now it is a very crude way to connect the rooms with corridors, as you see on the image below.

RoomLayout1

 

What I want to do is to prioritize shorter corridors. By that I mean instead of just picking two random rooms I want to first pick a connected room and then look for one of the three closest to that room that is not connected and make a corridor between them instead. That way the corridors will be shorter and lower the possibility for corridors that are three to four tiles wide.

Next week I will start with the player, making him able to walk and attack. I will also work on creating enemies, for the player to attack.

Standard
Game Design, Programming

Summer Project – Nemesis

It was a long time since I wrote here last time. A bit over 2 month I think it was, but I will try to remedy that during summer. I should be able to do at least one blog update per week.

During the coming 8 weeks I will be working on a new project which I have named Nemesis. The title is not set in stone, so if I come up with a better one, it will probably change.

The game I will make this time is a 2D top-down survival game where you play as a lone survivor after a world war that weakened the barrier between dimensions. You have to survive against the monster onslaught for as long as you can, scavenging resources to upgrade your equipment.

I will write the code in C++ and use the SFML-library for sound, graphics and input.

Standard
Game Design, Programming

Sixth Artifact: Level-changing

I have been working hard on bug fixing everything this week. A lot of progress has been made. For example, the guards no longer plays lighthouse when the player is nearby, was a minus instead of a plus when calculating the distance that was the reason for that. Anyway, let’s get to this week’s artifact.

So, we are going to have four levels in our game, and we do not want to load all four at the same time. I have not coded this part yet, but I have been thinking about it a lot the last couple of days.

We need a way to change from one level to another, but how are we going to do that? I got two ideas: one using if/else and the other using different states.

First, the idea about using different states. The way it is supposed to work is that depending on which level the player is on, different “level states” are loaded. So, a lot of code had to be copied from the game state into the different level states. This was the first way I came up with. At first it sounded like a good way to do it, but the more I think about it, the more I think that another way is better. Not so good on copying code, because if I have to change it later, I have to change in everyone.

The other way to do it would be to have a variable that says which level to load. Then in the Enter function in GameState, we look which level to load and set the path to the folder where the level information lies.

As I said, the more I think about it, the more I think the second way is the better. What I need to do to make it work is putting everything common to all levels in one folder. That would be all pictures, except the level background (which is specific for each level), animation text files, sounds, music and probably something more I have forgotten now.

Each level has its own folder which contains the information about walls, furniture’s, guards, starting position, etc.

Then, when the player has finished the level, we change the variable that indicates which level to load and manually call Exit() and then Enter(). So, instead of creating a new function where every wall, furniture and guard is deleted and then re-initialized for the new level, we use the two functions we already have for the state manager and seem to work as intended anyway.

The picture is a room on our second level.

Level2Picture

Standard
Game Design, Programming

Fifth Artifact (maybe not really an Artifact): Get it ready for beta presentation

The last week I have gone through the code, implementing and bug fixing the last things that needs to be done before we are ready for our beta presentation.

So, what needed to be done the last week? Well, a lot of things. The weeks between alpha and beta we have been working hard on getting things done. Pathfinding, furnitures, collision with things, guards AI, etc.

We had a play testing session the last Monday, and early Sunday we did not have a working game… Most things were not implemented. We did not have working furniture’s, guard pathfinding, lose or win condition, sound or music, doors, the right level (we still had the alpha map).

So, because I knew I would not have the time to make all of those things work, I had to prioritize what to do first.

I started out working on the guards AI, they did not behave as I wanted them to. They were seeing and walking through walls, some times. Some of them are standing in front, or even inside walls (see picture), I think that there is something wrong with their spawn positions and/or their waypoints for patrol.
I fixed most of the problems, but some rather huge are still there. They are kind of hard to pinpoint because they happen so rarely.

StupidGuards

I really dislike pathfinding at the moment. I could not find out what was wrong with my A star code, it did not prioritize nodes closer to the goal, but expanded equally in all directions. This made the pathfinding very inefficient and the game was lagging really badly during the play testing. But yesterday, when I sat with it, I realized that I had made the cost to move between squares 10, but the distance to the goal only weigh 1 for each square. After I had fixed this small miss step the code is about infinitely faster if it has to find a path to a target somewhat far away. Before it could freeze for a couple of seconds, but now, it is not even noticeable. I am so happy about that.

Monday morning I was hoping for some help with implanting the furniture’s, doors and those things that were ready for implementation. But because I had not worked with the manager’s for those, it till most of the morning. I got, kind of, done about 10 minutes before the play testing, but they had no collision detection yet. That part I did not have time for.

The problem with the sound and music was that I had moved them from their original folder to another, but forgot to change the path. So that was fixed really fast. I am glad that we didn’t get the footstep sound to work before the play test, because they are REALLY annoying to listen to. It sounded a bit like sitting and hitting two coconuts against each other. So, either we have to find another sound, or just scrap the idea of hearing the characters footsteps while running.

Tomorrow is Beta presentation, and I think I got everything that is essential for it done.

Standard
Game Design, Programming

This week’s artifact: Sprite Manager and a quick look at Animated Sprites

Even though it was long time ago they were made (like 5 weeks), I think it is time to talk some about them.

Both the guards and the player have a lot of different animations.
For example, the player has:

  • Sneak
  • Run
  • Idle
  • Dying
  • Attack
  • Strafing
  • Walking

And the guards have:

  • Draw weapon
  • WalkGuard1Walking
  • Run
  • Idle
  • Smoke
  • FallingGuard1KnockedOut
  • Rising
  • Guard1RisingShooting

And instead of asking the Sprite Manager for a new animation each time it needs to change it, each Animated Sprite holds pointers to each animation instead. So, all that is needed to change from one animation to any other is to tell the Animated Sprite which to switch to and it will search through all its animations and change the current animation to the new one.

 

The Sprite Manager is managing the textures, so maybe I should have named it Texture Manager instead. I think that would have been a more accurate description of what its main purpose does.

Its primary function is to make sure that the same texture is not loaded twice. When it is asked for an animation or sprite, it looks through all the previously loaded textures. If it finds another texture loaded from the same image-file, it will return a pointer to that texture. If it is not found, it will load the new texture and return a pointer to that new texture.

When the game changes state, it will release all the memory of the textures, so that it doesn’t hold them when they are not needed.

 

When an entity asks for an Animated Sprite, the Sprite Manager needs to know which text-file to look for. In this text-tile, all the necessary data for all that entities animations are stored. Like which picture to load, each frames duration, at which coordinates each frame starts, and its width and height.

The text is which image it should load. The first number is that frames duration. Second and third are x- and y-coordinate of the upper left of that frame. Fourth and fifth are width and height for that frame.

It would look something like this in the text file:

Guard1Running.png
0.1 0 0 96 96
0.1 96 0 96 96
0.1 192 0 96 96
0.1 288 0 96 96

Guard1Shooting.png
0.2 0 0 96 96
0.2 96 0 96 96
0.2 192 0 96 96
0.2 288 0 96 96

Guard1Searching.png
0.2 0 0 96 96
0.2 96 0 96 96
0.2 192 0 96 96
0.2 288 0 96 96

The Sprite Manager is then using this information to create an Animated Sprite. When it has come to the end of the text file it will return a pointer to the Animated Sprite it just created.

By doing it this way it is easy to add new animations to, for example, the guards. All that is needed is a new sprite sheet with the frames, and then add the information for that animation at the end of the text file. Then, that guard just have to call the function ChangeAnimation(std::string animationName), that is part of Animated Sprite, to start using the new animation.

Standard
Game Design, Programming

Third Artifact: Pathfinding and Grid building

This week I will talk a bit about our pathfinding. (Warning: Confusing)

There are a couple of different pathfinding algorithms out there, on the internet. There are Breath-first, Best-first, Dijkstra, A*(A-star), etc. Almost everyone, on different forums, suggest A* as pathfinding algorithm for most games. It is reasonable fast in most instances, even though some of the others were quicker in some scenarios.
A*, like most other algorithms, needs a tile based system to search through.
Each Tile, or Cell, is given three values: F, G and H.

  • G is the cost to move from the starting Cell to this cell.
  • H is the guessed cost to move from this Cell to the goal, as if there was no collision in between.
  • F is the sum of G and H. (G + H), the approximated cost to move from start to finish through that cell.

Each cell also holds a pointer that points to its “parent”, which is the cell that put the active cell on the open list.

It uses three lists to store cells in: Open, Closed and Final.

  • In Closed all the checked cells are stored, so we don’t check the same cell more than once.
  • In Open all the cells still to check are stored.
  • In Final we store the final path, when we have found our goal. We get the path by backtracking from the goal and go through all the “parent” cells until we are at the first cell.

Each iteration of the algorithm takes the cell with the lowest F-value in the Open list, and puts it on the Closed list. Then it checks all the surrounding cells that is not already on the Closed list and gives them values. It one of the cells is already on the Open list, it checks if the new F-value is smaller than the last. If it is, it changes the parent of that cell so it points to the new, cheaper, parent.

When the goal cell is finally found in the Open list, we backtrack from there. Going from parent to parent, storing each cell and when we are back at the start cell we have the shortest path.

The picture shows an example of A*. The Green tile is Start, Red is Goal, Gray are walls, Blue is on Closed list, Green on Open list and the yellow line shows the path we got at the end.

 

AstarSearch

Unlike the other Escape-concept groups, we chose not to have tile based. The reason for this is that we felt that tiles are too limiting when it comes to placement of walls and furniture’s. We wished to have more freedom, to rotate and place assets “however” we wanted, to give each room a unique feel.

Because of this I had to simulate a grid to use A*, otherwise, each pixel had to represent the tiles, and that would be too many squares to search through. The grid is stored in:

  • std::vector<std::vector<bool>>

Which is vectors in vector. The outer vector is the tiles Y-position and the inner its X-position.

Instead I divided the map into equal sized squares and checked each square for collision. If collision was detected I put its bool-value to false, otherwise true.

Then, to see if the grid worked I drew the grid on top of the level ingame, and each walkable tile was colored red and the unwalkable teal.

As the picture shows, it looks like it is working.

GridPathfinding

I hope I made myself clear, but I’m afraid that would be really wishful thinking…

Standard
Game Design, Programming

Second Artifact – Level Editor (kind of)

 

Another week, another Artifact. This time it will not be from the game itself, but a tool to make it easier to create the level.

 

So, I have been working on a Level Editor for our game, With Intent. The reason for having it is so that it will be easier and faster to build the level with all the walls, furniture’s, doors, guards and their waypoints, start- and end-positions. Without an editor we would probably have to input all those coordinates, degrees, etc., manually, in a text file.

 

I chose to create the editor in C# as a Window Application Form. It was an easy transition from C++ to C#, it took a couple of hours to get the hang of, but after that I have had no bigger issues with it. It has been fun to learn a “new” language, even if it is like a blend of C++ and Java, two languages I have worked a bit in.

 

All positions, numbers and degrees are saved in a lot of different Lists<>. Those lists work a lot like Vector<> from C++, except that it seems like you have to “new” them to use them, at least I couldn’t find any way to work around that. And now that I’m writing this I’m realizing that I have not “deleted” a single one. I really hope that it is done by automatic in C#, like in Java, and not like C++. Otherwise it would be kind of embarrassing to forget something like that…

 

Robin found out what was up with our bugged walls, those that could be seen through if the player got to close to them. It had to do with X being much larger then Y, or vice versa. So I did so the editor, when it saves to the files, “cut” the walls in smaller squares then very long rectangles. I thought this part wouldn’t be that hard but I had a hard time concentrating on the task so it took more than the three hours I had predicted. I’m up to six hours now and is still counting.

 

The first thing to do after the editor have been loaded is to load an image. This image will be the mold to see where everything should be. The next thing to choose is what to place, walls, guards etc. Some things, like the guards and tables, will also need a degree to say in which direction it will be facing when it is created.

 

When the Save button is pressed it will save everything in text files, that can then be read by the game to create the objects in game. The picture shows a small part of the code that saves all Lists in text files.

SaveButton_code_part

Standard