Advancing in game programming

Started by
10 comments, last by dashurc 15 years, 3 months ago
Hi. I'm a beginner programmer. I'm mostly interested in game programming (like probably everyone here :P) but different from most people I'm willing to spend years on learning to be able to code 3D games. The problem is that I don't know how to progress. I know the basics of programming but I know nothing about programming techniques and software design. I'd like to know what I'd have to learn to make large codebase games that are not just hacks. Are game programming and general programming the same in this aspect? Are there any books or guides that could lead me in the right direction?
Advertisement
One thing that may help you is reading other people's code. Even if you aren't going to use it, read it. What you want to program decides what kind of software you should look at.

On another note, the internet is a great resource. You can find discussions, tutorials, examples, etc. on software design patterns and anything else.

And remember, as long as your code works, fulfills your requirements, and your're happy with it, then there is no reason it shouldn't make it to production.
Denzel Morris (@drdizzy) :: Software Engineer :: SkyTech Enterprises, Inc.
"When men are most sure and arrogant they are commonly most mistaken, giving views to passion without that proper deliberation which alone can secure them from the grossest absurdities." - David Hume
Quote:Original post by Halifax2
One thing that may help you is reading other people's code. Even if you aren't going to use it, read it. What you want to program decides what kind of software you should look at.



EURGH! No!

Seriously, please don't do this. Reading other people's code is a terrible way to learn programming practices, for one simple reason - you can't ask them why things are the way they are. (OK, maybe if you're crazy lucky you can get John Carmack or Tim Sweeney to explain their engines to you, but don't bet on it [wink] )

For instance, the project I'm currently working on contains about 140,000 lines of code at the moment (250k if you include comments). Just reading that much will kill you. Secondly, trying to figure out the motivation behind some of our design decisions will kill you again. Finally, even though you're already dead twice over, you will not be left with any way to make sound design decisions for yourself, and this will, yet again, kill you.



The best way to learn is to screw up a lot. Write the code and don't worry about practices or design or any of that jazz - just make it work. Then sit down and write a list of every point in your code that was a pain in the ass to write or debug; then think of ways you could improve it (or ask someone else for their insights).

Nobody can just read a lot of software engineering manuals and come out of it a good programmer. You have to take a few hits and suffer through bad code for yourself before you will develop a sound intuition for design.

I've heard estimates that this process usually takes around 10 years of constant, consistent practice; from my experience, that seems pretty accurate.


You can be shown good code, but until you've been stung by bad code, you'll never fully understand why the good code is good. So go out there, get stung a lot, and soon enough you'll be a master [smile]

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Quote:Original post by ApochPiQ --- Quoted For Truth
The best way to learn is to screw up a lot. Write the code and don't worry about practices or design or any of that jazz - just make it work. Then sit down and write a list of every point in your code that was a pain in the ass to write or debug; then think of ways you could improve it (or ask someone else for their insights).


Listen to ApochPiQ here. And as far as progressing in the game development sense, I'd suggest starting with a small project, and then working your way up to more complex projects. I believe the "common" way, or at least it was in yester-year, is something along the lines of cloning Pong->Tetris->PacMan->Mario, somewhat in that order.

Basically anything that will gradually/continually build up your knowledge/skill. And, yes, I know you said 3D games, but I'm inclined to believe that the concepts and techniques you'll learn in making these 2D games will be better than just throwing yourself at 3D.
In my opinion reading other people's code is a great practice is especially if it is tried, proven, and has a huge user base. If you wanted to write 3D engine, you would pass up the chance to read Unreal Engine 3.0?

No one said you have to read the full 140,000 lines, but skimming definitely helps you. In the end YOU have to decide what is best for you out of what you know, and what you have read. And you can use the things you learn to test them out, screw up a lot, and decide what works.

To simply say that reading others code is not a beneficial practice is way off.

I did forget to mention that if need be you should ask questions on why they do the things they do. And if you can't find that specific person, then GameDev is always here to discuss things.

Really, ApochiPQ, you have great advice, but your response to my message seems a bit out of line. Just for the fact that I didn't go over every single thing that will make a good programmer doesn't mean that reading code is a beneficial practice. No one said a good programmer is somehow conjured from reading software engineering manuals. I simply suggest one piece of information that may have helped! I in no way implied that reading other people's code was a great way of learning programming practices either.

It really appears that you didn't read my actual post at all.

You could have easily responded with your own piece of advice, thus appending to what I said by saying, "Not only will reading code benefit you, but actually practicing what you learn and being stung, etc." would have been a much more fitting post.

To each his own though. In my opinion, a good software engineer knows how to read others code, dissect it, know what's good about it, learn from it, etc.!
Denzel Morris (@drdizzy) :: Software Engineer :: SkyTech Enterprises, Inc.
"When men are most sure and arrogant they are commonly most mistaken, giving views to passion without that proper deliberation which alone can secure them from the grossest absurdities." - David Hume
... Yes, I'd pass up the chance to read UE3. Seriously, the best games do not have the best code. I've worked on numerous games, and I've looked at the source code for MANY different AAA games and engines. You're not going to learn any black-magic secrets. What everyone eventually learns in the industry is that everyone's code is terrible. =)

To top it off, most large successful games have so much code that you can't possibly learn much from looking at it. Engines like UE3, Source, idTech, etc... were not created from scratch with the intention of being the "best" way to make a big 3D game. Just like almost all games/engines, they were organically grown over a very long period of time, spanning multiple projects. This means that they do some things very well, but they also all have lots of historical baggage. Without context to understand how things got to be the way they are, you're really not going to learn much.

If you have access to the author of something, then you can talk to them as you try to understand their motivations. But I think that commercial games and engines are not the right kind of code to learn from in that case. You'd be better off looking at something like OGRE, where the developers aren't forced to make tradeoffs to ship a product, and there was some up-front thought put into design. And of course, the fact that it's open source and has an active community means that it'll be easy to start an interesting and helpful conversation about why things are done the way they are.

Ultimately, though, I have to agree that you learn by doing. Until you've been horribly burned by poor design decisions at the 11th hour of a project, it's not really going to sink in why you should avoid those decisions in the future.
I've read plenty of other peoples' code. Not because I want to learn anything important from it, instead I like to see other peoples' style. I think it's interesting to see how other people format their code because sometimes you see that your style and logic flow could easily be changed for the better based on what you see from others' code.

I don't think you should totally avoid reading source code. I just wouldn't use it to learn a particular skill or task.
A good book on how to design a game all the way through is always a good place to start. Alongside a book on general code design (design patterns, for example) to expand your programming skills (game programming books tend to stick to a reduce set of methods and coding standards).

2D games are a easier for starters, and you will learn a lot about game programming (3D computer graphics is just a small subset).

Also, programming can be quite tedious after a while. It is good to work out a plan and try to stick to it (say, make a geometry wars clone, design the game features, ect...). Schedule time, break down your work in tasks, and complete the work.

The problem is knowing what to start with, a book will help you lay down the groundwork. There is a lot of trial and error involved usually.

Oh yeah, and the FAQs here are good for starters.

Everything is better with Metal.

Quote:Original post by Halifax2
Really, ApochPiQ, you have great advice, but your response to my message seems a bit out of line. Just for the fact that I didn't go over every single thing that will make a good programmer doesn't mean that reading code is a beneficial practice. No one said a good programmer is somehow conjured from reading software engineering manuals. I simply suggest one piece of information that may have helped! I in no way implied that reading other people's code was a great way of learning programming practices either.

It really appears that you didn't read my actual post at all.



I read your post; in fact I've read it several times now [wink]

Allow me to summarize the discussion:
New programmer: I don't know how to advance my skills and learn how to design good code. What's a good option?
You: Read code.


In the context of the thread, it sure looks like you're trying to say that reading code is going to help the OP learn good practices. I'm not sure of any other way to interpret your post, actually.


Anyways, I still disagree.


Here's a real life example:

CheckInterval = ParseAndEvaluateExpression(node.GetAttribute(SCRIPT_XML_DELAY), *this);


Can you tell me what this does? Probably not. So let's go have a look at ParseAndEvaluateExpression:

ScriptValue Scripts::ParseAndEvaluateExpression(const tstring& expression, const ScriptVariableContext& context){   ExpressionPhrase* phrase = ParseExpression(expression);   ScriptValue ret = phrase->Evaluate(context);   delete phrase;   return ret;}


Hmm. What's a ScriptValue? What's the Script class doing and why is it there? What's a tstring and how is it related to std::string? What's a ScriptVariableContext? What does ParseExpression do? What's an ExpressionPhrase and what does it mean to Evaluate it? Why is the phrase returned from ParseExpression deleted here?


I've started with one line of code, which has now - in a single function, mind you - raised eight questions, ranging from simple implementation detail to high-level architectural design questions.

Let's take a look at how long it would take to unravel what that one line is really doing:
  • To understand ScriptValue, you have to read several long files and some comments that describe its rationale

  • To understand Script, you have to read about a half dozen more files, all of which will raise dozens of design questions.

  • Understanding tstring requires an in-depth knowledge of STL allocators as well as our custom memory management scheme; this is several pages of dense and arcane code

  • Understanding the use of ScriptVariableContext requires you to understand the design motivations between no less than four subsystems of the game (AI system, mission scripting system, cutscene scripting system, and the game logic implementation)

  • Understanding ParseExpression will lead you into a full-blown custom lexer and parser system, which powers the entirety of the scripting subsystems we use. That in turn exposes you to several major subsystems, all of which must be understood (at least in passing) in order to understand the necessity of the custom lexer and parser.

  • Similarly, ExpressionPhrase requires you to fully understand the parser's design motivation and how it has been optimized for our particular needs; it is very easy to misuse if one doesn't understand it fully, and can cause serious performance headaches in poorly-written scripts. That's yet more stuff that needs to be understood. There are also several additional tricks used in ExpressionPhrase and its related classes, which cannot be understood without knowing the grammar of the scripting languages we use.

  • The phrase is deleted in this code snippet because it is no longer needed and has no ownership outside the scope of the function itself. This is an exception to the way phrases are normally handled, which involves a fairly sophisticated chain of destructors and some very delicate time-of-death handling code. This may sound like a nasty hack (ok, fine, it is a nasty hack) but it's one that is vital to getting the game to do what we need.



That barely scratches the surface. One line of code has given a programmer a week's worth of stuff to follow up on - and if that programmer doesn't know what to look for, it could easily be a month's job. Without someone sitting next to him to explain why things are the way they are, this code is just confusing and raises far more questions than it answers.

And yet, on whole, I'd rate this particular module as one of the better-crafted designs in our code base. (Full disclosure: I wrote it. But, being as objective as I can, it's still one of the more nifty bits of code we've got. I owe most of its brilliance to my colleague though, who envisioned the original system that turned into the script engine.)


Now, in case I haven't yet driven the point home, what about code that isn't so great? What about the hacks and one-off special case stuff that was crammed in at the last minute to meet a deadline?

My problem with telling beginners to read code is this: a beginner cannot, by definition, tell good code from shitty code from a hole in the ground. If someone picked the scripting module from our game to learn from, they'd learn some interesting and beneficial techniques, but never understand why those techniques are beneficial (or, in many cases, why they are essential).

So if someone decided to choose one of the uglier sides of things, like how we handled joystick input and input mapping in X3, they're going to learn a lot of very, very bad practices (and again, full disclosure, I wrote the input mapping system and joystick controls for X3). And since they're learning from the master's code, why shouldn't they take the bad advice just as readily as the good?


To be blunt, I'm a pretty experienced programmer and I would never presume to understand a codebase just by reading through it a couple of times or skimming it. In fact, it took me several months of full-time work just to build up a working knowledge of the X3 engine and how it is constructed - and there are still many things about it I don't understand, where I have to rely on the wisdom of my coworkers to tell me what is good practice and what isn't.

A newbie that is chucked into the middle of Unreal Engine 3, or Source, or one of the idTech engines, or any other major, established code base (including all those popular free/cheap 3D engines) is going to have no idea how to learn from it. A newbie probably won't even think of all the questions that I listed above, because he has no experience that tells him he needs to ask those questions.

I was a newbie once, and I remember it vividly: code was still mostly all magic to me, and I'd copy and paste indiscriminately without paying attention to whether or not I really knew what the code was doing. It burned me many times, until I learned and built up the experience. Every newbie I've ever met has followed the same progression.


Quote:Original post by Halifax2
In my opinion reading other people's code is a great practice is especially if it is tried, proven, and has a huge user base. If you wanted to write 3D engine, you would pass up the chance to read Unreal Engine 3.0?

No one said you have to read the full 140,000 lines, but skimming definitely helps you.


No, I wouldn't want to look at UE3. UE3 is far more sophisticated and complex than any engine I'm going to write by myself. If I were a beginner, I'd have no clue what 90% of the code was even doing, let alone knowing how to learn design or implementation techniques from it.

Skimming code is not beneficial. Code is not prose; you can't understand it by just scanning over it with your eyeballs. If you are not actively engaged in dissecting the code and understanding it, you will probably hurt yourself in the long run, because you'll use something and you don't know how it works, and when it stops working, you're up a creek.

Quote:Original post by Halifax2
In the end YOU have to decide what is best for you out of what you know, and what you have read. And you can use the things you learn to test them out, screw up a lot, and decide what works.


The point is that we're talking about beginners here. As a veteran coder, I could sit down with an engine like UE3 and learn things from it fairly easily - but that's because I know what to look for. Someone with no experience is just going to get lost.

Furthermore, a beginner has no way to decide "what works" and "what is best." Remember, code is still magic - how is a newbie supposed to be able to differentiate between good and bad code? If they have to screw up to learn, why waste time ripping off other people's overkill code when you could just be getting things done?

Quote:Original post by Halifax2
In my opinion, a good software engineer knows how to read others code, dissect it, know what's good about it, learn from it, etc.!


I completely agree. Except we're talking about beginners here, not veterans. You can't seriously expect beginners to know how to dissect, analyze, and cherry-pick good code.


In any case, I never said that reading code is bad, or that you shouldn't do it. I said it's a terrible way to learn programming habits, and I stand by that.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Thanks for your answers everyone. I'm already on the path of starting from simple games. I've made a snake game and a tic tac toe game with AI (not game tree based though). I'll keep coding games with increasing difficulty then and try to find some reading on design patterns. Hopefully in the future I can collaborate with someone or make a mod so I could read others' code too.

This topic is closed to new replies.

Advertisement