SFML community forums

General => SFML projects => Topic started by: man'O'war on August 21, 2016, 12:43:23 am

Title: GDF - GameDevFramwork
Post by: man'O'war on August 21, 2016, 12:43:23 am
Hello everyone,

I would like to share a framework i am currently developing which is dedicated for 2D game development

updated:

Preamble
The story began when i wanted to develop a game like Secret of Grindea. great game by the way :3
As you may definitely noticed, when starting up a game for the first time, at a certain point, your code starts to become heavy in a way that, it is not flexible anymore. It works only for what you've made and any future changes, or adding new ideas requires major changes in core code. 
(click to show/hide)

This is why it is necessary to structure your code, and create some base classes to manage your game, before even creating your first asset.

I was inspired from several references, such as the SFML Game Development ebook from packtpub. It was very good to start with, but does not have a flexible structuring of code.

Quote
What i mean by flexible structuring of code, is that, The game may grasp almost any kind of new concept/idea without having to make changes in core code. (or at least very few changes)

I've also tested UDK and Unity (documentation), which they helped me a LOT to learn more about organizing things together. Especially the GameObject/Component pattern.

The GameObject/Component design makes your game entities INCREDIBLY flexible.
Will be discussed later

Presentation
GameDevFramwork (GDF) is an open-source C++ framework for 2D Game development extending:

More .... ?
Yes... The purpose of the project is to build a totally modular open-source framework, by providing a set of base classes ( kernel module ) to make it possible to accept and easily integrate newly created modules.

The Kernel module
The kernel is a minimum set of classes that implements the core of the framework,
Here is the class diagram of the kernel
(http://image.k-upload.com/view-img-norm_2016-08-19-16eaae856kernelclassd.png) (http://www.k-upload.fr/afficher-image-2016-08-19-16eaae856kernelclassd.png.html)

starting by:

The GameObject/Component pattern allows the creation of a meaningless GameObject. And its context is defined by the logic carried by its components. Components can be added and removed at will.
For example
It can be seen as, equipping your hero (GameObject) with different weapons and skills (Component).
If you give your hero a sword, a helmet and a shield, then you've made a Warrior. But if you give him a staff, and a spellbook , then you've chosen to be a Sorcerer, despite it is the same GameObject.

    GameObject* hero = GameObject::instantiate();
    // Choosing to be a Warrior
    hero->addComponent<Sword>();
    hero->addComponent<Shield>();
    hero->addComponent<Helmet>();

    // Choosing to be a Sorcerer
    hero->addComponent<Staff>();
    hero->addComponent<Spellbook>();
    // or ...
    Spellbook* spell_book = hero->addComponent<Spellbook>();
 

But....
What if i want my Sorcerer to have not more than one Staff and one Spellbook. And cannot have a Staff without  wearing a Cape ?

Well, thanks to the KernelRules class that defines a set of rules ( dependency relationship between components ) in order to check the satisfiability of the add and the remove actions.
In other way
Quote
rule: X → A, B, C
A Component X cannot be added inside GameObject G if A, B, C Components are not available within G
vice-versa
A Component A cannot be removed if one or more other Components depends on it. ( herein, X )

Example-Code
    make_singleton("Staff");
    make_singleton("Spellbook");
   
    create_rule("Staff", "Cape");
 

make_singleton creates a cardinality rules, imposing the (HierarchicalContainer) or GameObject to only accept one instance of a given Component-type. Herein, "Staff", "Spellbook" are limited to one instance each.
AS for, create_rule method, it creates a dependency relationship between Staff and Cape, telling that, Staff depends on/ requires Cape to be available first in order to be created..

Quote
There are pre-defined rules applied for built-in components in order to ensure the good functioning of the kernel module


By taking advantage of these methods, and of the generic implementation of the GameInfo, any kind of component can be attached to the GameObject.
(http://image.k-upload.com/view-img-norm_2016-08-19-1d9238f71gameloopelem.png) (http://www.k-upload.fr/afficher-image-2016-08-19-1d9238f71gameloopelem.png.html)

Herein above, one elementary cycle of the gameloop.
Based on timestep update. Each elementary cycle, the GameInfo

Minimal example-code
To start in with the framework,
You must create a sub-class of GameInfo and Scene. ( And also override pure methods )

Quote
Note that, i am not using too much 'getters' in my code, but accessing data members directly, this is why some instruction are too long. 

TestCaseGameInfo.h
(click to show/hide)


TestCaseGameInfo.cpp

(click to show/hide)



TestCaseScene.h

(click to show/hide)

TestCaseScene.cpp
(click to show/hide)


Adding a new Component: the pre-declared MoveObject
g0 had a component called "MoveObject" that makes it move in the scene. i.e
create_rule("MoveObject", "Transform");

Here is the implementation of MoveObject

MoveObject.h
(click to show/hide)

MoveObject.cpp
(click to show/hide)

Quote
A MonoBehavior is a Component with more features than a regular Component, it is the base class for user-components
Quote
Note that a GameObject cannot be overriden. 

Built-in Components
In addition to the kernel module, there are some built-in components used in order to create basic objects, like:
Graphics, Sounds, Animations & animator, Shaders, Physics , Colliders, Joints, Gui, Renderers, AudioListener, Cameraetc.

Modules... as addons
Creating new modules and integrating them to the framework is very simple.
What needs to be done is to
And they'll be fully functioning. ( as long as Component's methods are overridden and used )



I've made aside some external modules to implement new functionalities for the framework.
resource management module
Resource management module offers a set of classes in order to load, use and unload resource automatically avoiding any kind of memory leak.

The resource manager unloads resource in a safe manner, means that, if a resource is still being used by any object, it cannot be unloaded. This is achieved using smart pointers ( the use_count member of std::shared_ptr ) . See, documentation for implementation details

time management module
The time management module define concepts about time.
the main classes of this module are:

exec ....
When the TimeWinder is launched ( eventually from the scene ), it retrieves all the TimeKeeper Components of all GameObjects. And plays the recorded timeline of each GameObject backwards, by generating an opposite event of the one initially recorded. Thus, simulating a backward execution.
However, any property that needs to be affected by time must have a dedicated event and must be called at the right place.
Example:



(http://image.k-upload.com/view-img-norm_2016-08-20-17fce88f8timekeeper.png) (http://www.k-upload.fr/afficher-image-2016-08-20-17fce88f8timekeeper.png.html)

In the diagram above, it displays the stack's content of the timekeeper at time = ti. The stack is divided in two part:
Events from the past, and events from the future

On a normal play, the timekeeper registers time-events in the past part of the stack, as shown on 'normal play' case

When entering a time manipulation session. The timekeeper stops recording events.
- ON BACKWARD PLAY - rewind: The timekeeper pops events one by one from the past, and pushes them onto future.
- ON FORWARD PLAY: The timekeeper pops events one by one from the future, and pushes them onto the past.

This allows to go back and forth in time at will,

When the session ends, events from the future are discarded, and time keeper starts to record new events.
 
Similar mechanisms of time manipulation can be found in the game Braid, steam link:  http://store.steampowered.com/app/26800/ (http://store.steampowered.com/app/26800/).

And so on ....
As future tasks, I am willing to add and/or integrate already built modules to the framework

Examples
There is not a lot of things to display right now, but i can show you a sample of the time management module. ( Time Reversal mechanisms )
c.f Attached video.

http://www.youtube.com/watch?v=EdxZK8fgfcg

The video shows Time Reversal mechanism. The scene contains 2 (Chicken=Cockatrice) GameObjects (  c.f RPG Maker Sprite ) spawned at the same location.
One Cockatrice does not move, while the other is moving under constant velocity ( x-axis only ) for a short period of time ..


Scenario:

Content of the Log window
What is displayed at the terminal is:

(click to show/hide)
&#8594; means → : The forum cant draw it ?!! ( or may be it is inside 'code' block )
(click to show/hide)

(click to show/hide)


(click to show/hide)


(click to show/hide)



(click to show/hide)


Contribution
The framework is designed to be fully open-source and community repo,

I designed a minimal kernel to be used as a starting point for anyone who wants to develop modules from scratch.
However, built-in modules can be included at will depending on the type of the developed module.
You are welcome to:


Thank you for your time,
And feel free to contact me or give your opinion, your feedback is welcome.

Cordially


Technical specification ( reminder )
Title: Re: GDF - GameDevFramwork
Post by: man'O'war on August 24, 2016, 03:31:30 pm
Hi,

The Github repo has been updated. including the README.
Title: Re: GDF - GameDevFramwork
Post by: hawke55 on August 30, 2016, 05:09:03 am
In the part where you explain how to compile it says to run the makefile with make but I cant seem to find a makefile. Im kinda new to compiling stuff this way and I may just be missing something.