Monday, November 15, 2010

C++ Project - Final Fantasy Battle System pt.4 - Input Handling

So, I've been continuing to slowly work on this project in my spare time. I've completed a simple scene management system as well as re-factored some of the base Game class into an Application class which contains most of the high-level engine components such as rendering and window setup.

Also, I've put together an input system which I think should be somewhat easy to deal with as I continue to add more functionality.

I decided to use a combination of the Observer pattern and the Command pattern so that I could have one central object that actually deals with the raw inputs and then passes friendly commands to interested parties.

Here's how it should all work:

1. InputController listens each frame for any new keys that we are particularly interested in.

2. InputController then notifies any interested controllers observering on the keys that were pressed.
3. The interested observers then decide which keys it is interested in and then creates ICommand objects on each one.

It should be that any object that wishes to implement a particular control scheme need only add the appropriate controller as a member variable.

Now, let's see some code.

The interface for InputController:

 class InputController : public IGameComponent
{
private:
CL_InputDevice m_keyboard;
vector m_keysThisFrame;
vector; m_commandObservers;
virtual void Initialize();
void notifyObservers();
public:
~InputController();
void Initialize(CL_InputDevice);
virtual void Update(unsigned int);
virtual void Draw(CL_GraphicContext& graphicsContext);
void registerObserver(ICommandController*);
void removeObserver(const ICommandController&);
};

Here are the interfaces for a high-level command system (ie. exiting the game, etc.)

 class Game;
class SystemCommandController : public ICommandController
{
public:
SystemCommandController(Game&);
~SystemCommandController();
void Notify(vector);
private:
Game& m_gameObject;
};
 class Game;
class SystemCommand : public ICommand
{
public:
enum SystemCommands {EXITGAME};
SystemCommand(Game&, SystemCommands);
~SystemCommand();
void Execute();
private:
Game& m_gameObject;
SystemCommands m_commandToExecute;
};
And the actual implementation of the SystemCommand class so you can see how the commands are handled:

 #include "SystemCommand.h"
SystemCommand::SystemCommand(Game& gameObj, SystemCommand::SystemCommands command) : m_gameObject(gameObj)
{
m_commandToExecute = command;
}
SystemCommand::~SystemCommand()
{
}
void SystemCommand::Execute()
{
switch (m_commandToExecute)
{
case EXITGAME:
m_gameObject.ExitGame();
break;
}
}

So, there you have it! A nice and clean input handling system. There will be slightly more work involved setting up the classes, but it is very easy to reuse across multiple objects.

This project seems to be moving slowly, but it is nice to really engineer something rather than just hacking and reacting! I've got the GUI system going, so hopefully next time there might be some screenshots of my programmer art screens!

Sunday, October 31, 2010

C++ Project - Final Fantasy Battle System pt.3 - Game Loop

So this past week was spent mostly learning the ClanLib GUI system and starting development on a Scene management system that is a basic implementation of a scene graph.

But more on that later. Today I just wanted to follow up on a loose end from last week. Namely the addition of a proper timed game loop to the project.

At some point I will be looking at animations or character movement and I will need the delta time for each frame in order to have proper frame dependent movement.

So the math for this is very simple. I have setup a constant which is my targeted time for each frame:

 static const unsigned int TIME_PER_FRAME = 16; // time per frame in milliseconds  


Since I would like to target 60 fps, I have set the value to 16 milliseconds per frame.

Now in order to calculate the frame time it will look something like this:

- Get system time before game loop
- while (gameLoop)
- Get time before executing game code.
- Calculate deltaTime = (time_before_loop - time_before_executing_game_code)
- GAME CODE
- Get time after game loop.
- Calculate timeToSleep = (TARGET_FRAME_TIME) - (time_before_executing_game_code - time_after_game_loop
- Sleep(timeToSleep)
- loop


Not too bad. And now the actual implementation in our Game class:

      unsigned int lasttime = CL_System::get_time();  
while (m_currentGameState == Running)
{
unsigned int startFrameTime = CL_System::get_time();
int deltaTime = startFrameTime - lasttime;
lasttime = startFrameTime;
DO GAME STUFF HERE
startFrameTime = CL_System::get_time();
int timeToSleep = TIME_PER_FRAME - (startFrameTime - lasttime);
if (timeToSleep > 0)
{
CL_System::sleep(timeToSleep);
}
}


Now I can pass my delta time per frame to my update functions in my IGameComponent class.

 virtual void Update(unsigned int) = 0;  


On other fronts, my Game class is starting to become a little unwieldy especially with all of the GUI stuff making its way in, so I think my next entry will be a bit of a lesson in refactoring.

Sunday, October 24, 2010

C++ Project - Final Fantasy Battle System pt.2

So with any programming project, the initial question is "where do I start?" I have ClanLib installed and the compiler configured and ready build, so now it's time to start planning exactly how to approach this project.


The heart of every game is essentially a loop which is responsible for updating and rendering. Since ClanLib does not provide a standard game loop or the means to track objects in our game, this seems like a good place to start.

So, we'll start with a base class, Game which will contain our loop.

 class Game   
{
private:
enum GameState {Stopped,Running,Paused};
// Singleton instance
static Game* m_instance;
. . .
Game();
Game(const Game& a);
public:
~Game();
static Game* GetInstance();
void Start();
void Initialize();
}

Notice that I have made the class a Singleton. Since I am anticipating other objects wanting to add/remove themselves from the main game loop, I want this class to be accessible anywhere within the program. Since the Game class is guaranteed to exist during the lifetime of the game, there should be no problems with initialization that is inherent with Singleton objects.

Also, I anticipate that we might want to add some simple functions for pausing the game, etc., so I have added an enum to track the current state of the loop.

Now that we have the outline for a basic loop, we need objects to actually render and update. In order to facilitate this I created a basic interface that we can use for any class that we might want to add to our loop.
 class IGameComponent  
{
public:
virtual void Initialize() = 0;
virtual void Update() = 0;
virtual void Draw(CL_GraphicContext& graphicsContext) = 0;
};

Now, let's add a container and a couple of operations to our Game class to actually track these objects.
 vector m_gameComponents;  
void AddComponent(IGameComponent*);
void RemoveComponent(IGameComponent* const)
Here is the full update loop for the game loop.
 void Game::Start()  
{
m_currentGameState = Running;
CL_Font font(gc, "Tahoma", 30);
while (m_currentGameState == Running)
{
Update();
gc.clear(CL_Colorf::cadetblue);
Draw();
gui_manager->exec(false);
wm->draw_windows(gc);
// Make the stuff visible:
window->flip(1);
// Read messages from the windowing system message queue, if any are available:
//CL_KeepAlive::process();
// Avoid using 100% CPU in the loop:
CL_System::sleep(10);
}
}
void Game::Update()
{
// Update loop
for (int i = 0; i < m_gameComponents.size();i++)
{
m_gameComponents[i]->Update();
}
}
void Game::Draw()
{
for (int i = 0; i < m_gameComponents.size();i++)
{
m_gameComponents[i]->Draw(gc);
}
}

And there you have it! A simple system for dealing with the game loop. Next up, I will need to add some sort of Scene Manager in order to track scene transitions and to encapsulate the elements that form each scene. I will also be adding in some hooks for the GUI system and the Input system into Game as well. Once, I have those in place I will start working on the design for the actual RPG gameplay.

Sunday, October 17, 2010

C++ Project - Final Fantasy Battle System pt.1

So in order to keep my programming skills in shape, I like to take a new engine and begin to develop some game systems utilizing it. Most of these are usually stalled due to lack of time or my curiosity about something new that is more interesting.


In order to rectify this, I've decided to start a small project that is not necessarily about writing a complete game for release, but rather something I can use to practice building game systems and further my use of design patterns within these systems.


So, I've chosen to go with a 2D C++ engine called ClanLib and what I will be working to build is essentially this:


That's right, I will be working on developing the battle system from Final Fantasy I. I'm a major fan of RPG games and this was probably my second or third RPG ever, so it holds sentimental value. Also, I've limited the scope slightly so I'm not overwhelmed with large complicated AI or physics systems, as it truly is the gameplay systems that really light my game developer fire. I've also picked something that can done with simple sprites as I am not an artist either.

So, within this project, I will be implementing the following:
  • General game loop
  • Input handling
  • GUI
  • Scene Management
  • RPG system (PC/NPC stats, item handling, spell casting abilities, etc.)
  • Battle system
I will be blogging each step of the way with my goals being:
  • Improve my design capabilities
  • Improve my coding standards to develop code that is highly readable and maintainable.
  • Expand my knowledge of 3rd-party game engines.
  • Expand my knowledge of game systems.
Anyhow, it should be a blast!

Wednesday, October 13, 2010

Time Flys When You're ...

I can't believe it's been almost two years since I've updated this blog. I'm not sure where the time went, but it sure has been a busy period.


The Past

In the last two years (other than NOT writing in this blog) , I've accomplished the following:
  • Developed and released an Xbox Live Indie Game.
  • Placed in the top five of the Old Spice Dream Build Play contest.
  • Developed a complete game in 48 hours.
  • Developed a match-3, RPG with dragons.
  • Released a children's MMO.
  • Met and worked with some truly unique and awesome people.
In addition to all of that, I was taking some classes at ACC and working on and off on some personal projects that unfortunately had to be stalled due to the above.

The Future

So what's coming next? Well, concerning this blog, I do have a new C++ project I'm working on in my spare time, so I think I'd like to start blogging that just to get some of my C++ code out there.

Regarding myself personally, I'm not real sure. I'll just keep developing, reading, and learning. I love developing games and as I found out the last few years, it's something that I can't not do.




Tuesday, December 2, 2008

Fallout 3 and the Illusion of Open Level Design

http://xspblog.files.wordpress.com/2008/08/fallout-3-1010.jpgI've been playing Fallout 3 for the past month and I'm very pleased with it overall. However, after playing for sometime I decided to explore the edges of the map and when it appeared that I could continue onward I was met with an invisible wall along with text stating that I could not continue any further. Now, this is not necessarily a bad thing. In fact, I recall that Oblivion had almost the same message when reaching the edge of the map. Does this break the illusion of the vast open world that Fallout boasts of? Well, maybe just a little.

This is not a problem that is not particular to Fallout however and it urged me to think about how level designers are always forced to impose physical limits on the player. The ability to poke and prod the player into the right direction, while keeping them on track is a related problem, but here I want to specifically discuss how to limit the player to remain in a finite space with the illusion that they are actually part of a much bigger world. Specifically, the only games effected by this are those in which the player is an active participant in an ever-changing world, so any open-world type of game will do. It is specifically within these styles of game that it is ever important to maintain this illusion of a large, unconstrained world.

So what are some of the strategies that have been or could be used to confine players within this type of game environment? Here are a few:

  • Invisible Walls - This is probably one of the least imaginative ways to let players know that they have reached the boundaries of the game world. This is the design that was chosen for Fallout 3 and Oblivion and simply tells the player they must turn around.
  • Geography - A more natural limitation is to design the world geography in such a way that it is physically impossible to continue. This could be the addition of mountain ranges or an island setting with an endless ocean (Morrowind,GTA) that is impossible for the player to traverse.
  • Design Enforced - This is similar to geography in that it places barriers that the player cannot physically cross, but which are in line with the theme of the game. For instance in Assassin's Creed, the player's screen is garbled at the edges of the map in accordance with the virtual reality theme of that game. This could also includes a death barrier, such as a radiation field that kills the player if he continue past the boundaries, thus making it impossible to continue. I would also include architecture based limitations as well, such as the ruined cities in games such as Gears of War.
In most types of games, it's a given that the world is finite, but it is up to the game designer to at least provide the illusion that the world is larger than it seems. While it may not completely invalidate the game experience if a poor decision is made when placing barriers around the game world, it can be a jarring moment for the player when they come across something that is out of place or blatantly obvious. I'm definitely going to be keeping my eye out for other ways that games attempt to do this as play in the future.

Saturday, October 25, 2008

Tabula Rasa - More MMO Playing

Tabula Rasa NTSC-U (North America) front boxshotSo, after several months of tinkering with Sword of the New World, I decided to finally take the plunge into Richard Garriot's Tabula Rasa. I don't really like to write full-on reviews of MMOs, so I'll just do my usual list of likes and dislikes. After having spent almost 30 hours in the game, I'm actually feeling very positive about the experience, so here goes....



Likes:

1. Combat that is actually a little more than target-lock, hit number keys, rinse and repeat. I like the fact that cover, range and direction are implemented into the combat system. This provides a very action-like experience. Some of the larger battles I faced in instances such as Devil's Den or Torcastra Prison were actually exciting.

2. Solo play seems like a viable option in this game, at least at this point for my level 25 Ranger. While it's fun to run some instances with a squad, sometime I just want to jump in, play for a bit and be out and not have to deal with managing people or looking for a group. With most of the other MMORPG's that I've played, I felt pushed into grouping with others if I wanted to continue to see new content which doesn't seem to be the case with Tabula Rasa.

3. Theme. Sci-Fi trumps Fantasy any day of the week in my book. That's part of the reason I was so attracted to EVE Online. Hopefully Tabula Rasa's gameplay won't betray me in the same way.

4. Character Tree, rather than a set class. I'm not sure why I like this so much, but it really feels like a good incentive to continue to level my character if I know an entirely new class expereience is waiting for me in a few levels. However, the stretch from level 15 to 30 is a long one indeed.

Dislikes:

1. Bland World. While the setting and story seem to depend on this, the world seems to be very bland with a lot of the same structures popping up around the place and the world looking very similar all-around. This seems to be an issue in the instances as well.

2. Low variety of enemies. This is actually a problem inherent to the RPG genre (electronic variety at least), but I must mention it. I don't know how many times I've fought a member of the Thrax Infantry that was only different in the last area by name and stats.

3. Finding a squad is not that easy. Locating a squad seems to be a little iffy at times. It seems most people don't use the advertising system, but rather just advertise in the General chat window. Not a big deal, but still something that could be better.

So, there are my current impressions of Tabula Rasa. Hopefully this will be the MMO that can maintain my interest for a longer period of time than the others, either due to gameplay or time issues.