Showing posts with label platformer. Show all posts
Showing posts with label platformer. Show all posts

Sunday, August 14, 2011

Powers Preview

Power-Ups are coming together!  The powers are selected when a player gains a new level, and are split into three "trees" - Attack, Defend, Explore.  Here's the menu to select the powers:


Attack will contain upgrades to the sword and gun, as well as a new attack called "Power Beam".  This shoots out a beam of pure power in a short player-directed burst.




Defend contains upgrades to health (double health, quad health), as well as a spherical Shield that will protect the player from attacks.  At higher levels, the shield will even do damage to enemies in range!


The Explore tree contains all the jump upgrades (double, triple, wall), the grappling hook and a new ability, called "Power Jump".  This is basically a jet pack, that lets the player "fly" anywhere in the map for short bursts.


All powers are limited by a "mana" meter that will slowly refill over time.  Stronger powers (Power Jump, Power Beam), will drain the mana meter faster, so watch out.

I'm thinking the powers will be a lot of fun, an the three different trees will give players different ways to play the game.  Of course, by the end game you'll have all the powers.  One of the keys will be tuning the enemies and maps so the game is still a challenge with the full arsenal!

Still some more backend coding to wrap up, one last boss fight, then putting it all together.  Hoping to have a playtest available for both PC and XBox AppHub first week of September!


Thursday, August 4, 2011

Script and Maps and Such

Added two new features.

1. Scripting window.  This is for conveying story to the player.  When the player runs over a trigger, it pops up a "dialog" window that can be read (press A) or bypassed (press B).  Poor man's cut-scene!


2. World Map.  The map will be used to select the level as you progress through the game world.  I found some great brushes on deviantart that were used to make the map: http://calthyechild.deviantart.com/art/Tolkien-style-Map-Brushes-138796530


The game is coming together quickly.  One more boss and the level-up / power system.

Then its on to fleshing out all the levels and polishing till it shines!

Saturday, July 30, 2011

Boss Fights Delivered

End result of a day of programming, two new boss fights!



The mummy boss chases after the player and melees them on the ground.  If the player is off the ground, the mummy will cast a spell which will launch the player into the air.

The dragon boss emerges from a random side of the screen and breathes fire.  Afterwards, he's vulnerable for a short time.  In between attacks, fire blocks fall from the ceiling to crush the player.

Lots of fun programming behind these guys, mostly abstracting all the code written for the spider boss, and cleaning up code for "beams" - which are basically a list of vectors that can be used for collision or "drawing" lines with particle effects.



Next steps - a world map, and some scripting for dialog/story!

Tuesday, June 14, 2011

Platform Hack Post-Mortem

Things That Worked

Stick with the Design

A clear design for Platform hack was laid out at the beginning: a mash-up of Metroid (platform jumping, exploratory powerups) with dynamic world creation of Roguelikes. This was followed through from the start. It helped to not have to change genres or styles halfway through, and the core gameplay feels very similar to what I had in mind.

Prototype, Prototype, Prototype

Breaking the challenges of the game into smaller problems, and then getting those working in isolated environments was key. The main issues - grappling hook, double/wall jump, traps, melee / ranged combat, level design - were all handled in a "sandbox" project. This way I didn't have to worry about breaking the game to try out a new feature, I could hardcode physics constants or whatever until the feature worked how I wanted it. *then* port it over to the game project.

Don't Reinvent the Wheel

Platform Hack borrowed from a lot of great sources, both for code and art. The samples on App Hub were essential, especially the Platformer starter kit, which included the core code for tile-based levels, basic physics (jumping, gravity), sprite-based animation, and collision detection. Other samples were useful as well - Game State Management, Pixel-Based collision with rotation. For the sprites, I ended up using sample spritesheets and having my artist base all the animations (run, jump, attack, die) on those models.

Limit Features...For Now

The original plan for platform hack had dozens of procedurally generated levels, 4 huge boss fights, an overarching story, and a leveling system that let the player specialize in different types of powers. Those plans are still on the table for the final release, but about a month out from the deadline, I realized I wasn't going to hit all those marks, and set my sights for a much smaller goal - a stable game with polished art and gameplay. In the end, I was able to deliver by the deadline.

Things that Caused Problems


Collision Detection

Pixel based collision detection can make you want to tear your eyes out. When it doesn't work, it’s very hard to figure out why (you can't step into and iterate through the 10000 item color array to see a certain pixel isn't set to alpha), especially if you are using matrix math for rotation and translation. One thing I ended up doing was creating a TestPixel object, which would basically flip on if it was "collided" with. This let me see a path of where swords, bullets and enemies passed through. Unfortunately, this was very slow (1 fps) and didn't always work. At the end of the day, I removed most of the per-pixel collision, and only used it where absolutely necessary.

Procedural Level Generation

I created a project that would use the Angband algorithms to generate a map, and throw in various enemies, traps and platforms. However, I still had to manually go through the text files and make sure there were no inescapable dead ends or unreachable keys. The tough part of procedural level generation is making sure the "maze" can be beaten, once you start adding in locked doors. The early levels also needed additional manual intervention, to give the whole thing a bit more flow and gradually increase the learning curve. As soon as the player uncovers a new trick (jumping boots, grappling hook), you want to give them the opportunity to use it, which you have to manually design. this is why I'm thinking, even in the final game, the procedural levels will only end up being 50%. Stages where you uncover a new item, or fight a scripted boss fight, will need to be hand-crafted.

Loading Assets on Xbox

The scripted boss fight was fun to put together, but not the most elegant solution. The first build I ended up with dozens of 1500x1500 images that not only had to be loaded into Texture2D objects, but also read into Color arrays for pixel-based collision. Needless to say, this caused some OutOfMemory exceptions when attempted on the XBox. The solution was reduce the size of the image files (to 800 x 600), and then build a manifest loader that would reuse certain textures for various animation frames (the idle frame is used in almost every animation), and also only generate the Color[] on frames that needed collision.

Animation State Machines

This is something I'm still dealing with. Animation is one big state machine - trying to map both the player input + the world controls into a believable animation for the player to be in. For instance, if the player is swinging his sword and then jumps, do you continue to play the first ground swing animation? or switch over mid-swing to the jump-swing animation? What if you can't transition halfway between animations and have to start at the beginning? This "transition" issue was a headache to get right. In the end, I decided that animations must be played from start to finish, and you can't start a new action while you are in the middle of one (aka start shooting while rolling, roll while swinging, etc). Of course, the button press will usually still be registered once the animation is over and you'd start the new action immediately. The more complex your animation state machine, the harder this problem becomes.

Lessons Learned

Get It Working First

Work on the hard items early rather than low hanging fruit. You never know how long it will take to figure out an architecture problem (loading assets, collision detection, etc). But its usually more predictable how long it will take to import new art, or tweak small cosmetic bugs. Leave that polish for the end, get the hard stuff working as early as possible.

Art / Sound = Morale boost

It's a huge morale boost when you see your crappy programmer art "skinned" with graphics that look good.

80/20 rule

There's always that last 20 percent you want to get done.  But leave 20% of your time for pure polish, not dev.

Lots of builds / releases.

Don't leave stuff in an uncompelled / untested state at the end of the day. During crunch time, do a daily play test. make a list of everything wrong. fix what you can. increment the build number. repeat.

Make what you can / borrow what you can't.

I knew I'd never be able to make original music or draw convincing sprites, so I either found good assets online (free music) or got a friend to draw me sprites. Other stuff that was less important (sound effects, in-game items) I mocked up myself using various free tools.

Monday, June 13, 2011

What's next for Platform Hack?

The game has been submitted to Dream Build Play! It should be showing up on the list of entries shortly.


So what's next for Platform Hack? The build submitted to DBP was a subset of what I originally envisioned. What I'd like to do is continue working on the game, primarily creating content, for the rest of the summer. The game would go into Peer Review late summer, and hopefully be released on XBox Live in September.

Here are the features I'd like to complete for the full release:

  • 4 Total worlds, with unique tilesets, enemies and boss fights (Forest, Mountain, Desert, Wasteland/Factory)
  • Leveling skill-tree and powers (Attack, Defend, Explore)
  • Procedural level generation (for 50% of levels)
  • Some form of narrative story that links the "quest" together
  • Infinite mode (similar to roguelikes, where you can continue to "dig" down into the dungeon, and everything scales accordingly)
  • Overall polish of menus, HUD, etc

The only tough programming challenge is getting the procedural levels dynamic and toned enough that they can be used. Right now I can randomly place enemies and traps, but they aren't set up in a way that makes the overall map feel both coherent and challenging. We'll see if it's doable.

Everything else is mostly content generation, which is slow and steady, but is well within reach for the summer.

Next, I'll be doing a post-mortem of the DBP process, a list of acknowledgements for the game, and a breakdown of the various tools used during development.

Thursday, June 9, 2011

Platform Hack Trailer



The finishing touches are being put in place! Here's the trailer for the game. A new playtest will be up this evening on App Hub. I'll also be laying out the plan for the game post-DBP.

Sunday, June 5, 2011

Taking Shape...



Latest build - beta 1.1. A new playtest is out on App Hub: App Hub Playtest - Platform Hack

Big thanks to everyone who has helped out so far. Anna D, Ena M, and Joe Roh! Without you guys this thing would not be possible!

Only 9 days left and still lots left to do -

Sunday, May 29, 2011

Crunch Time



Things are coming together. I've built some full levels with enemies, keys, locked doors and chests.

The XP system is also in place, so killing enemies will get XP for both the main player (HitPoints) as well as weapon (Sword, Gun) power.

The game still needs tons of balance, not only with the XP and advancement system, but also the level design.

And of course the graphics are pretty blugh.

Hopefully I can have a playable build (that works on the XBox) in App Hub playtest by the first of June!

Thursday, May 19, 2011

New Enemies, Miniboss



The latest build has some new enemies. In the forest, there will be 5 standard enemies:

1. Spider - paces back and forth between walls / ledges. Hits with touch.
2. Jumping Spider - Moves towards player, constantly jumping. Like the flying turtles in mario.
3. Throwing Bandit - Paces. Throws a dagger.
4. Slashing Bandit - Paces. Slashes his sword if you get too close.
5. Flying Birds. These "home" in on the player. I'm thinking of having these continually spawn from "nests" that must be destroyed.

I also added the miniboss that was alluded to in the previous post. The mini boss is the bandit king, and will "drop" the pistol when he's killed (probably early on in the game, lvl 2 or 3).

Basically, he'll try to maximize his distance between himself and the player, and if he has an open shot for half a second he'll start firing. The only way to beat him is to corner him and bash him down with a sword.

Next step is designing the HUD!

I'm still unsure whether I'll get the lvl/power up system working for DBP. Procedural levels are also looking doubtful for the DBP build, especially since the worst case scenario would be if the judges got a non-functional map and couldn't play. It's probably better to invest dev time in polishing the pure gameplay, animations and graphics.

Thats it for now!

Monday, May 9, 2011

Platform Hack Alpha Progress

The build is coming together. Here's a quick playthrough I put together that shows the latest features.

Wednesday, April 13, 2011

Grapple Hook Revisited

There was a request to go into some more detail for the grapple hook. Original Post



So what I've done is taken a fresh copy of the Platformer 4.0 solution and added only the Grapple Hook stuff. The ZIP of the solution is attached below.

Basically, there are 3 new classes and some changes to Player.cs

The three new classes are in the GrappleHook Folder:

Collision.cs - This contains the core functions used "under the hood".
DrawPrimitives.cs - This class contains some functions used to draw various shapes. The main method used is DrawLine2.
Grapple.cs - This class contains the guts of the grapple hook logic outlined in the initial blog post

Changes to Player.cs:
There are some new member variables and a few methods. I tried to comment everything that was new with "GRAPPLE HOOK"

I also added WhitePixel.bmp to the Content/Sprites/Test folder. This is used to draw the line. (Also removed the music to cut down the size of the zip)

A few changes to the logic and style of the Grapple Hook:
1. The grapple hook "rope" will now shoot out 500 pixels at a rate of 2000, which is pretty much instant.

2. The grapple hook will stay extended as long as you hold the button (instead of collapsing back to 0). This makes it easier to attach.

3. You can't shoot the grapple hook if isOnGround = true. This makes use a little more natural and prevents the odd bug where you would attach and then the grapple curve would force you under the world or the tile below you.

4. The swing itself is slightly slower (using 2000 as the gravity constant).

Places for Improvement:
1. Some games have the grapple hook continually "shrink" while it is attached (Hook Champ, etc). This gives the player the feel that the grapple is "elastic". You could implement this by moving the player slighly "up" the rope every tick, and then re-calculating the Swing Curve. The hard part is getting the velocities right so the swing is smooth, since we're not using actual angular velocities / momentum, but the path of the pendulum curve.

2. Prevent the Grapple hook from attaching to horizontal walls. This would require a change to the GrappleCollision function (and the getLineCollision function), to only attach if the Grapple "hook" is colliding through the lower X plane, instead of the Y plane.

3. Better formulas for angular velocities entering and exiting the swing. Right now I'm using some cheap hacks (delta position -> velocity) to determine the initial and launch velocities when starting or exiting the grapple swing. Some real physics might make it feel a little smoother.

Download: GrappleExample.zip

Tuesday, January 18, 2011

Mini-Maps

For games with complex level design, mini-maps are essential. Especially in games like Super Metroid where the focus of the gameplay is more on backtracking and using your new abilities than pure exploration, the many map is very important tool.

For Platform Hack, I'm planning on two different "mini" maps. One map will be accessible from the pause menu, and will show the entire level, along with special icons for the player, doors, chests, etc. The other map will be a true mini-map, in the upper-right corner of the HUD, showing only a tiny portion of the current level.



Originally I intended to draw a pixel directly on the screen to correspond with each tile in the level, but that turned out to be too slow.

Instead, what we can do it create a Texture2D object on the fly and display it on the screen. If we need to crop (for the small mini-map in the corner), we can calculate coordinates to center on the player, and then specify the sourceRectange parameter of SpriteBatch.Draw.

To build a Texture2D in XNA, we first have to set the size. Then we load in an Color array to specify the individual color of the pixels:



Drawing the full map is pretty straightforward:

spriteBatch.Draw(MapTexture,TopLeftPixel, null, Color.White,0,new Vector2(0,0),this.scale,SpriteEffects.None,0);

If we want to have a cropped version of the mini-map, we can use a function to determine the cropping rectangle, centered on the player position:



Then we can draw with these params in the Draw function:

spriteBatch.Draw(MapTexture, TopLeftPixel, getPlayerCenteredMapRec(this.scale), Color.White, 0, new Vector2(0, 0), this.scale,SpriteEffects.None, 0);

One important feature of mini-maps is the Fog of War. We don't want to reveal the entire map to the player from the beginning. Instead, we want to hide parts of it and reveal more as the player explores. Uncovering new sections of the map is one of the fun parts of games with complex level design.

To implement Fog of War, we store an extra 2D character array that determines which tiles in the map have been revealed. As shown above in the GetColorArray() function, sections that are not yet revealed (char '?') are drawn Gray.

The Fog of War char[,] array starts out completely filled with "unknown" tiles - '?'. Each time we draw, we make a call to update the Fog Of War, determine what tiles the player can see, and switch those tiles over to '.'.

I'm using an open source algorithm called MRPAS to determine what the player can see from his position. Full source available here: http://www.umbrarumregnum.net/downloads/mrpas

The code itself is somewhat complex, but essentially it draws lines out from the player until it hits an obstacle. One nice feature of the algorithm is you can specify to "light walls", which means the wall tiles themselves will be revealed in the Fog Of War, and therefore show up in the minimap.



I was a little worried that the whole thing would run slow, since we're doing a dozen nested loops on nxn mazes every Draw cycle, as well as running the MRPAS algorithm. However, it runs without hiccup. If performance started to become an issue (potentially on massive maps), you could simply keep track of which tiles the player has occupied. If we've already been to this tile, don't run the Fog of War / MRPAS algorithm. Similarly, only recalculate the Color[] for the actual mini-map tile if the player changes tiles.

Next time I'm going to look into everything related to enemies - path finding, line of sight, rudimentary AI, attacking, etc.

Monday, January 10, 2011

Building Mazes

Happy New Year!

From NetHack to Civilization to Diablo to MineCraft, lots of games have used procedural algorithms to generate semi-randomized levels. For a one man shop like myself, its a way to generate lots of gameplay without a ton of gruntwork.

So how to go you about building mazes?

One site that really helped me out was PCG.Wikidog.com - Procedural Content Generation. It contains algorithms for some of the classic roguelikes, including Angband.

A maze itself can be generated with a pretty simple iterative or recursive algorithm. The psuedocode is as follows:


1. Start out with a 2D array of size nxn.

2. Fill each cell in the grid with character '?' (undefined)

3. Carve out a random cell.
   a. Define function Carve: make the input cell empty '.'
   b. Make the surrounding four cells "maybe" ','.
   c. Add these surrounding cells to a coordinate list called Frontier

4. Iterate or Recurse through the Frontier list until it is empty.
   a. pick a random cell from Frontier. You can use weighted algorithms to pick near the front or back of the list, which lead to different styles of maze (tight and claustrophic vs long empty passages)
   b. Run function Check on the random cell. Define check (Note, this is the most complex part of the algorithm, so you may need to follow along the actual code below)
     i. get the EdgeState of the cell - sum up the cells surroundind the current cell. Empty to the north = 1, south = 2, west = 4, east = 8.
     ii. If we're not up against the side of the map, set the diagonal spaces adjacent to the input space as empty, and return false. Otherwise return true. This basically makes the maze have corners.
   c. If Check was true, Cave out the cell. Otherwise Harden the cell - turn it into a wall '#'
   d. Remove this cell from the Frontier list.

5. Once the Frontier list is emtpy, go through the entire map and change "maybe" cells ',' into empty cells '.' . Turn unknown '?' cells into walls '#'


Full Code:

private char[,] maze; //field
private List frontier;

private int height;
private int width;

private void BuildMaze()
{
 maze = new char[height, width];

 //traverse the maze and fill in unknown blocks
 for (int i = 0; i < height; i++)
 {
  for (int j = 0; j < width; j++)
  {
   maze[i, j] = '?';
  }
 }
 //carve out a random spot
 Carve(r.Next(width-1),r.Next(height-1));

 while (frontier.Count > 0)
 {
  double pos = Math.Pow(r.NextDouble(), Math.Pow(Math.E, branchrate));
  int index = (int)(pos * frontier.Count);
  Coord c = frontier[index];
  if (Check(c.x, c.y))
   Carve(c.x, c.y);
  else
   Harden(c.x, c.y);
  frontier.Remove(c);
    
 }

 for (int i = 0; i < height; i++)
 {
  for (int j = 0; j  0)
 {
  if (maze[y - 1,x ] == '?')
  {
   maze[ y - 1,x] = ',';
   frontier.Add(new Coord(x, y - 1));
  }   
 }
 if (y < height - 1)
 {
  if (maze[y + 1,x] == '?')
  {
   maze[y+ 1,x ] = ',';
   frontier.Add(new Coord(x, y + 1));
  }
 }
 if (x > 0)
 {
  if (maze[y,x - 1] == '?')
  {
   maze[y,x - 1] = ',';
   frontier.Add(new Coord(x - 1, y));
  }
 }
 if (x < width - 1)
 {
  if (maze[y,x + 1] == '?')
  {
   maze[y,x + 1] = ',';
   frontier.Add(new Coord(x + 1, y));
  }
 }
 //shuffle frontier?
 
}

private void Harden(int x, int y)
{
 maze[y,x] = '#';

}

private bool Check(int x, int y)
{
 int edgestate = 0;
 if (y > 0)
 {
  if (maze[y - 1,x ] == '.')
   edgestate += 1;
 }
 if (y < height - 1)
 {
  if (maze[ y + 1,x] == '.')
   edgestate += 2;
 }
 if (x > 0)
 {
  if (maze[y,x - 1] == '.')
   edgestate += 4;
 }
 if (x < width - 1)
 {
  if (maze[y,x + 1] == '.')
   edgestate += 8;
 }

 if (this.noDiagonals)
 {
  if (edgestate == 1)
  {
   if (y < height - 1)
   {
    if (x > 0)
    {
     if (maze[ y + 1,x - 1] == '.')
      return false;
    }
    if (x < width - 1)
    {
     if (maze[y + 1,x + 1 ] == '.')
      return false;
    }

   }
   return true;
  }
  else if (edgestate == 2)
  {
   if (y > 0)
   {
    if (x > 0)
    {
     if (maze[y - 1,x - 1 ] == '.')
      return false;
    }
    if (x < width - 1)
    {
     if (maze[ y - 1,x + 1] == '.')
      return false;
    }
   }
   return true;
  }
  else if (edgestate == 4)
  {
   if (x < width - 1)
   {
    if (y > 0)
    {
     if (maze[y - 1,x + 1 ] == '.')
      return false;
    }
    if (y < height - 1)
    {
     if (maze[ y + 1,x + 1] == '.')
      return false;
    }
   }
   return true;
  }
  else if (edgestate == 8)
  {
   if (x > 0)
   {
    if (y > 0)
    {
     if (maze[y - 1,x - 1 ] == '.')
      return false;
    }
    if (y < height - 1)
    {
     if (maze[y + 1,x - 1 ] == '.')
      return false;
    }
   }
   return true;

  }
  return false;
 }
 else
 {
  if (edgestate == 1 || edgestate == 2 || edgestate == 4 || edgestate == 8)
   return true;
  else
   return false;
 }

}
And that's it. You end up with something like this:
.#.##.#.#.#....#.#.#
....#.#.#.#.##.#....
###.#...#...####.###
#...###...#..#.#.#..
..#.#.##.#####.....#
###.#.#........###..
.#..#.##.#####...###
.#.##..#.....#.####.
....#.##.#######..#.
#.###.#...#...###...
The trouble is that the passageways are only a single tile wide or tall, which would make it very hard for our hero to navigate the game world, since he's two tiles tall! So we can scale the maze, simply by take a tile and copying it to 3 tiles to the east, south and south east. This doubles the size of the board. We can continue to double until the maze feels right - for my game it's a factor of 2, which is 4 times the size. You end up with something like this:
....########....####........####....####........########....####....########....
....########....####........####....####........########....####....########....
....########....####........####....####........########....####....########....
....########....####........####....####........########....####....########....
........................########....########........####....####........####....
........................########....########........####....####........####....
........................########....########........####....####........####....
........................########....########........####....####........####....
####################....................########............########....####....
####################....................########............########....####....
####################....................########............########....####....
####################....................########............########....####....
........................################################....########............
........................################################....########............
........................################################....########............
........................################################....########............
################....########....####....####....####............####....########
################....########....####....####....####............####....########
################....########....####....####....####............####....########
################....########....####....####....####............####....########
The world is still pretty boring, so one thing we can do is generate "rooms". These are large areas of empty space that we can later populate with platforms, elevators, traps and enemies. Generating rooms is pretty easy. Prior to building the map, select a few cells and expand them by random dimensions, changing them to type the "maybe" type ',' We don't want to completely empty them out, so the maze algorithm will still work. So now we have something like this. Better, but still not a game world:
....................########............########....####....####....####....####
########....####................############........................####........
########....####................############........................####........
########....####................############........................####........
########....####................############........................####........
....####....####....####....########............################............####
....####....####....####....########............################............####
....####....####....####....########............################............####
....####....####....####....########............################............####
....####################....################................####....####........
....####################....################................####....####........
....####################....################................####....####........
....####################....################................####....####........
....########............................####....................................
....########............................####....................................
....########............................####....................................
....########............................####....................................
........########....########....############....................................
........########....########....############....................................
........########....########....############....................................
........########....########....############....................................
The next step is to place special characters. These are tiles that will represent platforms, traps, enemies, elevators, items, powerups, etc. Once we have our fully scaled map, we can traverse through and check for certain patterns in which to place our special tile. For example, to place a platform '-', we want to be in a large empty room. So before we place a platform, check to see that the 5 spaces above and below are empty:
........................####............
........................####............
........................####............
........................####.......A....
....####................####....########
....####..............-.####....########
....####................####....########
....####................####....########
############............####............
############........-...####............
############...-........####............
############............####............
......................-.........####....
................................####..-.
................................####....
..A......A...-..................####....
############....-...........########....
############................########....
############................########....
############................########....
Lastly, we want to add some challenge and progression to our maps. We can do this with locked doors and keys. The easiest way is to generate lots of smaller maps, place a random key 'K' inside, enclose the entire thing with a wall and a single locked door as the exit 'D'. Connect all the smaller maps together, and we have a maze that requires some thinking to complete!
############################################################
#..................#............####...#............####...#
#....K.............#.....K......####...#.....K......####...#
#.A........A.......#..A.........####...#..A.........####...#
################...#########...........#########...........#
################.-.#########...........#########...........#
################...#########.-.........#########.-.........#
################...#########...........#########...........#
#..................D............####...D............####...#
#..................#............####...#............####...#
#..................#............####...#............####...#
#.A.............A..#...A........####...#...A........####...#
########....################....################....########
########....################....################....########
########....################.-..################.-..########
########....################....################....########
#..................#...................#...................#
#..................#...................#...................#
#..................#...................#...................#
############################################################
The fun thing about maze generation is that the possibilities are endless. You can instantly generate a new world to explore and jump around in.



Next time I'm going to look into minimaps, and "fog of war". We don't want to be able to spoil the entire maze in one glance!

Thursday, December 23, 2010

Where I'm At Now

Right now I have a pretty good idea of what I want Platform Hack to be in regards to gameplay. The original inspiration was actually Super Metroid, one of the best platformers of all time.



Super Metroid has all the standard action-platformer elements of jumping and attacking enemies, but what really set the game apart were the RPG elements, weapons and boss fights. As you make your way through the maze-world, you unlock upgrades to health and weapons. There are also tools you acquire that allow you to traverse the world more easily, including the the grapple beam and the space jump. The boss fights were also extremely polished, with animations to match, finding that great balance between challenge and cakewalk.



I'd like Platform Hack to borrow a lot of those elements, including the "movement" upgrades like the double jump and the grapple hook. Because the world in Platform Hack will be procedurally generated, there's the possibility of having super high vertical walls and cliffs, which could potentially post a problem for the standard jump. Of course, I'll have to tweak those maze-generation algorithms to limit the cliffs on the easier levels. But one of the goals of the game will be to acquire these "movement tools" in addition to more powerful weapons.

As far as development, I see the project in three stages:

1. Core Engine Development. This includes algorithms for collision detection, physics, player control, HUD, enemy movement and attacks, and boss scripting.

2. Game World Development. This is the world generation using procedural maze algorithms, different "features" like elevators, springs, doors, traps, as well as the more specific enemy and boss instances.

3. Asset Creation. This is where the game finally gets it's look - includes drawing and importing all the player, enemy and boss sprites, particle effects, tile and background images, HUD font and icons, sounds and music. Hopefully I have some help on board for this stage. But it's still a ways off.

Right now I'm still deep in stage 1, trying to work out the tweaks in collision detection for various movement tools, including the Grapple Hook and Jump Jets. But that's for another post -