Project: Gauntlet - Current Iteration

Saturday, December 19, 2009

Day X1: Main enemy model and unwrap.





Short clip demonstrating the model outlined below, in Unity with fog and awesome laser beam.

Main enemy - Giant Robot. 370 polygons.

Time to model, rig with skeleton, unwrap and animate with walk cycle and stop-and-look animation: 3 hours.

No concept art - the character was modelled from a brief idea in a dream. True story.

Model:




T-pose - which appears to show an unnecessary number of edge loops.
However - for the manner in which I wanted the robot to move, they were necessary - observe:




Unwrap:





As the robot will be very very big, and the player very small - most detail is required in the legs, the underarms, the fists and the lower chest.
The unwrap reflects this.

Day X1: Main human model and unwrap

A few models with their respective polycounts and unwraps for you to observe and consider.

Main Character - human biped: 350 polygons.

Time to model, rig with skeleton and unwrap: 3.5 hours.

Concept:


With kudos to Jessica Ellis for the concept art and design.

Model:




Unwrap:





Factoring the context in which the model will be viewed (small screen, above and behind) - the most space for detail was allowed on the arms, the back and the legs. When the character is throwing a projectile, the camera will pan to be beside him.

The player will only ever see a small portion of the characters face, and very little of the characters chest.

Thursday, December 17, 2009

Day Z: Raycast performance, Unity Profiler, unavoidable performance issues and damage mitigation.

As our giant robot rolls along - to uncertain horizons, his head-mounted laser moves too - relative to his skull.

Now, the aim is - to avoid this laser, whether it be by hiding behind a building, a car etc.

Technically - the laser is a basic primitive (a cylinder or cube) - with an Additive Particle shader that gives it the glowing/half transparent appearance.

The issue is this:

If you are hiding behind an obstacle, the laser will appear to come through this obstacle - which would negate the point of hiding.

As the laser is not a light source or physics object, the way I am assuring this does not happen is as follows:

  1. From the parent rotation object (the skull) cast a ray along the axis of the primitive (the laser).
  2. If the raycast strikes a collider, find the distance to this collider.
    1. Scale the laser to equal this distance.
      1. Assuring the laser has a starting scale of 0 along the length axis.
    2. Offset the laser by half of this distance.
      1. As primitives in unity begin with an origin directly in their centre.
  3. Presto, your laser is not penetrating the obstacle.
Now this is fine and functional, but if we refer to our beautiful unity profiler, you see that each raycast is causing a noticeable drop in framerate.

As our laser does not have to be 100% accurate, I have offset each check for boundaries (parametrically).

In a very primitive fashion....

Each listener has a counter, when the counter hits the defined check rate, it will check for a collision.

We mitigate the average damage, while still taking damage at the predefined rate.

The aim is to use this concept over all performance-detrimental tasks (collision detection, raycasting, etc), and offset the counters to assure that not all checks are occurring in one enormous spike.


A glimpse of my hilarious test scene, replete with a random cube (right), an orb flashing at 120bmp (center), a wall and the ray - white. As you can see, the ray does not penetrate the wall.

Wednesday, December 16, 2009

Day Y: The ADHD mindset, the beauty of code modularity - and how I learnt to stop worrying, and love the Giant Robot

As things will tend to do - and as the recent, slightly cryptic post has highlighted - concepts have drifted dramatically - and we have landed on a concept that I think is just as - if not more, engaging and purely awesome.

Allow me to set the scene for you:

A desolate street - cold stone buildings surround you.

You look at your watch... but it doesn't tell you the date - but if you were to guess from your surroundings, it's probably reminiscent of some time between the 1920's and the 1940's.

And where is everybody?

No idea. You're alone.

But what is that in the distance????

It's a GIANT FKING ROBOT WITH A MASSIVE LASER IN IT'S HEAD!


And what's it doing??


You don't know, but you can't help but feel it's your responsibility to stop it.

Quick, take that half-brick, and rain sedimentary destruction down upon his turbulent brow.


That's it, effectively.

One man against an enormous foe. Using nothing but projectiles (using the hold-to-power-up mechanic).
Avoiding certain vaporization at the touch of it's awesome laser eye.

Stay tuned, we have videos, models, concepts - the works!

And what will it be called???

No idea.

Friday, December 11, 2009

Realtime manipulation of an animated mesh and bones in Unity



As mentioned - this is a short and.... ok... video demonstrating realtime modification of a standard animated biped mesh. You can do anything really, this is just a simple demonstration of making an Alien-esque creature from a biped.

Await, with trembling anticipation, the performance of multiple realtime-modified entities on the iPhone.

Forecasts? Hypotheses?

Tricky.

Thursday, December 10, 2009

The Story: The Tree of the Knowledge of Good and Evil

That always bothered me about the Garden of Eden parable... wouldn't God want his children to reach for their fullest possible potential?

I think perhaps it's a reflection of Oedipal fear - that the child will grow to be stronger than the Father, and kill him and take his wife.....

In any case - you - you - you are a man. A man driven by a desire not for gold, or women, or hunger - but a desire to be the best that you can possibly be. To reach the maximum of your human potential.

During your childhood - this desire made you a prodigy, a boy who stood out amongst his peers as an individual who was going places. But - as your intensity grew, so did your distance from your peers and the societal bonds that hold us all from reaching their full potential.

Tortured and exiled by your society for daring to exceed your own capabilities through socially unacceptable means, you journey into the world - to become the most powerful man you can be.

The scenario:

You are an exiled monk - a scholar and martial artist. After having your right arm severed as punishment for your pride, you are left to roam the world - in search of power - whatever form that may take.

In Scene 1 (initial release) - you resolve to seek out the Kings of the four seas (Chinese-styled dragons) - in order to ask their blessing and gain from them some knowledge that will increase your power.

By capturing the Pearl that each Dragon chases, you may ransom it back to the Dragon in exchange for power of your choosing.

Each level will consist of two phases:
  1. Chase the dragon from the ground, attempt to leap onto it's back - avoiding obstacles and building speed until you can successfully make the leap.
  2. Run along the dragon's back - assuring you are not thrown off, until you reach the head and can leap to claim the pearl.
At the culmination of these phases, you are given the choice of one power - be it increased speed, increased jumping ability etc.

At the culmination of all phases, you will be granted your lost arm, and may begin your path to Martial Arts glory.

That's the thought, in any case.

And, in classic style, here's a drawing I made while I got distracted designing a UI communication system for my rent-paying job.



He's clearly got two arms there......

That's the thought, at this point in time. Story may or may not change over the coming weeks - but will be locked (obviously) by the time design and modelling begin.

Thoughts? Feelings?

By summary, the gameplay will be:
  • Run run run!
  • Jump jump jump!
  • Avoid stopping!
By even more abstract summary, the gameplay will be:
  • Build your speed!
Simplicity.

And then we'll see how the iPhone performs and grow from there.

Progress: Day Twenty-Three - Event handling, A modular component-interaction system, Procedural bone transformations on an animated mesh, and all at 120 BPM.

Nearing that oh-so-festive time of the year, and the accompanying professional panic that ensues when people feel the fine-grained sediment of their life slowly ticking away -
That's my romantic way of saying that I have been busy with rent-paying projects these past weeks >.<


But let's not dwell - what have we been doing?


Let's start with a picture, something relatively (relatively) pretty to maintain your interest:





That happy camper is a procedurally-modified version of the low-poly biped that featured a few weeks ago. We'll say he's some sort of.... alien ape of husky head.

As you can see, regardless of the manipulation of his body parts, he observes the original bone animations applied to the biped.

The process is as follows:

  1. Starting with a standard animated biped (using Bones, exported as FBX)
  2. For each body part we wish to modify:
    1. Apply rotation (x,y,z) to the body part
    2. Apply scale (x,y,z) to the body part
    3. Apply offset (x,y,z) to the body part
  3. And presto! play that bad-boy and you can (more or less) make any number of good-looking entities from a standard animated biped.
There were a few technical issues with this that you may need to understand:

  • Applying animated Bone transforms in Unity 
    • Transforms will appear to function until you play an animation on your model - this will reset your transforms (as that is what an animation is)
    • In order to consistently apply your transforms during animation, you must reapply the transformations during your LateUpdate() call.
    • Enjoy!
    • As to how this will perform on a mobile device (iPhone) I have absolutely no idea - stay posted as I purchase Unity Pro and run the profiler over this bad-boy!
You know what?

I might leave that post right here, so you get a succinct little package, and I'll repost with the details of my (now refined) message and event handling system, explain my cryptic 120BPM comment, and get into the real meat of it - gameplay!

Tuesday, December 8, 2009

Unity - Moving Platforms and You. (Triggers, Colliders, Rigidbody and the Character Controller)

Busy busy paying the rent, but here is a little snippet that you may find helpful in your Unity Endeavours.

To my surprise a Character Controller in Unity does not automatically observe moving Colliders within the game world - net result, a platform that moves around (up/down/left/right) will not support a Character Controller... you will just... fall through.

Here's my quick little solution - reasonably elegant - be wary of using CharacterController.isGrounded if you are observing a 'jump' effect - I recommend defining a global "isFalling" state that you can trigger in one of these functions.

Requirements:
A gameobject with a CharacterController
A gameobject with a Collider and a Rigidbody - tagged as "Platform", or utilizing any defining mark that you care to use - I usually use a small component that contains myriad tags and category information about an entity.


Apply these functions to a script on your your CharacterController:

   void OnTriggerEnter(Collider t)
    {
        Debug.Log("On trigger enter in " + gameObject.name);
        if (t.gameObject.tag == "Platform")
        {
            gameObject.transform.parent = t.gameObject.transform;
            Debug.Log("Parented");
        }
    }

    void OnTriggerExit(Collider t)
    {
        Debug.Log("On trigger exit in " + gameObject.name);
        if (t.gameObject.tag == "Platform")
        {
            gameObject.transform.parent = null;
            Debug.Log("Unparented");
        }
    }

Effectively, your CharacterController will move and be moved relative to the Platform while colliding (standing on), and relative to the world when not colliding.

It's really just a quickly-written piece of code for something you may or may not come across. Take it and use it in the spirit in which it was created.

Saturday, December 5, 2009

Progress: Day Eleven. Signals or Messenging in Unity / C#, the battle between modularity and performance.

A busy busy week of paying rent - was this week past, and it is this moment that we take the time to reflect on those who didn't make it to Sunday.
Free time *hold for applause*
Energy and enthusiasm *hold for applause*
x-hundred dollars for a one-use suit *hold for applause*


Yes, it's been one of THOSE weeks - a week of fulfilling the old 'non-optional social obligations'.


But rest assured, my dear friend - that you have always, always been in my mind. And with that, allow me to give you a rundown on what we have been doing in Unity and C# this week.

Signals and Messenging.

This week I was quite concerned with developing a small framework that would handle the management of states and variables between objects in the gameworld.

This framework had to fulfill a handful of contradictory requirements:
  • Modularity / Abstraction
    • I would prefer this framework to be applicable to ANY game design scenario, to allow reuse in the future.
    • HOWEVER the issue with this is that it extends the due-date of a deliverable. Working on frameworks is fine, BUT it must be actually used to make something. Keep on the straight and narrow.
  • Efficiency
    • Obviously, for iPhone, efficiency is key. So the elimination of un-necessary function calls is key.
  • Small memory footprint
    • I believe the iPhone has something around the 43meg memory mark for an application, which means that we want to eliminate sprawling data structures and retain memory for graphics and sound.
Unfortunately, these are relatively contradictory - as modularity and abstraction usually increase the memory footprint of a program and decrease (slightly) it's efficiency.

I understand this is an arguable statement without qualification, but it is generally correct.

We can try though, can we not?


So here is a breakdown of how the game object code is put together:

There are four main classes in the Game Object:

  • Event
    • An event is an action that is performed in the gameworld.
    • It may be user input (key down), or an internally-initiated event (game object-to-game object).
    • As the result of an event, one of many variables may be altered, and one or many states may be changed.
      • E.g: Key down - jumping = true, gravity = 20.0f, something = false and so forth.
  • Variable
    • A variable is set as a result of an event.
    • It may be the value of the input (axis value) or a predefined value (eg: speed += 10)
  • State
    • A state is a true/false indicator that the game object is in a given state (eg: jumping).
    • A state is evaluated either per Update() or upon state change, and will trigger one or many actions.
  • Action
    • An action is initiated when the game object is in a given state
    • An action has a lifespan that is internally defined and regulated
    • Upon completion, and action will revert given states and set given variables (through the use of an event).
    • The Action is the core of all gameplay-specific logic - all gameplay is contained in actions.
So this is the core of the state management logic - as all gameplay feeds from a common repository of variables, communication between gameplay elements can happen in a relatively transparent manner.

I have some very nice graphical examples to include later - stay tuned.

Friday, November 27, 2009

The importance of variety in Procedural Generation of game content

Variety - the spice of life - the tumeric in the casserole of our days and ways.


Not entirely sure if this whole '3 blogs in one day' is productive or counter-productive.
One perspective would be that any work on a Saturday - of all days, is productive.
One would be incorrect.

Short and sweet - before I get to dinner and subsequently back to Unity.

What aspects of the game will be generated and altered procedurally?
And by procedurally, we'll mean what we'll call 'pointed randomisation'.

A quick bullet list. Please - comment and contribute.

  • Level generation. 
    • Where you can walk, which directions - which twists and gripping turns, you are taken on.
  • Obstacle placement.
    • The type of obstacles you encounter.
    • The amount of obstacles you encounter.
    • The positioning of said objects.
    • The scale of these objects.
  • Enemy placement
    • The type of enemy encountered
    • The power of the enemies encountered.
    • The appearance of the enemies encountered.
    • The location of enemies encountered.
    • The quantity of enemies encountered.
    • The behavior (speed, jump height, attack type) of enemies encountered.
  • Item placement (if items do exist. I assume they will)
    • As above.
All this is well and good, but it really only reflects a fairly generic randomisation of levels.

I think - sadly enough - that procedural generation is not the ends, but only a means to get partway to the ends.

I think the most important thing we can have, for this project, is:
  • A variety of enemies, obstacles and items
    • A rarity rating of each object - to assure that there is that feeling of "Ooooh... Pokemon Johto just started! Will he choose Chikorita? I hope not".
  • Varied color and superficial changes - enough to assure that each generated level does not contain every single asset of variation the game engine contains.
Following this structure, I believe we can make a nice-looking, nice-playing game, with a good degree of replay value.

Replay value... there's a subject for a blog - but another time!
Now is the time for work.
Talk is Cheap.

The To-Do list. THE To-Do list.

And on that subject, what DOES the To-Do list look like?

This!



That little corner of desk you see there is where I'm sitting as we speak - per'se.

Let's break it down... what's on there....

Executive summary:

Over the next few week's you'll be seeing some real traction on this - run around, fight, TRIUMPH, all in a procedurally-generated environment - so your gameplay experience is varied every single time you play the game.

Hmm... variety - we need a blog post on that subject. How do we vary this up to assure that the procedural generation of levels is actually dynamic and awesome, as opposed to just.... whatever...

Bottom-left corner - some scribblings about another project I'm working on. I'd remove them, but there's a diagram of a turtle that I'm kind of fond of.

Bottom-centrish - a kind of... sketch? of how this Project will appear to the user. Kind of....

The majority of the board? 4 columns: Level generation, Movement, Combat, Goal - I think I outlined them in the first post.

And the most contextually relevant part?


In the bottom-right corner, beneath a small sketch of a flower - denoting 'Graphical Assets' - which I have labelled as 'effeminite', we have:
  • Animations - swing, run, jump animations for the main character
  • Modelling - extension of the biped to a real character, pending concept
  • Scenery - flavour items - rocks, trees - for placement in the path.
Beneath a small sketch of a piece of paper - denoting 'Programming work' - which I have labelled as 'productive work', we have:

  • Scenery generation and placement - intelligent procedural palcement of scenery (above) in the path to provide obstacles that don't make the level impossible.
  • NPC placement - spawning of NPCs with varying degrees of strength pending position on the path
  • Health system - management of dead/alive and degrees of alive-ness, as it were.
  • Control system - movement and striking have been handled, but I am cooking up something particularly special for this innocent-looking 'Control system' concept. More as this develops - particularly excited about this one.

Progress: Day Four-Point-Five - Animation, Jumping and primitive Pathing in C# and Unity

Saturday morning - ahhhhhh the weekend, sitting in a room in 35 degrees celsius / 95 degrees farenheit heat, avoiding deliverables for the rent-paying passtime - and writing tiny To-Do lists on the remaining empty space on the whiteboard... Fantastic!

 So what have I done on this hot Saturday?

Along with the consumption of 2 cans of redbull and 2 cups of delicious black espresso, and 3 subsequent bottles of water to attempt to avert the pending kidney damage, today has been extremely productive.

Let us look, shall we.

Last Night - Day Three (unblogged)

  • Rigged up a primitive "run" animation on our beautiful biped model, to give the demos a little bit of life.
  • Videos to come.
Today - Day Four.Point.Five

  •   NPC movement - NPCs will now run toward the player unerringly, unwaveringly - with a TOTAL commitment not often found in your softer organisms.
    • The NPCs don't path - as we've got aspirations to put this bad boy on your portable devices, I didn't relish the idea of implementing A* or such over it, so they follow the following procedure:
      • Face the player.
      • RUN!!!!!!
      • If you find you can't move for a little bit - JUMP
      • If you are within a given distance of the player, stop, you have been successful.
    • If the NPCs are all near the player, they will rotate until they surround the player in a swarm-styled circle.
    • The JUMP mechanic fulfilled a few requirements:
      • NPCs can jump over obstacles, avoiding the need for pathing.
      • NPCs look hilarious and awesome when they are stacked behind each other - eagerly jumping to attempt to viciously violate you.
  • Attack mechanic
    • When struck, the NPCs can be knocked back - a given distance and a given height.
      • When knocked back, the NPCs cannot move for a defined time.
    • This mechanic will graphically manifest as:
      • Knock back enemy and daze for a period.
    • And it looks awesome too. Of course.
But less talk, let's SEE this business!

Pending.... I'm recording it right now. Hang tight.

Uploading..... 30 minutes remaining. I DID compress, but it looked like junk, so I figured I'd take the time, and see if Youtube would do a better job than my encoder. We'll see! So..... how are you?


13.56 remaining! You could die a hundred deaths in that time. Or cook some eggs or such.


Uploaded.... processing.... please wait.... I really should just leave this blog open in Edit instead of repeatedly having to navigate through Blogspot to edit it.

Done!

Project Gauntlet: Video One

Man, can I embed video here????

Jesus... maybe I can... let's take a look....

Hmm....




Let's see how THAT badboy goes....

Of course! The worst crime you can commit - is to doubt yourself.

At least, the worst crime I can commit is to doubt myself. Feel free to doubt yourself, I don't know you.

Please - take a look, view it in the context in which it was made, and - until we next meet:

Stay crunchy.

Thursday, November 26, 2009

Progress: Day Two - 3D Assets into Unity - Procedurally placing items within the world.

Progress, progress. 

To quantify it, I believe we have roughly 2 hours to spend on this project per weekday - once the trivialities of travel, sustenance and domestic duties have subsided.

This evening the challenge was set:

Model, rig/weight and unwrap a low low poly biped character suitable for this project - insert into Unity and test, in 2 hours.

The Model itself should be suitable for a fast-paced action game from above-and-behind; thus no requirement for great amounts of detail - just proportional limbs and such (e.g: no fingers or toes).

Tricky business - being a relatively new hand at 3D modelling and such.

But - the results are quite reasonable.

Introducing, in the Red corner - the 320 polygon nightmare, proud representative of the people of the Blocks - Johnny the Rock.

Naked - and splendid. 





Ready to take ALL comers (in 3dsMax - excuse the harsh lighting).




Here he is, perched magestically above the aforementioned maze.

 A few additions to note, most of no consequence:
  • skybox
  • altered parametric dimensions of path nodes
  • procedurally-placed items within each pathnode
  • procedurally generated planes beneath path - upgraded from simply terrain.
  • 3rd-person camera and controls.


Wednesday, November 25, 2009

Progress: Day One - Procedural linear level generation in Unity with C#

As we drop a big old Progress bomb on you - the Internet Civilian, bear in mind that we all work fulltime jobs here - in one capacity or another... we do what we can, when we have time... and when we don't have time, we take the Laws of Space and Time and we shake them like a crying baby.

Progress progress -

Wrote up the path-generation system in faithful C#.
The algorithm will take a predefined worldspace (as a grid width and height), a path length, and will hack a path within this world-space that follows these rules:
  • Right-angled turns only - no diagonals
  • No path node may be adjacent to any other path node, with the exception of it's single parent and single child.
You would really think that this would be a smashingly easy task - but in my sleep-deprived state, it proved to be quite a logical trick.

Strangely, it was more difficult to exclude diagonal turns than it was to include them.

In any case, with this algorithm completed and extensively debugged (as extensively debugged as a randomly-generated path can be) - the presentation layer was developed in Unity.

Effectively - the algorithm will provide Unity with:
  • All coordinates of the walkable path
  • All coordinates of nodes that border the path.
With this information, the presentation layer:
  • Builds walls around the path from Prefabs (cubes in this case).
  • Builds a ground for the path from Prefabs.
And here is the baby - screenshot from within Unity inset with debugging work in Excel (conditional formatting is a winner).

All in all, not a bad day of work.


Tuesday, November 24, 2009

The Game

But.... what is the game? What do you DO?

It all begins on the whiteboard.

The time? A conservative 11.35pm / 23.35 military.

Let's break it down - into four subsets - of varying complexity.

The Goal

Starting at Point A - reach Point B.


Movement

Run, Sprint, Jump.
View: Above-and-behind.

Combat

Melee - Strike.
A character can withstand a number of strikes before being knocked down.
A character can withstand a number of knockdowns before dying.

So far, so simple.


Level Generation

Procedural generation of levels. That magical 'P' word.

Each level consists of a Path - a set of adjacent areas, the first of which is Point A, the last of which is Point B.

Each Path is of an arbitrary length - the longer, the longer the game.
Each Path is plotted in an arbitrary area - the smaller, the more winding and convoluted the Path.

Each Path is lined by Walls (invisible) - effectively creating a Gauntlet for the player to run.

Each Path is populated with Enemies - the difficulty and quantity of which are correlated to the position in the Path they fill - the higher the position, the more numerous and difficult the Enemy.

Each Path is populated with Obstacles - to be Jumped or Avoided.

Each Path is decorated with context-specific textures, and randomly decorated with 'flavour' scenery.

Executive Summary:

Run along a path, avoid obstacles, escape or defeat harder and harder enemies, and TRIUMPH - my son... Triumph.

The very essence of conceptual simplicity.

Project: Gauntlet - The Independent Game Project using Unity

Project: Gauntlet - no relation to the arcade game of the same name.

The ultimate aim of Project: Gauntlet is to create - in a short period of time, a small, elegant independent video game - presented in full 3D, utilising the Unity game engine - for propagation to iPhone and Web Browser.

Simplicity and Elegance are the qualitative metrics against which we judge the design of Project: Gauntlet - following the philosophy that a Work is complete not when there is nothing left to add, but nothing left to take away.

This blog will serve to track the progress of our various team members - to capture the victories and the difficulties inherent in an independent development and to serve as a reference for others seeking to follow the same path.