Sunday, March 11, 2012

My int is bigger than your float

Past weeks have been somewhat hectic with a lot of things to do both for AMA studios and the school. Finally I managed to free up some time to get back to working on my game.

The things I wanted to add at this point was the ability to load and unload maps to quickly test various level configurations. But prior to that, I needed some maps.


The key level building thing at this point is to create new elements to control the space where the player can evolve, and thus provide some control over the flow of the game.

Since the player can evolve at two height levels (upper and lower), I started by building some elements that can block the player at each level and force him to change the level if he wants to go further:


On the above picture you can see new barrier elements. Low barriers that are for blocking at lower level, high electric barriers that block at the upper level, and plain high barriers that completely block the player.

Note that I did some quick texture tests in order to see how transparency affects perception.

Now time for editing some levels with these new elements:


Ah,  I've had one tremendously annoying issue with the wall tiles. I needed to be able to turn them by 90 degrees. Fortunately Tiled just implemented that feature in one of its latest release...but...

Tiled encodes the rotation and flipping of a tile in its 4 most significant bits of the 32 bits integer tile index. Sounded fair enough until I realized that lua did not have enough precision with its 32 bits float (24 bits mantissa) to correctly interpret that data when converting from int to float (lua doesn't handle int). Unless you're working with double, you can't get a correct 32 bits integer converted into floating point. And on consoles we don't use double yet.

EDIT: Also I forgot to mention that there's no bit-wise operation in lua 5.1 anyways, I think that's something coming up in the next release.

So I came up with a rather twisted solution:

When parsing the xml file, I save the tile index as a string (I do not convert it from the file into a number).
Then I send the string to a C++ function that converts is back to int (actually a long integer) and then figures out the tile rotation based on the aforementioned most significant bits. It looks like this:


IA::tile IA::unpackTile(const char *tileID)
{
IA::tile currentTile;


unsigned long rawID = strtoul(tileID,0,10);
currentTile.id = rawID & 0x0fffffff; //mask rotation and flip info stored in the 4 most significant bits
int rotID = rawID >> 30; //keep only 2 most significant bits where the rotation info is stored
if (rotID == 0) currentTile.rot = 0;
if (rotID == 2) currentTile.rot = -90;
if (rotID == 3) currentTile.rot = -180;
if (rotID == 1) currentTile.rot = -270;


return currentTile;
}


Alright, now I've got my tiles with the right orientation, time to test some levels.

To choose the level to test, I need some menu. So while I was at it, I implemented a menu system that is completely data driven and allows me to add menu hierarchy and content in a simple lua table.


The first menu structure implements some basic states of the game, like Main Menu; Play; Pause; Game Over; Retry and Restart.

Here you can see the menu that pops up when the game is paused in the middle of an explosion (by pressing Start button) :


On this screenshot you can also see some of the barriers that forces the player to go to the upper level and confront the mines if he wants to grab the blue bonuses.

Next: life, shield and fuel management, and HUD


Wednesday, February 15, 2012

PSP Water

Today, a post that has nothing to do with my game project :)

I've been asked several times how we do our water effect on the PSP:
http://www.youtube.com/watch?v=QtIHRqt9dV0&feature=g-all-f&context=G2f3806aFAAAAAAAABAA

As the PSP is ageing now and slowly moving to the exclusives realms of homebrew and demo makers, I thought it wouldn't hurt to explain how we do.


It's a bit tricky so I hope I can make myself clear enough :) Here it goes:

The idea is first to have an animated map representing the waves moving. To do that I used some procedural texture generation tool to create each frame of the moving waves. Here is a frame of the animation.



You have to pack all the frames of the animation into a single 512x512 texture (the largest supported by the PSP) and then later do the animation by moving the UV coordinates over each frame.

I choose 102x102 pixels for each frame so i could pack 25 frames of animation into the 512x512 texture (five rows of five frames). I know it sounds weird.

I could have used 16 128x128 frames, but that would have been a short loop @ 60 frames per second.
Or I could have used 64 64x64 frames, but those would have been pretty low def.
Hence the peculiar resolution choice.

Then I used nVidia normal map filter pluggin for photoshop in order to generate a normal texture.


Then you need to quantize your texture using a very specific 256 colors palette. To create the palette, think of it as 16 row of 16 columns. In each column you can store the X component of a normal spanning an entire hemisphere, and on each row you can store the Y component.

Basically that gives you all the possible normals over an hemisphere stored into the palette:


Now when you quantize the texture with this palette, that means each of the texels now uses one of the 256 possible normals. It's a little rough, but when it's moving you barely see the quantization. Here's one frame from the quantized texture (cropped).


To render the reflection effect,you just have for each palette entry (256 entries) to compute the reflected vector from the eye vector around the normal vector that you know is stored in that palette entry (it's just a XY gradient so you can do that procedurally without actually using the palette).

That gives you a new vector that you can use as texture coordinates to sample an hemispheric environment texture. We use a small 32x32 texture of a sky with clouds and sun. The reflection and sampling with bilinear filtering is done in software using the VFPU (implemented by my partner @ Fresh3d Yann Robert), so it's very fast (a few microseconds).

Here's the environment texture:



Last you have to replace the palette entry used by the texture with this sampled color. So basically 256 vector reflection and color sampling per frame.

For every texel using this entry (normal) in the texture the reflected color will be displayed. And voila.

I think it's a neat method because of its fixed cost and no use of multiple pass fill-rate hungry methods.

There's a drawback in that the reflection is not in perspective, it's parallel, but it's hard to say if you don't know it. Furthermore this can be hidden by some billboard fake global, low freq, specular effect on top of it (that's what we do) to modulate the hi-freq wave effect.

Told ya it would be tricky :)

There's a envMap() lua function that applies to a color lookup table (palette) to directly compute all this and do the palette update. For those of you lucky enough to be able to use the engine :) Check this on the engine documentation here: http://freshengine.net/FreshEngineCommunity/documentation/scripting-reference-guide

Look for clut (color lookup table) in the effect section.

Monday, January 30, 2012

We come in peace

Mother
As you can see in my previous post, I've placed a mother ship symbol in my test map already. I'm thinking of having the mothership being out of reach from the player (for now) and dropping smaller objects that will attack the player.

What I did to prevent the player from shooting at the mother ship is to simply place it above the max player height. Basically you can only see it from a distance. I also added a large trigger sphere around the mother ship so that it triggers the launch of 4 tracking mines at the upper playable altitude when getting close.

Really my inspiration comes straight from movies with hanging motherships over large cities, such as V or Independance Day. I think it goes perfectly in line with the game's style.


Moving targets


The behavior I've been thinking for these tracking mines comes from memories of old C64 games I used to play when I was a kid.

More specifically Uridium  http://www.youtube.com/watch?v=P_wwiFrUTGY
and Z  http://www.youtube.com/watch?v=1hZBjZz5nWQ

In those games, some mine would chase you with strong inertia so you could avoid it simply by constantly steering up your ship in another direction.

I thought it would be nice to try that with many mines and see how the control performs. Initially I thought about the mines being able to change altitude as well, but when testing I realised they quickly would crash into the buildings and that made it too easy to the player to get rid of them. So instead they now keep waiting for you at the upper altitude.

The behavior is quite simple but effective:

  • Take the current direction vector of the mine and add a portion of the vector toward the player so that the mine move more and more toward the player.
  • As the mine gets closer to the player, it accelerates until a certain maximum speed is reach.
  • Each mine produces a sound, and the pitch is modulated according to its age. At a certain age the mines explodes. So the sound gives you a hint as to when it will explode.
  • All mines repulse each other (according to their respective distance), but if their speed is sufficient, they can crash one on another. This makes possible to eliminate mines without shooting by attracting several of them and then breaking away. With their own inertial speed they will crash on another.

Fireworks

Now that I have a basic shooting system in place (the player's ship fires bullets straight) and some moving enemies, it's time to see how shooting performs with moving targets.


Playing with the tracking mines is quite fun already, even at this early stage, but shooting them is not that easy because of the fixed fire direction. I take note and will investigate other possibilities later on.


Also in order to have a better feeling of accomplishment when shooting a mine (or when they self collide), I've added some temporary particle explosion. Here's a screenshot:



Next: Time to implement some game menu structure and the ability to load/unload levels to quickly test various level configurations.


Monday, January 9, 2012

Shoot, collide and collect

First, happy new year everyone!

Collisions
In order for the ship to collide with the environment, I have to setup collisions for the ship itself and for the objects of the environment (buildings for now).

In FreshEngine, you can use collision primitives (sphere, box, capsule...) for dynamic (moving) objetcs or static objects, and you can use arbritrary collision meshes (usually simplified geometry) for static objects only.

You can collide primitives with primitives, and primitives with meshes. You cannot collide meshes with meshes.

There's also the ability to ray cast against primitive or meshes, but I won't make use of ray casting for now.

So I will use collision meshes on the environment and collision primitives on the ship and bullets.

Let's start with the environment. Here you can see the collision meshes for my buildings:


Note that I've added a taller building since last time. This one is higher than the max altitude of the ship, making a barrier you cannot pass (or bullets can't pass).

Now I setup the ship's collision using primitives. I chose to use the capsule primitive for the ship as well as the bullet. I created also a mine with a sphere collision primitive because I've got some gameplay ideas that I want to test with a mine.


Notice how I have exagerated the length of the bullet collision primitive. That is to ensure it will collide with thin objects (like walls) even when moving fast.

Also for the screenshot here I moved the pieces apart but they are all centered at the origin for export.

Items
I'm planning to limit the amount of available bullets in order to create some startegic gameplay. Also I want to start with a low firepower and have the ability to improve that over time. The first implementation will be the ability to increase the fire rate (or shortening the delay between bullets).

So there will be two items that will represent these improvements.One (blue) will be extra amunition, the other (red) will be increased fire rate. At maximum rate (minimum delay), one bullet will be shot each frame, so 60 bullets per second.

So I create simple colored boxes to represent the items, and add a sphere collision primitive to them:


Pretty simple. You can see in order to make the item easily pickable I made the collision sphere quite larger.

Now I need to place the items in the map. I will make use of the ability to place objects at arbitrary location in Tiled:


I put these objects in my tileset, but they are not used as tiles. You can see I've created three new layers on top of the tile layer (Ground). These layers are objecs layers.

Objects on these layers can be placed with pixel precision in the map. So for instance I can put several items onto the same tile. That is why I made smaller icons for items.

As you can see, I've also added an icon for fuel and motherShip as I've got some ideas of how these should work. I'll implement them later.

Theres also a respawn point, which is where your ship appears when you start the map. I might need several of those later, so I made a layer specifically for that information.

Now the format for objects in the map file is a bit different than the one for the tiles, so I had to update my xml parser a little.

Item collisions
There are several filters you can use in FreshEngine to tell what collides with what. And there are several collision callback functions that you can use depending on the behavior you want to capture.

For the ship/items collisions, I've used the trigger callback, so it is called only once when the collision occurs.

All the collision behavior has been implemented in lua as the overhead is manageable and collisions won't occur all at the same time.



Shooting bullets

This one made my head hurt a bit.

There are two approaches here:

The first one is to create on the fly a new bullet when needed (by cloning the one from the library), and destroy it when it collides. Altough quite simple, this approach made me nervous because I could feel that creating and destroying objects on the fly at high rate could potentially create some serious performance problems.

The second idea is to create a pool of bullets (corresponding to the max bullets that can be on flight at a given time) with all bullets hidden at the beginning. When you shoot a bullet, you make it visible and when it collides you make it invisible again at re-initialise its position at the ship position.

That sounded much better in term of performance, but for me sounded a lot more difficult to implement as I don't have much programming experience...yet :P

The first challenge is to identify which bullet is to be hidden when a collision appear. To implement that, I made use of the ability to attach a custom attribute to an object in FreshEngine. So I added an ID to each bullet that I can querry when a collision occurs.

Next you need to manage your pool of bullets in order to know which bullets are available. I made use of a table of available bullets with a pointer to the top. When a bullet dies it is put back on top of the stack and he pointer increases, when a bullet is shot, the new bullet goes in flight and the pointer to the available is decreased.

That is not as trivial as it may sound because you might shoot two bullets in sequence, but the second could well be dead before the first one if it encounters a obstacle first.

Only the bullets that are in flight are updated. So it's very fast.

I have to say this was my first serious C++ implementation challenge (besides setting up the project in Visual Studio).

Here's the result (I will make videos further down the line, but you'll have to do with the screenshots for now)


It's quite fun to shoot everywhere. I've also quickly added some sound effects to have a feeling of the shooting rate. It quite helps to get the feeling and to know at wich rate you're firing.

I've also added some sounds when the bullet hits a building, with some random sample selection of broken glass sounds.

My only question for now is, as you need to orient the ship to orient the fire (fires straight in front of the ship), will this be practical and precise enough when surrounded by ennemies?

As a first step, I did some tests with the mines. Currently mapped to a button, they stay where you put them. There's a little rotation animation playing to give some life to them. I'm planning to use them with ennemies to create some sort of mine walls or something.


As you can shoot the mines as well, it is useful to evaluate if it's easy to shoot at static objects. I must say it's quite easy, but we'll see how it goes with moving object!

Next: First Ennemies implementation

Monday, December 26, 2011

First Implementation

For this first implementation loop I started with the map setup and control of the ship. I'm using temporary assets here for the sake of quick iteration. The ship comes from a FreshEngine PSP sample I did a while back.

Levels

I'm testing first on a city setting, simply because it is modular by nature and will help me defining the game constraints. I choose to use a 1 unit for a bloc of the city. So I can quickly and easily build large cities. I built 2 buildings blocs and one ground bloc in Maya and then exported them as static objects.



In Tiled, I created a test map using small 64x64 pixels icons for each of the tile. I export the map in the CSV format (Coma Separated Values).

I then wrote a small xml parser in lua to extract the values and generate the map in a lua table with each tile index.

At load time, I load the CSV file (a few kilobytes), generate the table and simply instanciate my static objects depending on the index in the table, and voila the map is generated in a few miliseconds.

Control

My first implementation of the ship control was in Lua so I could validate the functionnality. Now it's all in C++ and is much faster.

I'm using constraints to drive the ship so I can introduce some delay by simply changing the strength of the constraints on each axis. The camera is also constraint to the ship (using aim and position constraints).

Controling an object in camera space requires to take care of a few things.

In order to control the ship at even speed whatever the camera view, I need first to project the camera front vector onto the XZ plane otherwise the speed of the ship would vary depending on the camera pitch.

As my camera will not roll, I can take the camera Right vector as is.

Then I can modulate the stick vector by these projected camera vectors.

Next I need to check for the length of the vector not being greater than 1. It can happen when the stick is in diagonal because the diagonal is longer than each separate stick axis. If that's the case, I need to limit the length to 1.

To switch altitude, I simply change the altitude of the position constraint of the ship and the engine smoothly interpolates (weights inependently set on each axis) the ship position.

Here are some screenshot from the PSP version:
This is when flying at the upper altitude (1 unit). So the ship can fly above the buildings.


And now, when pressing the altitude switch button, it goes to the lowest level (.3 units):


Notice how the camera is now almost vertical to allow a better readout of the situation and enable the player to easily fly around the buildings.

I also change the camera field of view (FOV) so the view gets almost orthogonal when the ship is at the lowest altitude. This completely change the perception of the game and makes you fell more involved in this view. It will be useful when interacting with ground objects.

The shadow really helps to read the flying altitude. I don't have the shadow yet on the PC and PS3 versions since I need to write some Cg shaders first. On PSP the shadows is managed by the engine and doesn't require writing shaders since it's all fixed pipeline. I'll do that later.

Next post, shooting, collisions and bonuses.

Sunday, December 4, 2011

Story and Mechanics

As I'm planning to develop a personal specific universe for this game (as opposed to using the Zaxxon one) I need to develop a story around my game.

My story summary for now is the following:


'A week ago, invaders attacked the earth. Given their supperior technology, they defeated coalition forces in no time. They made all human prisonners, but one guy escaped. During his escape he found some special weapon. Now he wants to fight the aliens back and free earth from their hold.'


Let's first give a tentative name to the game (I need it for my project folder anyway). I need to convey the spirit of the game which I'd like to be somewhat tongue-in-cheek and kitch.

Key words I've assembled are: Invaders, aliens, revenge, aftermath, fight back, conflict, universe, galaxy, space, star, battlefield, earth, attack, freedom, mankind, unwelcomed, the clearout, species, roswell, area 51, armageddon.


Another important thing is to comme up with a name that is unique and has not been used anywhere else. Some google search will help, but generally the longer the name, typically with a subtitle, the least chance you have to get sued.


So I came up with this:


'Invasion Aftermath, Mankind's Revenge.'


Note this could be read as 'I'AM Revenge'.


Let's now talk a little about the game mecanics.


My planned process it to iterate around a prototype to remove risks and validate mecanics.

Here's my first process loop (essentially focussing around the 'toy'):




  • Is my control pleasant and intuitive?
  • Can the player easily understand the height of the ship?
  • Is it intuitive and easy to shoot static objectives on ground and in mid air?
  • Same for moving objectives?
  • I'm quite fluent with Lua, but can I implement and integrate custom functionnalities in C++ when I need higher performance ?
  • Do I have a fully functionnal and convenient pipeline for quickly building dozens of levels?
The first mecanics I'll implement are the ship control and the camera.


I'm a huge fan of SuperStardustHD (developped by Housemarque), and although my camera will be in perspective (as opposed to top-down in SDD) I do like the screen-space control scheme. It's a well acknowledged way of controling a character and it has been there since Mario64.


So to move the ship, you use Left analog stick. Relative to the screen.


That is something very different from Zaxxon, because here you'll be able to move in any direction on the XZ plane. This will allow for some specific gameplay patterns and could potentially allow for exploration mecanics. Great if the levels are potentially huge.


Also I need to control altitude change. In order to reduce complexity, I will assign a button to switch altitude. This way, I can avoid difficult situations where the ship would not be alligned with ennemies or item height. So we have two heights, low and high. I will then be able to design ennemies/traps..etc specifically for each height, and some might also be able to change height just like the player.


As the camera will always look pretty much toward the same direction, I do not plan to give control over the camera. It will be essentially automatic. I need however to give enough room around the ship in order to ensure sufficient visibility for the player. In other word, the camera will be quite distant.


That means I'll need some close-ups during cinematics or whatever, to create some binding between the ship/main character and the player. I think it's important for player 'involvement' and suspention of disbelief. I'll leave that for later, as I focus now on the core mecanics.


Allright, next post first control implementation and screenshots!

Monday, November 14, 2011

Let's get started

According to Schell, the four elements that will form the game are: Aesthetic, Technology, Mecanics and Story.

I recently made a slide for a conference I had at the school that sums it up:



As stated in my first post, I'll do the eye (ear) candy later. So I decide to postpone the aesthetic related decisions a little (including sound and music). I know from my experience I'll be able to handle all those aspects with no difficulties (apart from the immense amount of work to be done).

Let's talk a little about some technology choices I need to make. My goal is to produce the game on as many different platforms as possible. FreshEngine (www.freshengine.net) is cross platform and cross generation, currently supporting PC, PSP, PS3, X360, with Vita in progress and Android and iOS at the blueprint stage.

I however have to plan how to deal with the disparities in performances and graphic capabilities of all those platforms.

Although I know my vision of the game will evolve with time, I need a starting point. That's why I'm using Zaxxon ( http://www.youtube.com/watch?v=toSxQ3QHaTc ) as a reference. That means controling a 'ship' in lage environments with a 3/4 top down perspective, shooting at enemies, avoiding traps, and dealing with 'height'.

As I want the game to feature dozens of levels, I need some effiecient ways of building those levels, with the ability to quickly test a level within the game. I also need an abstract representation so I can edit a level once and automatically deploy it on all the platforms with their respective specialised assets.

For instance, I want to be able to place a building in the map, and automatically deploy a low-def building on PSP and an hi-def building on PC.

Also, to be honest, I have no idea how long making this game will take. Probably 2 or 3 years. Will it make sense to make a PSP version at the time? Probably not. Will it make sense to make a PS4-X720 version? Could be. The truth is I don't know. So I'd better prepare for them all.

Finally, I need this representation to be compact as I plan the game to be distributed via digital distribution only.

The idea is to edit the map using Tiled (http://www.mapeditor.org/), a free to use generic tile map editor. I use the 2d tiles to represent map elements in an abstract way. The map is then exported as xml file containing a reference to each tile and some other infos such as rotation, additionnal objets or items.

At run time, when loading a level, the xml file is parsed and, depending on the platform, each tile is referencing a 3d object instance from a library that has been previously loaded into memory. There is one library for each platform, but it is only loaded in that particular platform, when the game starts.

The libraries are created in Maya, and optimised for each major platform.

Next posts, Mecanics and Story.