Wednesday, 11 December 2013

Scripting and AI

Scripts are very high-level programming languages used to reduce the time it takes to compile code. These are usually files that can be opened with text editors like notepad, and can be edited. These scripts are used with programs and are loaded when the program runs. Scripts are usually used for data, loaded into the program such as variables that the user would typically initialize in code. Without the use of scripts, whenever the user compiles their code, changes a single variable and recompile their code again, the compiler will load in the whole program even though a single variable changed. This can become really tedious when debugging or balancing in video games (stats, weapons, enemy AI, etc). When a variable in a script is changed, all the compiler has to do is to reload the script again instead of all the code, and it will run instantly.

There are many different scripting languages, but one of the main scripting languages being used recently by a lot of developers is LUA.
Some features of LUA are:

  • Compiled to bytecode
  • Hot swapping
  • Highly embeddable
  • Highly customizable
  • Dynamic typing
Some Pros of LUA are:
  • Iteration Times
  • Expressivity
  • Designer-accessibility
Some Cons of LUA are:
  • Performance
  • Designer-accessibility
Scripts such as LUA give designers an easier time to balance or change attributes to the game itself without touch the code which really helps with the developing process. At the same time they can hinder or ruin the programmer's work by using the scripts. These scripts are essentially the pillars of the Engine itself and their components can be implemented in C++ or LUA. The scripts is basically a special sauce or the thing that glues everything together.

Typically scripts are used for data and what scripts should do are to save out the state of the scripts, drive the system with data and define the structure for both. LUA can define structures for engine-allocated data blocks, and the engine controls the lifetime of these blocks. LUA reads and write to the blocks but it is never allowed to allocate it's own dynamic memory. This essentially give the user a fluid design environment and it allows for the developers to put all their hacks, because every game has their own unique hacks or a "different" way to implement a feature.

 Generally what you want your scripts to deal with are:
  • Health/Damage/Death/Stats
  • Weapons/Equipment/Items/Abilities
  • Artificial Intelligence and Behaviours
  • Heads Up Display/User Interface/Menus
  • Missions/Levels/Objectives(Quests)
The difference between C++ and scripts is that C++ code is technology that can be used for other things such as for another game, it is a framework for your games. Scripts are the stuff the make the game unique from all the other games.

Scripts are also called DSLs or Domain Specific Languages which is a language designed to be highly adept at solving a specific class of problems these can include LUA, Python, Lisp, etc. DSLs are used for AI because firstly, for code cleanliness and the effects of mapping code directly into the problem, secondly, it eliminates low-level concerns that do not apply to the specific problem and finally, it speeds up productivity and removes excess overhead  that are not related to the problem.

The benefits for avoiding low level issues is that there is no manual memory management in code, no complex syntax and no complications such as undefined behaviour. It doesn't require a high level of knowledge in programming and it reduces the probability of severe bugs to occur in the code. DSLs should be simple that even the user with basic programming knowledge can use it. The goal of using DSLs is to place all data and logic into the DSL and out of the core engine code. 

The first things to do when created a DSL is to:
  • Identify the core problems the AI must solve
  • Select algorithms and solution for each problem
  • Break down the solutions into discrete chunks
  • Implement DSL concepts for each chunk
When implementing DSLs it is ideally better to keep syntax simple and clean, deploy simple code for parsing, map syntax elements to constants or classes and excute the DSL code in some fashion. The syntax should be able to parse easily, everything should be easy to understand and must make sense and use specific operations rather than general ones. 
When executing DSLs build a miniature interpreter, embed the DSL in C++, Lua, etc. or compile to another language. 

Everyone can benefit from the use of DSLs. Programmers have a safer environment, Junior team members can do critical AI work, Designers can write logic directly, code reviewers will be less burdened and QA testing will be optimal.


Monday, 9 December 2013

Nav Mesh

Navigation is important when developing video games because it creates an immersive and fun experience and Non-playable Characters (NPCs) play a huge roll in this. With navigation, it allows for NPCs to be able to "sense" the location around them, and react according to the situation. This allows for less scripting when trying to create AI and also create a more dynamic AI because instead of following a script on how the NPC should move, it reacts to the world itself.

The most basic use of an NPC command, is to go from point A to point B. The  steps used for this are:

  1. NPCs figure out their location relative to the world
  2. Get the coordinates of the point the NPC will travel to
  3. Find a path to the destination
  4. Scan for any objects that will be in the way of the NPC
Other uses for AI/NPC navigation is target scanning, monitor threat perception, determine spawn locations, and the ability to reuse levels.

Insomniac games uses navigation by:

  1. Game AI: set up NPC's navigation requirements (e.g. Go-To Command)
  2. Navigation: Path-Finding & smoothing
  3. Steering: Locate Obstacles in the path and avoid them
  4. Game AI: Transform steering output to animation-input
  5. Final Position & Orientation of NPC
Nav meshes are used as a layout of the level, that are used for AI navigation. These Nav meshes are divided into sections where the AI navigates through them to go to their end point. These sections also have properties such as elevation or areas where the AI will not go such as certain building roofs where the enemies can climb or jump to, or areas such as lava or water where the enemies will avoid.
To move around these sections in Resistance 2, A* is almost always used because hardly 10% of the nav SPU budget was used for it even with their coop mode with a maximum number of 100 NPCs using navigation on screen.

The AI steering in R2 was light weight or simple and barely satisfied the needs of the programmers/designers. The main issue Insomniac focused on was the issue where when animation around corners did not slow down enough and  a NPC had to not only get to the first bend point but also orientate towards the bend point along the path. What they used to fix this problem was using a bezier curve approach for the bend points. The used of bezier curves ensured that the NPCs will stay on the nav-mesh.

There are many areas of a level where a nav mesh alone will not be enough for navigation. Objects such as ladders, tunnels or actions such as teleporting or jumping will not work with the current nav mesh, because these are considered non mesh links. To fix this problem, Insomniac uses a custom clue boxes which help connect that specific point to the actual mesh itself.


This picture shows that there is a custom link where the AI is suppose to jump, so a custom clue is added at the bottom of the jump, and at the top of the jump. This lets the NPC jump up onto the high level mesh or jump down to the lower level mesh. Although this does have a problem where multiple NPCs will be using this custom link. Instead of creating multiple custom links around the edges, there are other alternatives such as finding a different path. 



This picture shows there is a hybrid climbing through the window, which is the most effective path to get to the 2nd floor, but since its occupied, another path opens up allowing for the 2nd hybrid to use this path (the door way) to get to the 2nd floor. Not only does is this efficient in terms of having multiple enemies able to navigate at once, it creates dynamic gameplay where there are enemies coming form multiple different paths. 

To create a nav mesh there are a few steps:
  1. Voxelize the scene geometry
  2. Build navigable voxels
  3. Clear Voxels NPC height above and below custom-override-polys
  4. Render custom-override-polys into the best filtered voxel grid
  5. Build watershed partitioning
  6. Trace catchment basin's contours with filtering
  7. Triangulate/tesselate to generate the nav mesh
Custom-override-polys are meshes created by the designers to fix areas of the original mesh that are disconnected or unwanted areas of the mesh. They basically override what the original mesh was in the unwanted area, and replaces it with the custom mesh to create a final desirable mesh that can be used for the game.



Nav meshes are really helpful when the developers want dynamic AI for their NPCs. It lets the NPCs use the level fully and create a more dynamic gameplay for the players. Nav meshes remove the need to use boring linear pathing since it allows the NPC do what they want, depending on the situation. It is always changing and different so the player cannot predict easily what the enemy's behaviour will be.



Friday, 6 December 2013

Ogre Particles Scipts

In our game, Bullet Devil: Attack of the Elements, we will be using the particle system with the Ogre engine. What we will be mainly using them for is to show off the effects of our elemental attacks in the game. One of the core mechanics we have in our game is the use of elements, where elements counter each other to deal extra damage as well as have unique effects. Other uses for the particle system is to create more appealing visual effects on things such as when a player shoots, or for our enemies making them look more fantasy like.

Currently, in our game we have 1 working particle effect that we are quite satisfied with, and that is our ice effect which has blue snowflakes and moves upwards around a character. What this effect shows (and what other elemental particles will show), is that that character (player or enemy) has been hit with that elemental attack and has a status effect now.


Ogre Particles uses their own scripts to setup attributes for their particles. These attributes include the amount of particles the user wishes to emit, the size of the particles, the type of emitter, the velocity of the particles, and many other attributes. By changing values and adding new attributes to their particle script, the user can create a large variety of particles.  

To create a particle script, the first thing the user must do is to create a text document but instead of ending the file name with .txt, the user should end their text document with .particle because ogre parses .particle files automatically. In the ogre particle script there are 2 main parts, the particle properties section and the emitter section. The particle properties section deals with the size of the particle, the amount of particles to be created per emitter, how many emitters the user wants. The emitter section has the type of emitter (usually box or point), the angle of where the particles will be emitted from, the rate that they will emit, the time each particle will live, the up direction of the particles and velocity. Of course there are many other attributes but these are most commonly used for most particle systems. 




This is a fireworks particle script using ogre particles. One thing unique about this script is that there are 2 emitters, this is because for fireworks, there are 2 parts to it, when the fireworks are shot into the air, and then the explosion. The affectors are what functions that will effect the particles in some way. This specific one interpolates 2 colours together to change the particle from 1 colour to another. 

The first thing in your .particle file is to write what your particle script will be called at the top of your file using particle_system particleScriptName{}, replacing particleScriptName with the name of your own particle script. Next is to get a material or picture of your particle, from a separate .material file (can also be edited with a text editor). Particle_width and particle_height change the size of the actual particle. Quota is the number of particles to be emitted. Billboard_type is how the particles will be rendered and orientate, the point billboard is used if you want the particles to orientate towards the camera. 

For emitters, you start with the emitter type, in this case it is a box, so the script is emitter Box {}. The first attribute for this box emitter is the name of the emiiter. This emitter has a special case because it emits a second emitter called explosion. Angle deals with the range where the particles can spread, 0 being one direction to 180 being the around the emitter. Emission rate is how many particles per second should be emitted, (I've found out from my own experience and asking someone else that your emission rate should be 1/10 of your quota). Time_to_live is self explanatory. Direction is where the up vector is for your emitter. Velocity is the speed of your particles. 

There are many more attributes to explain and most of them have a predefined value when they are not defined in the script itself or in some cases, if the values are set to 0. I can't explain every single attribute for ogre's particle script but they all can be found through Ogre's manual from their SDK (which I use frequently). It has many attributes that I still haven't tested myself, but I do plan to experiment with these to create more interesting particle effects.




Tuesday, 26 November 2013

Bullet Devil: Attack of the Elements

For our third year game, we have decided to make an arena survival shooter where you, the player, will have to defend against waves of enemies while protecting your objective. You play as the Bullet Devil (our main character from our year 2 game), and you had to make an emergency landing on a nearby planet to escape from your enemies. Sadly, your landing was not the softest landing and the natives of the planet has gone to defend their land against the foreign creature, you! You must defend not only yourself but your ship as well, and defeat the waves of native aliens on the planet. These enemies are different from the usual enemies you face, they know how to control the elements and they use this power to try and eliminate you. You steal this power and empower your weapons with the elements to help defend against the attacks.


Gameplay Mechanics:
One of our main gameplay features we plan to implement in our game are the power of the elements in the enemies as well as the player's weapons. Each element will have a unique ability that affects the enemies and the guns the player wields. We plan to have a feature that evaluates the player on their progress, and depending on how well he/she is doing, the difficulty will slowly increase to create either more of a challenge for the player or to help the player complete the level.

Elements:
We plan to have 6 element types by the end of the year. Each element has its own unique ability.

- Fire: burns  the enemy and deals damage over time
- Ice: Slows the enemy down by reducing their movement speed
- Earth: Snares or immobilizes the enemy
- Air: creates a big wave and knocks back the enemy
- Light: Blinds the enemy (changes the A.I so the enemy is confused for awhile)
- Dark: Strongest and most deadly weapons in the game (can cause damage to the user)

Each element will have a counter. Opposite elements deal bonus damage to their targets but similar elements will deal reduced damage.
The current counters we have are:
Fire <--counters--> Ice (fire deal bonus damage to ice and ice deals bonus damage to fire)
Earth <--counters--> Air
Light <--counters--> Dark

This is a very simple counter mechanic in our game that players can easily get (unlike starcraft 2 where i have to learn all the counters after awhile, sad face)

Items and Pick Ups:
Each map will have a set of chests that spawn after a few waves. When the player opens these chest, they will be rewarded with either money or ammunition. Money will be used to unlock weapons and elements for the weapons they use. This gives an incentive to continue playing since there is a goal (unlocking every weapon).

Current and Future Plans:
What we plan to have for this semester is a good base with most of our mechanics implemented such has basic movement and shooting. Implementing the basic features will also have to be done such as collision detection/response, wave spawning and basic enemy AI. For next semester not only do we want to make a game look really nice with particles and shaders, but also many other features in the game, one which is co-op (obviously), another possible game mode, and also a way to expand on the player's arsenal. Our main focus though is to make a fun game that everyone can enjoy playing for many hours.

Friday, 22 November 2013

Scene Graphs

Scene graphs are a very helpful tool when design games. They are used to show the relationships between objects in the game. Scene graph form a hierarchy where certain objects can be parents or children of other objects. These scene graphs are a collection of nodes and edges that form a graph or a tree. These nodes are connected by their edges spatially or physically.  


This is a really basic example of a simple scene graph of a typical house. The nodes show what the objects are of the house and the graph also shows how each object is related to each other. The desk would be the child of the bedroom but the parent of the computer. Or the pillow would be the child of the bed but the pillow is not a parent at all. The house node has 3 children but no parents, which makes the house the root node. 

Scene graphs are great for managing objects in a scene but what else can they do? If a game has any type of animation with a object, there most likely a transformation happening during the animations. When using a scene graph, if a transformation is applied to a parent node, all its children will be affected by it. 


Here is another scene graph with the bones in a human hand/arm. When a transformation is applied to the parent nodes, the children nodes will all be affected by it. Try moving your wrist around, your fingers and the palm of your hand will also move to a new position. If you try moving the tips of your fingers, other parts of your body will not move. This means that the fingers are a child to the palm of the hand. Therefore when a transformation is applied to a parent node, all children of that node is also transformed. But when rotating, there is a certain pivot points that the object rotates around. Parent nodes will rotate in their object space but what about the children? Children nodes will also rotate around the same point as their parents because of the hierarchy created by the scene graph.

Just like for animations and transformations, shaders and effects can also be used with the help of scene graphs. With the use of scene graphs, effects can be applied to the parent and also the children of the parent. For example, if you were to use shadows inside a building, the game would implement shaders in the whole building (since it is the parent node). All objects in the building will also have a shadow, but objects outside of the building will not. This greatly helps with the rendering that the game has to do because it is not rendering shadows outside of the building. Also documentation will be cleaner since the programmer will not have to apply shadows to every single object in the building, just the parent node.

 Scene graphs are a core component of a game engine. It helps organize/manage objects in a scene, create certain groups and relationships between objects (hierarchy), group transformations and shader effects. 

Monday, 18 November 2013

Design Patterns

Design Patterns are templates implemented in many aspects of coding to create a more efficient way to reuse code. Instead of just copying and pasting code many times, with the correct design patterns, you could use one design pattern for multiple situations in your code. Design Patterns also show the relationships between classes or objects. It is always general and not for a specific language such as C++ so others can easily understand Design Patterns and implement it themselves. Reusing Design Patterns helps prevent issues that can cause major problems in the future.


Advantages of using Design Patterns:
  • Speed up development process
  • Help with debugging
  • Increase readability of your code
  • Increase the usability of your code
Some Design Patterns are:

Singleton:
The singleton pattern restricts instantiation of a class to one object which helps with when a single object is needed to coordinate actions to the system. A singleton only lets an object to have one instance of the class. Singletons have many uses since it only allows for a single instance. With a single instance, a singleton can be used for the renderer, mouse or even single sets of global parameters. 

Facade Pattern:
A facade is an object that provides a simplified interface to code. It is a manager class that manages others. The facade provides a single interface to a large collection of classes related classes. This makes a really solid pipeline for your code and makes how the classes interact with each other much more easily. The facade pattern reduces a number of interactions between classes in 2 different subsystems and instead allows the managers from each class to interact with each other, where they can then relay the data to the appropriate class. 

State Pattern:
State patterns deal with the objects state and use many switches or enums. The more states there are, the more confusing the state pattern can get. It gets even more troublesome when multiple functions must be shared between multiple states. A good way to help design this is to have a manager that controls the state logic and state switching. With shared functionality, it is always a good idea to use inheritance to solve your problems. When you want to add a new class to the system, it is easy to implement and doesn't require a lot of modify with other parts of the code. State patterns are great for controlling different states when using Artificial Intelligence (A.I) since you can switch between different states for different behaviours of characters. 

An example of this is a typical character in a modern game has multiple actions or behaviours such as idle, walking and attacking. The game needs to know which state is should be doing at a time. The manager takes care of which is the correct state must be used at a certain situation, and once the correct state has been selected the character will change its behaviour and perform the correct action.

Factory Pattern:
Factory patterns allows for objects to be created without specifying what the exact class of the object. Factory pattern defines a separate method for creating objects, where subclasses can override to specify the derived type of the object that is to be created. This method allows for the creations of instances of all types. This can be as simple as passing in a specific ID and have your factory/GameEntity class to create an object for you. These can be simple primitives such as spheres or squares to more complex objects such as meshes and models. New functionality can be easily implemented without changing much of the code. 

Saturday, 16 November 2013

Basic Artificial Intelligence in Videogames

Artificial Intelligence plays a large role in video games where the players fight against the computer. They give behaviors and other features to objects in the game to produce the illusion of intelligence. Some A.I in modern games are done really well to imitate human behaviors. To create these illusions, game developers implement different algorithms to simulate intelligence in Video Games.

In most games, artificial intelligence can be broken down into three parts, Movement, Decision Making, and Strategy.

Movement:

Movement takes the decisions made by the program, and uses it to perform the specific motion. For example, a NPC can be just casually walking through a set path around the town, but when the player approaches the NPC, he/she will stop and “notice” the player. When the player moves out of range of the NPC, the NPC will continue walking along the path given.

Decision Making:
The game has to choose the correct decision based at any situation that happens in the game. This is where decision making comes in. When a situation changes, the A.I has to choose the correct behavior or action instantaneously. An example of this would be in Metal Gear Solid 4, where enemies would be doing their regular patrolling actions initially. But when they spot Snake or another enemy, they will change into a different action such as a seeking action. The game has to make the correct decision so the player will not notice any strange motions by the NPCs (unless intended). How strange would it be if instead of changing into seeking the enemies will change into a retreat action. A player would think that the enemies would be scared of you, but it would be strange. The enemies greatly outnumber the player, and can easily encounter the player. Without proper decision making it creates poor gameplay for the player to enjoy.

Strategy:
Strategy in Artificial Intelligence can be difficult or simple to implement. It is the behaviors of the game objects after the decision making has been made. Difficulty of implementing certain strategies depends on what the game developer wishes their game objects to perform. A simple strategy would be to have a single enemy attack the player. Generally implementing what a real person would do in that situation would be a difficult strategy to implement. The reason being is that people can think for themselves and are also unpredictable. Computers are very predictable and requires the game developer to write some sort of code so the computer can understand what to do. 

Here is a great example of what NOT to do when you want good A.I in your game. This video shows the lack of decision making and strategy in what a good artificial intelligence should have.


The Walking Dead: Survival Instinct