eTek World Forums
A community for developers that want to learn and share ideas!

Home » Game Development » Game Programming » [Book] Game Programming Patterns (A book about game design patterns!)
[Book] Game Programming Patterns [message #6] Mon, 09 February 2015 14:15 Go to next message
lede is currently offline  lede
Messages: 52
Registered: February 2015
Member
Administrator

After reading the first couple of pages on my Kindle Phone app I bought this book to read. In almost every game I have developed I come across some of the most common issues that should of been solved a long time ago. This author seems to have read my mind and has brought his experience and knowledge into this book about patters of design.

Since this is about patterns of design there is no better book then the one written by the gang of four called Design Patters: Elements of Reusable Object-Oriented Code. I have this book too and may even dust it off for a discussion thread.

Anyways back to the book at hand. The main reason I went ahead and got this book was I like how the author used humor and back story to start his book. Update to come....

[Updated on: Mon, 09 February 2015 14:34]

Report message to a moderator

Update: [Book] Game Programming Patterns [message #7 is a reply to message #6] Tue, 10 February 2015 06:58 Go to previous messageGo to next message
lede is currently offline  lede
Messages: 52
Registered: February 2015
Member
Administrator

I've read quite a bit of the first section of the book already. Not sure what chapter I'm on the Amazon Kindle doesn't list chapters it seems.

After getting through the first few introductory chapters and reading some history about the author and patterns of design I have to say I like this author's writing style! And for those of you reading the book I have master ditch digging which is why I wanted to move into programming....

Now to the content of the book. The first couple of patterns are enlightening. Not only does the author describe the technical gorgon of the original Gang of Four Patterns of Design (GoF) he breaks it down to something very understandable and then shows why we would care about this particular pattern with very concrete examples. Take for example the command pattern. When I read this in the GoF book it made no sense and was really confusing why we designers would even care about this pattern. Well now I know why I would care. It is a very elegant class that makes many of our programming techniques easier. If your wondering why I'm not giving the information to you in this review it because I want you to buy this book and not give away all the great information. Robert Nystrom has spent a lot of time writing this book and I feel it is worth you time and money!

Even at 10% complete reading this book is full of some great information. Now time to get back to reading and programming.


[Updated on: Wed, 11 February 2015 06:57]

Report message to a moderator

Re: Update: [Book] Game Programming Patterns [message #8 is a reply to message #7] Wed, 11 February 2015 06:54 Go to previous messageGo to next message
lede is currently offline  lede
Messages: 52
Registered: February 2015
Member
Administrator

I'm already a quarter the way through this book. Some of the topic the author covers are good and shows solid examples of where we would use a particular pattern. But like most purists he makes it evident that the Singleton pattern is worthless because of its global scope. My take on this is many developers jump into programming and fall in love with the singleton pattern because its easy to understand and you can quickly get access to its members.

I'll be the first to admit that this I over use the singleton pattern because there are so many places I need to access common structures it just makes sense to create it once and use it multiple times. We could of used a little more real answer to why we shouldn't use singleton and give solid ideas on what we can do to replace them. Granted the author did say we would find better solutions later in the book.

So far though some of the patterns he has discussed are very enlightening. More and more I find myself compelled to keep reading to find those great secrets the author has locked in this book. The next post I make will have some experimental code for review and discussion.
Re: Update: [Book] Game Programming Patterns [message #11 is a reply to message #8] Thu, 12 February 2015 15:47 Go to previous messageGo to next message
lede is currently offline  lede
Messages: 52
Registered: February 2015
Member
Administrator

This is more of a rant today about the Amazon Kindle App for my Windows 8.1 phone. After getting though 40% of the book I have found it is hard to know where I'm at in the book. I'm not sure if this was a cost saving measure of the publisher or what but removing the chapter numbers from my pages kind of removes the relevance. Maybe it was a pixel saving measure but please put chapter numbers back into my books to make it easier to follow along.

Anyways today I was reading a bit about the different patters of the game loop. Finally someone has given me insight into how the DeltaTime can be calculated in the game loop. The game loop chapter is very informative and provides a good discussion about how important to game play that the main game loop plays into performance. I also liked the discussion on game development and some of the history. It maybe more because I remembered some of the older games and have more respect for those developer now then when I played their games.
Re: Update: [Book] Game Programming Patterns [message #13 is a reply to message #11] Wed, 18 February 2015 08:11 Go to previous messageGo to next message
lede is currently offline  lede
Messages: 52
Registered: February 2015
Member
Administrator

Well after the long weekend I spent a lot of time reading more on this book and getting really excited about programming games again. I took the time and started to work on building a start of a game engine working with the patterns presented in the book. For now I'm just playing with the concepts and building the game loop based on what was presented. So here is the basic game loop I wrote in C++ minus some of the namespace code for brevity. All object types that start with the letter "I" are interface classes. I did this by design so concrete objects could be passed into the game engine in a generic way. Also this helps me setup the Type and Virtual Machine patterns.

As always feedback is more then welcomed!

// GameEngine.h file
#include <deque>
#include <list>
#include <limits.h>
#include <ctime>
// C++11 features
#include <chrono>
#include <thread>

#include "IObjects.h"
#include "IEntity.h"
#include "ILogger.h"

using std::list;
using std::deque;

class GameEngine
{
	private:
		list<GameObjects*> ActiveObjects;
		list<GameObjects*> SleepingObjects;
		deque<int> SkeltonIds;

		ILogger* Log;
		unsigned int NextObjectId;
		bool IsRunning;

	public:
		// Standard C'tor methods
		GameEngine();
		GameEngine(ILogger* log);
		virtual ~GameEngine();

		// Initialization method so we can support multiple instantiation paths
		void Init();


		// World Management Methods
		IObject* AddObject(IObject* obj, bool AddLogger=true);
		IObject RemoveObject(IObject* obj);
		IEntity* AddEntity(IEntity* entity, bool AddLogger=true);
		
		unsigned int GetObjectId();

		// Create a quick way to log information
		ILogger WriteLine(std::string line);

		int PlayGame();
};

// GameEngine.cpp file

GameEngine::GameEngine()
{
	Init();
}

GameEngine::GameEngine(ILogger* log)
{
	Init();
	Log = log;
}

GameEngine::~GameEngine()
{
	if(Log != NULL)
	{
		// Need to clean up log object
		delete Log;
		Log = NULL;
	}
}

void GameEngine::Init()
{
	// Clear pointer so we don't accidentally use a random spot in memory
	Log = NULL;
	NextObjectId = 0;
	IsRunning = true;
	//... Other things that need to get initialized
}

IObject* GameEngine::AddObject(IObject* obj, bool AddLogger/*=true*/)
{
	obj->SetId(GetObjectId());
	ActiveObjects.Add(obj);
	if(Log != NULL && AddLogger)
	{
		obj.SetLog(Log);
	}
}

IEntity* GameEngine::AddEntity(IEntity* entity, bool AddLogger/*=true*/)
{
	// IEntity is a child of IObject
	entity->SetId(GetObjectId());
	ActiveObjects.Add(entity);
	if(Log != NULL && AddLogger)
	{
		entity->AddLog(Log);
	}
	
	return entity;
}

IObject GameEngine::RemoveObject(IObject* obj)
{
	if(obj->IsSleeping)
	{
		SleepingObjects.remove(obj);
	}else
	{
		ActiveObjects.remove(obj);
	}
	// Add Id to list of assignable IDs
	SkeltonIds.Add(obj->GetId());
}

unsigned int GameEngine::GetObjectId()
{
	unsigned int id = 0;
	// Check if we have any re-usable Object IDs
	if(SkeltonIds.size() > 0)
	{
		id = SkeltonIds.front();
		SkeltonIds.pop_front();
	}else if(NextObjectId + 1 < UINT_MAX)
	{
		// Create a new ObjectID
		id = NextObjectId++;
	}else
	{
#ifdef _DEBUG
		// This should never happen but if it does tell the developer about it
		throw new Exception("No more available IDs!");
#endif
	}
	return id;
}

ILogger* GameEngine::WriteLine(std::string line)
{
	if(Log != NULL)
	{
		Log->WriteLine(line);
	}
	
	return Log;
}

int GameEngine::PlayGame()
{
	WriteLine("Ready to play game!");
	deque<IObject*> transObj;
	unsigned int frames = 0;
	clock_t timer;
	static int TICKS_PER_LOOP = CLOCKS_PER_SEC / 60; // 60 Frames Per Second
	
	while(IsRunning)
	{
		timer = clock();
		for(list<IObject*>::iterator it = ActiveObjects.begin(); it != ActiveObjects.end()l it++)
		{
			if((*it)->IsAsleep())
			{
				transObj.push_back(*it);
			}else
			{
				(*it)->Update();
			}
		}
		// Check for objects that are sleeping
		while(transObj.size() > 0)
		{
			IObject* obj = transObj.front();
			// Remove from deque and move object to bed
			transObj.pop_front();
			ActiveObjects.remove(obj);
			SleepingObjects.Add(obj);
		}
		// Calculate how much time has elapsed		
		int sleepTime = (timer + TICKS_PER_LOOP) - clock();
		// Check if we have time to render
		if(sleepTime > 0)
		{
			// Render objects to screen
			// ... Render code goes here
		}
		
		sleepTime = (timer _ TICKS_PER_LOOP) - clock();
		if(sleepTime > 0)
		{
			// C++11 native sleep method
			std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
		}
		
		// Setting this to only run for n number of frames until there is a user way to close loop
		IsRunning = frames++ < 90;
	}
}

[Updated on: Wed, 18 February 2015 12:57]

Report message to a moderator

Re: Update: [Book] Game Programming Patterns [message #14 is a reply to message #13] Sun, 22 February 2015 15:51 Go to previous messageGo to next message
lede is currently offline  lede
Messages: 52
Registered: February 2015
Member
Administrator

Well today I've completed a few more chapters and have been learning about the importance of memory allocation and how important it can be to the performance of a game. I really like the analogy of how main memory gets piped into the process for usage. He explained it very simple terms to describe a very complex concept.

The simple concept of just aligning your data into memory properly can change the amount of work that can be performed by a factor of 50 times. So far all the games I have done have been very simple and don't have a large number of objects to deal with. But reading about in-lining my data had turned on a few light bulbs. I have one game engine I've designed that when you add a bunch of objects and then throw in the physics the FPS drops down to about 5-10 FPS. This is because of two issues. One the physics engine was calculating all collisions in the scene, the other issue is there were many objects in the scene that even at rest were needing calculations.

These two problems have lead me to understand the importance of dirty bit settings and caching major calculations for times when we can take the processing hit without affecting game play. I've started playing around with a new code base with different scaffolding based on the books suggestions. One of the best things I learned was trying to deal with not using a singleton pattern in my designs. My logging class this time was not a singleton pattern but instead now I can pass multiple logging system into the engine and now not have to wade through a log file ten million lines deep to find what I need to know.

So far here is an example game I'm working on:

index.php?t=getfile&id=2&private=0

Yes I know the graphics are one of the best things you have ever seen and want to know how I did it...

Okay your right this is a designed based on one of my favorite BBS games I played as a teenager back in the 1980's. The idea want that I wanted to make this awesome graphic based game but to build a conceptual engine that could either use ASCII as the graphics or swap it out with another render engine. Even though right now it is using a simple render engine with ASCII art the design allows for a quick swap out of the render engine.

Now time to learn how to work on a memory management system Very Happy
Re: [Book] Game Programming Patterns [message #15 is a reply to message #6] Mon, 23 February 2015 08:46 Go to previous messageGo to next message
lede is currently offline  lede
Messages: 52
Registered: February 2015
Member
Administrator

Today I just created a very simplistic AI controller for the monster and surprisingly this was easier than I had expected. I was able to reuse the player controller class I created for the user and hook a simple AI system to the player controller and viola the monster on the screen started to move. Here is the quick code I wrote for the AI controller:

bool AIMonster::ChkInput(int vk)
{
	// Calculate the distance from player
	int deltaX = abs(_me->x - _player->x);
	int deltaY = abs(_me->y - _player->y);
	int dist = deltaX + deltaY;
	if (deltaX > 1 || deltaY > 1 || dist > 2)
	{
		// Handle X movement
		if (_me->x - 1 > _player->x && vk == 'A')
		{
			return true;
		}
		if (_me->x + 1 < _player->x && vk == 'D')
		{
			return true;
		}

		if (_me->y > _player->y && vk == 'W')
		{
			return true;
		}
		if (_me->y < _player->y && vk == 'S')
		{
			return true;
		}
	}

	return false;
}


The key here was to make sure the AI had the monster's position in the game world and the player's position in the game world available. The other factor I did with the monster entity was set it up so that it doesn't update every frame. This would make the monster move really fast so I just did a simple calculation like:

CurrentFrame = (CurrentFrame + 1) % UpdateFrame;
if (CurrentFrame == 0)
{
	Zaxis::Entity::IEntity::Update();
}


I put this code in the monster entity update method and viola the mover gets called once every n frames. So now with this I will be able to control the difficulty of the monster.
Re: [Book] Game Programming Patterns [message #16 is a reply to message #15] Wed, 25 February 2015 07:46 Go to previous message
lede is currently offline  lede
Messages: 52
Registered: February 2015
Member
Administrator

I finished the book last night and I have to reiterate this is a must read for developers who want to get a better understanding of how good patterns can be used. Heck you may already be using a pattern in your design and don't even know it. But the author really brings some thought provoking ideas to mind with this book!

As for the game engine I stated from this book I'm moving it to a new thread for discussion.
Previous Topic: Global values
Next Topic: [Book] Game Engine Architecture, Second Edition
Goto Forum:
  


Current Time: Tue Oct 17 02:18:39 PDT 2017

Total time taken to generate the page: 0.01465 seconds