   Engine design -- feedback?
  Howdy everyone!I'm developing a persistent world 3D development system using Direct3D 9 and was hoping to get some feedback on my latest design.  Positive feedback is fantastic, but please keep it professional :)The engine core is constructed inside a number of static and dynamic libraries, consisting of client code, audio, graphics, platform, network, math and common utilities (among others); the game client is also written inside a dynamic library.The engine is commonly started from an executable included with the entire development kit: For all intents and purposes all it does it initialize the client code and nothing more.  Once this process is started, the client code proceeds to load and initialize the platform (window, input, etc), graphics (DirectX or OpenGL), audio then finally the game client code.Since the client code is located inside a library, the game client itself is able to link to it statically and load resources, render the game world / GUI, etc.If anyone sees flaws in this design, I'd love to hear about them.  And although this isn't the correct place for this (I'll be posting a help request in the near future), if anyone is interested in working on a freely available persistent world development system, feel free to email me at nate at foreverknightsgaming dot com.Regards,Nate Strandberg   
  Don't take this in a hostile way, but I don't think that's even remotely close to the amount of information one would need to give any sort of meaningful assessment.A better thing would be a rough description of the DLL layout, (i.e. what you've chosen to throw in there and why) your interfaces for using each of these components, if/how they talk to each other, your stances on/approaches to parallelism, etc.   ;Quote:persistentPersistent in what way? Networking is mentioned - server-side, client-side, P2P?Let's say I add a car to the world (mesh, stats, controller, physics, AI). How does that work? Since all of this is persisted, how do I upgrade the AI? Perhaps I need to add or remove a variable - but some other content may rely on old behavior? How are these situations handled?Let's say I add car to my state, and connect to someone else who does not have the car content. What happens? Do they need to transfer entire car content? What if they have a different version of a car already?How do I remove content from the world? Let's say I have a building, into which others have put in furniture, and the city simulation calculates surface area of the building trying to determine taxes. Now I remove the building, and replace it with a different one. What happens to the furniture? What happens to the city module that calculates surface area?   ;  @InvalidPointer -- I see no reason to take your reply as hostile; my original post was put up with very little time left before I had to leave for work.Platform Library -Contains all the platform specific code (windows, linux, mac OS):Window creation, message handling, input handling.  In a nut shell, this dynamic library is the only one that any code thats platform specific can reside.  This library does not call any other part of the engine, it only interfaces directly with the Client.Graphics Library -Contains all the core rendering code for your specific API; DirectX 9 is currently functional, plans for DirectX 10 and OpenGL are on the drawing board.  This library exposes a class based on the RenderDevice pure-virtual interface which allows the Client library to initialize the specific API, create and delete textures, vertex && index buffers.  This library also doesn't call any other part of the engine, it interfaces directly with the Client.Audio Library -Same as graphics; allows you to choose different APIs:  Direct Sound is currently all we have developed, plans are in the works for OpenAL.Network Library -Wrapper on top of ReplicaNet (http://www.replicanet.com):  An extremely powerful networking engine.  This library is very generic and is designed to be used by both the Client library and the different server applications.Game Client Library -This is where all client-side game specific code resides and is exposed to the engine Client using a macro that wraps a few basic export functions; I'm working on a system that will make this process easier (I'm considering a very watered down COM style interface) as I approach a functional release.  The engine Client will call specific functions which need to be overridden to allow functionality; specifically onInitialize, onTerminate, onPreUpdate, onUpdate, onPostUpdate.  This library is also responsible for creating the initial connections to the different servers, verifying version numbers, etc.  I'm more than happy to go more indepth if you need it :)The other parts of the engine are server specific and are honestly not designed yet.@ Antheus - To be frank, I prefer the term persistent verse "MMO engine".  The network design is purely client -> server; and as with most online games, the client is not trusted in any way except with physics calculations and the likes.--> Let's say I add a car to the world (mesh, stats, controller, physics, AI). How does that work? Since all of this is persisted, how do I upgrade the AI? Perhaps I need to add or remove a variable - but some other content may rely on old behavior? How are these situations handled?  <--For the most part, this is done using ROL files inside replicaNet along with the server side game code; although currently this is TBD.--> Let's say I add car to my state, and connect to someone else who does not have the car content. What happens? Do they need to transfer entire car content? What if they have a different version of a car already?  <--This is something I'm still considering; I'd love to setup a system where content is downloaded on demand, and doesn't require the client to download / install the entire game at once.  Again, TBD.--> How do I remove content from the world? Let's say I have a building, into which others have put in furniture, and the city simulation calculates surface area of the building trying to determine taxes. Now I remove the building, and replace it with a different one. What happens to the furniture? What happens to the city module that calculates surface area?  <-- Sadly this is currently TBD also; I'd love feedback on how you'd implement this technology yourself if you're willing.Again, more than happy to answer any questions that arise.  If you need direct contact, email is best.Regards,Nate S.;  Looking at your layout there-- seems pretty straightforward; should work pretty well. One caveat I'll give you (from personal experience!) is that extremely strict adherence to 'platform-specific functionality goes in the platform helper class' has a nasty tendency to INCREASE interdependence; think long and hard about what you decide to retain there and why. Often times a handful of #ifdefs can be just as clean/readable as a call into an external library, especially for small yet important program logic changes. Typedefs and pointers can also help with this immensely, in particular when dealing with interfaces and platform-dependent data types.Also, how exactly do you plan on handling renderer differences? Virtualizing the hell out of *all* your objects (i.e. the O.G.R.E. way) is a flat-out bad idea, but I'll hold off on that until I know a bit more. You can do very impressive things using only simple offsets into arrays and some clever typedefing.   ;  The primary reason for using dynamic libraries was purely to give developers using the tech the ability to write their own platforms / graphics APIs and not gain straight access to the core engine code.  The more I look at how the engine is evolving from the original designs I wrote up / put together on paper while slow at work make me wonder if it might be best to just integrate a lot of functionality directly into the core library as you suggest.  Honestly the way I'm looking at it now, I'd hope developers would be more focused on their game project verse writing a new graphics API wrapper ;)I'm not exactly sure what you mean with "renderer differences".  Are you referring to how the renderer interface varies from DirectX to OpenGL, or are you asking about the scene graph system?Also, how do you feel about Unicode?  Most parts of the engine that deal with the file system or displaying messages are fully Unicode compliant, but I've strayed off in some parts and used straight std:: string VS wstring.-Nate   ;Quote:Original post by InvalidPointerVirtualizing the hell out of *all* your objects (i.e. the O.G.R.E. way) is a flat-out bad idea.I fail to see what is so flat-out bad about it, would you like to elaborate?@ OP: I suppose your design looks good, but you'll only know if it's a good idea once you get it up and running [wink].  Just be careful with all the flexibility, sometimes things need to be coupled together tighter for better performance/understandability/etc.   ;  I'd like to think the engine is quite easy to understand.. I'm a bit of a OOP and comment nut; also all my classes are buried deep in namespaces to make it very obvious where you can expect to find different interfaces for different needs.This is the third revision on the engine project as a whole, so I've seen how it handles when coupled together and how it handles as it sits now- separated.Another thought did occur to me, what do you guys feel about singletons?  I know many people find them extremely chunky and avoid them like the plague, others use them often.  As it sits now, the client class, asset "manager" (basically a glorified virtual FS) and the asset loaders themselves are all singletons, but I'd like to keep it at that if possible and not force everything to rely on the client singleton and not have direct access to others when needed.-Nate   ;Quote:Original post by nullsquaredQuote:Original post by InvalidPointerVirtualizing the hell out of *all* your objects (i.e. the O.G.R.E. way) is a flat-out bad idea.I fail to see what is so flat-out bad about it, would you like to elaborate?@ OP: I suppose your design looks good, but you'll only know if it's a good idea once you get it up and running [wink].  Just be careful with all the flexibility, sometimes things need to be coupled together tighter for better performance/understandability/etc.Well, for starters-- why would you even consider passing an COpenGLTextureObject or whatnot into a DirectX-based renderer? It sounds all fine and dandy at first until you realize you're setting yourself up for unwitting disaster. It doesn't even have to be intentional, either; one of them could merely be skipped during a change of renderer and all of the sudden you're well into the land of undefined behavior. Worst-case scenario with the alternative, your textures are just going to look wrong; that's much easier to track down and fix.In short, it's polymorphism you don't need nor should you even want. As an added bonus, you can avoid a lot of needless overhead for the virtual function call, especially since such manipulation forms a large part of the renderer functionality anyway.