Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎯 Unreal

Game Engine help

Started by Jedimace Oct 15, 2008 at 1:20 PM 11 replies 2.5k views
Original Post
Jedimace
Jedimace
I am making a game engine. I decided I want to use Boost for stuff like networking and memory management, OpenGL and DirectX 10 for graphics with a graphics layer, OpenAL for audio, GLFW for window and input handling, and to do the rest of the stuff, like physics myself. I may decide to use a physics engine later, if it turns out to take too much time to do everything else. Do you think this is a good choice of tools to use, and more importantly, do you think Boost would work as good memory management, with Boost::Pool or something? Also, I made a timer class for my game engine. I used the C++ time class to do it, as seen here: http://www.cplusplus.com/reference/clibrary/ctime/time.html. This is my class:
#include "../include/CTimer.h"

CTimer::CTimer() {
    sTime = time (NULL);
}
void CTimer::tick() {
    lTime = time;
    time = time (NULL);
    delta = time - lTime;
    rTime = time - sTime;
}
double CTimer::getTime() {
    return delta;
}
double CTimer::getTotalTime() {
    return rTime;
}
void CTimer::setTime(double newTime) {
    time = (time_t)newTime;
}
CTimer::~CTimer() {

}
And my include file:
#ifndef CTIMER_H_INCLUDED
#define CTIMER_H_INCLUDED

#include <time.h>
#include <stdio.h>

class CTimer {
protected:
    time_t sTime;
    time_t delta;
    time_t time;
    time_t lTime;
    time_t rTime;
public:
    CTimer();
    ~CTimer();
    double getTime();
    double getTotalTime();
    void setTime(double time);
    void tick();
};

#endif // CTIMER_H_INCLUDED
And the error might help:
C:\Projects\Orange3d\Orange3D\System\CTimer.cpp||In constructor `CTimer::CTimer()':|
C:\Projects\Orange3d\Orange3D\System\CTimer.cpp|4|error: `((CTimer*)this)->CTimer::time' cannot be used as a function|
C:\Projects\Orange3d\Orange3D\System\CTimer.cpp||In member function `void CTimer::tick()':|
C:\Projects\Orange3d\Orange3D\System\CTimer.cpp|8|error: `((CTimer*)this)->CTimer::time' cannot be used as a function|
||=== Build finished: 2 errors, 0 warnings ===|
I appreciate anyone and everyone's help.
-Jedimace1My company siteEmber StudiosAlmost Done
Feralrath
Feralrath
You have a variable name time and are tying to use the function time at the same time. The compiler thinks that you are tying to use the variable time as a function.

Just rename the variable time to something like ctime.
shwasasin
shwasasin
The libraries you've selected are completely fine for writing games. Although I have to wonder why you're bothering to create memory pools on a PC title? Generally that type of stuff is more important when dealing with console development and limited resources. As well, I am curious why your supporting both OpenGL and DirectX(3D?) 10? Why not focus your efforts on make one rendering system work well instead of writing two, which inevitably will take longer have basically force you to re-invent the wheel.

As for your code:
- You're variable names are difficult to read. Although you may not have others see your code, it makes "code beautify" difficult and is much more tough when debugging. i.e. lTime = time; time = time (NULL);
- The line 'time = time (NULL);' is causing an error because there's a function and a variable by the same name (sort of referring to the last point there)
- You should stop using doubles *unless* you really need the precision they offer because it's more expensive for the process (although if we're talking a few timers that's no problem).
- Although not a big deal, there's no reason to put 'C' at the beginning of classes. The word class in-front of the object explicitly states that. :)
- Here's a nitpick, when casting, use the C++ method (i.e. static_cast, reinterpret_cast, const_cast, etc...) instead of C. i.e. time = (time_t)newTime;
Jedimace
Jedimace
I just copied off Irrlicht. I thought the "C" thing looked nice. Also, thanks for the help with the error, I will fix it. Also, Schwasasin, about your other two problems. 1- How should I name my variables? I read some stuff on how I should code, and I thought that would work fine? 2- I do want my engine to support consoles in the future, because I want to be able to get my hands on it.
-Jedimace1My company siteEmber StudiosAlmost Done
shwasasin
shwasasin
Quote:
Original post by Jedimace
I just copied off Irrlicht. I thought the "C" thing looked nice. Also, thanks for the help with the error, I will fix it. Also, Schwasasin, about your other two problems. 1- How should I name my variables? I read some stuff on how I should code, and I thought that would work fine? 2- I do want my engine to support consoles in the future, because I want to be able to get my hands on it.


Variable naming conventions are really up to the developer. Some people praise/follow Hungarian Notation, while others hate it. I have one similar to the older C styles with some Hungarian notation thrown in as well. Don't feel you have to follow what I do, but here's an example:

- All variable names/functions should use Camel Case (i.e. int iTotalVariable)
- Base variable types (int, bool, float) should have the first letter of their type in their name in lower-case (i.e. fDeltaTime for float, bDidTimeRunOut for bool, uNumTimers for unsigned vars where i is used for int's).
- All variable types that are structures should have the first character in the variable name lower-case (i.e. Struct PlayerInfo, var is playerInfo)
- Pointers, Globals (if needed), and Statics will use override any prefixed variable type character (i.e. int iTotal is static int sTotal when static)
- Classes do not contain the character C at the beginning
- Pre-processor macros should be uppercase

There's more, but I got lazy typing. :) Hope this helps dude.
Zakwayda
Zakwayda
A few comments:

1. In general, C++ headers are of the form (e.g.) rather than . I assume this applies to the 'time' header, and if so, a better solution to your name clash problem would be to include the correct header and then write (e.g.) time = std::time(NULL).

2. Opinions differ, of course, but I think there's a growing concensus that 'C' prefixes for class names are of little use and should be avoided. The fact that Irrlicht uses them shouldn't influence your decision (there's plenty of otherwise decent code out there that doesn't follow current 'best practices' with respect to C++ technique and programming style).

3. Your questions suggest that you may be getting a little ahead of yourself (what you're proposing would be a huge project even for an experienced developer). That's not to say you shouldn't pursue it, since whatever happens with the project, you're bound to learn a lot. My only advice would be, don't build an engine because you think that's what you're 'supposed' to do, or that it's something you need to do before you can write an actual game. If your goal is to write a game (rather than an engine), then you should do exactly that: write a game. There's no reason to create some vast, cross-platform, multi-API game framework first.
Jedimace
Jedimace
Thanks shwasasin, that should help a little. Also, jyk.

1. Ok, that should make it a little easier.

2. I just copied of Irrlicht because I thought it made it look professional.

3. I know that I could just be using another engine to do my games in, and I have done that before, using Irrlicht and JME. I learned a lot. I learned a lot of how I want to do my engine from looking at the Irrlicht source, and it looked like a goal I could accomplish. But another thing I learned is that none of the engines support the features I want from the base. Some of these wants include multi-threaded core(which is in JME, but I don't like how they implemented it) and a simple, all in one package. None of the engines I looked at came with a simple installer, and their documentations were not always the best. On top of that, I have a few people helping me. The last thing I want to comment about this is that I, sadly, don't believe everyone saying making an engine is hard, or at least, hard for me. Everyone says everything I will do will be hard and I have not confronted hard yet. It may be time consuming, but not hard. I also want to prove that not everyone of the age 14 is an idiot. But thanks anyway, I expected to get questioned about if I really want to do this, and my answer is, yes.
-Jedimace1My company siteEmber StudiosAlmost Done
Jedimace
Jedimace
Also, I get this error after I fix it and try to use it. I create it simply with CTimer timer = new CTimer();. Here is the error. C:\Projects\Orange3d\Orange3D\DemoStart.cpp|18|error: conversion from CTimer*' to non-scalar type CTimer' requested|. Thanks for any help and the help I have already.
-Jedimace1My company siteEmber StudiosAlmost Done
KulSeran
KulSeran
CTimer timer1; // is just fineCTimer *timer2 = new CTimer; // is also ok, but consider why you need thisdelete timer2; // since you have to call this now too when you are done with it


Pointers can be a pain. Learn to avoid them when they aren't needed. Learn to use them well when they are.
PKLoki
PKLoki
ToohrVyk wrote a blog entry on the topic of naming convention 'warts' such as preceding class names with 'C' and variable names with a type indicator like 'i' for int. http://www.nicollet.net/blog/cpp/9-warts

Personally I'm quite convention agnostic - the appropriate coding convention at any given time is the one your boss expects to see before company cash hits your account. If it's consistent and makes some sense, so much the better.
link3333
link3333
Just my two bits on naming conventions: I've always been under the impression that if a variable is named well enough, you won't need to use Hungarian notation to note the type of the object. Say you have a variable with the word "count" in it, most likely it is an integer of some sort. If you have a boolean that is prefixed with "is", it can be a little more clear and readable ( e.x.: if( isRunning ) vs if( bRunning ) ). That might have been an poor example. Also, if a variable has "name" or "list" in it, it's probably a string or container/array. I really haven't used other compilers, but if you're really not sure on the type just by looking at a variable, hover over it in Visual Studio, and it will tell you.

Also, if you stick with particular naming conventions, then you wouldn't need to prefix classes with "C". You could keep classes camel case with the starting letter uppercase, while having variables be camel case with the starting letter lowercase. One look at the first letter will tell you. You might even want to create constants and defines in all caps.

At least be consistent. Try out particular ways of naming things and stick to it. You may want to extend this to the way you layout functions and classes.

BTW, here are my naming conventions:
ClassesAreLikeThis
local_variables_are_like_this
_parameters_are_like_this
m_member_variables_are_like_this
CONSTANTS_ARE_LIKE_THIS

The reason for the "_" prefix to parameters is mostly due to member initializer lists. It's so easy for me to toggle the "m" as such: m_variable( _variable ), especially when I have a bunch of parameters. Because I use the "_" in constructors, I use it everywhere else to be consistent. This style fits me. Find one that works for you and is truly useful.

Another note: While your time variables can be guessed to be time_t structs, by reading them I still have no idea about the difference between sTime, rTime, and sTime. Think about the names of them if someone else was to read your code or if you come back months from now to try to make sense of it. Comments can also be your friend in those cases.
android_808
android_808
I have encountered the same naming clash issue before, in my case with some iterator type definitions. When someone else looked at it and told me I felt really stupid.

Like yourself, I am writing an engine but for me it is with practically no previous experience so it has been a long trawl with many rewrites, but finally things are beginning to take shape, even if it currently only renders a spinning cube. I too used Irrlicht to start with as a base, messing around with the demo supplied in the SDK, following the naming conventions used (CTimer, ITimer etc.). Then I went on to looking at the structure of OGRE, looking at the differences, finding a better way of doing something and rewriting the project from scratch. Next came Quake 1 source code, trying to make a simplified C++ version...didn't go well. There were also versions based off SuperPigs' Enginuity articles.

After these failed attempts I took a step back and looked to find the bits I liked in all three and made use of them. I like some of the structure associated with OGRE (Singletons), the lack of STL in Irrlicht, the simplicity of SDL and the structure of the .Net libraries for example. Even my string class based on another library (bsting). Finally, I feel like I have a structure and style in place which I can make use of.

The point, as link3333 also pointed out, is to write how you feel comfortable. Write using a naming convention YOU like, one YOU can understand. I've used several getting to where I am today in the project. I could never get on with Hungarian Notation but I can stand Camel Case, having used it for Visual Basic coding whilst in college because it was their recommended way of doing it, a way the teacher could understand. I used Irrlichts convention for ages because you can use CEngine as the class name allowing the object to be called Engine, can't get much clearer than that! That was OK until I looked at the what would happen with a global or static object? Using static objects with a C prefix when everything else doesn't have one didn't seem right, on the other hand at least you could tell it was static.

You can use comments to help others understand your code and to remind yourself what something does (think we've all had a point where you look at something and think "Huh?"). I have 3753 lines of code with 1730 comments. Use them to make your API documentation.

As shwasasin says, trying to write for both OpenGL and DirectX is going to slow things down. Why not follow Irrlicht further by doing an interface class IVideoDriver and an implementation for one library like COpenGLDriver. Once you get an idea of the layout of your renderer you could then stick the DirectX code in. Functions that are identical in each could either be put into the interface class (it may not be pure virtual then but neither is Irrlicht reference counting class) or into a base class. Irrlicht has a IVideoDriver > CNullDriver > COpenGLDriver structure but once you get one driver sorted you can just make the CNullDriver using the header from COpenGLDriver and creating empty function for everything and then inherit from it.
Jedimace
Jedimace
I don't want to put in the DirectX stuff till later, at the start I will be using OpenGL.
-Jedimace1My company siteEmber StudiosAlmost Done

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.