Thursday, 31 October 2013

Playing with Atoms


The Atoms of Total War : Rome II

In this game there a 6 core game atoms that when blended together provide a fluid experience that is both fun to play in the short term and provides a long lasting experience over the course of an entire game.

Empire Management:
Empire management is broken up into protons which are:
  1. Empire management requires preparation in the form of planning your actions. 
  2. The solid core mechanic is to manage your empire successfully.
  3. There is a a range of challenges that you must complete on the empire level, including food management.
  4. These challenges require various skill sets.
  5. There is a feedback system provided through a empire score ranking.
  6. Failure to properly manage your empire will result in disaster.

Province Management: 
Province management is broken up into protons which are:
  1. province management requires preparation in order to decide what buildings to construct and what troops to raise in any one province, with the former effecting the latter.
  2. The solid core mechanic is to create a province that can run by itself without too much micromanagement.
  3. There are a range of challenges presented to the player including dealing with unhappy provinces which can lead to a rebellion, and provincial tax rate management.
  4. These challenges require a good deal of though process and can often rely on your empire management as input factors.
  5. The feedback system is provided through your province happiness and income.
  6. Failure here would be denoted by losing your province to a rebellion or even a province that does not generate enough income caused by building to many buildings that effect on of the feedback values.

Economy: 
Economy management is broken up into protons which are:
  1. Preparation is required in the form of thought on what type of economy you want to have.
  2. The solid core mechanic is money because everything revolves around money. Well and food.
  3. There a range of challenges thrown at the player from food shortages to insufficient tax revenue.
  4. A player has different ways to deal with these challenges.
  5. The way in which a player handles the challenges can effect the overall game.
  6. There is a feedback system in place by listing your budget and food stocks.
  7. The mastery problem is dealt with because there are effective and less effective techniques each harder to learn, but once a player masters them going back would be bad for the game.
  8. Failure can result in food shortages which make regions unhappy, weaken armies and bankruptcy. \

Diplomacy:
Diplomacy management is broken up into protons which are:

  1. Diplomacy management requires preparation because the player needs to carefully consider who he wants as allies, enemies or neutral relations with it.
  2. The solid core mechanic is to manage your diplomatic relations in such a way that you can successfully defend your empire.
  3. The AI will be provide a range of diplomatic challenges.
  4. A range of diplomatic options are open to the player to deal with these options.
  5. Unfortunately there is not much skill in using the abilities.
  6. A feedback system is in place in the form of AI relations to you.
  7. The mastery problem is not dealt with because there are a limited number of options and the AI responds to them the same.
  8. Failure to have effective diplomacy would result wars that can cost you troops and regions.

Military Strategy: 
Military Strategy is broken up into protons which are:

  1. Preparation is required to raise armies and decide on what campaigns you will undertake and how many at a time.
  2. The routes you choose to move your troops and the locations you decide to attack will effect the battles so locations will be important.
  3. The core mechanic is moving your troops around and placing them in strategic positions to benefit your cause the best.
  4. There are a wide range of challenges associated with military strategy around placement and movement of your armies, as well as knowledge collection on your enemies and allies.
  5. The player is given different tools to solve the various situations he will in. 
  6. The better able the player is able to use the tools he has at his disposal the better his empire will preform
  7. The mastery problem is dealt with because if a player uses poor strategies that are easy to learn they will not be as effective as harder to master by more effect strategies.
  8. Failure can result in the loss of a region or armies which can set a player back greatly.

Military Tactics: 
Military Tactics is broken up into protons which are:

  1. Preparation is required on the battle field so you can inflict many enemy causalities while minimizing your own. A player needs to deploy his troops intelligently.
  2. The physical locations on the map will effect the battle outcome.
  3. The solid core mechanic is the battle itself, everything revolves around it.
  4. There are a range of challenges that the player will face that vary based on terrain, weather, buildings and the nation you are fighting.
  5. A range of different abilities is required to solve the different challenges put forth.
  6. Depending on the skill of the player he will be able to perform the abilities better.
  7. The feedback system is in place in the form of a battle results screen.
  8. The mastery problem is dealt with because if a player uses poor strategies that are easy to learn they will not be as effective as harder to master by more effect strategies.
  9. Failure can result in the loss of a battle and many casualties which can also result in the loss of a city.

Friday, 4 October 2013

Grind Quest: Objectives


A list of my favorite games in no particular order:
Total War Series: The objective of this game is become the most power nation in the game, you achieve this through military, financial or shrew diplomatic means.
Diablo II: The objective of this game is to defeat the forces and hell and save the world from destruction.

Settlers of Catan: The objective of this game is to acquire 10 victory points before any other player. You achieve this by building villages & cities, gathering resources, building roads and raising armies.

Survive: The objective is to get the highest point value people to safety before the island is destroyed.

Empire Earth: The objective of this game at its most basic level is to defeat your opponent(s) on the field of battle.

Dungeon Siege: The objective of this game is to prevent the destruction of the world by the forces of evil.

Zombie Flux: The objective of this game is to be the player to who completes the current goal that changes and the game progressed.

Small World: The objective of this game is to collect money from provinces over the course of the game, at the end the richest person wins.

Minecraft:  There is no single objective to this game, you basically set your own objective based on what you want to achieve. For mean I like making complicated machine with redstone in Vanilla minecraft.

Pandemic: The objective of this game is to purge the world of various diseases and viruses.

Starcraft: The objective of this game at its most basic level is to defeat your opponent(s) on the field of battle.



































Ticket to ride: The objective of this game is to collect the most victory points by building long railroads.
Civilization Series: The objective of this game is to rule the world through various means, whether by conquest, cultural or space race means.



So the first thing you will notice is I picked 13 games, in order for you to get a better picture of the type of games that I enjoy.

So what games do I enjoy, aside from breaking them down into real time strategy and role playing games, I tend to enjoy games that have epic goals like civilization and total war where games can take many weeks or months of time to complete. The strategy of these games really appeal to me. Of course I am a huge fan of real time strategy games, and I only listed two above, but really I have never met an real time strategy that I do not like. My favorite part of real time strategy is the story element, although I also enjoy the online competitive play. When it comes to liking role playing games I have more selective tastes, I prefer the more traditional older ones, than the new ones which try and do something new. The best ones are the ones that channel dungeons and dragons. Of course Minecraft gets it's own special category where I can basically do whatever I want, I prefer to play around with redstone and creating adventure maps. Nest we come to board games and card games. I am a huge fan of these types of games, the best times being playing them at my cottage with friends and family while enjoying some beer and the like. There are several categories that I like. There are the games where you have to collect victory points over a set period of time using various means, this appeals to me because I like the strategy and competition involved. There are also games like pandemic where the players are all competing against the system in order to obtained victory, the teamwork really appeals to me in this case. One of my favorite games is zombie flux where you are a human trying to survive the zombie apocalypse. The game is a funny more than a serious game, with lots of jokes hidden throughout the cards. Survive is another good game where you play as a group of survivors trying to escape the the destruction of Atlantis to the surrounding islands, you have to navigate the dangerous seas filled with sea monsters, whales and sharks.

That pretty much wraps up my favorite games and why I like them.  








Wednesday, 11 September 2013

A Course as a Game, Awesome!

Introduction:

Let’s start off by talking about how excited I am about how Game Design II is being run; I am a huge proponent of bringing games into the class room. I strongly believe that this course will be a blast to participate in. One of the reasons I am really excited is because I am looking towards doing a masters focusing in on Serious Games and Education. I will be watching this class closely and taking plenty of notes that I can reference in the future.

This course is formatted as a game where we the students create our characters and enter the world know as the “classroom” where we will have to complete quests, slay monsters and craft wondrous creations in order to gain fame and fortune in the form of experience on the long path to our ultimate goal of being a Game Design God.

Details:

We each get to create a basic character, which includes a name, class, and a set of skills that embodies the character.
There are 20 levels that we can earn as we gain more experience, each of these levels has a title that our character will carry with them as a badge of honour. As we level up we also can acquire additional skills for our character.
There are a total of 19 (currently) different tasks we can complete in order to earn experience for our characters.
We are required to form a guild

Issues:

Any new idea is not without growing pains and there are some here from reading over the course design.
I am concerned that the experience is not any kind of mathematical function for increasing progress, the numbers are intelligently, but almost randomly picked.
I am also concerned with how many experience items are weighted, and while I understand that some kind system is required, I do not believe weighted experience is always the best option. I would prefer using an approach where the goal for each task is more clearly defined which would remove uncertainty from some of the tasks. Now some of the tasks are well suited to weighted experience; for example the final game design presentation.
I would also like to see more diversity in the ways to earn experience and to have more options, where players have multiple ways to reach the max level much like in most Massively multiplayer Online Role Playing Games.

Conclusion:



Overall I think this course is going to be a good test case and a lot will be learned and changed as the course goes on. I am really looking forward to this course and it is going to be a fun ride.

Sunday, 8 September 2013

Why Raw Input?

Lets talk about RAWINPUT and why it is a useful tool for any game engine programmer to understand.

So what is RAWINPUT?
Well it is an alternative to using the standard method Windows input method, it provides methods for not only accessing the keyboard and mouse, but any HID device.

Before the RAWINPUT API was implemented you had to according to MSDN:

To get input from the unsupported HIDs, an application had to do many things: open the device, manage the shared mode, periodically read the device or set up the I/O completion port, and so forth. The raw input model and the associated APIs were developed to allow simple access to raw input from all input devices, including the keyboard and mouse.
RAWINPUT is different that the standard windows input which relies on posted messages which means only devices that Windows implements handling for can be handled. With RAWINPUT the user needs to according to MSDN.

for raw input an application must register the devices it wants to get data from. Also, the application gets the raw input through the WM_INPUT message.
Lets talk about how to implement a basic RAWINPUT setup in code.

This assumes you are already using the Windows API for creating and opening a window and have a basic knowledge of the Windows API.

The first thing you need to do is register the input devices, for this example I will be sticking to just the mouse and the keyboard.

      RAWINPUTDEVICE keyboard;  
      RAWINPUTDEVICE mouse;  
      keyboard.usUsagePage = 0x01;  
      keyboard.usUsage = 0x06;  
      keyboard.dwFlags = NULL;  
      keyboard.hwndTarget = hWnd;  
      mouse.usUsagePage = 0x01;  
      mouse.usUsage = 0x02;  
      mouse.dwFlags = NULL;  
      mouse.hwndTarget = hWnd;  
      if(!RegisterRawInputDevices(&keyboard, 1, sizeof(RAWINPUTDEVICE)))  
      {  
           Logger::getInstance()->write("Failed to register the keyboard device");  
      }  
      if(!RegisterRawInputDevices(&mouse, 1, sizeof(RAWINPUTDEVICE)))  
      {  
           Logger::getInstance()->write("Failed to register the mouse device");  
      }  

After this you need to handle the input as part of the windows loop. All you need to do here is add an additional case to handle WM_INPUT, then you can break up the input into a type and pass it off to whatever handlers you want.

    case WM_INPUT:  
           {  
                RAWINPUT InputData;  
                UINT DataSize = sizeof(RAWINPUT);  
                GetRawInputData((HRAWINPUT)lParam,  
                                    RID_INPUT,  
                                    &InputData,  
                                    &DataSize,  
                                    sizeof(RAWINPUTHEADER));  
                if(InputData.header.dwType == RIM_TYPEKEYBOARD)  
                {  
                     // Pass InputData.data.keyboard to your keyboard handler
                }  
                if(InputData.header.dwType == RIM_TYPEMOUSE)  
                {  
                     // Pass InputData.data.mouse to your keyboard handler. 
                }  
                return 0;  
           }  

In order to handle the input data you need check what value the Vkey variable is. Here is a condensed list of the most common keys. for a more complete list check Here. The following is for the keyboard.

  0x08 // BACKSPACE key            
  0x09 // TAB key            
  0x0C // CLEAR key            
  0x0D // ENTER key       
      if(MakeCode == 0x1C && Flags == (RI_KEY_MAKE|RI_KEY_E0) || Flags == (RI_KEY_BREAK|RI_KEY_E0)) // Right Input Key       
      else if(MakeCode == 0x1C && Flags == (RI_KEY_MAKE|!RI_KEY_E0) || Flags == (RI_KEY_BREAK|!RI_KEY_E0)) // Left Input Key            
  0x10 // SHIFT key  
      if(MakeCode == 0x2A) // Left Shift  
      else if (MakeCode == 0x36) // Right Shift            
  0x11 // CTRL key  
      if (MakeCode == 0x1D && Flags == (RI_KEY_MAKE|RI_KEY_E0) || Flags == (RI_KEY_BREAK|RI_KEY_E0)) // Right Control  
      else if (MakeCode == 0x1D && Flags == (RI_KEY_MAKE|!RI_KEY_E0) || Flags == (RI_KEY_BREAK|!RI_KEY_E0)) // Left Control            
  0x12 // ALT key  
      if (MakeCode == 0x38 && Flags == (RI_KEY_MAKE|RI_KEY_E0) || Flags == (RI_KEY_BREAK|RI_KEY_E0)) // Right Alt  
      else if (MakeCode == 0x38 && Flags == (RI_KEY_MAKE|!RI_KEY_E0) || Flags == (RI_KEY_BREAK|!RI_KEY_E0)) // Left Alt  
  0x13 // PAUSE key            
  0x14 // CAPS LOCK key            
  0x1B // ESC key       
  0x20 // SPACEBAR       
  0x21 // PAGE UP key       
  0x22 // PAGE DOWN key       
  0x23 // END key       
  0x24 // HOME key       
  0x25 // LEFT ARROW key       
  0x26 // UP ARROW key       
  0x27 // RIGHT ARROW key                 
  0x28 // DOWN ARROW key            
  0x2C // PRINT SCREEN key            
  0x2D // INS key            
  0x2E // DEL key            
  0x30 // 0 key            
  0x31 // 1 key       
  0x32 // 2 key            
  0x33 // 3 key            
  0x34 // 4 key            
  0x35 // 5 key       
  0x36 // 6 key       
  0x37 // 7 key       
  0x38 // 8 key       
  0x39 // 9 key            
  0x41 // A key       
  0x42 // B key  
  0x43 // C key  
  0x44 // D key  
  0x45 // E key  
  0x46 // F key  
  0x47 // G key  
  0x48 // H key  
  0x49 // I key  
  0x4A // J key  
  0x4B // K key  
  0x4C // L key  
  0x4D // M key  
  0x4E // N key  
  0x4F // O key  
  0x50 // P key  
  0x51 // Q key  
  0x52 // R key  
  0x53 // S key  
  0x54 // T key  
  0x55 // U key  
  0x56 // V key  
  0x57 // W key  
  0x58 // X key  
  0x59 // Y key  
  0x5A // Z key  
  0x60 // Numeric keypad 0 key  
  0x61 // Numeric keypad 1 key  
  0x62 // Numeric keypad 2 key  
  0x63 // Numeric keypad 3 key  
  0x64 // Numeric keypad 4 key  
  0x65 // Numeric keypad 5 key  
  0x66 // Numeric keypad 6 key  
  0x67 // Numeric keypad 7 key  
  0x68 // Numeric keypad 8 key  
  0x69 // Numeric keypad 9 key  
  0x6A // Multiply key  
  0x6B // Add key  
  0x6D // Subtract key  
  0x6E // Decimal key  
  0x6F // Divide key  
  0x70 // F1 key       
  0x71 // F2 key  
  0x72 // F3 key  
  0x73 // F4 key  
  0x74 // F5 key  
  0x75 // F6 key  
  0x76 // F7 key  
  0x77 // F8 key  
  0x78 // F9 key  
  0x79 // F10 key  
  0x7A // F11 key  
  0x7B // F12 key       
  0x90 // NUM LOCK key  
  0x91 // SCROLL LOCK key  
  0xBA // Windows 2000 for the US standard keyboard, the ';' key  
  0xBB // Windows 2000 for any country/region, the '=+' key  
  0xBC // Windows 2000 for any country/region, the ',<' key  
  0xBD // Windows 2000 for any country/region, the '-_' key  
  0xBE // Windows 2000 for any country/region, the '.>' key  
  0xBF // Windows 2000 for the US standard keyboard, the '/?' key  
  0xC0 // Windows 2000 for the US standard keyboard, the '`~' key  
  0xDB // Windows 2000 for the US standard keyboard, the '[{' key  
  0xDC // Windows 2000 for the US standard keyboard, the '\|' key  
  0xDD // Windows 2000 for the US standard keyboard, the ']}' key  
  0xDE // Windows 2000 for the US standard keyboard, the 'single-quote/double-quote' key  

 For the mouse you will need these codes.


 case 0x0001: // Left mouse button down  
 case 0x0002: // Left mouse button up  
 case 0x0004: // Right mouse button down  
 case 0x0008: // Right mouse button up  
 case 0x0010: // Middle mouse button (three-button mouse) down  
 case 0x0020: // Middle mouse button (three-button mouse) up  
 case 0x0040: // Windows 2000: X1 mouse button down  
 case 0x0080: // Windows 2000: X1 mouse button up  
 case 0x100: // Windows 2000: X2 mouse button down  
 case 0x0200: // Windows 2000: X2 mouse button up  
 case 0x0400: // Mouse Wheel            

You should handle these in any way you see fit, but everything above will get you started in implementing RAWINPUT into your engine.

For additional information visit MSDN RAW INPUT

Tuesday, 26 March 2013

Bloom in Soaring Steele

One of the shader effects that we have implemented in our game Soaring Steele is a bloom effect, this effect is great because it helps being our game to life because for the most part you are flying through the bright sky with the sun beating down.

Definition:

Bloom (sometimes referred to as light bloom or glow) is a computer graphics effect used in video gamesdemos and high dynamic range rendering (HDR) to reproduce an imaging artifact of real-world cameras. The effect produces fringes (or feathers) of light extending from the borders of bright areas in an image, contributing to the illusion of an extremely bright light overwhelming the camera or eye capturing the scene. (Wikipedia)


Before and After Comparison:


C++ Code Sample:
Here is an example of how I integrate bloom into my draw loop.
Steps: 
  1. Draw the Scene to an Frame Buffer Object
  2. Draw the Frame Buffer Object with a Bright Pass Shader
  3. Blur the Bright Pass using a two pass Gaussian blur
  4. Combine the Bright/Blur pass and the Scene pass together and draw as the final image.
1:  particleBase->bind();  
2:    
3:            Scene::draw3D();  
4:    
5:            particleBase->unbind();  
6:    
7:            particleBrightPass->bind();  
8:    
9:                 BrightPass->begin();  
10:    
11:                      BrightPass->setUniform("luminance",luminance);  
12:                      BrightPass->setUniform("middleGrey",middleGrey);  
13:                      BrightPass->setUniform("threshold",threshold);  
14:    
15:                      glActiveTexture(GL_TEXTURE0);  
16:                      glBindTexture(GL_TEXTURE_2D,particleBase->getColourTexture(0));  
17:                      BrightPass->setUniform("particlebase",0);  
18:    
19:                      particleBase->draw();  
20:                   
21:                 BrightPass->end();  
22:    
23:            particleBrightPass->unbind();  
24:    
25:            guassian1DBlurX();  
26:            guassian1DBlurY();  
27:    
28:            combinePass->bind();  
29:    
30:                 CombinePass->begin();  
31:    
32:                      glActiveTexture(GL_TEXTURE0);  
33:                      glBindTexture(GL_TEXTURE_2D,particleBase->getColourTexture(0));  
34:                      CombinePass->setUniform("baseInput",0);  
35:    
36:                      glActiveTexture(GL_TEXTURE1);  
37:                      glBindTexture(GL_TEXTURE_2D,particleGuassianTwoPassYBlur->getColourTexture(0));  
38:                      CombinePass->setUniform("adjustmentInput",1);  
39:    
40:                      particleGuassianTwoPassYBlur->draw();       
41:    
42:                 CombinePass->end();  
43:    
44:            combinePass->unbind();  
45:    
46:            combinePass->draw(1);  

Shaders:

Bright Pass:

Here is where I apply the bright pass.
 #version 330  
 in vec2 uv0;  
 out vec4 colour;  
 uniform sampler2D particlebase;  
 uniform float luminance = 1;  
 uniform float middleGrey = 1;  
 uniform float threshold = 1;  
 void main()  
 {  
      vec3 color = texture2D(particlebase,uv0).rgb;  
      colour *= (middleGrey / luminance);  
      colour *= (1.0 + (colour / (threshold * threshold) ));  
      colour -= 0.5;  
      colour /= (1.0 + (colour * colour));  
      colour.rgb = color;  
 }  

X Pass Guassian Blur:

In this pass I take the result of the bright pass and blur it along the x axis.

 #version 330  
 vec2 uv0[5];  
 float weights[5];  
 in vec2 uv1;  
 out vec4 colour;  
 uniform sampler2D brightpassInput;  
 uniform vec2 pixelSize;  
 vec3 GuassianBlur()  
 {  
      vec3 result = vec3(0.0);  
      for(int i = 0; i < 5; i++)  
      {  
           result += texture2D(brightpassInput,uv0[i]).rgb * weights[i];  
      }  
      return result;  
 }  
 void CalculateUvs_Weights()  
 {  
      uv0[0] = uv1 + vec2(-pixelSize.x*2,0);  
      uv0[1] = uv1 + vec2(-pixelSize.x,0);  
      uv0[2] = uv1 + vec2(0,0);  
      uv0[3] = uv1 + vec2(pixelSize.x,0);  
      uv0[4] = uv1 + vec2(pixelSize.x*2,0);  
      weights[0] = 0.01330373 / 0.47365426;  
      weights[1] = 0.11098164 / 0.47365426;  
      weights[2] = 0.22508352 / 0.47365426;  
      weights[3] = 0.11098164 / 0.47365426;  
      weights[4] = 0.01330373 / 0.47365426;  
 }  
 void main()  
 {  
      CalculateUvs_Weights();  
      colour.rgb = GuassianBlur();  
 }  

Y Pass Gaussian Blur:

In this pass I blur the x pass, along the y axis.
 #version 330  
 vec2 uv0[5];  
 float weights[5];  
 in vec2 uv1;  
 out vec4 colour;  
 uniform sampler2D brightpassInput;  
 uniform vec2 pixelSize;  
 vec3 GuassianBlur()  
 {  
      vec3 result = vec3(0.0);  
      for(int i = 0; i < 5; i++)  
      {  
           result += texture2D(brightpassInput,uv0[i]).rgb * weights[i];  
      }  
      return result;  
 }  
 void CalculateUvs_Weights()  
 {  
      uv0[0] = uv1 + vec2(0,pixelSize.y*2);  
      uv0[1] = uv1 + vec2(0,pixelSize.y);  
      uv0[2] = uv1 + vec2(0,0);  
      uv0[3] = uv1 + vec2(0,-pixelSize.y);  
      uv0[4] = uv1 + vec2(0,-pixelSize.y*2);  
      weights[0] = 0.01330373 / 0.47365426;  
      weights[1] = 0.11098164 / 0.47365426;  
      weights[2] = 0.22508352 / 0.47365426;  
      weights[3] = 0.11098164 / 0.47365426;  
      weights[4] = 0.01330373 / 0.47365426;  
 }  
 void main()  
 {  
      CalculateUvs_Weights();  
      colour.rgb = GuassianBlur();  
 }  

Combine Pass:
Finally I combine the two passed using a screen filter.
 #version 330  
 in vec2 uv0;  
 uniform sampler2D baseInput;  
 uniform sampler2D adjustmentInput;  
 out vec4 colour;  
 vec3 screen(vec3 color1, vec3 color2)  
 {  
      return (1.0 - ((1.0 - color1) * (1.0 - color2)) );  
 }  
 void main()  
 {  
      vec3 colorA = texture2D(baseInput,uv0).rgb;  
      vec3 colorB = texture2D(adjustmentInput,uv0).rgb;  
      colour.rgb = screen(colorA,colorB);  
 }