Looking for some "best practices" advice

Started by
15 comments, last by Delphawi 12 years, 7 months ago
I'm slowly getting my head wrapped around programming and I was wondering if there are any "best practices" out there that I should be following. I know the idea is to be "object oriented" but I am a little fuzzy as to how to apply/organize that. If a game has weapons, are each of those weapons in separate classes (or inherited classes from a "master weapon blueprint"?) Are the behaviors of these weapons governed by methods/functions? Are games organized in such a way that objects are "seen" (IE have access) throughout the game code via references or pointers more easily?

I realize these topics may be incredibly huge but I figure that since I really don't know where to start, I figure I'll start somewhere and just keep going :).

Any input, suggested reading, links, etc. would be greatly appreciated.

Ulfhedhin

Advertisement
What language are you talking about? There is no requirement to have an object oriented design, but it can make things more logical. If you are making weapons, you might want to derive a basic weapon class from an item class, and then derive the item class from an entity class. From your base weapon class, you could derive ranged and melee classes. That would be using a hierarchical entity system, but you could also use a component entity system where you essentially add components to an entity to make it what you want. You can make objects accessible to other parts of the game through references and pointers, but that doesn't mean make everything entirely global.

I'm slowly getting my head wrapped around programming and I was wondering if there are any "best practices" out there that I should be following.


There are, but what they are depend on what you're doing, what your doing it with, who you're doing it with, etc. Even then it often depends who you ask.

As a beginner, you're going to do bad things; don't worry too much about it. Write code, when you make bad code, learn from it.


I know the idea is to be "object oriented" but I am a little fuzzy as to how to apply/organize that. If a game has weapons, are each of those weapons in separate classes (or inherited classes from a "master weapon blueprint"?)
[/quote]

Not generally.


Are the behaviors of these weapons governed by methods/functions?
[/quote]

Usually. Sometimes the behavior is stored as data that drives some interpreter function.


Are games organized in such a way that objects are "seen" (IE have access) throughout the game code via references or pointers more easily?
[/quote]

Sometimes; not generally. One of the generally recognized best practices is to give things the least amount of access needed to make them work. The more things that touch a class means that many more things you have to look at when an instance of that class has somehow gotten into a odd/wrong state.

Sadly, the scope of 'best practices' is super huge. If you have more pointed questions as you write code (hint!) we can probably help you better.
Yikes! I guess I should have mentioned C++ LOL.

Yea, I know everything doesn't need to be global. But I'm noticing as I am creating a simple text-based RPG (as an exercise), I am needing to "see" various classes within my code and am having a tough time doing it sometimes. Perhaps it is poor organization on my part (hence me asking for "best practices" advice :) ) or just lack of experience (or both). But I am stumbling through it and I do a LOT of searching for solutions and more often than not I find what I need. I just have this nagging suspicion that it could be done better. That much is probably a given though LOL. It is just that feeling that I am on the cusp of understanding something vital but I haven't gotten that "lightbulb" moment yet.

An example would be my weapons in my RPG. At first I started out as having them listed in a struct with variables as their stats which were set to default values. These values would be determined when I created the character. I wasn't satisfied with that. So I gave each weapon its own struct with its own stats already initialized when the code was compiled. I wasn't satisfied with that either. So I had the bright idea of storing these items in a multidimensional string array (weapon name, weapon range numbers, etc) and I could cast the numbers to integers when I needed to. That turned out to be a huge headache. So then I thought that perhaps each weapon could be initialized on the fly via its own method that would set the variables as needed. I'm currently working on that one. So for right now, I am having weapons in one class with a separate method for each different one (the game is very small so there are only 5 weapons). So far it seems to work but I am trying to figure out a way for the game to call these methods when necessary from within the player's inventory and the "store" in the game. And I'm trying to wrestle with creating a vector array that'll serve as the player's inventory.

It's slow going and I know I'm making headway...even if what I'm doing comes to nothing. I know as well as anyone that you learn a lot when you mess up. Yet I also know that I learn very well when I either approach things from different angles or get different explanations on them. My brain wires all that together and I get that "lightbulb moment" :).

Thanks for the replies!

Ulfhedhin

This is not something based out of a book but something based on my personal experience:

Make sure you know what your making before you make it, I don't know how many times I have ran into a problem because my idea is not fully fleshed out.
Also be aware of feature creep (its a bitch =) )

Make sure you program in such a way that you understand whats going, if you program 10000 lines of code and you dont know whats going on but it works you need to learn some more =)

Yea, I know everything doesn't need to be global. But I'm noticing as I am creating a simple text-based RPG (as an exercise), I am needing to "see" various classes within my code and am having a tough time doing it sometimes.


This seems to be a common "hump" to get over when learning OOP. It seems so much easier to just have a global collection of objects that can be accessed when we want them - but we are told that globals are "evil". Also, we are told that encapsulation is good, but it's sometimes difficult to decide which class members to hide, and which to expose. Another early difficulty is over-designing classes - it often seems nice to add all of this functionality that we think may need for a class, but then we are told about KISS and YAGNI.

Experience, especially in the form of having the above mentioned things bite you in the ass, is probably the best way to learn.


So I gave each weapon its own struct with its own stats already initialized when the code was compiled. I wasn't satisfied with that either.
[/quote]

Why weren't you satisfied with this? All weapons are going to share a set of stats, so make a Weapon object (class or struct, whatever is appropriate for the language). If a particular weapon type never changes its state (stats) during the game, then you will not need a separate instance for each weapon - just keep a master list of weapon types and their stats, and index into it as needed. If weapons can change state during the game (their stats can change, such as current ammo, upgrades, wear and tear), then each weapon will have its own instance. In this case, the master list of weapon types is like a collection of blueprints, and is used to initialize a weapon instance.

Maybe if you focus on one particular aspect, and post some code, you will get some more specific suggestions.
To simplify things, try to think OOP as something you do to reduce complexity and duplication. With complexity you can start simply by reducing the number of if and switch clauses. Many times the you reduce code duplication at the same time. Using weapons as example, you might have something like this:


// the code might look like Java, sorry :P

void shootPlayersGun(){
if(reloadSeconds == 0 && (gun == PISTOL || gun == SHOTGUN || gun == SMG)){
if(gun == PISTOL){
reloadSeconds = 0.5;
createBullet();
bullets--;
} else if(gun == SMG)
reloadSeconds = 0.1
createBullet();
bullets--;
} else if(gun == SHOTGUN)
reloadSeconds = 1;
createBullet();
createBullet();
createBullet();
shells--;
}
} else if(heatPercent < 100 && (gun == BEAMWEAPON || gun == FLAMETHROWER)){
heatPercent++;
if(gun == BEAMWEAPON){
createBeam();
} else if (gun == FLAMETHROWER){
createFlame();
fuel--;
}
}

}


Now if you have a 10 weapons you are going to have really long if and it would become more and more complicated. If you define a weapon interface you can reduce this to:

player.weapon.fire()

Now you can put all your weapon code in different weapon classes that implement the weapon interface and you don't have to wonder what code is associated with you beam weapons and so on. You don't have as many if's so your code is less complicated. To create a new weapon you just create a new weapon class and put your code there. At this point you can also start using inheritance, composition and other OOP stuff to start reducing code duplication too. You might not have less lines of code but this less duplication means smaller chances of bugs and when you fix a bug in one place it gets fixed everywhere.

In C++ I guess you could use completely abstract classes to define an interface.
I'd suggest that you're coming at this the wrong way round. You're thinking with an OOP hat firmly on, and trying to force your intended end result to meet the requirements of OOP. That's not going to work out well at all; instead think more about your intended goals and select design paradigms that serve those goals best. So instead of asking "what classes do I need to create in order to do blah?" you need to ask "I want to do blah, what's the best way of doing it?" Because otherwise you've selected a solution before you've really analysed what the problem actually is, and have a high risk of over-engineering.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

I did not entirely read the thread but based on your posts, it looks like you have few design issues at hand. You should read a good OOP design book or a tutorial to get the hang of it. Most of your problems could easily be avoided with a good understanding of OOP design. It is very broad topic so I will not even try to cover it in this reply.

Other keywords to search for would be software design, software engineering, design patterns and so on, but be aware that these are even broader and more advanced topics(and require good OOP base).
[size=2]Ruby on Rails, ASP.NET MVC, jQuery and everything else web.. now also trying my hand on games.
Always remember to Keep It Simple (KISS)
Also, don't force things into some OO structure, or you can easily end up with convoluted code that is hard to extend.

One example:
A player could be a class, and a weapon could be a class, but making the weapon part of the player class is not so obvious to me.
I mean, how is the player going to leave the weapon behind, or hand it to another player if it is a part of him?
In this simple scenario, I would probably create three classes instead: Player, Inventory, Weapon.
The inventory could be part of the player, and the inventory could have one or more slots for items, like weapons.

That's just an example though. It may be more than you need, in which case you should make things simpler.

Basically, always make sure that the member function (operation) you add to a class actually belongs to that class.
Sometimes it does, other times it makes more sense to introduce a new class.

Also, to avoid globals you are going to have to pass objects around as parameters to other objects and their member functions.

Another good practice is to take full advantage of the C++ standard template library.
For a small RPG game you should make yourself familiar with the string and the vector class as a minimum.

This topic is closed to new replies.

Advertisement