base code and engine layout...

Started by
31 comments, last by yodaman 20 years, 12 months ago
Hello, Well ive posted a few questions simular to this one, but know one has been seeming to know anything about making an engine so I asked again, but this time in a more general manner... Ok, for one thing, the whole AI, PHYSICS and Rendering thing... most people start by making the renderer wich seems more logical to me given that it takes the most time and is the most critical aspects of the engine. Anyway, a physics engine makes objects move in a lifelike manner, handles collision and reactions to events, while AI basicly handle where the bots going, what the bot needs, how to fire his gun, what state of animation it should be at, and how to get to its destination. while these two objects are different, they need to communicate with each other thru some common interface, this interface could be a entity class. This is where my trouble begin... whats the best way to incorperate a entity class with the AI, rendering, and physics in a way that you can still make sub class's of the entity, handle physics with other objects (not just bots) and have your AI cooperate with the rules of physics? If anyone can give me a GOOD answer, i would very, very much be GREATLY appreciative to them! Thanx alot ~Jason ps.. The topic name doesnt really fit [edited by - yodaman on April 6, 2003 11:57:48 PM]
www.jinx.com www.thebroken.org www.suprnova.org www.mozilla.org
Advertisement
Give your entity class methods for your physics, rendering, and AI engines to get the info that they need. These will be inherited/overriden by your sub classes.

Some examples of these could include the following:

* A method for your physics engine to get the location, width, height, depth etc. of your entity so the engine can calculate colisions, gravity, whatever

* A method for your physics engine to tell your entity that is has colided with something, and what that something was.

* A method for your AI engine to tell the entity what to do next, e.g. "Fire Weapon"

* A method for your rendering engine to see what your entity is doing, eg. "Firing Weapon", "Exploding", so that it can render this.

Some of these methods may be read by more than one of the engines, eg. all three engines would probably probably read the first example for different reasons.

I hope this was what you were looking for.
ooh ok, I see...

Well, I actually just started my entity class and basic physics class(s). What I did was make two entity class''s.
heres what I did (very rough example)

class Mass
{
...
};

struct CollisionInfo
{
...collision_type;
...
};

//static entitys
class Centity
{
int state;
Mass mass;
CollisionInfo cdi;
entity properties
};

//moving/movable entitys
class Centity_M
{
Centity base;
Cvector velocity;
... moving propertues
};

thats basicly it, and then to bet working with AI, Physics, rendering code, I could simply do something like:

R_SetModelState(mod->state)
HandleCDResponce(mod->cdinfo,...)
AI_DecideWhatToDO(mod[loop])

Ive never realyl written an entire AI engine before, but have done many little demos and such, but heres how i would go about
handling it:

AI_SetCurrentGoal(mod[loop])

The ai function would take the info needed and make a
goal based of what input it got, and then change plans if some event happens that would stop it from completing this goal (ie, was blown up, or out of ammo switch weapon, still out of ammo, check each weapon to see wich has ammo, if none do, then look for ammo, if confronted by enimie, run away and procede to look for ammo etc)

same goes for the rendering and physics: If a collision has occured, react on impact, send new position and state to renderer, draw model in new pos and state)

doesnt seem to hard now

Thanx


www.jinx.com www.thebroken.org www.suprnova.org www.mozilla.org
well thats depressing. I had a massive reply all lined up and *poof* it''s gone.

anyway... here goes again but in shorter form. (edit: so it didn''t turn out that way then)

My guide to building an engine. vol 1.

First things first when setting out to design an engine, you need to decide if the engine will be built in a structural manner (C) or with objects (C++). The two are vastly differnent and impact apon your code greatly. I''m not saying one is better than the other, thats not my place to do that (I personally greatly prefer C++ if you ask me) but DO NOT under ANY circumstances EVEN TRY to mix both! If you find your design plan includes things like CRenderingEngine, CPhysicsEngine, CAIController, CObjectControl, etc, then your project will fail. No question. You cannot mix strcutral and object methodoligies whatsoever. You can certainly try, but you will not succeed.

now. that uglyness is out of the way:

things to remember:


PLAN PLAN PLAN PLAN.
PLAN.

and plan some more.

don''t take this lightly. Don''t go too indepth, but make sure you have a good idea of what needs to be written and how to write it. This is important. Try to imagine how things will fit together and work, if you find that you need to make workarounds in your design, then scrap it. Start over. An example of a workaround is if a common class you use has a static function for getting it''s instance. That would be bad.

What you do now, is not code. ohh no.
think of something you want to make with this engine. You may start with an idea of what you want but I guarentee you taht thats not what you will get when you finish. So think of something similar you might want to make.
Imagine how you''d code this using your design.
Chances are you''d have to do a whole bunch of workarounds and screw with some existing stuff. That shows your design has flaws, which absolutly need to be fixed before any coding is done.
Do this at least 3 times. Chances are you will end up with something completly differnt to what you started with. This is good.


Next,
now you have a basic design.

Set you aims, set your limits.
This is REALLY important.

An example aim from my engine was that I decided I would port it to Direct3D one day. This truend out to be a really good and really bad idea. First it''s really good because you learn so much and Direct3D is honestly better than GL right now, Also it was fun. Bad, though, because I didn''t quite design the engine right for this sort of abstraction. So I had to do a lot of recoding.
If you were to do this, it would set A LOT of limits on the rest of your code. You could forget about having entities call their own GL code, in fact they wouldn''t be allowed to call ANY. But, on the flip side, this had some HUGE payoffs, not only did I get D3D support, but I was forced to design my rendering code in such a way as to make it significantly more powerful than before... How, for example, would you do depth ordering of transparent objects, texture sorting, efficient lighting, etc, if every object was responcible for drawing itself? And other more complex stuff like vertex buffer validation, error checking, and other optimizations.... It just wasn''t possible with my older desgin.

So the other side of setting what you want, is setting what you don''t want. Setting limits. This is even more important, in a way.
Don''t, under any circumstances, decide "I want my engine to do terrains, indoor maps, space battles, etc". You will almost never finsish your engine. I did this with mine, my engine was started over a year ago.
So set limits. Set what can and can''t be done.

This is still in your design btw. You should have not written a single line of code yet. And yes, you should have already spent days on this. Not 10 min going "hmm, quake 3. yes. I can beat it"...

Now. it''s time to think about what you will need.

Still no coding. That is in the next step.

Needs.

having an existing tool set built before you build your engine is a GOD SEND.
By this I don''t mean to go off and download xyz dll, lib, etc. Make it yourself. Make everything you possible can yourself. You will learn INFINITLY more this way. If you had the choice of writing a DirectSound3D sound engine, or using FMod, use DS3D, it''s much harder, but you a) have control, b) learn.

but anyway. onto what you need.

by this I don''t mean sound engines, I mean tools.

the tools make the engine.

95% of your engine will not be GL. Heck, 99% of it won''t be. Don''t think it will be. It''s the same for sound, etc.
There are around 200 lines of GL code in my 40-50k line engine. Even less D3D. that makes around 0.7% of my engine is calls to a rendering API.

so what are the most important tools? well, in reality, they are what may seem like the least important.

the biggest, is a template for an array. DO NOT UNDERESTIMATE THIS.

if you have a template for an array, that in release mode just acts like a pointer, but in debug does full bounds checking, etc, you will have halved the time your project will take.
The first biggie you get from this is if you code it right you will never have to worry about new/delete every again. The second biggie you will (when debugging) know instantly if you have done something wrong, like out of bounds array errors, etc.
Further more, consider if this template has the ability to sort it''self, save itself to an output stream, etc. The time that will save... Consider it.

But don''t stop there,
there are more tools... consider the following:

Doubly linked lists. I use these EVERYWHERE. because of that I worked mine to reuse memory.. which equalled a nice (and noticable) speed boost.

String class. By god you need one of these. stl string is ok, but not too user friendly. I use a wrapper for the stl string.

A basic file IO class/namespace or whatnot. Load/append/read/searching etc. Very useful.

A hash table template, don''t underestimate the use of one of these puppies.

stack/queue template. not too useful, but dead easy to write if you have a good D-LL.

A heap template. also useful, but not critical.

A configuration file parser... very useful again...

A matrix class! ohh god! don''t even think about not having one of these!

A full array of vector classes, eg, 2,3,4 component float/int vectors.. dot/cross/operators/etc. ditto as matrix.

a quadtree/octree template. Took AGES to write mine, but by god is it useful.

a Thread abstract class. quite useful later on.

smart pointer class. Very very useful... very good if you want entities to do a lot of tracking of others.. consider it.

the list goes on.


NOW,

once thats done, consider the rest of your engine. And now consider how much easier, cleaner, and smaller it will be to make.

Now it''s time to actually think about designing an engine.... (yes )

firstly you need to consider how things interact in your ideal game world. What controls what, who controls who, what interacts with what.

Put limits on now. Consider making evey entity completyly independant of everything else. This can have a lot of benifits later on.

make the basic entity that can do all the basics first.
this is important. but do not specialize this entity.

plan branches for the entitiy. say, a branch may slowly lead towards an entity that bounces around the world, another may lead off to one that ''thinks'', antoher may lead off to one that efficiently renders animated models, or such. another may lead off to a sound effect. Don''t try and merge all these traites, have serperate defined objects. (This ofcourse assumes your writing C++).

the base entity needs some standard virtual functions..
two examples I think are mandatory are:

render (called every frame, with arguements passing a pointer to the renderer, the time elapsed over the frame, a bool saying if the object is on screen, and possibly some extra stuff).

update (called, say, 100 times a second for all objects that want it... could pass in the elapsed time (eg, 1/100), etc. maybe a pointer to a world controlling object that does things like line of sight tests for collision detection, etc).

with this alone it wouldn''t be very hard at all to make all those classes I mentioned above, yet they all require no code outside of their class. This is the golden rule to strive for. if you ever find yourself writing code outside of an entities class, just for that entity, then you have done something very wrong with your design.

anyway. I actually am out of time, sure I didn''t end too well, this is a subject that can be talked about on end so I just hope I''ve steered you in the right direction. Writing an engine is incredible fun, you learn A TONNE, it''s just if you don''t want it to end in dissapointment you need to put a lot of effort in before a single line of code is written.

anyway.

| - Project-X - my mega project.. getting warmer - | - adDeath - an ad blocker I made - | - email me - |
(Yodaman)

Alrighty, well you gave me a lot to think about and yes you did steer me in the right path. I do have though, some things already coded but they are just windows/opengl initialization
routines and math lib. I agree, I prefer coding everything myself, Ive never done anything the easy way except for when I was learning how to right matracies. But I do have matracie class(s) 3x3 and 4x4, vector class(s) xy,xyz quaternion class
I also have a log system wich every class has a debug or log output, and many of the same functions but work in different cases. Im working on the windows wrapper right now. This includes input, sound, child windows, buttons, etc.
Im trying to make windows code hidden from everything else so
im working on things like video structures wich hold FOV,BPP,WIDTH,HEIGHT etc and also, how im handeling the main windows loop, scene updating, input, scene init etc is thru a derived class form C_OpenGLapp, so after everything else is made, ill simply put all functions in the right class functions and voilet!

ex: InitScene()
{
LoadMs3ds();
LoadMd2s();
LoadTextures();
etc
}
UpdateScene()
{
usecamera():
drawModels();
drawterrain();
etc
}

Im also working on my file I/O code, such as searching,
texture loading, pak system, strings, etc.


So I did do alot of planning on the base code.
But, this is one reason that i really posted the post anyway
is because I wanted to know if i was making a mistake by desinging my entity, physics, rendering plans wrong.

Heres my new plans for the systems...

base entity class
Centity()
{
Cvector3 origin;
Cvector3 norigin; (position)
etc
virtual bool UpdateEntity() {return true; }
virtual bool Render() {return true; }
etc
}

CentityState
{
int state;
bool isvisible;
etc
}

CLightEnt : public Centity
{
...
}

CRobotEnt : public Centity
{
...
}

CTreeEnt : public Centity
{
...
}

and on and on...

Ok, now i also have collision detection functions in them as
well, but thats not important right now. Ok so in my game plans, I said I want to have robots, rockets, lights, trees,
water, buildings, etc, so i simply make a seperate derived entity class for each one of those objects. Now the virtual functions are also implemented in each class, when i get that code done, I simply pass on to these function the drawing routines(in render) and the AI & physics routines(in update).
I use a simple bounding box test for visibility tests...

Ok, now what i have is a basic structure for all entitys so
then all thats left is to implement code for each instance of the entitys. you said that code should never have to be made out side of the entity class, i agree, so what i meen is, implement the rendering and updation routines for each object. Something though that isnt necessarly coding out side of the entity class, is the physics. if i come across a "special case" where the entity needs a special physics routine, then that would have to be one, but what Im thinking though is that I could simple make the physics in the same way as the entity class(s) and make one base class and then individuals for each instance of a physical rule or each different case where it would require a special physics routine.

As far as the rest of the code goes, such as error checking array systems etc, I have it under control, I just need to implement this. One thing though I didnt quite understand, was the quadtree/octree template? How the heck could you make on of these? lol. O well, sounds fun!
I must learn templates I quess, blah!
Oh, and im a little rusty on dynamic pointer checking and such, any links for me?

Thanx alot man, I actually wrote this post after reading your a couple of times, and then started to replan mine, so this is the product of your reply! Thanx alot!

~Jason

ps. if i wrote something stupid, or mis spelled alot of words
Im really tired
www.jinx.com www.thebroken.org www.suprnova.org www.mozilla.org
quote:Original post by yodaman
most people start by making the renderer wich seems more logical to me given that it takes the most time and is the most critical aspects of the engine.


not true.

most people start by making the renderer because they can then do some cool looking stuff.

renderers aren''t difficult, and aren''t that much. todays opengl and dx wrap most of the work, so that you don''t actually have to do much, once you understand how 3dgraphics math and the pipeline goes.


and think about it. graphics can be simple flat shaded triangles, nontextured tetraeders moving around as enemies. thats enough to actually see how its going, the rest is artistic +. sound can be simple peeping.

but if physics/ai don''t work as expected, your player can run trough walls, your enemies can stuck into edges, your ball can roll walls upwards, etc.

physics and ai are two things that have to be done carefully, espencially physics have to work completely correct.

its quite difficult to do so. drawing some fancy colored triangles isn''t.

THATS why everyone starts with rendering. easy to get something working that looks cool.

"take a look around" - limp bizkit
www.google.com
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

Hmmmm, I had a really long post on collision detection and entitys (if you dont know what your colliding with in the first
place, how can you go about asking it what it is and if you have collided) I was going to test every object in the world each frame for a collision, but then I gazed down at riptorns post and got an idea, only test whats on the screen, this meens I can testfor collision against octrees alone and then once I have collided with something... but still how would you actually test what you collided with? errr... this is driving me nutz! What about a line of sight test? Then still even once I collide with something, how do I check what it was that i collided with?

if any one can get where im comming from, and can help, PLEASE do so!

thanx

~Jason

www.jinx.com www.thebroken.org www.suprnova.org www.mozilla.org
Wow, RipTorn that was a great lecture! I guess I''ll go rethink my engine
RipTorn, I need some help, and a few explanations.

First how do I write a template for an array, what is it, what do I use it for, why do I need it?

Second what is a smart pointer, how do I write one, what do I need it, etc.?

Third How do I write an octree/quadtree template?

Ok, so it took me five minutes, but now I know how to write template classes... Again, (I had simplty forgotten ).

But what do I want the array template class to do?

I''m still wondering about the smart pointer

And about the quad/octree, I''m not sure, either...

Enlighten me, please?
Thank you!!

This topic is closed to new replies.

Advertisement