Grey: The Lost Technology

About the Game

Grey: The Lost Technology is the first project for Team Aurora, the independent game studio a few friends and I co-founded. Grey was successfully Kick-started in May of 2012. We were able to travel to PAX East and meet with a lot of fellow developers and met some really cool people. The game is an action RPG that explores the possibility of an overpopulated Earth and the humans who leave to find a new planet to call home.

Development

The game is programmed in C# using the XNA Framework. The game does not use external libraries, and instead uses the game engine we have programmed called “Aurora2D”.

Game

The game is primarily Quest/Narrative driven. What this means is that you need to speak to someone, who will give you a quest. Once this quest is completed you will be awarded with another quest, or you will tasked to talk to a person who will give you quest. The dialogue system is something that I spent some time working on to make sure it functioned just right. Imagine the dialogue mechanic like any RPG, or text-based action game: The text shows up in a box and then continues to show up in chunks until a response is required. Each response can link to certain objects in the game. Talking to someone can give you:

  • Quests
  • Money
  • Health
  • Experience
  • Items

Alternatively, it can direct you to more dialog. Implementing this is primarily about a good structure and design of the dialogue objects themselves. A Talker, when spoken to, evaluates each dialogue that is tied to them. They accept commands and react accordingly.

Another large contribution of mine is the design and implementation of the map system. A map is designed like so:

  • Map
    • Levels (Can be viewed as subsections of a map)
      • Layers
        • Tiles
      • Group Objects
      • Spawners
      • In-location markers
      • Characters

A map is broken down into levels (read: sections), then a level is broken down to handle each component that is drawable from the tabs in the editor (See below). So the structure is simple, each type of object has their own list, and when the maps are saved, they are serialized in an overridden XmlWrite that structures each object list as a group. However the most revolutionary part about the serialization is about saving the tiles. When serializing the tiles, there is a dictionary that holds a dictionary, kind of like this: Dictionary<int, Dictionary<int, Tile>>. This can be seen as [x][y] = tile. You might be thinking that it should be stored as an array, but when saving an array it saves all the empty positions, and we don’t want that. So I wrote a loop that writes out each tile within an <X> element and a <Y> element. The <Y> element holds the tile position in the texture, and then also holds an index to a texture that it uses. The ending result looks kind of like this:

<Level>
  <ScreenWidth>20</ScreenWidth>
  <ScreenHeight>12</ScreenHeight>
  <Position>0,0</Position>
  <Textures>Content/Textures/Tiles/Sand_01.png</Textures>
  <Layer>
    <Name>Sand</Name>
    <Priority>-15</Priority>
    <CollisionType>0</CollisionType>
    <X0>
      <Y1>0,1</Y1>
      <Y2>0,2</Y2>
      <Y3>0,3</Y3>
      <Y4>0,4</Y4>
      <Y0>0,0</Y0>
      <Y5>0,0</Y5>
      <Y6>0,1</Y6>
      <Y7>0,2</Y7>
      <Y8>0,3</Y8>
      <Y9>0,4</Y9>
      <Y10>0,0</Y10>
      <Y11>0,1</Y11>
    </X0>
  <Layer>
<Level>

This saves us a tremendous amount of space and is a lifesaver in terms of distribution of the final product (because there are less files to transfer, it’s much easier to share). To read more about my theory and logic behind this serialization concept, check it out here: Problems of Storing Maps

Editor

Since we created the game with a framework, and did not use an existing game engine, we needed to create a game editor. The game editor is something of my own creation with the exception of the Navigation Mesh Editor written by our other programmer, Jacob Jackson. The editor is an XNA project that is supplemented by Windows Forms. When the game launches is creates the Control Panel that the designers will be using to manage game assets and map textures.

Control Panel

Grey Editor: Control Panel
Grey Editor: Control Panel

The control panel offers all the flexibility and options that a game designer needs to fill in a level and create everything that is going to be in the level. On the surface you can see that you have the ability to manage:

  • Texture Placement/Selection
    • Animated
    • Static
  • Objects
    • Map Links
    • Characters
    • Enemy Spawners
    • Location Marker/Zones
  • Particles
  • In-Game Items

By adjusting the Edit Mode, you will have access to different functionality offered by the editor. For example switching from TILE (which allows you to place all of the items offered in the tabs) to PATROL_EDITOR, you will be able to draw patrol path lists that and have the ability to customize them. There is also an Edit Mode for drawing the Navigation Mesh on a map. Lastly, there is another edit mode for drawing world-space collision geometry.

The Draw Mode combo box allows a designer to change between:

  • Drawing – Draw an object in the scene
  • Deleting – Delete an object in the scene
  • Editing – If drawing collision, use to add vertices to a shape
  • Transforming – If drawing collision, use to grab and move vertices of a shape

Tools

Collision Editor

animationeditorSome of the coolest parts of the editor are in the Tools Menu. The tools menu provide a designer with the ability to add collision geometry to each and every character model/animation that exists in the game. Using the Collision editor is simple. A list is populated with all the animations from the spritesheets and then the selected spritesheet is drawn and all that is required is to click and drag to draw a collision box. Rotating the collision box is done by holding space after you dragged the box out to it’s appropriate size.

Data Editor

The Data Editor gets into the nitty gritty of the actual game itself and allows the designer to

  • Create all items in the game
  • Create all the quests of the game
  • Create magic effects
  • Alter “New Game” configuration options

questeditorThe quest creation system is a portion of the editor that I had a lot of fun working with and was able to really break down a solid questing architecture.  The quest system is broken down like so:

  • Quest
    • Quest Steps
      • Continue Requirements
      • Failure Conditions
      • Rewards
      • Items to Remove
    • Rewards
    • Items to Remove

A quest must have steps to be completable. Think of a game like The Elder Scrolls: Skyrim where a quest often times has a few parts that must be completed to complete the overall goal. To evaluate each of the Continue Requirements, I hook events for each running quest and then when anything in the game happens and fires an event, each quest you are completing will be updated concurrently. This event driven implementation is the core of the quest system. As a supplement, I created what I like to call an action list. The action list is a rolling list of every action that our hero, Oren, performs in the game, whether it’s killing an enemy, clearing a spawner, or changing maps, it all gets recorded as separate actions. This implementation solves the problem of a player exploring the map and killing a boss or character that spawns once in a game, then getting the quest tells you to defeat him, and not being able to complete it. A quest checks the action list in parallel to the events that it handles.

createitemThe Item Editor is also really cool because to complete this I implemented a class parser using C# reflection to handle populating the editor. There is a main recursive function that handles the population aspect. This function takes the object and uses reflection to evaluate each public property and generate a component that best fits the type of property it’s evaluating.

Engine

The engine is a set of utility classes and objects that offer a full suite of functionality and easily pluggable into different situations. Some of the tools offered include:

  • Texture Parsing for Animations
    • Texture Atlases
    • Grouped Textures
    • Single sprite sheets
  • XML Serialization
  • Quad Trees
  • Separating Axis Theorem (SAT) Collision Detection
  • Baseline Menu Creation
    • Including Buttons and Sliders
  • Lots of Extensions for Primitive Classes
  • Input Management
  • Resolution Management
  • Event Management

The library is fully featured and provides us with a very solid base to build Grey with.

Simulating the Solar System in C++

Hey everyone,

Recently I’ve been working on simulating our solar system and it has been a difficult endeavor. There are a few big problems that I faced in this project:

  • Float Point Imprecision
  • Conversion from actual (metric) values to something smaller

Let’s evaluate each of these items.

Floating Point Imprecision

A float is a 32-bit data type in many languages that allow you to hold decimal data. You may have heard of floats referred to as Singles, this is because floats have a bigger brother known as a double. They are called doubles because it is a 64 bit data type. This allows a double to hold a much larger number, but you have the overhead of using a lot more memory. Due to this, there is a tradeoff in the manipulation of the data. Further, floats are use in many existing libraries and utilities, so now there is build in imprecision. What is imprecision? Imagine working with some really small numbers, something like 1.0 x 10-10 then dividing this number by say 1000. After these operations, the values will be getting so small that you are bound to lose some digits simply because the data type cannot hold numbers of that size. Imprecision is basically a limit on decimal digits, resulting in “unintended” rounding.

Actual Value Conversion

Because of the previous point having been stated about imprecision, using the real solar values is not preferrable because after all of our calculations, much of the data will be cut off. I found this part very difficult because finding a suitable size was nearly impossible. However, in the end I was able to make a decision and for distances, I decided to go with Astronomical Units and for weight, Earth Masses. Getting these values was easy because all I had to do was perform a simple Google search and I could find the AU’s a given planet was from the sun, and their weight in Earths.

Formula

To perform this simulation, I am using the Newtonian Universal Gravitation Equation

universal gravitation equation

Because of the units that I chose to use to scale the actual values (AUs and Earth Masses), it was extremely difficult to convert Big G to a number that accurately represents Earth Masses and AU’s. For this I used the good old, Guess and Check method. I just tried values that I thought might work really well for what I was doing. Ultimately I was able to find a value that fit well with my solar system.

Notes

This project is programmed in C++ using OpenGL (Libraries: GLFW3, Glut, Glew, and GLM).

Video

Check out the video below to get a better idea of what the project is like

 

Senior Production: Initialization

Hey everyone,

My final semester at Champlain College has begun, and I am once again required to write about my experiences in the last half of my capstone class.

This last week was about reworking the networking for the game. Our new programmer, Dan, and I were working together to remedy some of the hacky solutions I came up with while rapidly developing VacuuLab. We decided it would be best to create an authoritative server set up to ease the implementation of game features and be able to monitor the game closely. Having a dedicated server would allow us to control the games and be able to make better decisions for level design and etc.

As far as the development, we have implemented smoothing and simple game play.

That is all for now.

Tom

Easy C# Custom XML Serialization

Hi everyone,

In the past, I spent time working with XML serialization for Grey: The Lost Technology, and I ended up writing a blog post about my findings and experience with “compressing” data to create smaller xml files, which is seen here: Grey Dev Diary: Problems of Storing Maps.

Now I want to show you a specific method that I use when writing a custom serializer for an object that needs special processing during (de)serialization. First, you would implement the ISerializable interface, and you would need to implement the following functions:

public System.Xml.Schema.XmlSchema GetSchema()
{
    return null;
}

public void ReadXml(XmlReader reader)
{
}

public void WriteXml(XmlWriter writer)
{
}

For me, reading the XML had always been the hardest part, until I came up with this:

public void ReadXml(XmlReader reader)
{
    while (reader.Read())
    {
        if (reader.IsStartElement())
        {
            switch (reader.Name)
            {
                case "Name":
                    Name = reader.ReadElementContentAsString();
                    break;
                case "ValueA" :
                    ValueA = reader.ReadElementContentAsInt();
                    break;
                case "ValueB" :
                    ValueB = reader.ReadElementContentAsInt();
                    break;
                case "DeeperObject":
                    //If object has more information and is its own class, deserialize that one.
                    reader.ReadStartElement();
                    DeepObjectInstance = (ObjectTypeClass)new XmlSerializer(typeof(ObjectTypeClass)).Deserialize(reader);
                    reader.ReadEndElement();
                    break;
                default:
                    //Do something if no case for the start element
                    break;
            }
        }
    }

    //Any sort of post processing
}

The main idea is that you loop through the start element of each entry, and then if you have a case for it, read the values. It’s super simple, and if you need to scale the object you’ve been serializing you won’t break anything.

Writing the XML is just as simple, but you don’t need to loop through anything to do it.

public void WriteXml(XmlWriter writer)
{
    writer.WriteElementString("Name", Name);
    writer.WriteElementString("ValueA", ValueA.ToString());
    writer.WriteElementString("ValueB", ValueB.ToString());

    //Don't forget you can call the WriteXML of another object and serialize it in the
    //same file as the one you're already writing to. It just means more processing later.
    //OtherObject.WriteXml(ref writer);

    writer.WriteStartElement("DeepObject");
    new XmlSerializer(DeeperObjectInstance.GetType()).Serialize(writer, DeeperObjectInstance);
    writer.WriteEndElement();
}

That’s all I have for you! If you have any questions, don’t hesitate to comment!

C++ Library Wrapping Weather.gov REST API

I’ve began creating a library that wraps the REST API offered by weather.gov. It’s not much right now, you can only input a latitude and longitude to get the highs and lows for the next 7 days, but it’s pretty neat nonetheless, and I had a pretty good time trying to get everything to work the way that I wanted it to.

Information

Why create a library for this? TO LEARN! I wanted to learn how to make a library in C++, and learn how to use the CURL library in C++, and then take these libraries and use them in a project. I don’t have a real project to use them in for now, but eventually I will use it, and add more to it.

Pro-Tips for C++ Libraries

In Visual Studio, you’ll see that there is a template for creating a Class Library in C++. This is for creating a library that uses managed code that is compiled with CLR (Common Language Runtime). This is not what you want. It’s a pain to get this set up if you plan on solely using C++ for your library. The best way to do it is to create an empty project then go from there.

Quick Tutorial:

First, create a new Empty Project, call it TestApp. Now, in the same solution, create a new project, and make it an Empty Project, this will be our library. You can call it TestDLL. The next thing we are going to do is create some classes to use in our library. Add in a header file called TestAPI.h. We will not be adding in any C++ Source Files (.cpp) because it creates issues in the namespacing. We are going to start it off really simple:

#pragma once //sorry, windows only. Too lazy to make ifndef

namespace TestAPI
{
	class Mathematics
	{
	public:

		Mathematics() {}

		int Multiply( int num1, int num2 )
		{
			return num1 * num2;
		}

	};
}

That’s all you need as far as code for the library. Now we are going to configure our TestApp project to use our library:

 

Resolve some dependencies
Add a reference to the TestDLL Library

Now, after that, you should be able to just reference your Mathematics class really easily. Now lets create the main function for our TestApp project that’s going to use our library. Go ahead and create a C++ Source File called main.cpp, and add the following code:

#include <iostream>
#include "TestAPI.h"

using namespace std;

int main()
{
	TestAPI::Mathematics math;
	int result = math.Multiply(3, 5);

	cout << "Results: " << result << endl;
	// Results: 15

	return 0;
}

That’s it!

Problems

In my implementation of the Weather REST API, I found that when I tried to use libcurl in my project, I had to include it in both my TestApp and my TestDLL. Other than that, everything went smoothly.

 

Download: C++ Weather REST API Wrapper

C++ Event System using Delegates

Recently I’ve been working on an Event System in C++. You might be reading that right now and wonder why that small sentence makes it sound like a true endeavor. Well, it was. As many of you may know I’m a student at Champlain College, and in one of my classes, each of the students are tasked to use an event system or a messaging system in their game. The teacher provided us with one, and it’s really great and all, but I couldn’t help but feeling restricted, especially after having used C# for so long where the code is so forgiving, and easy.

I did some research and it turns out that a lot of event systems in C++ are organized in such a way that when you want to do events you must:

  • Create an EventManager class (nothing wrong with this)
  • Create an EventListener class (for setting up events)
  • Create and Event base class
  • Be restricted to use only one function to handle your events
  • Create a huge enum holding a key for each of your events (Can hash it for speed)

I saw those and my heart dropped. I immediately thought that is way to restrictive, there must be an easier way to get events to work. And so the researching began.

Continue reading “C++ Event System using Delegates”

Understanding C# 2D XNA HLSL – Part 2

Read the first part here

I know a lot of you loved the first part of this breakdown, and now I’m back to continue the explaining!

Breakdown of Effect Parameter

Continuing from the end of the first part: What the effect parameter does here is that it takes our effect and then applies it to all of the textures that you draw then on. This is effective for coloration effects such as black and white, or inverting colors, but if you have an effect that works based on certain coordinates or is constricted similarly, then you need to be  very careful! To avoid issues like that, there is a rather simple solution when you want to apply an aforementioned size/position constricted effect to the screen.

Further Implementation

Adjusting the Effect parameter of the SpriteBatch.Begin() function is not the only way to use HLSL effects in your projects. Another method that you can do is draw all of your textures to one RenderTarget2D (Think of this as an empty texture, or a blank canvas). After you’ve drawn all your textures to that, it’s really easy to apply your effect to “the screen”.

RenderTarget2D MainTexture;

//In the Initialize function set up the rendertarget:
PresentationParameters pp = GraphicsDevice.PresentationParameters;
MainTexture = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight);

        //Then create a function to draw your game textures to, and draw it all up       

        private void DrawGame(GameTime gameTime)
        {
            GraphicsDevice.SetRenderTarget(MainTexture);
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            spriteBatch.Draw(bg, GraphicsDevice.Viewport.Bounds, Color.White);
            spriteBatch.Draw(player, new Vector2(200, 300), new Rectangle(0, 0, 128, 128), Color.White);

            spriteBatch.End();

            GraphicsDevice.SetRenderTarget(null);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            DrawGame(gameTime);

            GraphicsDevice.Clear(Color.Black);

            // Use Immediate mode and our effect to draw the scene again, using our pixel shader.
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);

            mainEffect.CurrentTechnique.Passes[0].Apply(); // for every pass that you have you can apply
                                                           // all them to the texture if you want.
            spriteBatch.Draw(MainTexture, Vector2.Zero, Color.White);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }

Alternatively, you can use the effect parameter in the spriteBatch.Begin() function when drawing MainTexture, because remember: The effect is applied to the texture in every Draw() function call. If you only have to draw one texture and want all the passes applied when drawn, then you can use the Effect parameter.

Why do this?

In a project I was working on I really wanted to have an INFINITE amount of 2D lights in my game, and after countless attempts at getting a high number lights (higher than 5) from all HLSL effects, I found that by drawing a my lights to a texture, and then my game to another, I could then use an HLSL effect to blend my lights together.

 

I hope this helped.

-Tom

Understanding C# 2D XNA HLSL

Introduction

Firstly, what is HLSL? What can we use it for? HLSL is an acronym for High-Level Shader Language, and because it is a shader language, it runs on the GPU of the computer. With HLSL you can perform many post-processing effects, such as: blur, point lights, black and white, bloom, and pretty much any filter you can think of that can be done in Adobe Photoshop.

When working with HLSL on the Xbox 360, you are limited to using Pixel Shader 2.0 (This way you can support all Xbox’s) rather than 3.0, which isn’t terribly bad, but it could be so much better. You can do a lot with pixel shader 2.0 with up to 64 mathematical operations per-pixel. Because it is a pixel shader, the code that you write will be executed on every single pixel that is on the texture you’re working with. If your game resolution is 720×360, totalling to 259200 pixels, and if you have 3 mathematical operations per pixel (for example you are using sin, cos, and +), totalling to 777600 mathematical operations done for every time this shader code is ran (typically the total amount of times you draw the effect to the screen).

 

Examples

Nearly any filter that can be done in photoshop can be done with a shader. So, check out an example (more to come):

Radial Blur Example
fig. 1.0: Radial Blur

Continue reading “Understanding C# 2D XNA HLSL”

Zong, pong for the Zune

Well, this is a little pong game for the Zune that I whipped up. There’s probably a better way of doing this, but I just ported it from this guy’s source code:

Flaim – PONG in AS3 in ~ 1KB

Now, here is the source code for Zong (you need visual C# and xna 3.0 beta to open and run it):

[Zong.zip – Source Code]

Have fun, and if you can fix the enemy paddle’s shakyness, post a comment!

Thanks