Jump to content

  • Log In with Google      Sign In   
  • Create Account


Preventing Chaos in your game code


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 Vero   Members   -  Reputation: 138

Like
1Likes
Like

Posted 25 July 2012 - 01:00 PM

Hi Everyone, I've been coding a simple game in C++ with OpenGL. I'm pretty new to creating games and though I've had a lot of college experience in coding with C++ and Java and .Net I've never really developed anything professionally on this large a scale. The thing is I'm worried things will become more and more disorganized as I progress in making the game.

So far the game is a maze where you load the maze data from a text file and then you have to navigate to the goal. It will progress from there but I want to go over how I'm implementing it.

the Game Loop:
Level1= new Grid("data/Testlvl.txt",20,70);
max_fps=2; //TODO may need to incorporate a file load or mabye just play game from start to finish
int fcount=0;  //frame counter
long long fps_sum=0LL; //sum of frame rate
long long start=milliseconds_now();
//intialise player speed
Level1->player->Velocity.x=40; //40 pixels per second
Level1->player->Velocity.y=40;
while(!done) //Game LOOOP!
{
  if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //is there a message?
  {  //peek will not halt program while it looks for a message
   if(msg.message==WM_QUIT) // have we received a quit message?
   {
	done=TRUE;
   }
   else{ //if not deal with the window messages
	TranslateMessage(&msg); //Translate the Message
	DispatchMessage(&msg); //Dispatch the Message
   }
  }
  else{ // if there are no messages
  
   // Draw the Scene. Watch for ESC Key and Quit Messages From DrawGLScene()
   if((active && !DrawGLScene())|| keys[VK_ESCAPE])
   {
	done=TRUE;  // ESC Signalled a Quit
   }
   else{ //not time to quit, update screen
	//drew scene in the if statement
	while(FPS(start,milliseconds_now())>max_fps)
	{/*wait*/}
	if(fcount < 60)
	{
	 fps_sum=fps_sum+FPS(start,milliseconds_now());
	 ++fcount;
	}
	else
	{
	 fps=fps_sum/fcount;
	 fcount=0;
	 fps_sum=0LL;
	}
	start=milliseconds_now();
	SwapBuffers(hDC); //SwapBuffers (double buffering)
   }
  }
  }  if (!gameover && active)				// If Game Isn't Over And Programs Active Move Objects
  {
   if (keys[VK_RIGHT])
   {
	Level1->MovePlayer(M_RIGHT);
   }
   if (keys[VK_LEFT])
   {
	Level1->MovePlayer(M_LEFT);
   }
   if (keys[VK_DOWN])
   {
	Level1->MovePlayer(M_DOWN);
   }
   if (keys[VK_UP])
   {
	Level1->MovePlayer(M_UP);
   }

   Level1->Step(start);// what happens next?
  }
  //outside of live play:
  if(keys['A'] && !ap)
  {
   ap=TRUE;
   max_fps++;
  }
  if (!keys['A'])					 // If 'A' Key Has Been Released
  {
   ap=FALSE;				   // ap Becomes FALSE
  }
  if(keys['Z'] && !zp && max_fps>2)
  {
   zp=TRUE;
   max_fps--;
  }
  if (!keys['Z'])					 // If 'A' Key Has Been Released
  {
   zp=FALSE;				   // ap Becomes FALSE
  }

  //*********update scene****************
  /// Beat first Level Snippet
  if(Level1->player->isTouching(*Level1->goal))
   levelend=true;
  ///end of snippet
}


So right now inorder to switch scenes in the game loop I set global flags to true and false ( good or bed way to do it) and the DrawGLScene() will check the flags and determine which scene to draw,

After declaring a few setup variables I move everything along via time, I even force a max frame rate so that i can control the FPS. (I did this starting out just because I could and now I'm thinking about turning the FPS into something like a reward system collect items increase the FPS makes for smooth gameplay)

All my classes are contained within the Grid Class, the Grid Class will contain a player and a List of objects (coins enemies and such all will inherit the MObject class which has a bunch of virtual functions so I can iterate through the list and call Step() and Draw() functions. Step basically updates all the objects positions and other such statuses given that point in time. everything goes through Grid so when the user enters any key commands the Grid can determine what information flows to what objects it's managing. I keep most things public right now but I hope to eventually makes the objects private and get implement public functions to keep things from getting confuzzled.

so kind of breaking it down to the flow so far psuedo codeish:
GameLoop:
     DrawScene:
		  [chooses what scene to draw based on flags]
    	  assuming game is running 
          Draw header()
          Grid->Draw()
                    Draws grid 
                    Draws Players
                    Draws Goal
                    todo: draw enemies
                    todo: draw items
     Isgamerunning? 
     Check for input
          Move player, enemies
     Step
          grid.Step()
			   update animated items, players enemies,

          Are game changingg conditions met
               progress game


I'd really appreciate constructive criticism and how to make it better, methods to keep things organized, what your own ways to coding the loop are.

I hope my post makes some sense too

Sponsor:

#2 freeworld   Members   -  Reputation: 325

Like
4Likes
Like

Posted 25 July 2012 - 02:04 PM

This from my phone so excuse the horrible grammer/spelling.

For now i wouldnt worry about the chaos (spaghetti code) sounds like you just need a little more experience. So just keep on coding. Thats how youll get that experience.

Imho the biggest killer of projects is the same mentality that youre getting into. That everything has to be perfect feom the get go. Take a great example... diablo 3. Blizzard sold billions in the first day and the game is still plagued with bugs two months after release.

Not saying its alright to make buggy games. But that productivity is very important. You should focus on finisging the game first and for most. Assuming you have some worth finishing. Then refactor once youre in the optomizing phase of your prohect.

So get back to coding. Play your game often while developing. And worry about fixing things when something is actually broken.

[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.

#3 laztrezort   Members   -  Reputation: 959

Like
3Likes
Like

Posted 25 July 2012 - 03:12 PM

I usually refactor when I see one of the following:

1 - I have the same code in mutliple places - a good sign that the common functionality needs to be refactored out into its own method or object
2 - I have a largish glob of complex or hard to read code - a good sign that I should seperate the logic into multiple methods/classes.
3 - I keep having to tack on extra checks or variables to handle corner-cases, or the code is beginning to feel "hackish" - this is usually a sign that I need to rethink my design on a higher level.

I don't necessarily see any of this in your posted code, although these rules are somewhat subjective anyway. There may be idiomatic C++ concerns as well that I am not qualified to comment on.

As the complexity grows, you may find that you want to isolate your input handling code, or message dispatch, etc. Personally I try and avoid long if-else-else-else... chains if possible, they tend to confuse me when revisiting code later, YMMV.

An easy trap (for me, anyway) to fall into is to try overengineering too early - I may feel clever with the results at first, but later humbled when I find that I need my design to go a completely different direction anyway.

#4 frob   Moderators   -  Reputation: 20302

Like
3Likes
Like

Posted 25 July 2012 - 03:34 PM

It is a good idea to think in systems. Don't update a single object, notify the system to update itself.

Your pseudocode example does this fairly well, much better than your actual code sample does.

Example: Rather than iterating over each particle in your main loop, have a particle system manager that runs every update; this in turn updates each of the active particle systems, which in turn iterate over every particle. Yes there is some overhead involved, but machines are multi-core multi-gigahz, and a few nanoseconds of overhead is a great tradeoff in exchange for keeping your sanity.
Check out my personal indie blog at bryanwagstaff.com.

#5 Vilem Otte   Crossbones+   -  Reputation: 1393

Like
0Likes
Like

Posted 25 July 2012 - 04:50 PM

#frob This needs one of my favourite quotes: "Sanity? I don't remember having such a useless thing in a first place." Posted Image

To the topic...

Anyway if you want to investigate some more into how to "prevent chaos in code" - try reading something on design patters, language conventions, naming conventions and it's never too late to start to use F.e. Doxygen style commenting, that is actually very helpful to keep code nice and clean...

Also I recommend reading something on coding style, naming conventions, etc. - and try to keep single coding style and naming convention in every single of your project (and don't always use just one, use different coding styles in different projects - you might once come to contribute to applications on SourceForge - then it's huge advantage to adapt to different coding styles) Posted Image

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com


#6 Servant of the Lord   Crossbones+   -  Reputation: 18501

Like
4Likes
Like

Posted 25 July 2012 - 05:50 PM

While I agree that productivity is important, and that your coding will improve with time, I also feel that you yourself can increase the quality of your coding style greatly by adopting a few tricks and tips at a time and integrating them one by one into any new code you write. Basically: Don't beat yourself up over bad code, but don't pretend it'll get better on its own and actively invest in learning cleaner coding practices.

I'd strongly recommend Code Complete (2nd Edition) by Steve McConnell. Best programming book I've ever read - It contains tons of good "Do this to improve your code quality, and here's why" advice.

I also wrote a series of posts in a thread about half a year ago about some clean coding practices. There are multiple good posts if you keep reading down (particularly the second page), and should be a good place to pick and choose some techniques.

Edited by Servant of the Lord, 25 July 2012 - 05:52 PM.

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#7 thok   Members   -  Reputation: 684

Like
1Likes
Like

Posted 27 July 2012 - 02:03 AM

As others have said, reading books and other resources about clean code, coding style, and design patterns are all very useful.

Here's my advice:
- Use static analysis tools to check for styling issues and possible bugs. For Java, there's Checkstyle and Findbugs. For Python, you have pep8, pylint, and pyflakes. There are equivalents for other languages; just check google.
- Check your code/test coverage. (You are writing unit tests, right?) I found this immensely helpful in pursuing game programming as a hobby. Before I started doing rigorous testing and coverage analysis, I was just kind of thrashing around and things just sort of worked. Now, when I implement a new feature, I check my test coverage. If there's a large body of code with no coverage, I stop coding and I test it. If it can't be tested easily, it probably needs to be refactored.
- Write as much as you can in a pure functional style. That doesn't mean you have to go crazy with functional programming concepts, but the fact is purely functional code is much easier to test. So if you can move a bunch of the complexity into small, easily testable functions, you'll that you'll have greater confidence in your code and that it's easier to make changes. (BTW, John Carmack has talked about the benefits of writing functional-style code: http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/)

That's my 2 cents.

#8 Postie   Members   -  Reputation: 916

Like
1Likes
Like

Posted 27 July 2012 - 06:26 PM

First things first. Does it work? If not, get it working. Then think about refactoring.

A good metric for determining if refactoring is required is if the code makes sense to you at a glance a few weeks or months later. You can often overlook obvious design flaws when the code is fresh in your mind.

IMHO, it's better to code an imperfect solution and then improve it later (if you have time) than spending hours agonising over producing the perfect design first time. I know this because I'm guilty of it all the time.
Currently working on an open world survival RPG - For info check out my Development blog: ByteWrangler




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS