Thursday, September 26, 2013

Stick Man Trampoline : Designing the Mechanics

So in my previous post about multi-platform programming, I mentioned that I was planning on doing a small game to practice/test my theory on multi-platform programming.  That game is called Stick Man Trampoline!

To start off, I wanted to keep the gameplay simple.  I wanted the actual implementation to be basic, so that I could easily test how it worked on multiple platforms.  I decided to take the old game Breakout, and simplify it.

So, we start off with the paddle, and a "ball" that will bounce on it.  In Breakout, the skill comes from controlling the ball in different ways to hit and destroy all the bricks.  As the amount of bricks get reduced, you have to aim in different directions to hit the remainders.  With my game, I wanted there to be one target or goal, and the entire level is focused on reaching that goal.  I decided to put a hole in the roof, and make that the target.  Hitting the walls, floor, or anywhere on the roof that isn't the hole results in a loss.

Next step is how you control, or work towards this goal.  I knew I wanted to give the player a level of control as to which direction (left or right) they can fling their character, so the further from the center of the trampoline the character hits, the more 'in that direction' they'll fly as they go up.  This is cumulative, so if you've hit the left edge twice, you'll have to hit the right edge twice to equal it out to 'straight up'.  The other option was to reset the horizontal movement each time you hit  the tramp, giving the player more control.  I decided this was too forgiving, however, and wanted the player to have to think about every jump.  The last part is how long it takes to get to the goal.  Basically, there's a set number of 'jumps' it takes to get to the roof, and you have that many 'jumps' to get the character oriented correctly to make it through the hole.

Next step is how difficulty increases across levels.  One way to vary difficulty is to affect the goal.  I decided to randomly place the hole in the roof, to give some variance to each level.  On top of this, as you progress in levels, the hole will get smaller.

Next, I wanted to make the game a little more intense with each level, so as the level increases so does the amount of horizontal motion you get from the trampoline.  As levels progress, the player has to be more careful about where they place the tramp.  A slight nudge in one direction early on, becomes a mistake that will fling you straight into the wall in later levels.

The last area of gameplay I wanted to vary with difficulty was the number of jumps required to reach the top.  There were two options here, each of which would change the feel of the game.  First, was to decrease the amount of jumps with each level.  This would create a sense of urgency, and focus the player on small, discrete movements of the trampoline.  The other option, is to increase the required number of jumps.  This would give the player more time to line up to the hole, but also allow more room for mistakes.  I decided to go with the second option, favoring the thought of the player frantically trying to fix an erratic 'bad jump' before they hit the roof.

Well, I feel like that explains all the mechanics that went into Stick Man Trampoline.  My next post will be going more into the graphical elements of the game, focusing on making it "Juicy".

Sunday, September 8, 2013

Code Snippet : An Exercise with Multiplatform Programming

So today I'm going to address an issue I ran into while creating Snake Hunt.

Snake Hunt was built in Monogame, an open-source framework that wraps around XNA.  The reasons I chose to use Monogame are because it's simple and Monogame promises to be incredibly multi-platform.  With this in mind, and the thought that after programming once I'll be able to release on pretty much every device, I jumped into making Snake Hunt.

Visual Studio Monogame Templates

So I threw together a Windows Store Project, and started coding assuming I could worry about the other platforms later.  See, this is how I perceived Monogame worked:


So, I finished the game, had it running perfectly, and decided to try other platforms.  First thing I realized was the project I was using was designed to build only to Windows 8.  Fair enough!  So I made a new Windows Phone project.  Now I needed the code to be moved over. . . so I just made copies of all the files and tried to build the project and I got a boat-load of missing reference exceptions.

See Monogame isn't a 100% wrapper around anything you could write, it simply wraps around the XNA framework.  Though the majority of what's written in a game would be within that framework, there are certain things that aren't, that would still be platform specific.  An example of this would be in app purchases and ads, which are handled differently on every platform.  A more accurate diagram of this follows:

So Monogame isn't the whole game, just part of it.  The remaining parts can easily be programmed for each platform, but the problem comes with how the game refers to it.  Since every platform works differently, the game would need to reference different code for each platform you're building for.  At this point that means you'd need a separate copy of the code for each platform, and then change each copy to work on that platform.  The problem with this is it causes a LARGE amount of duplicated code, and whenever you change something in your game, you have to change it in multiple places.

The solution to this is to use something called an interface.  An interface is a programming construct which defines different methods, and then allows other 'classes' to implement it, promising that those implementations will also have those methods.  We can then take the game code, and refer to just the interface, which would have methods like "PerformInAppPurchase" or "ActivateApps" etc.  Then, in each platforms project, we use the same game code, but just pass in that platforms specific implementation of the interface.  What we end up with is the game referring to each platform in the same way, keeping one copy of the code, and each platform handling their own specific stuff.  Like this:



So, with these realizations, I'm starting work on another project.  I'll post more information later, but the goal of this project is to put this design to the test.  It'll be a simple game, with basic gameplay and art, but will (hopefully) work on any of the platforms Monogame supports.

Project Setup

Even with these discoveries, I was still having trouble keeping the code base shared between so many different projects.  Everytime I made a new class, I had to copy it as a link to all the other projects.  In searching for a solution to this, I discovered this magical chunk of xml:
<Compile Include="..\MonoGUI\CStudios\**\*.*"> 
 <Link>%(RecursiveDir)%(FileName)</Link>
 </Compile>
EDIT:  Working with this a little further, it turns out that using this with Content needs to be done a little differently.  Assuming that you've made a WindowsPhoneXNAContent project (the only type that works in Visual Studio 2012), you'd use the following:
<ItemGroup>
    <Content Include="..\ContentProject\ContentProject\bin\Windows Phone\Debug\Content\**\*.*">
      <Link>Content\%(RecursiveDir)%(FileName)%(Extension)</Link>
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
Where "ContentProject" would be the name of the Content Project you made.
The problem I was having was that the .xnb was being cut off of the extension, which stopped the ContentManager from loading it.  Using %(Extension) fixes this.
END EDIT


Used in conjunction with the following project layout:
Basically, we start off with a "Library" project.  Create a folder within that, where we put all the source code for the game.  It doesn't matter what platform we put as the build target, since that project will never really be built.  From there, we make a project for each platform, and place the chunk of xml within the project file (Replacing MonoGUI with the Library project name, and CStudios with the folder that contains the source).

From this point on, every project now contains a "Link" to all files in the library project.  Not only will the sub projects automatically add any files you add to the library, but it keeps them up to date.  By setting them as a "Link" Visual Studio doesn't copy them into the local project, but instead keeps a reference to them.  When changed in the library project, the sub projects immediately have that update.

There are other files that remain local to only certain platform-specific projects, such as entry points (each platform launches the game differently, but they should all call something in the library code to do so), and the "Platform Specific" interface implementation I referred to earlier.

Hopefully this helps someone figure out how to do multi-platform programming!  I'll be putting another post up soon about my next game, that will be implementing this style.