Thread: In a game Engine...

  1. #1
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968

    In a game Engine...

    Okay, So I've busted my ass for 2 months getting a competant resource manager running, and I can now say it will run successfully with no memory leaks at all! A nice combination of boost shared_ptr and boost weak_ptr does the trick nicely...

    Now, I'm going to take a leap and assume that a Render engine simply draws stuff, and requests instances of resources from the resource manager, right?

    Now with that, I'm going to ask, what tells the render engine what to draw?! I'm talking in terms of pure geometry, not special effects or anything, because we all know that the render engine will perform nifty special effect techniques in the end...

    But where the heck does the render engine get its information? From a logic engine? Is this where I actually start programming my game? Are you serious?

    Another thing, how should you arrange Objects in your game? What system controls the creation and arrangement of logical, renderable, and physical objects? Is that the logic engine too? Blehh, hopefully someone can answer my questions..
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  2. #2
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    You need to tell the rendering system what objects to draw, or have the rendering system figure it out using the entire list of objects. I'd start with frustum culling as a way to choose which objects to draw and which not too.. then you can add things like space partitioning.

  3. #3
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    Hmm, so the render engine doesn't really flirt with the resource manager at all...

    A logic engine of some sort requests resources to be added and counted, the resource manager counts references needed for those resources..

    Then the renderer just requests the list of resource objects with counted references, and then does its thing with the resources it now has..

    So much simpler than I've been making it..
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  4. #4
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    Thats one approach, there's nothing set in stone though. At some point you'll need to iterate through your resources and decide which are visible and should be rendered. Which component does this is up to you.

  5. #5
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    The renderer will perform occlusion, as well as assign matrix data to each object which will be given by the logic engine...


    I can't believe I'm finally here, I'm at the point where I actually start programming a GAME
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  6. #6
    Computer guy
    Join Date
    Sep 2005
    Location
    I'm lost!!!
    Posts
    200
    Ok, there goes the render. So the physics data will be set up the same way? as well as the functions for each object (collision, power, blah blah...). Anyways, inherit classes would be a little bit messy, but that'll do the job.
    Hello, testing testing. Everthing is running perfectly...for now

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I can't believe I'm finally here, I'm at the point where I actually start programming a GAME
    You're not. Have you implemented animation classes, input classes, sound/music classes, frustum culling and/or space partition classes, collision classes, physics, and the biggy - a script class as well as a script language to develop events with?

    It all has to fit together seamlessly.
    Last edited by VirtualAce; 02-12-2006 at 02:50 AM.

  8. #8
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    We have a renderer, a resource manager, an incomplete physics engine, collision classes, input classes, a camera class... I just added a scene graph to the equation...


    So it goes like this..

    Logic Engine->Resource Manager->Scene Graph

    From the scene graph, to the physics/rendering engines.

    I can't believe I could never find this written down anywhere..
    Last edited by Shamino; 02-12-2006 at 10:15 AM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  9. #9
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    >I can't believe I could never find this written down anywhere..

    So write it down for the next person that can't find it written down

    edit: oh, and do tell me about your scene graph

  10. #10

    Join Date
    May 2005
    Posts
    1,042
    You're not. Have you implemented animation classes, input classes, sound/music classes, frustum culling and/or space partition classes, collision classes, physics, and the biggy - a script class as well as a script language to develop events with?

    It all has to fit together seamlessly.
    I'm programming a game just fine without an animation and scripting class.

    >>I can't believe I could never find this written down anywhere..

    I don't believe there is any set way of doing things. The best advice I've seen in this thread was perspective's comment that 'nothing is written in stone.' I like that you are busting your ass and working hard, because you are gaining experience and that is what is worth the most.


    I simply have a class called GameExport which ultimately ties everything together. In my main message loop, it just calls 'Game_Cycle()' which is the universal 'Update()' function. That goes through and then delegates work to other managers: Every type of object that 'plays' in the game (hovertanks, ambient entities, the player) are all Update() 'ed. Once the updating is done, the physis manager runs a certain number of physics frames. Once that is done, the renderer draws everything it contains.

    The renderer and physics manager both hold pointers to 'stuff.' The physics manager holds rigid bodies, and the renderer holds renderable pieces of data. The renderer draws everything that is sent to it: culling is done outside of the renderer, because the job of the renderer is only to draw, not cull. Plus, there are many culling mechanisms that exists in my project, subsequently in order to implement every possible method of culling the renderer would have to know far too much information about what it needs to draw; subsequently, if something wants to cull itself using a sphere-to-frustum test, then it does that in its Update() hook: if it is visible, it adds itself to the renderer and the renderer just draws it, else it just doesn't add itself to the renderer (that was just one example, a BSP tree culls itself differently from a hovertank which culls itself differently from a bullet, and some things I just don't call at all because I know its faster to just draw them).

    A hovertank for example is both a GameEntity and a rigid body (and also a sound emitter, and a couple of other arcane things)...these are all classes it derives from.

    psuedo code
    Code:
    class HoverTank: public GameEntity, RigidBody etc etc
    
    ...
    
    Hovertank *pHovertank = new Hovertank;
    PhysicsManager.AddRigidBody(pHovertank); 
    
    ...
    Hovertank::Update()
    {
       RunAI();  //Changes linear/angular momentum 
       if(Frustum.DoSphereTest(this->mRadius))
        { 
           gpGLRenderer->AddMS3DModelToRenderer(this->mpModel,LightInfo,TransformationMatrix);
        }
    }
    
    My game loop:
    
    main_loop()
    {
    ...
    Export.GameCycle();
    }
    
    
    ...
    
    Export::GameCycle()
    {
       gpPhysicsManager->UpdateTime();
    
    if(EnoughTimeForPhysicsFrame())
    {  
       Update_Entities(); //Calls Update() for each object
       gpPhysicsManager->Run_Physics_Frames();
       gpGLRenderer->RenderScene();
    }
    I'm not immature, I'm refined in the opposite direction.

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You guys are missing one important facet. You must have a script system. Otherwise how are you going to create levels, actions, events, and so forth?

    The script is the game and the engine just runs the script. Let's say even for a game like Asteroids you would still need some type of script action for the way certain baddies move and attack the player.

    A script system is not that hard to implement but it is key to actually gaining control over the game without hard-coding it into the engine itself.

    The way our system works is the script engine first parses the text file and compiles it into an array of C structures. Each command or script function evalutates to an ID number. Each object also evaluates to and ID number. So a command like this:

    IDToWP(1,1)

    would mean that object with ID of 1 would move to waypoin list with ID of 1.

    So how do you go from script to action? We thought about this for a long time and here is how we do it.

    The objects in our game are exactly like windows in Windows. Each object has a MsgProc function that responds to messages. So the in-game portion of the script engine sends the message to the Object::MsgProc(). So in the above case the message might be ID_TO_WP with parameters of 1 and 1. The object is then responsible for reacting to this message. IF it does nothing, it can pass it to default handling like in Windows API or it can simply ignore the message.

    This means that most of the code is in Object::MsgProc which would then call Object::SomeFunc() to get the job done. Note that with this system you can derive from CObject and as long as you provide a MsgProc, the script messages will get passed to your new object. So no hard-coding at all until you get to the object, which is where I think it should be anyways.

    Each function returns a bool so that they can be used in internal script structures such as IFs and other comparisons.

    IF (IDToWP(1,1))
    aPlayMusic(1)

    If object 1 has moved to waypoint list 1, start playing music track 1.

    Note that the script system would identify that aPlayMusic was an engine command (anything with an ID over 0xFFFF) and would send it to Engine::MsgProc(). The engine would then play the correct track.

    But without a basic script system for particles, objects, engine control, etc, I think you will find yourselves coded into a corner rather fast. With a script system you can test your game, levels, and even make intro demos for it since everything can be controlled from the script - it also makes your engine quite capable of multi-player without changing the underlying code base at all. Just add new messages and respond to them in Object::MsgProc() or Engine::MsgProc() and you have multi-player support.

    I'm just trying to help and prevent you from hard-coding every action as that will get you nowhere fast.

    Here is a sample of some basic engine commands that are available to the developer.

    Now if you notice this type of system lends itself very well to building upon script actions to create new actions. Let's say we want a baddie to slide left and right as it approaches the player (The player always has ID of 32767).

    //Attack pattern definition file

    def ATTACK LRAttack
    aAttack(ID,32767)
    if (Random(30))
    MoveLeft(ID,10)
    else
    MoveRight(ID,10)
    endif
    end ATTACK
    This attack is called LRAttack.
    First it tells the object in question to attack object with ID of 32767 or the player.
    Then it picks a number and compares it to a magic number. If the number matches the magic number 1 time out of 30, it moves the current object left by 10, else it moves right by 10.

    The ID is converted into the current object ID using the attack pattern at run-time. The script engine knows that ID must be resolved before calling MsgProc().

    This is also how quests and other things are built as well. Quests are just composed of a lot of ifs() and checks to see if certain tasks have been completed. Usually quests will be composed of multiple events to make them simpler. An event is usually composed of ifs().

    The ID numbers are very hard to code by hand and because of this, I've added all of this to the editor so you just pick which object you want and it fills in the ID in the text file. The editor script utility writes the script for you.

    I feel that scripting is key in making any game come to life. You may want to look into it in great detail. Nearly every book about game programming will have scripting in it somewhere.
    Last edited by VirtualAce; 02-12-2006 at 05:22 PM.

  12. #12
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    @Bubba: I'll definately keep that in mind Bubba, but I think I'll work on a scripting language after I've hard coded my engine and made a few simple hard coded games.

    @Bob: I know theres no "right" way to do it, but I can't believe I couldn't even find suggestions compiled up leading me to this point, or a similar point, or any point, yknow?

    So the GameExport class basically holds an update function that is compiled by your game logic (or script engine), and sends it to whatever engine part gets it first... In my case, all logic will hit the resource manager first..

    For all "Game" entities (this is in your game logic part, right?), you basically set them up like a scene graph as well, they all have update functions, which modifies what is finally sent to the first part of you engine.

    You've set your scene_graph up so it culls out things, I would assume that this would be much faster than sending things to the renderer that it doesn't need, and then sorting them out there.

    @Perspective: I have a scene graph set up, it is at its infantile stages at the moment, all it really holds is a geometry node and a DOF (Depth of Field) node. I'll give you some snippets.

    Code:
    #ifndef SCENE_MANAGER_H
    #define SCENE_MANAGER_H
    
    #include <list>
    #include <gl\glaux.h>
    #include <gl\gl.h>
    
    
    class CSceneNode
    {
    public:
      // constructor
      CSceneNode() { }
    
      // destructor - calls destroy
      virtual ~CSceneNode() { Destroy(); }
    
      // release this object from memory
      void Release() { delete this; }
    
      // update our scene node
      virtual void Update()
      {
        // loop through the list and update the children
        for( std::list<CSceneNode*>::iterator i = m_lstChildren.begin();
             i != m_lstChildren.end(); i++ )
        {
          (*i)->Update();
        }
      }
    
      // destroy all the children
      void Destroy()
      {
        for( std::list<CSceneNode*>::iterator i = m_lstChildren.begin();
             i != m_lstChildren.end(); i++ )
          (*i)->Release();
      
        m_lstChildren.clear();
      }
    
      // add a child to our custody
      void AddChild( CSceneNode* pNode )
      {
        m_lstChildren.push_back(pNode);
      }
    
    protected:
      // list of children
      std::list<CSceneNode*> m_lstChildren;
    };
    
    class CGeometryNode: public CSceneNode
    {
    public:
      CGeometryNode() { }
      ~CGeometryNode() { }
    
      void Update()
      {
      // Draw our geometry here!
    
      CSceneNode::Update();
      }
    };
    
    class CDOFNode: public CSceneNode
    {
    public:
      CDOFNode() { }
      ~CDOFNode() { }
    
      void Initialize( float m[4][4] )
      {
        for( int i = 0; i < 4; i++ )
          for( int j = 0; j < 4; j++ )
            m_fvMatrix[i][j] = m[i][j];
      }
    
      void Update()
      {
        glPushMatrix();
        glLoadMatrix( (float*)m_fvMatrix );
    
        CSceneNode::Update();
    
        glPopMatrix();
      }
    
    private:
      float m_fvMatrix[4][4];
    };
    
    #endif
    CSceneNode is the base class for the scene graph.
    It contains a constructor with no args (this is how we create parents).

    It has a destructor that calls Destroy() (see destroy).

    It has a release function (deletes the current scene node)

    It has a virtual Update function (Calls update on all children nodes)

    A Destroy Function (Deletes this node and all of its children)

    An Add Child method, (so we can tell a child, "who's your daddy?")

    And Finally a list of Children...

    A Geometry node will be compiled of a raw resource (from the resource manager), and transformation information (coming from the logic engine, or physics engine, not sure yet?) It then sends this compiled information to the render engine for drawing, simple .

    Geometry nodes are created by compiling two pieces of information together, a bit of matrix data, and a bit of raw resources, the problem is this, accurately tieing the two together in a fast and efficient manner.. Right now I'm working with string ID's, because they're less arbitrary than integers for ID's, I tried implementing something like that but I failed miserably, I will have to switch to integers undoubtebly though someday.

    A DOF node, (depth of field), simply holds transformation information..

    Its kinda hard to explain, but this might make sense..

    Lets say you have a Table Geometry node, relative to table you have a plate, and relative to plate you have a scoop of mashed potatoes.. There are 3 fields of depth in that lil graph right there... Generally you only need one.. Well, that isn't true, If you wan't models that can hold guns, hold swords, wear armor, have dynamic hair, etc etc, they all require more fields of depth..

    And thats about all I can say accurately about this scene graph at the moment..

    @Hdragon: The Physics engine will acquire information the same way the renderer does from the scene graph, I'm still working out the complexities of what exactly happens code wise in this process, but I'm able to tell you that it is quite similar.
    Last edited by Shamino; 02-13-2006 at 09:04 AM.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  13. #13
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    An alternative to writing a scripting engine is to write your engine as a library (instead of a framework) and write your games as driver programs for your library. That way no game specifics are hard coded into the engine. The downside is that games will have to reproduce a lot of the same code to use the library.

    I was considering a scene graph model for my latest design but I haven't put it in. Being that the design is just a class diagram on the back of a notebook and a few new ideas in my head, maybe I'll still toss it in

  14. #14
    Absent Minded Programmer
    Join Date
    May 2005
    Posts
    968
    There are lots of tuts out there for scene graphing.. Just google it :d.
    Sometimes I forget what I am doing when I enter a room, actually, quite often.

  15. #15

    Join Date
    May 2005
    Posts
    1,042
    I know theres no "right" way to do it, but I can't believe I couldn't even find suggestions compiled up leading me to this point, or a similar point, or any point, yknow?

    So the GameExport class basically holds an update function that is compiled by your game logic (or script engine), and sends it to whatever engine part gets it first... In my case, all logic will hit the resource manager first..

    For all "Game" entities (this is in your game logic part, right?), you basically set them up like a scene graph as well, they all have update functions, which modifies what is finally sent to the first part of you engine.

    You've set your scene_graph up so it culls out things, I would assume that this would be much faster than sending things to the renderer that it doesn't need, and then sorting them out there.
    Yeah, you've got the right idea.

    An alternative to writing a scripting engine is to write your engine as a library (instead of a framework) and write your games as driver programs for your library. That way no game specifics are hard coded into the engine. The downside is that games will have to reproduce a lot of the same code to use the library.
    This is precisely how I am writing my game (same with quake, doom, half life, any game that has an sdk)...although, just having this setup doesn't mean you can't use scripting, but to be honest I find trying to write an elaborate scripting engine overkill because the amateur games I see posted on here and gamedev aren't complicated, and it just seems horribly, horribly limiting for the way I am implementing AI (fuzzy logic networks for decision making)...script-written AI is still, ultimately hard coded AI as far as I can tell.

    Bubba asked this question:

    You guys are missing one important facet. You must have a script system. Otherwise how are you going to create levels, actions, events, and so forth?
    My answer: quite easily. I create my own home-grown entities and simply place them in the map editor. QERadiant has an entity definition file which you can edit...you can add the name of an entity and the parameters it accepts, and the map maker will let you place these entities in the world. It's cake. The game engine deals with stuff that never changes, and the game itself is pretty much just the definition of the entities from the programming side and how they behave. But, keep in mind, I'm writing a pretty basic game right now, for something more elaborate you'd need scripting, but otherwise I don't feel it's absolutely necessary.
    Last edited by BobMcGee123; 02-13-2006 at 12:53 PM.
    I'm not immature, I'm refined in the opposite direction.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. ShellView as a Game Engine
    By Mastadex in forum Windows Programming
    Replies: 1
    Last Post: 01-21-2008, 03:51 PM
  2. Game Engine Link Prob
    By swgh in forum Game Programming
    Replies: 2
    Last Post: 01-26-2006, 12:14 AM
  3. KJ game engine
    By Lionmane in forum Game Programming
    Replies: 4
    Last Post: 11-18-2005, 06:16 AM
  4. Game structure, any thoughts?
    By Vorok in forum Game Programming
    Replies: 2
    Last Post: 06-07-2003, 01:47 PM
  5. game engine
    By onurak in forum Game Programming
    Replies: 1
    Last Post: 07-27-2002, 06:29 AM