20100125

Data Sources

                When storing data, there are typically 3 major choices, Databases, XML and custom Binary Files.  I’ll be discussing several pros and cons to each method.  I will also be discussing a 4th option that has been recently emerging, involving living network data.


                Before emerging into any as the end all be all solution for your project, you should look into the values and strengths of each option.  Weigh them carefully, once you select a route, it is often very difficult to change it later.


                Databases are very good at storing lots of information, and being able to pull it out very quickly as well.  It is very common and simple for most database system to hold on to millions of records of data and search, sort and update very quickly.  Most databases follow a simple language called SQL for retrieving, inserting and editing data, which (when taught well) is not difficult to learn.  Databases can also be expanded to additional machines to help improve overall performance in larger systems.


                Databases tend to lock the format of your data down.  It becomes difficult and time consuming to continually change and support databases as they grow.  Typically this produces a decent amount of administrative work.  Data storage be wasteful. (if 5% of your users use 3k for a description field, but the other 95% only use 0.5k,  Every row still requires 3K, whether used or not)


                XML is very flexible to data formats.  If you are constantly updating and changing data, XML can provide a solid system to work with it.  If you format your changes well, saved files can be forward and backward compatible with different versions of your application, without needing to write additional code to support it.  XML is humanly readable, which means that a notepad can easily edit and read the data for you.  Not only is it human readable, but it is descriptive, so just by looking at the XML file, you can determine what and how it is used, making it easy to edit files from programs you didn’t write.  XML is also easily transferred over the Internet, saved locally on any machine and is supported quite well on Every reasonable OS and programming language.


                XML is not intended for large amounts of data.  When reading it, it all has to be parsed and stored in memory.  Because of this constraint, it is often not easy or fast to conduct searches of XML.  XML is stored as plain text, which also means it takes up more space.  Since Lengths can be anything, your program has to be written to expect any length.  Also, data types like numbers and Boolean values are stored as strings, so they have to be specifically converted into numbers.  XML is also a poor choice when storing and loading binary data, like images, sound files or movies.


                Custom Binary files have been used for a long time.  This means storing the data (typically) in the smallest amount of space it possibly needs.   It also means that it is harder to use outside of your own applications, which is often helpful for protecting local data.  You control entirely control the format, and can decide how best to shape it, making portions of it similarly searchable like a database, and other portions flexible like XML.  When storing large amounts of data that will only be used by your application, this is a common practice to use.


                Custom Binary files lock you into a format.  Any changes you make have tend to require a decent amount of code to transfer from one version to another.  They are difficult to read, and if bugs are caused by misplaced data, or some accident in writing the data, the entire file can be ruined.  It does not allow your data to be easily read by other systems, which could be negative depending on your user’s needs and interests.   They also require more design time because you are not only deciding the format of the data, but also writing all the tools and code for handling the data.


                A fourth option I referred to as “Living Networks” is demonstrated quite well by a system called “Terracotta”.  The reason I selected a particular brand name for this, is because it is new (and old, as similar concepts have been around for a while) system, that I have not seen a valid competitor for yet.  In this system, it manages memory over multiple networked servers.  It has proven faster than the best databases when the data is designed for it.  It is also flexible like XML, and also provides (by its nature) redundancy and load balanced data access.  It is a system that I look forward to in the near future becoming a new standard for data storage and retrieval.


                Terracotta only supports Java, leaving C++, C#, VB, PHP and other languages out.  Because of that lack of interoperability, when selecting this, you are forcing your data to be accessed through JAVA/J2EE alone, meaning your data has now limited your application choices, not very sustainable in mixed environments.    It is not intended for home computing and should not be considered a solution for local data. 


                Each of these 4 data solutions target different audiences.  Even within these systems, we are not very technically mature.  It should be noted that every one of these areas is coming out with new and better ways of storing information, (XML being an exception) and will continue to do so for a while.  While one solution might be the most optimal at the moment, improvements in other environments may make them your optimal choice a year later.

20100118

Game Text...

                This post has to do with a Human Text reaction system.  It was a common tool used in many telnet games, as well as similar principals are pulled in from Intellisense, and even web searches in some places.  It’s the ability for the application to determine ideas of what you meant from less letters than even a complete word.  A simple idea is a text based game that you have to constantly move East, West, North and South.  It would be a pain for the players to have to type West 20 times in order to go from one city to the next, so the words can be “shortcutted” (interesting word).  Instead of typing in “west” you could just type “w” and it would determine that the most logical word is West, and treat it as if you had typed the whole word.

                I happened to build one out of boredom the other day, so I figured I would share that.  The code is fairly well documented, so this is only going to cover the principals, and basic use of it.  First off, it should be noted that this needs more than a light understanding of C#.  It’s using Events and Delegation, which is roughly the same as turning methods into variables so they can be set, replaced and passed around. 

                Essentially, the first word in a line is a command.  In my case I chose the word “Verb” to name the class for it.  Essentially a Verb is given a word that it relates to, and then it is tied to a method, so if it ever gets triggered, it will call that method.  That part only requires a simple understanding of delegates.  The next part of the complications was in the “Manager” class. 

                The Manager can hold multiple verbs.  When a new verb is passed into it, it looks inside its list of verbs and places it in Alphabetic order.  So if you added West, then North, then South, it would be sorted as North, South, West.  A command called Execute in the manager separates out the first word from the text passed into it, then compares it against each word in its list to see if it matches up.  So, when I type in “s” for south, it goes to the first word, and compares the first letter, “s” does not equal “n” (the first verb being north), so it moves on the next word (south) and sees that the given letter “s” matches.  Once found, if executes that verb, passing in any additional text that was with it.

                When the manager is created, it needs a verb to execute incase it doesn’t find any matching verbs.  So if I typed “X”, which has no verbs, the manager would trigger the “unknown” verb. 

                There is one step farther.  Some words are used far more commonly, like North, South, East and West for various games.  (The words would be different for different systems)  Given this, I wanted to give priority to certain words over others.  Let us say that my game had a command called “Next”, which automatically reads the latest message or something similar.  My players now have to type in “no” at minimum for the system to know they meant North.  Or worse yet, perhaps there is a verb called “Norse” if my game has certain mythological tendencies of some sort, now my players have to type in “nort” before it recognizes “North” as the verb. 

                The priority system is simple.  If you want 2 levels of priority, which should probably be the most you ever use, then you create a “PriorityManager”, with 2 priority levels.  This class would then create 2 managers, and assign each one a priority.  This system treats the lowest priority as the lowest number.  It also uses 1-Based indexes, instead of 0-Based indexes.  It creates its own unknown verb for the managers, and when one manager doesn’t know the word, it passes it all on to the next.  If it gets through all the managers unsuccessful, the priority manager calls its own unknown, to let the system know that the command is unknown.

                The attached project was written in VS 2010 Beta 2, as many of my personal practices and projects are now written in that.  I believe it is free for everyone to download from Microsoft, but the CS files are easy enough to import into C# Express 2008 or 2005.

Download the Project Files Here

20100111

Collision Detection...

There are many ways to do collision detection in games, but only 1 I recommend.  1 method literally prints both images over each other, and checks each border pixel to see if its colliding with another from another object.  Imaginably, this can take a while.  Another checks each boundary as a box and uses basic if statements to determine how effective it is.  The third, and one I will recommend is using a Pythagorean distance checking formula.  First, I’ll get into the bounding boxes, and consider what it takes. 


With bounding boxes, you make the presumption that each of your objects fit within a rectangle.  Each object gets a location vector (Vectors were discussed in a previous article), and a Dimension vector that defines the rectangle’s height and width.  In order to compare the bounding box, we need to find out if any part of the box in inside the other. 


To do that it is somewhat straight forward, but repetitive and with small changes.  Essentially, you need to consider each border. And whether or not it is inside the other box.  Lets Presume, the following Object Fields:  Box.X, Box.Y, Box.Width and Box.Height.


The first part is easy.  Are either of the vertical sides of Box2 to the right of Box1.X.    If either are to the right of the left side of the box, it has the potential of being inside the box.


Boolean CollisionDetection(Box1, Box2)
{
If Box1.X < Box2.X OR Box1.X < Box2.X + Box.Width, Continue checking;
}

               
                Another way to write the same line, is to decide to stop checking, Like so:


Boolean CollisionDetection(Box1, Box2)
{
If NOT (Box1.X < Box2.X OR Box1.X < Box2.X + Box.Width), Return False
}


                Essentially at each validation line of the collision, it can stop processing, to save work, when it has already determined that it can’t be touching.  The line for determining the Top is almost the same as the height.


Boolean CollisionDetection(Box1, Box2)
{
If NOT (Box1.X < Box2.X OR Box1.X < Box2.X + Box2.Width), Return False;
If NOT (Box1.Y < Box2.Y OR Box1.Y < Box2.Y + Box2..Height), Return False;
}


                Detecting the bottom and right sides are similar, and to make it easier, I’ll add a few variables.


Boolean CollisionDetection(Box1, Box2)
{
                Top1 = Box1.Y;
Top2 = Box2.Y;
Bottom1 = Box1.Y + Box1.Height;
Bottom2 = Box2.X + Box2.Height;
Left1 = Box1.X;
Left2 = Box2.X;
Right1 = Box1.X + Box1.Width;
Right2 = Box2.X + Box2.Width;
If NOT (Left1 < Left2 OR Left1 < Right2), Return False;
If NOT (Top1 < Top2 OR Top1 < Bottom2), Return False;
If NOT (Right1 > Right2 OR Right1 > Left2), Return False;
If NOT (Bottom1 > Bottom2 OR Bottom1 > Top2) Return False;
Return True;
}


                So this is checking to see if one box is colliding with the other.  This includes checking if one is inside the other.  Reviewing this code though, it takes at least 4 equations, and at least 8 if statements.  So for every comparison you have 12 steps being processed.  At 2 objects to compare, this happens only once, but with 3 objects, you’ll have to repeat this 3 times, and with 4 objects, 6 times.  Lets presume the game has 20 objects on the screen that you need to detect collisions for, that means it has to run this 190 times.  That means 760 mathematic equations and 1520 comparisons.


                Its easy to see that this builds up quickly.  It also limits your areas to boxes.  Sometimes boxes are exactly what you need.  This is often true of Map based games, where things are set on squares (even if the squares are not so visible to the player).  But in free floating games, like flight simulators, water or space games, using circles is faster and easier.   Don’t worry about Cosines or Tangents, this won’t require any Trigonomic functions.


                Pythagorean Theorem is all that we’ll need.  If you haven’t gotten to it in school, or forgot it, here it is; In a right triangle (it has a 90 degree angle) the hypotenuse (the side opposite the 90 degree angle) is equal to the square root of the sum of the other 2 sides squared.


                In plain mathematics, the triangle below, C√(A*A+B*B).   In code, that looks like C = Math.SquareRoot(A * A + B * B);.  The order of A and B don’t really matter in this case. 


               

               


                The next question is how to apply this to in our code.  X and Y are also 90 degrees apart.  Lets say X is A and Y is B.  What you need is the X and the Y differences, and you get the points where A and C connect, and where C and B Connect. 


                In our new Game Objects, we will use location and radius or size.


//Game Object
{
                Vector2 Location;
                Float Radius;
}


To test if they impact, we will get the distance, and decide if it is greater than the radius of the 2. 


//Compare Objects
Boolean DetectCollision(GameObject g1, GameObject g2)
{
                Vector2 Diff = g1.Location – g2.Location;
                Float distance = Math.SqRt(diff.X * diff.X + diff.Y * diff.Y);
                If distance > g1.Radius + g2.Radius, return true;
                Return false;
}


                This code is considerably smaller.  Vector2 math uses 2 equations for each equation we use on it.  “g1.Location – g2.Location” is the same as “g1.Location.X – g2.Location.X” and “g2.Location.Y – g2.Location.Y”.  There are 7 equations and 1 comparison when checking 2 objects.  For 3 objects, there is 21 equations and 3 comparisons.  For 20 objects there is 1330 equations and 190 Comparisons.  So that is a significant improvement over bounding box collisions.  (As a reminder, that was 760 Equations and 1520 Comparisons, for 20 objects)


                But part of my statement isn’t true.  Bounding boxes can work better in some conditions.  For instance if the most common collision detection is between the player and everything else, and the player is typically at the bottom.  Your first check can be the top border.  If that fails, it can be only 1 equation and 2 comparisons.  Which means your most average check would only be 190 equations and 380 comparisons for 20 objects.  That is dramatically less.  Bounding box comparisons can leave earlier. 

               
                I recommend implementing both systems for practice, and doing some comparisons early in your game to decide which works best and why.   Do some performance testing on how it effectively works.

20100104

Vectors in Game Design

                When we first start creating 2D video games, we most often manage the variable X and Y for the object’s location on their own.  While all physics can still be applied this way, it makes it more difficult, and usually harder to enhance your game over time.  The modern world uses Vectors and for good reason.


                A Vector is simple, it holds 2 or more numbers.  For 2D sake, (since 2D has less to explain) we will use a Vector2.  A Vector2 is made up of 2 variables, X and Y.  The X and Y are used in more than just location; they are used for movement, dimensions and ranges.  For instance, perhaps your game needs to know the screen size.  At the beginning you create a Vector2 called Screen.  At any time, your program can ask for Screen.X, which is the width of your screen or Screen.Y which is the height.


//Settings
Vector2 Screen;
Screen.X = 800; Screen.Y = 600;


                Each of the objects in your game also carry a location vector, which defines where they are.  At the drawing cycle of each game loop, it will find each object, and draw it based for its location. 


//GameObject
{
                Vector2 Location;
}


                However, each of those are just setting a variable to identify a location.  Screen defines the Bottom Right Corner of the screen (0,0 being the Top Left Corner) and Location giving exact coordinates for anything that needs to be drawn.  Another perspective is Movement.  Movement, or momentum is a highly valuable feature.  My previous article discusses the use of momentum when applied to a single variable. 


                Imagine that if you pressed UP, it simply subtracted your Force variable (engine torque) to your Momentum.Y.  (By subtracting from the Location.Y, you move the object closer to the top of the screen)  If you pressed down, it added your Force to the Momentum.Y.    This takes care of your momentum for speeding up and slowing down, but now I’ll throw another variable in, Handling.   Handling will define how affective your steering is.  When you move left or right, it will subtract or add your Handling to your Momentum.X. 


(NOTE: “A += 5” is the same as saying “A = A + 5” it is a short cut in most languages used to reduce the typing for this common use.)


                OK, now given past knowledge, we might just say location.X += momentum.X and Location.Y += Momentum.Y.  With Vectors in programming, there are certain overridden operators, like + and – and * and \ and =.  This means that I can say Location += Momentum, and it will Add the momentum to my location, taking care of both X and Y.  If you are using DirectX, XNA or other game engines, this is probably already taken care of,  but if you are writing your own classes, you will either need to add your own methods, or you will need to learn about Overriding Operators and add methods for +, +=, -, -=, etc…


//GameObject
{
                Vector2 Location;
                Vector2 Momentum;
                Void Move()
                {
                                Location += Momentum;
                }
}


                In addition to Adding Vectors, you can also Multiply or Divide them by a single number.  Like Friction.  Such as, Momentum += 0.85. 


//GameObject
{
                Float Friction = 0.85;
                Vector2 Location;
                Vector2 Momentum;
                Void Move()
                {
                                Momentum *= Friction;
                                Location += Momentum;
                }
}


                I leave this article off with a request for you to go try it.   The only way to gain experience and timing knowledge is to practice this.