Week 3 Naar Big Game Project

the third week of the project was going as planned, almost. What I did was to add the spells for the boss to the spell UML. This UML is now more of list of spells loosely indicating how they can be connected rather than an absolute and definite spell setup. This is because of a newly acquired feature of the UE4. A spell system. This system is dedicated to make custom spells within the engine and can make almost all the spells required in the game. This meant that it would be more efficient to use this system and possibly add just a few completely custom made spells. I did not like this system because I could not overlook its features in a satisfactory manner because I am not yet familiar with the engine and there was no good documentation included in the pack.

So that is one thing I have started doing, playing around with the spell system so that we can implement spells asap. I am specifically doing a spell called fireflies. It is a non attack spell that can be combined to an attack spell. it is supposed to float at a position near the player character and throw some particles around lighting up the surroundings. We decided to make an object with particles that have a collision box, and then use the system to cast this object to a certain offset from the player. This way we can target it and shoot fire at it for it to become a different spell..

I also fixed the blend space animations with new animations. And I implemented new jump animations.. There are a few problems with the jump animations.. I think I will need new animations from the artists, same as the last animations because there are glitches in the transitions between the animations and they are not grounded. Hope this will be solved by newly plotted animations.

I have also begun work on the PM. the synopsis hand in.

A list of what is implemented now. One shooting spell for mokhtar. the animations: idle walk run and jump. one attack animation. the lock on target system is functional, a way of reading input for the gesture spells.

AI for the first enemy. he can see mokhtar, hear sounds and attack with a spell. the sound trigger their attacking mechanism. This week we’ll be struggling with the spells and damage control if there is time and by the end of the week, if there are spells and if an enemy can be defeated we will have made our own deadline and we’ll be good for the official alpha deadline the following week. Things are going pretty much according to plan.

Advertisements

Big Game Project

I am in week 2 of the production of our game Naar. It is a roleplaying game set in an oriental fantasy world. You play as Mokhtar, a djinn who set out to defeat an evil demon Iblis. The main feature of the game is spell casting and combining spells to create new spells. In this production I took on the role as lead programmer, which means I have to overlook the programming, plan code structure and if necessary, delegate tasks. I do a little programming as well as much as I can.

The first week was all about playing around with the game engine, Unreal Engine 4.  That week I set up an animation state machine using the visual scripting feature of UE4 called blueprint, a repository on bitbucket using Source Tree which is a version control software used to merge versions of a project to allow everybody in the group to make changes in the same project from their own computers and an animation state machine.

The animation state machine contains four different states: Idle_walk_run, jump_start, jump_loop and jump_end. In Idle_walk_run I use something called blend state which is a method of merging together different animations so that there is such a smooth transition between animations as possible. In this case the animations are: idle, where Mokhtar stands still and breathes. Walk, where he is walking and Run, where he rolls around and dies. No he runs of course.

The three different jumping states is a way to make jumping or falling animations easy to deal with. For example, if there were only one jump animation in which the avatar jumps, lingers in the air for a while and lands, this animation would loop all the way down to the ground, jumping and landing while still falling if you would jump of a cliff. If you cut these into sections, the character starts to jump and when this animation is almost done, the jump_loop state executes and a section of the jump while the character is in the air loops until they reach the ground. On the ground the last state Jump_end executes and the landing animation plays. Then the last transition occurs back to the idle_walk_run state again.

This week I have been doing a UML-Diagram for the spell-hierarchy. I thought that since UE4 is made in the language C++, an object oriented approach would fit in naturally plus this way of thinking code is what I am used to, as opposed to data oriented – or component oriented design which is unfamiliar to me as of yet. The difference between data oriented approaches and object oriented design is that with data oriented design, the actual data handling is considered first hand to optimize efficiency for example, while object orientation sorts classes based on common features, for example a rocking chair is a chair, the chair has a seat, some way to rest your back and four legs. A rocking chair could be thought of to inherit these features from a chair because it has those qualities in common. What separates a rocking chair from a chair are the rounded things attached to its legs. But it is still a chair.

I have also made a prototype shooting animation that can play from every animation state and is handled by controller input events using blueprint. when you press the X-button on an xbox 360 controller the light spell casting animation will play. No additional functionality is implemented yet. I have also created a Behavior Tree for the first enemy. It is very simple. The enemy is only supposed to walk around following a set of targets until Mokhtar comes into a certain distance of it, then it attacks him. When it attacks it sends an event message that can be picked up by surrounding enemies, reveling Mokhtar’s position and the other enemies would start attacking as well.

Last but certainly not least, the first version of the boss’s behavior tree is also done. The boss will move toward different positions where he will lift rocks using a gravity spell and then throw them at Mokhtar. if mokhtar is close he will be pushed away. He can be rendered unconscious by getting hit by one of those rocks if Mokhtar uses his spells to throw them back at the boss. In that case he will let out a cloud of gas which can be ignited by a fire spell. The following explosion damages the boss and sets him into the next stage where he will start using more aggressive spells. There are three stages before he is defeated, each will add aggressive behavior to his behavior.

Here are links to pictures of work I have done until now:

Mokhtar’s spells:
Mokhtar's spells photo SpellsMokhtar_zpsusjzghq2.png

animation state machine:
Animation FSM photo AnimationFSM_zpssrpfxbqe.png

Boss BT:
Boss behavior photo QadherDesignDoc_zpstlqmhf9l.png

enemy BT:
Enemy behavior photo EnemyBTDesignDoc_zpsgatdgk6s.png

Assignment part one, part two

Binary Search Tree

I’m doing the rest of part one of the assignment today, the binary search tree.

In my recent post I explained my linked list and what a binary search tree is. I’ll just link the wikipedia link to a binary search tree here if you want to read about them before I explain how I made mine.Binary Search Tree

It is a template class with T as the template type meaning basically that T is any type that has been defined by the user, such as an int or a float.

I will try to make my blogs easier to overlook so I am now listing my functions and explain them, but first a link to the code! CODE. the comments are strange in paste bin’s text formatting.

  • void insert()
  • Node* search()
  • void erase()
  • void removeLeaf()
  • void RemoveWithOneChild()
  • void RemoveWithTwoChildren()
  • int size()
  • void Traversal_pre_order()
  • void Traversal_post_order()
  • void Traversal_in_order()
  • void delete_post_order()

 void insert(T data)

This function first looks to see if the root node is empty and allocates a new node and set root to point to it. If not it looks whether the new node’s data is larger or lesser than the root’s data. If it is larger it checks if the node the right link points exists, and if the data is lesser than the root it checks the left link. The same thing is done for every node that is already in the tree until it encounters a nullptr link. Then that link is set to point to the new node.

Node* search(T data)

This node searches the nodes in the tree in the same manner, look to the right link if the data from the parameter is larger than the current node and to the left if the data is lesser. If the data is equal then it returns a pointer to that node. If it is not found it returns nullptr. This is because when you want to erase a node, you can reach that node directly via a pointer to it. Plus should the nodes in the tree hold many different types of data, all of the different data types can be accessed via this pointer.

void erase(T data)

Erases a node based on its data. This is probably the most complicated function because depending on where in the tree the node is located, different methods must be used to maintain the structure of the tree.

Let’s start with the simplest case: the node to be erased is a leaf node, meaning it has no nodes after it. This one can simply be erased. The only thing that has to be considered is that the link that used to point to this node must be set to nullptr, or else there can be errors if some other function tries to access data on this freed memory location.

The second case is if the node to be erased has one child. In this case, the parent of the node to be erased is linked to this child instead, and then the node can be safely deleted. If this node had its own children, they will be maintained linked in the tree, because its own links will still point to the same memory locations.

The third case is if the node to be erased has two children. What the function in this program does here is that it replaces the node’s to be erased data with the closest value data in one of the node’s children or ‘grand children’.

This is done by either choosing the left most grand child of the node’s to be erased right child. Or symmetrically, the right most grand child of the node’s to be erased left child. This function goes to the right and then to the left most node. When the data values are swapped, the node furthest down can be erased.

erase1and2child

This figure is how a node with two children can be deleted (left) and how a node with one child can be deleted (right)

The function accomplishes this by making use of the separate functions :RemoveLeaf(Node* previous, Node* eraser), RemoveWithOneChild(Node* previous, Node* eraser) and RemoveWithTwoCHildren(Node* previous, Node* eraser). (in one of these function there is a redundant parameter T data that I simply forgot to remove.) These are the functions that take care of these operations, and the erase function checks the conditions to determine which of the functions to call and calls them.

int size()

Simply returns a member int m_size which is pre – incremented and pre – decremented when a new node is added and removed.

void Traversal_pre_order(Node* node)

This function traverse the tree in a specific order. The order, at least in my function is like this: start by the root, print its value and then recursively call the function again with the left link and print every one until reaching a nullptr node. This exits the current function call and continue where the last function call ended, namely the previous node. There another recursive call but with its right link and print every one of those until nullptr.

In other words, print every node to the left and then every node to the right of the previously printed nodes.

void Traversal_post_order(Node* node)

This one works the same way only the printing of data is the last thing that happens in the function. This way all nodes to the left are traversed until nullptr and then the left nodes of the right nodes, and when all the nodes have been traversed, they are printed in reverse order.

void Traversal_in_order(Node* node)

In this function the printing takes place in between the recursive calls. This walks to the smallest data value (farthest down left), print its data when the left child is nullptr, then checks any right child, and goes down as far left as it can. The result is this prints all values from smallest to largest in order.

void Delete_post_order(Node* node)

Finally, I wanted to clear all the nodes in the tree and I noticed that the root was traversed last, or at least printed last in the traversal post order algorithm. That means that this is perfect for deleting the nodes, because then all the nodes would be deleted in an order that deleted the root last.

I don’t know if this works for all cases, unfortunately. Say the tree had been dealt with in a manner that the root only had, say right children. But I believe that it would still work because it would still traverse all the right nodes’ left children and delete in reverse order or symmetrically the left side. So I think that my idea is general for this purpose.

Summary – Binary Search Tree

So that was pretty much the what and how I did it and in some cases why. I can try to explain why I did the erase functions (except the delete post traversal) iterative and the traversal functions  recursive. The erase functions became iterative because that was how I looked upon the problem from lectures and the notes I made while thinking about these problems. I drew a lot of boxes with diagonal right and left links and arrows here and there to try to figure out how I would go about doing it. This way of looking at the problem was very iterative and that reflected in how I coded it.

The traversal functions was recursive quite simply because I saw a class mate do her functions like that. I had no idea how I was going to make them before I saw her functions and I must say, I really enjoy how recursive functions work in general, not only in programming, but also mathematics such as fractal geometry, where the whole picture can be described by many elements identical, or similar to the whole and vice versa, or to give another concrete and simpler example: N! (factorial). The product of N! can be described like this; N! = Nx(N-1!). If you look at this you can realize that you call the same function N!, but with a smaller version of the original: N-1. This is done until the stopping condition 0!, which is defined to be = 1.

A numerical example N = 5:

5! = 5 x (4!) = 120 which is the same as doing this:

5! = 5 x 4 x 3!  = 5 x 4 x 3 x 2! = 5 x 4 x 3 x 2 x 1! = 5 x 4 x 3 x 2 x 1 = 120.

So I went over the traversal functions until I understood them, which made me feel ok about using them. These could be translated into an iterative process as well but the code would be both longer and more difficult to read. I think that a while – loop with two pointers, one to iterate and one to take the place of its parent, much like I have done in the iterative functions, and a few if-statements and a print at the correct placement would do the trick as well. Perhaps a few loops after one another because you would need the ‘grand parents’ all the way back to the root at least in the post order traversal.

Hope it was of some use.

For assignment part two we will create a web server in C. This will be tricky since I have no experience in this before.

Game Programming III

I have just taken a new course, Game Programming III.

There is one major assignment which is divided into three steps. The first part is to construct the most common data structures used in programming, a linked list and a binary search tree. Both are used to store data. The linked list is a list of objects containing data, called nodes. The nodes are linked to each other forming a kind of chain of nodes. The binary search tree is similar, but instead of one potentially long chain of nodes, it branches from one original node into two directions. The following objects can also themselves branch into two sub chains of nodes.

This post is about this part of the assignment. The other parts will be blogged about later, as I do them.

What I’ve done is a doubly linked list. As opposed to a single linked list that links the data nodes from head to its end, my list are linked from head to tail and from tail to head. This is a little more efficient than the single linked lists because if you’d want to place something in the back of the list, you don’t need to follow the whole list from head to tail to place it there. With the doubly linked list you can simply place it at its tail directly.

I have also created functions to add nodes at the front or at the back and to delete nodes from the front or the back. A function to search the list for specific data, another to erase a node at a specific index and a function to see how many nodes it contains.

To add a new node at the front, I instantiate a new node and allocate it to the heap memory and set its data member to the desired value. Then I point its link going in the direction towards the tail to the node which the head is currently pointing to. Since this new node is to be added to the front, its other link is set to point to null. This is to mark the end, or beginning depending on what direction you start from, when iterating through the list. Then the head is set to point to this node instead.To add a node to the back, the exact same thing is done only instead of the head pointer I use the tail pointer and link the new node in the opposite direction.

To delete the front node, a temporary pointer is instantiated and set to point to the node currently pointed to by the head pointer. Then the head pointer is set to point to the following node and the node now currently pointed to by the temporary pointer is now deleted. Again, same procedure when deleting the back node.

To search the list, I take a value to be looked for and create a temporary pointer and set it to point to the head node. Then I let it follow the links until I find a nullptr link, indicating the end of the list. Every loop I evaluate if the nodes data is equal to the target value and return the pointer to that node. If I can’t find the value I return nullptr. I return a pointer because there could be other data to be accessed from the node, should the node hold other data than a number.

The erase function was a little trickier. If you only iterate through the list the number of times equal to the given index number to erase, you would loose the rest of the list and perhaps be unable to recover it. Another problem was if there only was one or two nodes there. I use no less than three different node pointers, so one would definitely be invalid  in these cases. How I did was this:

First I check if head is nullptr, which means that the list is empty and tail is also nullptr. In that case I print a string informing that the list is empty.Then I check if size() (the function count the nodes and return the value) is lesser than index and return an out of range message. Then I check to see if head == tail, meaning there is only one node in the list. Then I chose to call pop_front(), but pop_back() would have worked as well. After that I check to see if size() == 2 and index <= 1, meaning if there are two nodes in the list and index is 0 or 1, I use pop_back() if index is one, and pop_front() if index is zero. Then the rest of the cases have at least three nodes, required for the following operation. I iterate trough the nodes and each loop I check if a counter is one less than the index, equal to the index or one more than index. When I find them, I set the temporary pointers: before, delete and after respectively to the current node being pointed to in the loop. Then I bypass the designated node to be deleted by assigning before’s and after’s corresponding links to the delete node’s links and delete that node.

singleVsDoubly

figure 1 illustrates a singly linked list and a doubly list

For those interested in the code, here: http://pastebin.com/UsW7hse9

the comments look a little weird, but never mind that.

The next thing to do is the binary search tree. I will have to update on that later. It’s sunday night, I can’t finish it today.

Post 2 – Gears of War

GoW2
This time it’s the Gears of War board game. First of all it is a real time shooter on a board game which itself is difficult to even imagine how it would work, at least it was for me.

It is a cooperative game best suitable for four players. You play as one of the characters from the video game Gears of War and you help each other win the levels by planning strategies and/or reviving players that are wounded.

The board is a sort of jig saw puzzle with each piece consisting of rooms that can be placed so that they form different levels to go with different missions.

Every player have six action cards that both determine what they can do during their turn and these cards also serve as their health. Each turn, the player can choose any of these cards to use as their action. The card is then discarded. When the action is done, which could be either move, attack or both, that player draws an AI card. These cards determines what the enemies do such as moving and/or attacking. The next turn the players start their new turn by drawing up to two action/health cards. They can have a maximum of six cards in their hand. When getting hurt by an enemy the player discards the same amount of action cards as the attack points generated by the battle.

Example: Player A is attacked by an enemy. The outcome is then determined by rolling attack dice and defense dice. The amount of dice rolled are determined by the character cards of both the player and the enemy. One defense point cancels one attack point. The excess (if any) of attack points is the damage dealt to the defending party, in this example player A.

At certain places on the board you can pick up items, such as grenades or weapons. Enemies can also drop items when they are killed, they have special markers for when they are dead that either contain items or not. If a player is within the tile where the item is located they can pick it up.

You win the game by completing the mission and lose the game if all players are dead.

For player and enemy representation there are very detailed plastic figures of the characters and enemies in the game. The player figures are red and the enemies are grey. This means you could paint them yourself if you want, like in the Warhammer game series.

The best side of the game

Gears of War is a real time third person shooter game and I did not know how that would play in a board game context. It does how ever really feel like an action packed shooter game because of the AI cards. After each player action these cards are drawn, which means that the enemies move toward you and try to attack you all the time. It does feel like the enemies are constantly moving. The AI cards can also make more enemies spawn from their little spawning holes located around the board, unless you have managed to seal the holes with a grenade. You do not have to play many rounds until you feel swarmed by enemies and this creates a lot of tension. This feature of the game make you feel very powerful if you, for example, trow a grenade into a room and kill four or five enemies in one blow. That creates tension relief as well, but only for a short time because the next AI card could spawn four new enemies. Those would spawn in another location to give you some room for breathing, fortunately. This is the best side of the game because this kind of feeling is what you would expect from a real time shooter game.

The worst part of the game

All though the rules were very thoroughly describing how to set up the game and how to read the cards and how the weapons worked there were a lot of things that felt left out for interpretation. One example was when one stage of a mission was completed there were some confusion regarding what to do with the enemies that were left, should they be removed so that other of the same class of enemies could spawn at stage two of the mission or should they stay? In this case the map was directly linked between stage one and two and this made it feel a little strange that they should disappear. On the other hand, there were not that many figures left to be spawned for stage two and it would have been very strange if there would not spawn any new enemies for stage two, or that instead there would spawn enemies that were not included in the specific mission. This rather simple rule turned out to be quite difficult to find because it took something like ten to fifteen minutes to find it. It turned out that you remove left over enemies and that does make the most sense, since there were not enough enemy figures to both keep the left over ones and spawn new ones. Confused states like this because of unclear rules make it feel like they have not play tested the game sufficient to be clear on certain rules. This one should have been clearly marked under the chapter “locust spawning” or “completing a mission objective”. Unclear rules removes quite a lot of the smoothness of any game and this is therefore the worst side of the game.

The core system

The system I define being the core system is a three component system of action cards, AI cards and the weapon system. The weapon system is also a system by itself, however it is necessary for completing certain missions such as the very first mission for example. This mission is basically to seal the emergence hole in the end side of the level. To do that you need to throw a grenade in it and while doing so you also need one of the attack dice to have the special symbol face up. This means that in order to win this and perhaps other missions as well, the weapon system is important.

So the core system works like this: Action cards are drawn, the player chooses to play one of them to move and/or attack. Then they draw an AI card and the enemies move and/or attack back, this is not very complicated but this is how the enemies and players progress.

The weapon system works like this: Each player start out with one rifle, one pistol and a grenade slot. To the rifle and pistol they have two or three ammunition tokens and two or three grenade tokens. To attack an enemy with either the rifle or the gun with a standard attack you do not need to use the ammunition tokens. A standard attack can be done as many times as you want. You simply throw as many attack dice required to do the attack. But if you use the tokens while attacking you can roll more attack dice and do a more powerful attack. If one of the dice show the special attack symbol there is an additional attack bonus. The grenades can only be used by discarding the grenade tokens but the attack is affecting all of the enemies in a room. Discard a grenade token, roll the number of dice specified on the grenade card and after that, roll the number of defense dice specified on the enemy cards to determine the damage for each of the enemies in the room. With the special attack symbol you seal an eventual emergence hole (enemy spawn point).

The weapon system is perhaps the system that differentiate the board game from the video game the most because in the video game it is more skill based than an act of chance because in the video game you can aim, and in the board game you roll dice.

The most interesting system

For me, the most interesting system is the AI card system because it is the main system that makes this game actually feel like a real time shooter. It does not feel turn based even though it is since the enemies move in between the players and come very close. It makes them very aggressive and you are pretty tense during the whole game play because you know that the enemies will come closer or increase in numbers, you just don’t know which ones will attack you first or from where they will come.

There are a number of different actions to all the types of enemies, and for each mission there are three types of enemies. That means you take a specified amount of relevant AI cards to each mission and draw them as you progress in the game. If you draw an AI card for a type of enemy that is not currently on the board because you have just killed all of them, you simply discard it and draw another one until a possible enemy action is done. When the pile is empty, shuffle the discarded cards and draw them again.

Target audience

Because of old gender ideals I would say that this game is aimed at young boys the age of, say 12 to 18 and young adults up to 25. Because the characters you play are very macho, big, mean looking hard core male warriors with extreme weapons whose purpose is to kill ugly, dangerous, even meaner looking aggressive aliens. With this said, I don’t think that girls or young women could not enjoy this game.

Summary

The Gears of War board game offers the feeling of a real time shooter game with cards, a board and dice, and a cooperative strategic experience for a group of four people. I think that enthusiasts of the video game Gears of War series would especially enjoy this game because the different missions are similar to the missions of both the first and the second game.

It’s a turn based, real time, cooperative board game shooter game.

Board Game Analysis – first blog post, advanced game design 2014

IMG_0382

Munchkin Pathfinder

Munchkin Pathfinder is a card game for a minimum of three players in which the goal is to reach a a certain level first. There are two different sorts of card decks. One is action cards and the other is bonus cards. Every round you draw one new action card from the deck. If there is a monster behind that card you must fight it or try to run away. When you defeat a monster you increase your level and can draw bonus cards.

First time playing it

There was a small piece of paper with rules on it not much larger than a standard A4 page. I looked at it for a little while but stopped, the other people in the group had played it before so I figured I’ll just catch up on the rules as we played. There was a little confusion about how the rounds went, expecting to have some difficulties in remembering what to do. But the confusion was not because of that, it was because there was almost nothing to remember.

I met a monster and the other players looked at his level and one of them said something like:

oh, I can help you with that one for one treasure.

I said: yes, ok.

And the monster died. The person who helped me could then draw a bonus card. Then it was the next person’s turn. Similar things happened until it was my turn again. I found a weapon when I drew the action card and put it face up on the table. It made me stronger. A few turns later I realized I had other cards I could put on the table to increase the strength of my character. Some few turns after that I started helping people and/or helping their monsters because they had an alarmingly high level. I asked the others if I could use this or that card in this or that way, and almost every time I could. That’s how incredibly easy it was to get started. Sure it takes a few times of playing to fully understand everything, but compared to other board games that sometimes can take twenty minutes of discussion to agree on some little detail, because the rules are that complex, it was easier than I expected. But I sensed that there were cunning features of it just because of that.

The good things about the game

It is easy to understand the rules. And that is because all rules are simple and straight forward. It does not take a lot of time to finish one round even if all the participants are playing for the first time. The ability to make deals and help other players defeat monsters make it interesting and rewarding in the first few rounds, even though it is a competitive game, because you can get some bonus cards that help you later in the game, most certainly to help the monsters your adversaries encounter instead.

Cheating is allowed in the game such as lying about how many cards you currently hold or taking too many cards each round but if you get caught cheating you must confess to your cheat immediately. This adds an extra dimension to the game in a way that invokes suspicion about the competitors, making the players more alert. It also increases the players’ suspension if they cheat themselves because they don’t want to get caught. The low penalty for getting caught cheating encourages players to play the game in a sneaky fashion.

The bad things about the game

Even though you need to reach a certain level first, and that it is accomplished by defeating enemies, the combat system is quite hollow; check your current level, add eventual attack bonuses to that number and if is is higher than your enemy’s level you win, gain one level and can draw one or more bonus card(s). If you loose the fight you can get a curse, loose certain cards or die. What happens is determined by the individual monster cards. Dying in this game is very often a good thing, because then you get dealt a whole new hand of cards which means that you can actually become more powerful by dying. You even keep your current level and power ups. This feature makes dying a trivial matter. Many efforts to stop the leader in the game during combat by spending valuable cards to help a monster defeat him, can be totally in vain if the leading player dies and only becomes more powerful. Other consequences for loosing a battle such as loosing a weapon or multiple cards are often worse than dying, which can feel counter intuitive.

The core system

As in any card game the core system is dependent on what cards the player has and how he uses them. Some cards can be put in front of the players to enhance their attack strength or give them special abilities, other cards can be used once to gain extra strength or to deal damage in another player’s fight, for example. The goal, to be the first person to reach a certain level, is reached by defeating enemies, each defeated enemy increases the player’s level. Each turn a player draws a card from one of the two decks that can be referred to as the action card deck. These cards contain enemies, curses – events that are affecting the character in a negative way, such as being unable to run away from an enemy – or cards that enhances the character by giving them special benefits such as the ability to take two cards instead of one each round. All players can interfere in someone else’s monster combat, they can either help the other player currently in combat or help the monster, making it more difficult for the opposing player to win the fight and gain a level. When a player wins a fight they also get to draw one or more bonus cards. This opens up for possibilities to make deals among the players. For example;

player A is in combat with a monster who is stronger than him, he asks player B to help him fight the monster because their combined strength would defeat that monster. But why would player B do so, since player A would increase one level point and come closer to winning the game? If player B would get the bonus cards player A would get by winning the fight it could turn out to be such a good deal for player B that it would be worth it to him. He could get a hold of cards that would help him defeat player A later in the game, to slow down player A’s progress towards the goal of the game or to help him progress faster himself. As it turns out this sort of dealing and backstabbing is what you actually do throughout the game while the turns of the game progresses. The lack of, or rather the simplistic approach to game rules make the suggested courses of action a big part of the core system in this game. There really is not much more to the core system and all special information on how every individual card work is available on the cards them selves.

The most interesting core system

I would say that the most interesting core system is that the simplistic set of rules open up for many variations of the game and that encourages players to play it again and challenge each other personally by perhaps creating secret pacts and catch each other cheating. This simplicity is a very deliberate design choice because it creates an increasingly complex game dynamic the more a group of people play it. It makes it a very social game for anybody to play.

Main audience

The main target audience feels very broad. Anybody who is old enough to read and is able to play a game with at least two other people can play this game. The cartoon-ish art style suggests that the game is aimed at kids from the age of 12 to 18 with either gender. The quick rounds suggests the same age because you do not need a lot of patience to play the game trough and could be played at lunch breaks, for instance. But the game is certainly not limited to this target group and can serve as a good ice breaker in social encounters among adults of any age as well.

Summary

The game relies on cards and interaction between human beings. The game is what the players make of it. A simple set of rules open up for a free game experience and make every game feel unique. This also opens up for expansions to the game in the form of new cards with new features. The simplistic set of rules let you mix every compatible version of the game and play it without learning new rules.

If you do not pay close attention and remember what level you are currently on there could be some level of uncertainty about how much of strength you have. On the other hand, this can open up an opportunity to cheat and defeat an enemy that you could not defeat considering your real current level. This is good or bad depending on what sort of player you are yourself. There are many grey areas like this and that is the whole point of the game.

So if ever you are looking for a fast paced card game that you can just pick up and play with some friends and back-stab them while cheating and making deals, oh yeah almost forgot, and kill monsters, you should definitely try any of the Munchkin card games.

Artifact 6 – AI and stubborn Glowing effects

This week I have done The final AI-state “AttractedState” and I have started wrestling with the mixture of three super intelligent coding chefs in this soup of code. It’s lovely but it’s like fitting a cube inside the point of a needle.

Let’s start out with the attracted state.

This is a hunting state as explained in the previous post HERE but instead of a unit vector pointing from the enemy to the player fish, there is a vector pointing to the center of the light bulb. As of now, all fishes swim towards the light bulb when it’s lit. When the light bulb is not lit, the grey fishes flee to their “safe” distance and return to idle. The green fish are also attracted to the light but if they are close and you turn of the light, they enter hunting state. Hunting state has been updated so now when they collide with the player fish they take a bite from the player fish (dealing it damage) and flee until they are at the “safe” distance and return to idle. I believe this way is the final AI behavior with perhaps some tweaking in numbers deciding from what distance these behaviors are triggered.

The thing I am working on right now is the color coding of the fishes. The enemy fishes are supposed to have a glowing aura around them letting the player know instantly if they can eat it or if he or she should run away in shear panic while trying not to soil their pants.

If the fish has a green glow about it, it is smaller than the player’s fish and this means you can eat them. If they have a yellow glow, the player knows they are the same size, this means you can eat them and they can deal quite a bit of damage to the player’s fish.

If they have a red glow about them, the player should consider turning of the computer or risk suffering a heart attack in a primitive form of absolute panic – it means the fishes are bigger then the player’s fish! They can kill the player’s fish in a blink of an eye.

That is why and what. How is still on the drawing board.

What I’ve done so far is I am using the built in SFML VertexArray with four elements creating a rectangle. then I need to have a texture, this is also a built in class of SFML. This texture is drawn out separately but using the same position as the vertrices using the SFML’s window. The texture also uses four coordinates in the sprite sheet I use for the glowing image. This image is a transparent picture with white outlines of the fishes. this allows me to make them change colors. The Vertex array can set any color(s) to it’s shape.

I can say I wasn’t really sure where to start making these vertrices or how to fit them perfectly to the fishes since they are in different sizes as compared to the actual size in the sprite sheet. Because I use vertrices, who’s coordinates are defined at each of its corners and not in their top left corner or a specified origin such as sprites are, I need four coordinates to move it around the map. The very first thing that came into my head was the global boundaries of the sprites. Global boundaries is yet another feature of SFML. It returns a floatrect (or perhaps it’s an intrect) that gives you the coordinates – left, top, width and height of the image in question. That didn’t work out for some reason, probably because I overlooked something. In the process of doing and learning my responsibilities in a early stage of the production and because of some changes in the way we finally decided to handle our sprites, I missed a little information.

The colliders on the other hand I know inside and out. So I used the position of the colliders to update the vertrix. The colliders are placed on the sprites originating from the center of the sprite. From this information I can get all the corners. The left corner from the center of the collider is exactly the center position’s X-value minus the half of the width and the center position’s Y-value minus half its height. In the same manner you can get all the four points needed.

I just tried it and it works perfectly fine, it’s a master piece of hard coding and awesome art work.
Updatingglowposition

Just look at this wonderfully perfect fish and its glow:

GlowingFishes

The only problem right now is that the glow does not turn with the fish and that’s sort of annoying. I have three different theories that I will try after this blog.

Either I need to change the order in which the vertex array’s elements are created. In other words instead of from the top left corner to the right top corner to the right bottom corner to the left bottom corner, to draw it from the top right to the top left to the bottom left and to the bottom right. This could make the image inverted.

or I could change the texture coordinates to emerge in the same inverted order.

Or I need to do both. One of these ways should work out. I know the order does matter because I had a problem with the picture being all wrong when I had one coordinate mixed up with another.

So there you have it.