Advertisement

HowTo? Customizable Engines (Advanced)

Started by March 31, 2001 09:08 AM
5 comments, last by Dino 23 years, 10 months ago
Hello everyone, Here''s my question. I am working on a highly customizable game engine. This means that once the core engine components and base game objects have been written, people can build on those objects and add to the game their own monsters, items, etc. At first, the answer seemed simple. Use C++ classes and inheritance. The drawback is that I don''t want people need any code from the core engine. Second option: Using function pointers and structs, make up your own homegrown version of classes. The drawback? My implementation resulted in single inheritance only, which I don''t mind. If this is a good solution, I''d like to know. Basically the way the second way works is that there is a base struct that represents all game objects. In this struct is a pointer to a messaging function (like a Win32 WndProc). Messages are sent to the object via this one function. As people add on to the base object, they replace the existing messaging function with their own. If the message is not handled by their object, then the original function is called with the same parameters. But as I worked with this solution, I realized that all this work in the end simply game me a limited version of the C++ classes. The people adding onto the engine still needed the code (or at least the header files) from the base classes. I''m stuck back at the same spot C++ classes left me with but with less functionality! Is there any nice alternative that I''m missing? Thanks for any help.

Dino M. Gambone

Good judgement is gained through experience. Experience, however, is gained through bad judgement.

Dino M. Gambone
Good judgment is gained through experience. Experience, however, is gained through bad judgment.

Currently working on Rise of Praxis MUD: http://www.riseofpraxis.net/

Can you specify a little more what you mean by objects and give some concrete examples of your problems. That will help us help you.
Advertisement
Basically I want the core engine to define a set of game objects, such as:

Base
-Item
--Weapon
--Armor
--Container
-Sentient
--Biped
---Human
--Quadruped
---Horse
---Dog
etc...

I want to make it so that other game developers can then build on these base game classes. I don''t, however, what to force the programmer to have header files and classes like C++ classes do. I want them to be able to compile a new game object class with only a small number of files (such as headers with globals).

I guess I could go the route of using the C++ classes and defining all the functions as being virtual. It couldn''t be any slower than anything I could come up with myself. I guess it would only require that the add-ons pass a function pointer to a sort of class-factory to create those classes and the return value would be the base object.

That''s my dilemna. I was just wonder if anyone had any better ideas.






Dino M. Gambone



Good judgement is gained through experience. Experience, however, is gained through bad judgement.




Dino M. Gambone
Good judgment is gained through experience. Experience, however, is gained through bad judgment.

Currently working on Rise of Praxis MUD: http://www.riseofpraxis.net/

You said you had some problems with function pointer and struct version since the object code need to call the core. What in the core did it have to call ?
Sounds like you want to look into a script engine... but those sorts of things might take a very long time to develop, depending on what style you use. Maybe look into compiled Java(Script) code, or some of the more popular methods (check out Amit''s Game Development).


MatrixCubed
http://MatrixCubed.org


Use a scripting language like Python. Define events for your classes that allow the base functionality to be overriden by a script. An examples would be an idle event, spotting the player, being attacked, running out of ammo, etc. Also provide a library of script classes that a script can inherit off of. Through those classes provide the means to change attributes and event handlers. Most importantly provide an editor that lets them set attributes and event handlers as well. You should also allow them to "seem" to create new classes by defining a set of default attribute values and event handlers for a "new" class. You can extend the illusion a bit by providing the ability to add attributes that a script can use but otherwise that your engine does nothing with. Adding events is a bit more difficult, but you can provide a check event event that gets called to identify when the newly defined event should be called. It is really just an OnIdle handler, but if you do it right in the editor it can look like they defined a new event.

Visual Basic, C++ Builder, Delphi and PowerBuilder provides good examples use event handlers and attributes in an editor to provide a fair degree of custimizability without actually having to create new classes. I don''t use Visual C++, but I assume there is an editor for MFC that does similar things. Even if there isn''t you can still use MFC as a guide.
Keys to success: Ability, ambition and opportunity.
Advertisement
We''re currently implementing something similar, with the engine residing in the EXE, and the game in the DLL (similar to Half-life, Quake 2 & 3 etc.). Half-life makes a fair bit of use of virtual functions, but it''s a largely C-based engine. Most of the non-commercial engines use DLL-based engines, and this makes things a lot simpler -- just link to the DLL''s LIB and you get instant access to it''s code. For my situation, it''s a little more difficult...

I have a series of C functions which perform common functions. Those required by the DLL are added to a virtual pointer struct which is passed upon loading to the DLL. So now the DLL can call simple functions. But what about using the complex C++ objects, like the rendering or sound systems?

The key idea is to seperate the data which the client uses, and that which is used internaly. We have a whole seriese of classes which the client can use for creating scene graphs -- that''s how we send data to the EXE for rendering. Every frame, the client supplies data to the EXE, and the EXE processes that data, and displays the output to the screen.

The first traversal of the graph produces a new graph, which lists only the visible and partially elements. Each member of this new graph is just a pointer to it''s place in the main graph, thus saving memory. To draw it, we use each element''s specific drawing code, which is listed somewhere within the DLL. To overcome the need to have the rendering code included in the DLL, we provide a header for the rendering system which, rather than provide virtual methods (void Function(bool yes)=0, provides empty methods (inline void Function(bool yes) {} ). The Rendering system is the only one which uses such a system (Input is handled differently, and sounds are handled by the scene graph system). This header is included in the client''s C++ file, so it doesn''t break dependencies. Unfortunately, you need to pass a pointer to your rendering system to each member of the scene graph (void Draw(RenderAPI * renderer), but I''m sure you can live with that :-)

That''s just a few ideas, and it''s not exactly what we''re doing, and I''ve never tried that. I''ve been coding for 10 hours so far today, and it''s only 4pm, so you''ll have to excuse my bad spelling and incoherent text...

Hope this helps :-)

Simon Wilson,
XEOS Digital Development
XEOS Digital Development - Supporting the independant and OpenSource game developers!

This topic is closed to new replies.

Advertisement