Post feature Report RSS Engine API and Implementation Informations

A longer answer to a question from the comment section about the engine API documentation as well as implementation specific informations.

Posted by on

To start first the question involved (by Bahl) and then the answer. Put it in an article so it does not collide with post length restriction and has comments separated from the rest (for better readability). The question revolves around the Drag[en]gine WIP Documentation.

Thanks for updating the doxygen :-). Let's see if I can summarize the API in a few handy words.

- under common the folders curve, math, shape for base geometry, color data classes and operations on them.

- the folder filesystem plus under common the folders string, xmlparser, file for base text persistence classes and operations on them.

- the folders logger, errortracing plus under common the folders exceptions for cross cutting error handling.

- the folder resources which seems to include mid and high level visual entities, artificial intelligence, physical and networking.

- the folder systems, containing the folder modules, containing interfaces for all modules, which then probably during runtime get their different implementations plugged at the will of the user.

All in all a neat setup :-). Maybe slightly unbalanced folder tree and a bit inconsistent sorting of the related structures, but oh well, systems grow and have a life ;-).

Now taking a look at the scripting:

- first impression is, it seems to be heavily relying on events and the implementation seems to be required to implement a lot of callbacks for AI, physics, rendering, network... . That sure covers the necessities for game logic, but seems quite cumbersome as a base layer.

- first idea is, I'd want to provide base game logic entities like avatar, tool, material, product, monster, machine, and some abstract game facilities to bind all the nuts and bolts together to something easily accessible. But maybe my short skim over the documentation made me overlook some gems that possibly already fulfill such desires?


I know it's a bit difficult to see the structure of the engine just from the DoxyGen without proper documentation in place yet. The basic view you obtained is not bad but there's actually sense behind the structure there. Let's see if I can state this quickly.

common: Contains classes which are used across various engine modules (hence do not belong to one module type). Scripting usually does not expose them directly with a few exceptions (curves, xml just for the case the scripting module has no XML itself). Hence for example to define the shape of a collider the scripts would use "collider.addSphere( center, radius )" instead of exposing a true sphere shape class (at the discretion of the scripting module). "string" is just a common place string/unicode implementation especially to simplify handling strings. "file" contains low-level stream handling access similar to iostreams. Hence it's not text-only and especially not require to be about files at all. "xmlparser" obviously provides xml read/write support using streams. "exception" provides a basic exception object for try/catch handling since C++ lacks this.

filesystem: Virtual File System. Independent of anything else. It just defines the structure of the VFS using containers and provides streams if asked for but by itself has nothing to do with "string", "xmlparser" or "file" (decPath is due to historical reasons in the wrong place, will be moved later on). So to handle a file you first get the stream from the VFS and then you can do whatever you want with it (like for example feeding it to an xml reader).

logger: Provides logging support for the engine, modules and launchers. Not made for error handling but debugging in the first place. Scripts usually never touch this. Supports multiple linked or independent logging chains.

errortracing: Provides error informations in the case of failure. Works like an exception trace. Used only by the engine, modules and launchers. Scripts usually never touch this.

resources: Building blocks of a game world and game behavior. Resources are low-level objects just containing definitions and states. Scripts manipulate the definition while modules provide the functionality and update states if required.

systems: This one is a bit special. A system is a class handling "single type modules". Something like this would be the "Graphics Module". Only one module of this type can be active at any time. It is also only resources affected by single type modules which have "peers". A peer is a per-resource, module-local storage space and one of the main reasons for why this engine rocks. Systems are required to handle creation and destruction of peers when single type modules are started/stopped. Hence peers live as long as their owner module is running while resources live longer (even through stopping/restarting the engine). The peers are found in "modules" as you noticed grouped by module type alongside the module interface. The scripts never touch peers at all as they are handled by the engine and modules.

Hopefully this improves a bit the understanding of the structure as the directory layout is like that for a reason. Concerning the events this is correct. You do not push states and data around between the engine, scripts and modules as this would create coupling and bad performance. For this purpose events are used which have been thoughtfully chosen so modules know what to do. The way the events are set up scripts scripts trigger events only if necessary. Furthermore event passing is fast as modules in general just acknowledge that something changed postponing the change to when it is actually needed. This is only possible since modules have full control over their peers. For modules this is indeed a bit more complex to deal with but this is not a problem since the idea is that modules are used across many games. The scripts themselves do not get in contact with events. You just alter objects the way you want. The scripting module and engine takes care of dispatching events where required.

Now concerning this system as the base of the game it is not. Sounds strange but unless you use a hardcore low level scripting module (which all three current modules are not) you never get to use this layer directory. Between your game and engine sits the scripting module which provides already a framework build on-top of this layer. In my game case there are even two layers. The DragonScript module provides a framework of classes (which you could not know off since there is no documentation of it available yet). This contains a bunch of classes handling game entities, game entity classes, preloading of resources, world management, player input handling and so forth. The game in turn is build on-top of this framework extending it with more classes related to game logic, player logic and game handling in general. Once the first release is close I'll move classes from the game into the script module so it is easier for people to begin.

So to sum it up the layering looks like that in the end (higher levels are based on the level right below skipping only further down if not otherwise possible):

1) Game Scripts (with game-mod framework, game implemented as a game-mod)
2) DragonScript Scripts
3) DragonScript Module (wrapping of engine classes as script classes)
4) Drag[en]gine

Hence what you can see only already in form of documentation is level 4 and to some degree level 3 as it is mostly wrapping level 4 but also adding some convenience classes. What you actually work with though is level 2. This way you get already a script framework at hand. Furthermore since it is fully build on level 3 below you can exchange the framework with another one. This gives the potential to add later on for example frameworks suited for certain types of games. Nothing of that requires any changes to the game engine.

Post comment Comments
Bahl
Bahl - - 72 comments

Thank you for your in depth article :-). I guess the way we can express ourselves in text is inherently limited, though. As far as I understand your description, you are promoting the concept to implement such a game logic library as I intend in level 2.

My intention is however, to bend the scripting concept in level 3, implementing a separate 'language' that has inbuilt support for basic game logic concepts. You could possibly see it as an alternate to DragonScript, with more (and more complex) abstract datatypes (an extension of your convenience classes in a sense).

With your exchangeability of the framework, you probably mean, taking the game logic scripts to another platform? Surely that is possible but implementing level 3 on another engine, but I assume it would be easier with a more accumulated game logic library. The script would then be scripting the libraries classes, instead of the engines classes. As far as I assume, engines may look rather different when it comes to the structure of their implementation, but game logic comes in rather constant concepts.

I'm proposing a library of those concepts built on the engine, made scriptable.

Instead of a library of those concepts built on the scripting module that inherits the structure of the engine.

I assume, the library of those concepts can be better focused on easing the game scripting if the script language is designed exactly for that, instead of when it is designed to allow an implementation of such a library or any other library.

I'm not sure if I was able to make my point, but I tried my best on an evening after two rather straining days at work :-). I'm trying to convince you of DSL, domain specific languages, in this case a domain specific language for gameplay design.

Reply Good karma Bad karma+1 vote
Dragonlord Author
Dragonlord - - 1,934 comments

That's actually not bending the scripting concept at all. One has to not take the word "scripting" too tightly in this context. A Scripting Module simply provides an "entry portal" to the game engine. This can be anything from a straight wrapper without any additional bells and whistles all the way to an RPG Maker type module where you work on a rather high abstraction level. In general the scripting modules simple define a language and an abstraction level. The developer can then choose the one which matches his intentions.

Concerning the framework in the DragonScript this is not about platforms. It's more about an abstraction layer on-top of the engine classes making your live simpler as well as providing a system which provides already a basic game environment. This is like comparing an FPS game with an RTS game for example. Each of these games has a framework in place geared for the genre in question. So using this exchangeable framework it would be possible to have a basic game system available matching your project. This way a lot of time and effort can be saved by choosing a framework matching best your game. Currently there is one framework in the DragonScript module but more could be added for this purpose.

What goes for the engine I designed it (and still am until it is finished) in a way to provide a system which covers the basic building stones of making a game no matter what genre. The DragonScript module simply wraps something concrete (the framework) around it. In general though you could go down and dirty using these building stones directly but it is more efficient to use a framework instead (I'm saying here on purpose "a" framework since each scripting module at your disposal usually has its own).
(...)

Reply Good karma+1 vote
Dragonlord Author
Dragonlord - - 1,934 comments

(...)
And it's true that everything below layer 3 is not your problem. You know that there is a Drag[en]gine game engine running on the user computer no matter what platform this is or what language the engine is written in. You know it's there and configurated to run optimal. So "theoretically" this could be even a different game engine. Important is only that the classes provided by the scripting module looks the same no matter how it is mapped to the underneath engine. Of course trying to force this onto a different engine than the Drag[en]gine does not make much sense but in theory it would be possible.

Your proposal of a library using these concepts and being scriptable is actually what the current modules are doing. They just provide first the mapping on the engine structure (layer 2) and then the concept you propose as a framework (layer 3). This way people can use them both ways either through the framework (layer 2) or straight down and dirty (layer 2).

Concerning DSL it would be for sure possible to make a scripting module with it. Actually this is one of the nifty things on my engine that you can just go and experiment with such a DSL implementing it as a scripting module. If it's great it's going to catch on with others. If not no damage done to the engine itself. Great for researching new concepts and testing them on real (and released) games.

Reply Good karma+1 vote
Bahl
Bahl - - 72 comments

That sounds all very promising, but for now I guess I should be simply patient :-).

Reply Good karma Bad karma+1 vote
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: