Engine into 1 .DLL? --->>> round 2

Started by
7 comments, last by skillfreak 21 years ago
I have a question regarding setup and communication between the engine and requesting program ( game or map editor or whatever ). Currently in my game engine i exort a crap load of functions that the map editor may need to call to change various game things. I feel this is a completly bad idea. I skimmed over the thread preceding this one, and someone mentioned the idea of messages.. I''m thinking, if this is even a good thing, that the game( client program ) msgs would be to slow. Map editing is fine, if message passing is really the best idea. So i''m at a cross road here. The engine is also riding on lua. So most engine states, etc are covered in lua. Any ideas are apreciative. thanks.andy
Advertisement
It sounds like some type of messaging would be good for your purposes. I recommend that instead of exporting a single function for all incoming messages, write a few that are related to particular entities in your game engine (i.e., PostPlayerMessage, PostEngineMessage, PostCameraMessage, etc.). You can always write another exported function that dispatches to all of the other functions if necessary.

This allows for faster lookups for handler functions since your Player object doesn''t have to worry about filtering Engine messages.

About Map/Level/Monster editors. An editor really has no need to talk to your game engine. It has a need for the data being used by your game engine, however. So this should limit the amount of functions you would need to export. Think about it this way, engine states usually come from some sort of file. Your editor can modify the file and alert the game engine to modifications so it can reload the data and press on.

I guess you could say this is a data-driven architecture. Personally, I think that data-driven architecture is a misnomer since ALL applications are data driven to one extent or the other.

Here''s an example:
User types command into console (EXE)
Lookup a message for the command (EXE)
Send it to the game engine for processing. (to DLL)
engine handles message (DLL)

An editor to game engine is basically.
Editor creates a map, populates it, sets the start location (EXE)
Editor saves level to disk (EXE)
Editor
A) Launches Game Engine with command line params
B) Creates the game engine internally to run in some window
If B
Editor sends a LOAD_LEVEL message to engine and steps aside.

In my previous post I do this:
1. Game held in EXE
2. Game loads level and resources through COM object in DLL (really not necessary since I could have exported it out of the executable but I wanted to be able to reuse my level and resource loading in other projects).
3. Editor command recieved by game.
4. Editor loaded and activated in the game''s primary window. Rendering and input layer on engine dispatched to Editor instead. The Editor layer consists of many objects stored in a COM DLL.
5. Editor can be unloaded and game play resumes with the new modifications.

I will probably move the game engine(timing, camera, player, universe, etc.) into a COM DLL at some point but have been working on the internals of the editor at the minute. Trying to figure out how to make a generic VertexNode that responds properly to input...anyway, that''s off topic.

If you are unfamiliar with COM, don''t dive in right away. Read a bit about it. It makes communication between DLLs and processes a breeze. Implementing COM objects is easy with ATL but it is also very easy to make mistakes with it if you don''t know what it''s doing under the hood. Beginning ATL COM Programming and Professional ATL COM Programming are great books to get into it.

One final thing:
Sometimes it isn''t necessary to worry about separating your engine and stuff into DLLs. For one, your developement time may expand significantly and debugging is sometimes a major hassle.

If you''re new to the game development scene, write everything in one application and get something working that you can see. It will help keep you motivated. Later, start thinking about separating functionality into DLLs.

Happy coding!
If i were to create a warcraft 3 like editor off this method, i suppose it would work just as well as anything else; however, if i want to raise terrain and watch it get bigger by simply doing something along the lines ( building off your method ).

SendMapMessage( TERRAIN_RAISE, MouseX, MouseY, Offset );

But the engine would raise the terrain and allow you to view it right there. I''m completly visualizing warcraft''s map editor here.
Thoughts. I do tip my hat to your method tho. +) clean.

Andy
I understand what you''re getting at. So instead of providing methods that work on individual vertices according to some message sent to the engine, why not provide a way to gain access to the actual memory location where the map information is being held?

Since you are running in a DLL, you get to share the same address space so you can pass pointers back and forth. So if your map is a 128x128 area loaded in contiguous address space, why not request a pointer to it and make your modifications? As long as you''re not multithreaded, you can modify that data without any problems.

Sending thousands of messages to raise the level of a landmass would be extremely time consuming. Provide access to the memory location and replace your message call with a pointer access and you will fly with blazing speed.
i don''t think sending messages would be a slow as one may think.
Plus, it provides a clean way to talk to the dll without an understanding of how it does things.. just.. '' i want that land here to be higher'' or whatever
thoughts? good stuff here.
andy
Perhaps you are thinking something similar to what I have thought. Ever since I saw Active Worlds a couple years ago I’ve imagined having a first-person 3D game in which editing the game and playing the game are seamless. You edit the world you are “in”. I’m not sure how practical this is. Depending on how you designed it, you may need to have extra code for editing that you wouldn’t normally need, and that will bloat the game engine. Designing it so that the editing code is somehow separate would be a bit harder to do.

Take the example of editing terrain height, as you mentioned. You might like to adjust the height of the vertices, then immediately walk on that terrain to try it out. Suppose that you have terrain divided into patches of, say, 8x8 vertices. A terrain patch may be a class and each instance of a terrain patch would be an object. So that class might need member functions to allow it to be edited. Perhaps you can adjust individual vertex height or just supply a whole new array of 64 vertices. Also, the class would include a function to tell the object to save its data out to the permanent data file. (This is all just an idea for discussion; not a recommendation.) In keeping with object-oriented philosophy, you would want all the terrain patch functionality together. This would include editor-type functions like AdjustVertices() and Save() along with non-editor-type functions like Render() and Load(). If you wanted to split these up so the editor functions are not always in memory, you might think about doing it through inheritance. (I don’t really remember, but I don’t think there is any way to inherit implementation across DLL boundaries; you’d need to use some sort of interface inheritance such as COM.)

I don’t have the Warcraft editor. But I do have the Morrowind editor and so that’s what I think about. I suppose they might be similar. In the Morrowind editor you can raise and lower terrain.

I don’t think message passing is the answer to everything. It’s useful in some situations to decreasing coupling and increase modularity. But in other situations it’s not appropriate. For example, I wouldn’t send a “render’ message to all objects that need to be rendered. I mentioned it in the context of DLL because it helps with modularity, and the kinds of events that occur across DLL boundaries are commonly not time-critical. (Ugh, sorry, this is starting to get long.)

The message-passing scheme I use is a sort of very simple design pattern I picked up many years ago (like around ‘90, lol) although I suppose it may be common now. Objects that want to generate an event send that event to a central “event manager”. Other objects that want to listen for particular events register with the event manager as an event handler. When the particular event occurs, the event manager will call them. (Note this is unlike Windows where every window gets every message sent to it.)

Here’s a bit of code:

          // Abstract base class to define the interface for classes that receive events.// Classes that want to register as event handlers must derive from the EventHandler class.class EventHandler{public:    virtual void OnEvent(Event &event) = 0;}; class EventManager  {    typedef list<EventHandler *>  ListType;     // When an event is received by SendEvent(), it is passed    // to each of the registered handlers in this list.    // There is a list of handlers for each different event.    vector<ListType>              handlers;     // The one and only instance of the EventManager     // class (a singleton)    static EventManager           eventManager; public:    static void Register(byte eventType, EventHandler *aHandler);    static void Unregister(byte eventType, EventHandler *aHandler);    static void UnregisterAll(EventHandler *aHandler);     // called by objects that generate events    static void SendEvent(Event &anEvent);          static void Exit();protected:    EventManager();    virtual ~EventManager();};        

One nice thing about doing it this way is that it makes the program flexible. For example, one of the objects that generate events is the keyboard input. When the input class detects a new keypress, it sends a keypress event to the EventManager. It doesn’t know what other parts of the program might be interested in keypresses. So later I might add a player character object that moves forward when the “f” key is pressed. It registers for this keypress with the Register() function and gets called when the “f” key is pressed. When I added the player character, I didn’t need to change the input class. Even later, I might add another class that listens for the keypresses as well. It might be a debugging class that I insert to monitor keypresses or any other messages. When I add the debugging class I didn’t need to change either the player character class or the input class.

Let’s say I want to further abstract things. I don’t want the player character to be tied to using the “f”. So I add another class called a Translator. The translator listens for raw keypresses and converts them into other messages, such as a “move forward” message. When it receives an “f” (or whatever the user has configured the key to be) it will send the Move Forward message to the Event Manager. Now the player character object listens only for the “move forward” message.

A benefit of this design is that now the input is not tied to the player character. Let’s say that I wanted to remotely control the player character as if I had a scripted part of the game. (Remember how Ultima VII used to take over control of the characters to execute a specially scripted scene?) I can inject some “Move Forward” messages into the system using SendEvent(). The player character wouldn’t know the difference. It would be easy to add this to the game without changing much if any of the existing code. You wouldn't need to hard link to the player character class or know it’s interface. And scripted movements could be a sequence of event messages, perhaps stored in a separate file.

The player character may in turn send out its own events, such as “I just died”. The player character would not have to know which other parts of the game needed to be notified of this death. Instead, any other part of the program that was interested in that death event would just register for it.

I went through this long explanation just to give some context to my comment about using message passing. You give the example:

SendMapMessage( TERRAIN_RAISE, MouseX, MouseY, Offset );

Another way to consider might be to just send a generic mouse event and let the terrain class interpret that as a terrain-raise or terrain lower. It’s a trade-off and depends how you want things to work. But I don’t think performance would be a problem. Mouse movements are already messages. And it’s not a time-critical thing anyway. If there are too many you can filter some out. Message passing is good for events that don’t happen regularly or often.

quote:Plus, it provides a clean way to talk to the dll without an understanding of how it does things.. just.. ' i want that land here to be higher' or whatever


Yes. It’s a good way for one part of the program to avoid having to know the detail of another part. Of course, they sill have to agree on the structure of the particular message. But often new messages can be added and removed from a design without affecting other parts of the program as much.

[edited by - JimH on April 1, 2003 4:33:04 PM]
Good post.

What I''m trying to understand is if you are writing a game engine or an editor?

Does the game engine allow deformable geometry? If so I still think it would be better to provide whatever modifies the geometry with actual pointers to the memory location of that geometry.

As far as passing a message being slower, it will be. Perhaps not significantly but you do have a jmp plus some data being put on the stack every call. If you''re modifiying 1000 vertices, then you will (1000 stack pushes * amount of data pushed + 1000 pops(stack offset register modification) + 1000 jmp) instructions + (1000 * modification code instruction count). With pointer access you have 1000 dereferences + (1000 * modification code instruction count).

So let''s define the difference between an editor and an engine.
The engine runs data created through the editor. The engine does not modify the data provided by the editor. You don''t want the engine to save the data to disk else you won''t be able to restart the level with it''s original form. You can save a geometry modification file that the game engine loads to alter the original geometry. Say a bomb makes a crater, provide a MAKE_CRATER message or a volcano errupts, MAKE_VOLCANO, etc. There can be dozens of these types of messages. Saving them would only require the MSG_ID and the coordinates and parameters of the message.

The editor is concerned with creating those original files that represents the current level. An engine just runs the existing geometry and provides special functions to alter that geometry without breaking the original gameplay.

So instead of having the engine provide ''hooks'' into the level geometry, have it provide information like, current level filename or pointer to loaded geometry.

It sounds like you''re blurring the lines between editor and game engine a bit. Not saying that''s a bad thing but when it comes to bug hunting, you could have a headache on your hands.

Happy Coding.
quote:What I'm trying to understand is if you are writing a game engine or an editor?

I assume you’re asking that question of stillfreak, but I’m not sure. Perhaps, depending on what he is trying to do, it would be wise to separate the editor and game as is typically done.

In my case, I’m interested in the idea of making the game and editor as one. You would be in the game but you could change anything, including the terrain. It sounds unconventional. But imagine an online game where you could do this. You could go in and design an area and other people can see what you’ve done. Active Worlds worked this way to a degree, although it had no elements for games, only for building the world. What I discovered is that there is a huge potential for tapping the creativity of people that way. I saw some amazing creations that seemed to reflect the unique mind of its creator; things I don’t think would have existed if designing is limited only to a few designers in game companies. So I think your comments about the editor and engine needing to be distinct are correct...unless making them combined specifically what you are trying to accomplish.

I don’t think you would typically be editing 1000 terrain vertices at a time. And if you were, you probably wouldn’t send an individual message for each one. You would send a single message to modify a group of vertices. Or you would just pass along the raw mouse message itself. A message is only a little slower than a function call, since a message is essentially a function call, or rather two function calls since it is indirect. I’d expect that a much bigger performance concern would be in actually modifying the vertices, especially if you need to update the hardware vertex buffers.


[edited by - JimH on April 3, 2003 1:03:31 PM]
Sorry for replying so late.

I do like the idea of having the game and the editor one in the same. However, I''m thinking in a different context. +) For instance, say i''ve mocked up a map in an editor and i''m running around in the level in my engine ( seperate ). Now, perhaps i notice that i need an RPG where i''m standing. I''m thinking that i could bring down the console and say, ''PlaceObject RPG'' or something like that.

Lemme jump to a bigger idea.

I''ve never played ultima online or infantry zone ( iz back when the editors would change various things before your eyes ), but I have heard of these and admin interfaces. Superhuman ''I AM GOD'' interfaces. Def ultima online.. where a "GameMaster" can grant you any item that exists in the game, give you health and cast you off to heaven. Whichever. I''m sure that this same admin interface, though i''ve never heard of this ( which is why i bring in the iz )that can edit the map, entities, game objects, drop sheep or raise volcanos right before your eyes.

So I would like this.
I would like the ability to, as an admin of my game, to have an extremly versitile interface where i can give players items that perhaps i just created ( out of game - special game editor ). Maybe drop items throughout the map ( as an easier way to make modifications without leaving the game and firing up my map editor ).

Perhaps i''m simply stewing up ideas off the extension above, as I really think your ideas are great.

How should i go about thinking of this.
Ultima online i''m sure has a seperate exe all together, so that crackers cannot reverse engineer the software, sploiting various admin only options. ( which i''m sure even then requires a password or what-have-you )

// reread... and thought here...

ok. If i were to create an engine, which was self propelled but had functions to pass msgs and other to it. I could create an admin exe ''shell''.

But this is no good. Because all a cracker would then need to do is experiment with exported functions from the game engine.
hmmm..

perhaps another thing to note is the engine uses lua.

ahhh.. mind storms off into oblivion.
trying to stay on topic. ( no more chop )
GREAT STUFF. thank you very much for all your input.
Andy

This topic is closed to new replies.

Advertisement