Showing posts with label Xbox. Show all posts
Showing posts with label Xbox. Show all posts

Sunday, 3 February 2013

Alpha Playtest Version

UPDATE: This playtest has now expired.  The forum remains for anyone interested and there will be future versions when I have made sufficient changes for more testing to be worthwhile.

I'd like to thank everyone who tested the game.  I received some excellent feedback and and am working through it all to make changes.

==

I have just uploaded the first version that other developers can play.

For those who may be interested please be aware that this is only available to Xbox Live Independent Game (XBLIG) developers who have a premium subscription with Microsoft.  That's the way Microsoft set up the publishing mechanism for the Xbox.  That's a long way of saying only other Xbox developers can get this download:

http://xboxforums.create.msdn.com/forums/t/110018.aspx

 
 


I am a bit nervous and excited because this will be the first time that anyone other than me has played it. I've demo'd older versions to a few friends before but these only had partial test levels. No one else has played a version where a level can be played through from start to finish.

The game is still a long way from completion.  Lots of the graphics need improving both in game and on the menus.  I need more player characters, more types of aliens, better animations and most importantly I need to write the network code so it can be played on line.

That's what's not there but what is there...

- Character selection.
- Single player
- Two player split screen
- Playable level with an end objective (a bit simplistic at the moment I admit)
- Selection of weapons including different types of grenades
- AI controlled Bots. Despite their limited skill set they still make difficult opponents
- Ammo counters, weapon sights, grenades, the usual stuff...
- Weapon and ammo pickups
- Lots of enemies to shoot at
- End of game scores
and more...

If you are an XBLIG developer I hope you try it out and enjoy it.

http://xboxforums.create.msdn.com/forums/t/110018.aspx

==

For anyone else at this stage it took about 3 hours between uploading the file and it being available to download.

Thursday, 30 August 2012

Consequences

I made what I thought was a tiny change to the code to fix a problem and now when I test on the Xbox the steady 60 frames per second (FPS) sometimes drops momentarily to 58 FPS.  This is not noticeable in game but I know it is there.

It demonstrates how close to the limit my current code is.



The change was required to fix a problem where a small model in some positions viewed from some angles would disappear from view.  It was either a bug in the frustum to sphere intersection testing code or I was just being over zealous with what I culled from the view.  Whatever the problem was, it was solved by increasing  the area used for testing what was potentially in the view.  The consequence is that more models are likely to be drawn each frame.

Those few extra models being drawn was enough in some places on my first level to tip the balance between drawing everything in 16.6 milliseconds (one frame) to not being able to draw everything in that time.

I'll tinker with the code to try to fix both problems.

Sunday, 18 March 2012

The Rocket Launcher

Every shooter needs a BFG.  In this case it will probably be this rocket launcher.


That was the concept I drew a few weeks ago.  I've been thinking about it for years, on and off.

3D modelling, as I've mentioned before, takes a long time.  The time spent at the computer to turn that idea in to the the finished model ready to use in game has taken over 20 hours of work.


Where possible I want to use off the shelf models to save time.  I have managed to find plenty of sci-fi environments that will be ideal for my levels but there are no sci-fi weapon sets that match the style of the game I want.  In fact there are hardly any sci-fi weapon models at all and even less that are of low enough poly count to use in my game.

The above model has a few over 2900 faces.   I would have been happy with anything less than 4000 polygons but I like to keep everything to a minimum.  In my opinion the more important bit is the quality of the texture.

The time works out at about 6 hours modelling, 6 hours UV unwrapping and the rest of the time creating and applying the texture.  I mainly use GIMP for that with lots and lots of layers.  At the moment I'm using a 2048x2048 texture but if the Xbox 360 struggles with too many of those I'll drop it down to 1024x1024 before the game is released.


And There's More...

I managed to sort out some bugs on the next bit of code I'm looking at.  I want to be able to test multi-player without dealing with the networking troubles at the same time.  Therefore I need split screen.


The screenshots are all taken on the PC and I use an Xbox game pad connected via the wireless adaptor for one player and the keyboard for another.  I managed to sort out a bug which had been preventing it from displaying on the Xbox 360.  Now I know the concept works on both the PC and the Xbox I can sort out the other details.

On the Xbox 360 the names in the top right corners of each view show the GamerTag names.

Despite it not being anywhere near finished my wife and I still found it great fun on the Xbox to run round the level together shooting at each other and the alien.

It's starting to feel like a game rather than just a project.

Monday, 23 January 2012

Behaviours are Working

I had enough coding time at the weekend to sort out the troublesome behaviours.  My test Bot will now run, walk, strafe or face the direction being travelled and hardly ever gets stuck.  It even ducks down behind cover.  Not always quite where expected but it does not look daft.

Compared to the frustration of a week ago I am very pleased with the results.

The main change was to be consistent with what code updates the movement.  It now always uses a route generated from the path finder class even if that ends up being a straight line.  There was a lot of tidying up to be able to do this.

To be able to strafe I had to add an enemy target location and then a bit of tweaking to smooth the movement, especially aiming up and down, to stop it looking too jerky.


I reached a convenient point to test it on the Xbox 360 and I am pleased to say it works well and I still get a solid 60 frames per second.  Not surprising because all the Artificial Intelligence (AI) and pathfinding code are carried out in separate hardware threads.


Now to make the behaviours find cover properly and to shoot back!

Wednesday, 21 December 2011

AI Behaviour Tree

It has taken me a couple of weeks to get the Behaviour Tree processing up and running.  I still don't know how effective my artificial intelligence (AI) will be but the mechanism for controlling it is now in place and appears to work.



I am pleased with the design:
  • Runs in a separate thread (separate hardware thread on the Xbox)
  • Shares processing fairly between all the AI controlled entities (Bots)
  • Unlimited levels of child behaviours
  • Parallel behaviours

It is the ability to add parallel tasks that I needed.  I got stuck at that point with my earlier state machine version.

The problem I had with the state machine was that a Bot may wander about and while wandering needs to be able to look out for enemies in the area.  In addition when the Bot enters combat it needs to be able to shoot at a target while running for cover.  In this Behaviour Tree design the behaviour can replace its own parent behaviour or launch a new behaviour to enter combat. That combat behaviour then launches two more behaviours, one to shoot at a target and the other to decide where to move to.

Each behaviour is a separate class so I have things like, Hide, Chase, Evade, Combat, Find something to do, Wander, etc.  I had to create twelve separate behaviours before I could even test it.  This is because so many of the behaviours are made up of other behaviours and so few actually control the Bot.

To avoid creating garbage** I had to design the structures and classes carefully.  I finished by having only one instance of each behaviour shared by all the Bot classes.  Instead of adding the behaviours as needed and using the individual behaviour classes to store results, the results are passed in to and returned from the behaviour classes.  The results being stored between updates within their respective Bot's class'.

This image shows a simplified version of the design:


I have added a method to show on screen what any individual Bot is thinking.  I have this running in the game and I can see that the Bots respond to changes in the environment by changing their behaviour.



At the moment some of the behaviours themselves are not carrying out the actions that I would like but as each one is now independent and broken down in to smaller and smaller behaviours I can work through them to adjust each in turn to get the results I want.

==

** Garbage is the term used for adding and then freeing up memory on the heap.  This freed up memory needs to be collected for re-use by a framework process that is relatively slow on the Xbox. Just adding to the heap is eventually sufficient to trigger the slow collection process even if there is no memory available to free up.

Thursday, 13 October 2011

More On Shadows

I think I might finally have a solution that works for shadows.

I tried ID shadow maps and they worked well and in combination with the baked in ambient occlusion (AO) the scenes looked good...     in most places!

There is always a catch.  Objects that went underground shadowed the ground incorrectly!  As I had slopes it would have been very difficult to avoid some models that had to be partially underground on at least one side.

To cut a lot of time and trial and error out of this story, the solution was a combination of percentage closer filtering (PCF) and ID shadow maps combined.  I tried variance shadow maps (VSM) with ID but the limitations of the surface formats available on the Xbox meant I could not get enough depth precision at the same time as storing the object ID.  I might still be able to do it with VSM by packing the three variables in to the available formats but that is for another day.  PCF with ID only needs two variables so the Vector2 surface format works well for that.



The sampling method first checks the ID and avoids self shadowing models.  Only then does it resort to the common PCF method using 4 samples.  Anything much more than four samples on the Xbox results in a sudden massive halving of the frame rate which I put down to predicated tiling.


The following is the most significant part of the shader.



float PID_Sample(
        float2 vTexCoord, 
        float fLightDepth, 
        float entityID)
{
    float lit = 1.0f;

    float2 fSample = 
        SAMPLE_TEXTURE(ShadowMap, vTexCoord);
    float casterID = fSample.y;
    // The render target is initialised to white 
    // GraphicsDevice.Clear(Color.White)
    if (casterID < 1.0f && 
        casterID != entityID && 
        fLightDepth >= fSample.x)
    {
        lit = 0.0f;
    }
    return lit;
}


float PID_BoxSampleLightFactor(float4 shadowTexCoord)
{
    float fLightDepth = 
        shadowTexCoord.z - ShadowDepthBias;
    float texelStepSize = 1.0f / ShadowSize;
    // Work in floats
    float entityID = IntToFloat(ShadowEntityID);
    // Sample round the position
    float shadow[4];
    shadow[0] = PID_Sample(shadowTexCoord, 
        fLightDepth, entityID);
    shadow[1] = PID_Sample(shadowTexCoord + 
        float2(texelStepSize, 0), 
        fLightDepth, entityID);
    shadow[2] = PID_Sample(shadowTexCoord + 
        float2(0, texelStepSize), 
        fLightDepth, entityID);
    shadow[3] = PID_Sample(shadowTexCoord + 
        float2(texelStepSize, texelStepSize), 
        fLightDepth, entityID);

 float2 lerpFactor = frac(ShadowSize * shadowTexCoord);
 // Linear extrapolate between the samples
 return lerp(lerp(shadow[0], shadow[1], lerpFactor.x),
    lerp(shadow[2], shadow[3], lerpFactor.x),
    lerpFactor.y);
}



The shadows fade out after about 40m from the camera.  I have found that anything less is a bit distracting in game but 40m is hard to see.  Even with a 2048x2048 shadow map the shadows are a tiny bit more pixelated than my ideal but it is the best I can manage at the moment.




The most important thing is that it works on the Xbox 360 and keeps a solid 60 frames per second with room to spare.

I can now move on to other things... again.


Tuesday, 4 October 2011

XBox HLSL Peculiarity

While fiddling with my shadow code to try and get more reliable performance on the Xbox I changed my HLSL shader code so I could quickly make changes to a pair of nested loops that calculated the weighted average.

Most of the testing was done on the PC and it all worked fine.  When I tried it on the Xbox the shadows had completely gone!

It took a while to find but it was the simplest code possible that did not work on the Xbox but worked perfectly on the PC.




 float shadowTerm = 0.0f;
 int sampleCount = 0;
 for (float y = 0; y <= sampleRadius; y++)
 {
   for (float x = -sampleRadius; x <= sampleRadius; x++)
   {
     float sample = something();     
     shadowTerm += sample;
     sampleCount++;
   }                      
 }    
 // Average by the number of values
 shadowTerm /= sampleCount;
  


That code does NOT work on the Xbox.
Note the sampleCount immediately following the shadowTerm in the middle of the loop.
What could be simpler code.

Take it out and replace with a sum at the end after the loop and...
the following code does work on the Xbox!


  float shadowTerm = 0.0f;
  for (float y = 0; y <= sampleRadius; y++)
  {
    for (float x = -sampleRadius; x <= sampleRadius; x++)
    {
      float sample = something(); 
      shadowTerm += sample;
    } 
  } 
  // Average by the number of values
  shadowTerm /= 
        (sampleRadius + 1) * 
        ((sampleRadius *2) + 1);
  


If anyone has a reason other than the compilers are different, please let me know.

Thursday, 28 July 2011

What Can My Game Already Do

An article by Nick Gravelyn over on his blog inspired me to think about what I have done.  Theirs shows a screen shot of what a team of three achieved on their game engine in 6 months.

I've been working on mine for over two years on my own and I'm pleased to say my game can already do a lot, in fact code wise there can't be much more to add.  I hope!

This list of features is a reminder to me of what I have achieved:
  • Walk round a 3D world
  • - Jump
  • - Spectate
  • First person controls
  • Over the shoulder view of yourself (more fiddly than it sounds)
  • Animated
  • - Blend animations
  • - Merge in arm movement to follow which way the player is looking
  • - Hold attachments that move with whatever they are attached to
  • - Shared animation files (and a way to get them in to the pipeline.)
  • Collide with characters and structures
  • Terrain and game editor
  • - Change heights
  • - Change textures
  • Add and remove:
  • - models
  • - triggers
  • - particle effects
  • - goals
  • - trigger goal success
  • - trigger add a new goal
  • - trigger spawn player
  • - trigger spawn non-players
  • - trigger particle effects
  • - Waypoints for AI pathfinding
  • - Spawnpoints
  • Lighting
  • Shadows (not a trivial task, many many months spent on this)
  • Full menu system
  • - Select which map to play
  • - Customise the player character with hats etc.
  • - Load and save character choices
  • - Change music and effect volumes
  • - In game pause menu, resume or exit
  • - Display goals outstanding and completed
  • Select weapons
  • Shoot weapons
  • Bullet trails
  • Bullet impact decals (instanced)
  • Bullet impact effect, debris and smoke
  • Muzzle flash
  • Most things have sound effects
  • Drop weapons
  • Pickup weapons
  • Pickup ammunition
  • Head Up Display (HUD)
  • - Weapon sights
  • - Sniper sights
  • - Zoom in
  • - Display ammo as used
  • - Compass
  • - Radar showing friend and enemy positions if close
  • Non-Player AI
  • - Pathfinding
  • - Select a target if in range
  • - Follow a player (target)
  • and I'm sure there's more...

All the in game stuff runs on the Xbox with a development version running on the PC as well.

In addition to all that I had to write a Python script for Blender to be able to export models from Blender to XNA and as a short distraction I am currently trying to unify that with the built in FBX exported in Blender so that in future one exporter works with everything!

I'm still a long way from finishing the game though.  That is because most of the above use placeholder graphics and so I am now working to create the finished 3D models to go in the game.  Then I will post a video to really show off :-)

I'd like to thank all those people on various forums that have helped along the way.

Saturday, 14 August 2010

Windows vs Xbox360

I do most of my development and testing on Windows. It's a much quicker cycle from code to test to code again. From time to time I have to test on the Xbox360 to make sure it all runs.

Whenever I test on the 360 there are always differences. The number of times I have seen a code 4 error! This time it was very unexpected because it was type casting.

I had tidied up my storage code. I had lots of the same loading and saving code where the only difference was the class of file it was working with. I did the obvious and converted it to a generic function using the base 'object' class and type cast to the type I needed.

This all worked perfectly first time on Windows. Not at all on the Xbox360. Turns out that no matter how I try I cannot return a value when I cast it back from the 'object' class. On the Xbox360 it always returns null.

I re-wrote the code so I didn't have to return a value. I keep the generic 'object' in the one method and have a set of if statements to store the results in the correct type. Not as neat but it works.

While on the subject of peculiarities and storage the Guide function on the 360 can be misleading. Sometimes it returns busy when it is not or perhaps it was a moment ago but it's not now! I have had to add several automatic retry loops in my code to avoid that problem.