Kylotan, modules are the way to go. Develop each part of your game separately and individualy, and join them together with the final game code when you finish them. While developing them, test them completely.
That way, no module ever gets too big, and if one module is starting to become truly massive, break it down into smaller modules.
This is, as I''m sure you know but for those who don''t, known as the test harness or ''testbed'' developing method.
The_Minister
1C3-D3M0N Interactive
The 5millionth post on OO design principles..
[email=mwronen@mweb.co.za" onmouseOver="window.status='Mail The_Minister'; return true" onmouseOut="window.status=' '; return true]The_Minister[/email]1C3-D3M0N Interactive
quote: Original post by The_Minister
Kylotan, modules are the way to go. Develop each part of your game separately and individualy, and join them together with the final game code when you finish them. While developing them, test them completely.
That way, no module ever gets too big, and if one module is starting to become truly massive, break it down into smaller modules.
I wish it were that easy. My game is split into
142 source files (including 66 header files). Generally, it is 1 class = 1 source file + 1 header file, but some smaller classes are grouped together. Nearly all of my game data structures are STL containers of pointers to objects. Now, the main problem here, is that in order to use a container of pointers to type XYZ, that file needs the entire class definition of XYZ. It shouldn''t , but this is a template implementation limitation / STL bug. So, a lot of source files include headers that they shouldn''t need to, just so it will compile without errors.
Secondly, about 3 or 4 of these classes are so integral to the system, that nearly everything needs to include the header file. And these classes get added to on a fairly regular basis: it''s not bad design - it''s just iterative design If I wish to add a feature, generally one of the main 3 or 4 classes needs to get altered, which will result in having to recompile 60-80% of the code.
It isn''t a ''normal'' game where you could separate out a SoundFX module, a Music module, a GameWorld module, and so on. This is a text-based multiuser game which doesn''t lend itself too well to modularisation. It''s kind of hard to explain any better than that, since obviously any design can be well encapsulated, it''s just that this kind of program revolves around several important classes which change as the design progresses. (The game will never be ''finished'', it''s always in a state of evolution).
Kylotan:
What version of STL & compiler are you using? I always used forward declarations when I''m storing pointers in a container, and I''ve never had any problems. I normally use STLport, but I''ve just tried it with the default VC6 STL at it works fine. Borland''s compiler & STL also have no problems with it.
quote:
Now, the main problem here, is that in order to use a container of pointers to type XYZ, that file needs the entire class definition of XYZ. It shouldn''t , but this is a template implementation limitation / STL bug. So, a lot of source files include headers that they shouldn''t need to, just so it will compile without errors.
What version of STL & compiler are you using? I always used forward declarations when I''m storing pointers in a container, and I''ve never had any problems. I normally use STLport, but I''ve just tried it with the default VC6 STL at it works fine. Borland''s compiler & STL also have no problems with it.
quote:
My whole project is now about 150.000 lines of code, about 1000 files and it re genereates an exe from scratch (compile,link with resouces add) in about 1 (ONE) second on a P2/400 computer
That''s great, but with incremental linking I only generally need to recompile one file when I''m going to run it, which means that I can compile and run my stuff in about 1 second, as well.
Besides, I actually like the wait between compiles. It gives me time to think about what I''m going to do next and what I should perhaps change.
quote:
dont forget its all about SPEED in games....(think at AI, GFX)
Speed is actually one of the lesser things on the list of importance. Obviously, you don''t want to write bloated software, but you should always put robustness, maintainability, and functionality first.
quote:
today most "optimized" compilers only make about 100% up to 300% slower programs then ASM
Can you actually back that up with some proof? I''ve never seen anything near the stats you''re mentioning.
quote:
If the OOP ONLY disadvantages are (you say):
=============================================
1.slow
2.ineficient
and let me add:
=================
3. complicated
It''s only more complicated if you can''t design properly. OOP code is almost always simpler if it''s designed right, and generally much more robust (stable) as well.
quote:
Yes there are advantages to OOP but those are more likely to be used in database visual programming rather then fast games.
Are you kidding? Games are almost the perfect domain for object oriented programming. You''re creating worlds which contain, you guessed it, a lot of objects.
quote:
I just wanted to kindly say: take care OOP can ruin your game speed...and generated a flame...ooops...not my intention...but if u want i can give you more arguments....just dont think i have to...
Once again, can you actually back up that statement?
quote:
Yes ASM is much simpler than OOP
and OOP is very complex compared to ASM...
Assembly is simpler in that there is less to learn, but programming wise, it isn''t "easier". OOP is very simple in most respects. Which parts of OOP do you find to be "complex"?
quote:
I am not against OOP...just against too much OOP in games in every position...
You should always be consistent in your design. If you''re using different programming methodologies all over your source, it''s a sign of poor design.
quote:
I will just like to use my P3 like a P3 and not like a 286 because of slow OOP and people''s urge to finish a project faster with less work...
First off, that''s a giant exageration. OOP doesn''t kill that much speed (and if you want to argue that point, at least give some numbers from real projects to prove that, not just "well in my experience"). Second, what''s wrong with wanting to finish a project faster with less work? The quicker you can get something out, the better. If you want to spend fiveyears on a project in ASM only to have it dated by the time you release it, fine, but I''d much rather keep up with everyone else.
January 03, 2001 07:40 AM
quote: Original post by Wilka
What version of STL & compiler are you using?
MSVC5, with supplied Dinkumware STL, all publicly available STL patches applied. No service pack applied to MSVC5, since it doesn''t work on the ''cheap'' version.
quote: I always used forward declarations when I''m storing pointers in a container, and I''ve never had any problems.
It gags on the destructors, because there is no explicit destructor defined for user-defined pointer types (ie. there is no MyType*::~MyType*() {} ). Errors in the destroy function in <xmemory> if my memory serves me correctly.
There are supposedly some workarounds available, including doing your own specialisation of the destroy function, etc etc, but I never found enough info on how to do that.
quote: I normally use STLport, but I''ve just tried it with the default VC6 STL at it works fine. Borland''s compiler & STL also have no problems with it.
I can''t use STLPort, since my compiler chokes with a "Too many nested #IFDEFs" error. Probably because it''s the ''standard'' edition rather than one of the Big Money editions.
Borland C++ Builder 4 has exactly the same problem with the pointers in containers, as I tried it there with the same results. I don''t remember if I tried it with v5 or not.
Apparently it''s a common problem, since 1 or 2 STL sites have described it, and either suggested the explicit instantiation workaround, or the more fascist answer "don''t use pointers in containers: they''re not designed for it".
quote: Original post by SiCrane
Well, when you come to the cloaked ship issue, there are a couple of ways to approach it. The first is to say that a cloaked ship is a special kind of ship. Another is to say a cloaked ship is a ship that has a cloaking device. So the choice becomes encapsulate or inherit.
A good combination of inheritance and encapsulation would be the following:
Every ship has an array of CModification, and there are a maximum amount of modifications. The CModification class would look somewhat like this:
class CModification{private: char* name = NULL; // the name of the modification (for engineering // displays and menus and suchpublic: // constructor takes the name of the modification CModification(const char* newname) { name=new char[strlen(newname)]; Initialise(); } ~CModification() { delete name; Destroy(owner); } virtual void Initialise(); virtual void Destroy(); virtual void AllocatePower(int amount); virtual void Activate(bool activation = true);}
You would then have in the CShip class an array like this:
*CModification modifications[MAX_MODS];
and you could assign elements of this array to classes which inherit from CModification, and implement the pure virtual methods.
PS. What is this design pattern called? I see it often in Java games and the like.
''Smile, things could get worse.''
So I smiled, and they did.
You''ve a got a virtual function call in the constructor for CModification, it works in Java but it''s a no-no in C++. I realise it''s not real code cos there''s a few other things that won''t work, but virtual functions in ctor/dtor can lead to nasty bugs so I thought I''d mention it.
what about calling a super class''s virtual destructor from a subclass?
like
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I have no name that you may call me. I am merely Succinct.
~Succinct Demos Online~
"Hey, where''d that display list rotate off to now?"
-(Drop me a line here)-
like
class foo{protected: virtual ~foo() {};};class subfoo: public foo{public: ~subfoo(){ foo::~foo(); }};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I have no name that you may call me. I am merely Succinct.
~Succinct Demos Online~
"Hey, where''d that display list rotate off to now?"
-(Drop me a line here)-
-- Succinct(Don't listen to me)
quote:
what about calling a super class''s virtual destructor from a subclass?
In that bit of code you posted, you''re not calling the function virtually so the function call is safe. But the fact that you''re calling the function isn''t safe. The destructor of base class is automatically at the end of the derived class dtor, so you''re calling it twice here which could make very bad things happen.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement