Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Feather Kit - A C++ Game Framework  (Read 45412 times)

0 Members and 4 Guests are viewing this topic.

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Feather Kit - A C++ Game Framework
« on: January 21, 2014, 04:36:01 pm »
Hello!

For the last year or so, I have been spending time developing a modular lightweight game framework for C++. I am posting this thread here as a first peek out into the public to hopefully get some user feedback and opinions on the library. :) It is a quite lengthy post, including a description of features. If you're uninterested in reading the features, skip to the "Live demos" part.

featherkit.therocode.net

I have developed this framework for my own use and for educational purposes, and my aspiration is that this library would turn into something useful for other people as well. :) During the past year I have added various components to the library at the same time as using it. It was even used by a few people in a private game jam LAN. So I feel that the library has reached a point where it would be beneficial to get more users into it, to let it mature more.

So, what is Feather Kit really?

As stated, it is a framework. It is not an engine. What I mean by that, is that it is not a tied-together system, a ready application to just stuff content into to make a game. Rather, it is a toolbox with various independent components that you can pick and select from to help you build your game. It contains no gluing code and it is up to every user to use the tools in the way he/she finds best. Following this philosophy, the amount of dependencies are kept to a bare minimum, to make as few assumptions about the user's system/platform as possible.

The general idea of these components is that they should deal with problems often encountered in game development and provide solutions for these in a clean, lightweight and object oriented way.

It is divided into independent modules. Here is a list of the current modules and some of their features.

Entity system
The entity system right now consists of a way to create and store entities along with an arbitrary number of attributes. Right now it only deals with entity data, not entity logic but some kind of component based logic system is planned. Entity templates can be created and loaded from JSON files.
Example on how to set and get attributes on an entity:
entity->setAttribute<glm::vec2>("velocity", glm::vec2(1.0f, 4.0f));
bool isScared = entity->getAttribute<bool>("isScared");
entity->addToAttribute<uint32_t>("health", 20);
 

Messaging
The messaging module contains a message bus, and a general message class. This lets various parts of your game communicate with each other without explicit dependencies. Built heavily on C++11 features such as variadic templates to provide a really clean messaging interface with almost no boilerplate code. Most dispatching logic is also handled compile time which makes for a really low runtime overhead. Read more here: http://blog.therocode.net/2013/09/messaging-using-variadic-templates/

Example on how to define a message:
struct EntityMoved_tag{};//                              id      position
using EntityMovedMessage = fea::Message<EntityMoved_tag, size_t, glm::vec2>;
 

Example on how to send a message:
messageBus.sendMessage(EntityMovedMessage(1337, glm::vec2(5.0f, 2.0f)));
 

Render2D
This module aims to be a complete tool to render 2D graphics for a game. It is build on raw OpenGL and in a sense it reinvents a lot of what SFML can do. I chose to write this part from scratch to be able to more easily take Feather Kit to more exotic platforms. Right now it contains sprite rendering with animated sprites, tile maps, text rendering, with an inheriting interface to add new drawables. It supports a camera and a viewport, blend modes and shaders. More features and some cleanup are planned.

Structure
A module dedicated to structuring the code base of your game. Contains a general application class which helps you take command line arguments and create a main loop. It also lets you compile to emscripten to run your game in the browser without having to tailor your code to work with the asynchronity of the web. There is also a game statemachine and a general tree class which can be used as a quadtree, octree or NTree.

User Interface
I wanted Feather Kit to not be strictly dependent on any sub-system. So this module is mostly about reinventing a window class and an input handler. It does not however implement it from the bottom up. Instead it uses a backend approach where it translates the window/input things from the underlying backend to a more general Feather Kit format. That way you can by changing about 4 lines of code make your game run on SFML instead of SDL or any other platform which has a backend implemented for it. Furthermore it also implements an action handler where you can bind raw input to actions, and store that configuration to file.

So that's all modules there are for now, but planned modules (that will be added Some Day™) include a resource manager, audio, 3D rendering and networking.

I have also made the effort to make Feather Kit work out of the box with Emscripten. Emscripten lets you compile C++ code into javascript for direct deployment on the web.

Live demos

Alright, congratulations if you read this far, haha. Here are a few examples of what you can create without that much effort with the help of Feather Kit. They are all built for the web using Emscripten and if you have a reasonably new browser they should work.

Interactive textures: http://featherkit.therocode.net/wip/ (steer with WSAD)
Tilemap, actions, animations and lights: http://pallkars.net/~zagabar/bladepit/ (steer with WSAD and click the mouse to fire)
Tilemap and animations: http://featherkit.therocode.net/tutorials/tilesanimationexample.html (press space to get past the first screen)

End section

That is pretty much it. I would be very happy to get some feedback so you are very welcome to test it out if you have time. There is documentation and tutorials (more will be written) on the website. If you need help getting started or have general feedback or feature requests, there is an official forum and an IRC channel. Everything can be found on the website.

Keep in mind that the library is still very new, and has not received user feedback or haven't been used that much so a few quirks and bugs could exists, but I'll do my best to fix them as soon as possible. I also aim to be open for criticism and take all suggestions open mindedly to make this library as good as possible.

Thanks for reading! :)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Feather Kit - A C++ Game Framework
« Reply #1 on: January 21, 2014, 05:10:48 pm »
Your framework looks really interesting, and it's one of the few ones that actually uses modern C++ :)

With its entity, message and state systems, it also looks like a nice addition to my own library Thor (which has a similar philosophy, but is tailored more towards SFML extensions than general game programming). As far as I see it, SFML is only one of multiple rendering/windowing backends, right? Do you plan to provide an abstraction layer so that one can easily switch between SFML and SDL, for example?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

select_this

  • Full Member
  • ***
  • Posts: 130
  • Current mood: just ate a pinecone
    • View Profile
    • darrenferrie.com
Re: Feather Kit - A C++ Game Framework
« Reply #2 on: January 21, 2014, 05:33:45 pm »
I really like what I've seen of the messaging system; I must admit I'm not a huge fan of the syntax of variadic templates (and templates in general, to be honest - I cringe every time I have to dive into Boost's source) but I like the syntactic sugar of the end result.
Follow me on Twitter, why don'tcha? @select_this

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #3 on: January 21, 2014, 05:35:53 pm »
Your framework looks really interesting, and it's one of the few ones that actually uses modern C++ :)

With its entity, message and state systems, it also looks like a nice addition to my own library Thor (which has a similar philosophy, but is tailored more towards SFML extensions than general game programming). As far as I see it, SFML is only one of multiple rendering/windowing backends, right? Do you plan to provide an abstraction layer so that one can easily switch between SFML and SDL, for example?

Thanks for your kind words! :)

I have checked out Thor and it indeed seems nice! I have been keeping my eyes open for opportunities to try it out but these days I have had my time dedicated elsewhere than making SFML based games hehe.

There are no rendering backends, rendering is pure OpenGL. But indeed SFML is only one of multiple window/input backends. Right now there are backends for SFML, SDL2 and SDL, and such an abstract layer is provided. You use fea::Event for instance which the input backend is responsible of generating.

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: Feather Kit - A C++ Game Framework
« Reply #4 on: January 21, 2014, 06:03:56 pm »
Interesting, I was working with similar ideas awhile ago. It was workable but I was never happy enough with my solution to release it though. Will have to dig into your code more to see how you approached some parts.

For events most my woes came from how I used std::function instead of inheritance for the message receivers. My main issue was with handling removal of a receiver (since you can't compare), and in the end I settled on adding a receiver returned a movable RAII object that on final deconstruction would remove the handler from the dispatcher. A solution with problems, but workable.

I guess the main difference looking is the higher level stuff.

My entity-component system didn't have entities directly knowing their components, instead they only existed as a UUID EntityId stored in a centralised datastore that mapped that id to components. Then the interface was based around getting all entities with a specific subset of components and doing operations on the datastore to CRUD those entities.

I also opted not to use a stack or FSM system for game state, instead there were a set of discrete Controllers that responded to events and enable/disable themselves as needed.

But yeah, looking at this I like the basic design of it. The emscripten support is awesome, and I can appreciate the headaches that must of caused to get working.
« Last Edit: January 21, 2014, 06:21:17 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Feather Kit - A C++ Game Framework
« Reply #5 on: January 21, 2014, 06:11:57 pm »
Woaw... This sounds amazing :o

Your framework is there just in time, I was about to implement the messaging system in a game but now that I've seen it, I'll wait a bit.

I'm a begginer with variadic templates and not sure what Nexus mean by modern C++, but I'm not an idiot and I understand how to use it. But... I'm not sure I understood well how your messaging system works.

What I think I understood is :


1) The programmer needs to define message-type-structures and give it with message "parameters" to the fea::Message class. The tag is needed to differenciate several messages that could have the same "parameter(s)". Some using (as typedef) are used to make the naming easier.

2) The programmer has to create a MessageReciever class that is templated to get a message of that template type/class. So if I have a
using EntityMovedMessage = fea::Message<EntityMoved_tag, unsigned int, sf::Vector2f>;
I can handle that kind of messages like
class TargetComponent : public MessageReceiver<EntityMovedMessage>
{
public:
     virtual void handleMessage(const EntityMovedMessage& mess) { ... }
};

But my question is : why MessageReceiver do need to inherit from a MessageReceiverBase in your example ?

3) [that's the part I'm not confident with] The lib code is able, at compile time, to "link" messages senders or messages to their recievers ? How is it done, I don't get it.

4) The programmer just has to send messages through the message bus and it delivered to interested reciever(s)
bus.sendMessage<EntityMovedMessage>(EntityMovedMessage(42, sf::Vector2f(32.5f, 12.f));
// My TargetComponent will recieve a message (handleMessage)

What's wrong/right/am I a complete noob ?

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #6 on: January 21, 2014, 07:04:00 pm »
I really like what I've seen of the messaging system; I must admit I'm not a huge fan of the syntax of variadic templates (and templates in general, to be honest - I cringe every time I have to dive into Boost's source) but I like the syntactic sugar of the end result.

Thanks!

I think template programming is fun and I often try to find solutions for things with them. But they can indeed turn messy but i try to make the result have a clean API.

Interesting, I was working with similar ideas awhile ago. It was workable but I was never happy enough with my solution to release it though. Will have to dig into your code more to see how you approached some parts.

...

Feel free to do so! :)

I guess my entity system works similarly to yours. The entities themselves are just an ID. The entity manager is what holds the data. However, for convenience, I added getter and setter functions to the entities themselves which actually peeks into the entity manager.

And sure, Emscripten took a bit of a headache to get working, but actually not too much. It is a really cool piece of technology and I really like it.

Woaw... This sounds amazing :o

...

What's wrong/right/am I a complete noob ?

Thank you! :)

And you understood it fine, that is indeed how it works/how you use it. Except you forgot a detail. When the target component inherits from MessageReceiver<EntityMovedMessage>, it is just capable of receiving messages. It also needs to subscribe to them, to actually get them:
bus.addSubscriber<EntityMovedMessage>(targetComponent); //let target component subscribe
 

Optionally, what I usually do is putting it in the constructor of targetComponent:

TargetComponent::TargetComponent(fea::MessageBus& bus) : mBus(bus)
{
      bus.addSubscriber<EntityMovedMessage>(*this);
}
 

And remember to use the removeSubscriber whenever the object is being destroyed, or the application will crash when the message bus tries to send it a message!

How this works behind the scene is that it uses type_info to resolve the message types into a numerical index during compile time. The subscribers are then stored in a multimap with such type id being the key and all subscribers being the value. Whenever a message is sent, the type is resolved, then the subscribers are extracted from the multimap and the message is sent to the virtual handleMessage function, which will be sent to the right overload using polymorphism. I hope that makes sense.

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #7 on: January 21, 2014, 07:32:38 pm »
Hey zagabar! Awesome work, your library is looking really neat!

I was mesmerized to see it running on emscripten! So much I really want to do the same myself! Would you be able to elaborate a little more on what it took to make it happen?

Thanks :)

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Feather Kit - A C++ Game Framework
« Reply #8 on: January 21, 2014, 07:36:02 pm »
That's all clear, I indeed missed a part !

Thanks a lot =)

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Feather Kit - A C++ Game Framework
« Reply #9 on: January 21, 2014, 09:13:41 pm »
I double post to notify you of an error I got while compiling the lib with CMake :

include/featherkit/rendering/textsurface.h:5:39: fatal error: featherkit/rendering/text.h: No such file or directory
#include <featherkit/rendering/text.h>

And indeed there is no file with such a name in the rendering folder. I managed to compile the lib by commenting this line. Was just to warn you.

eigenbom

  • Full Member
  • ***
  • Posts: 228
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #10 on: January 22, 2014, 04:27:42 am »
Great stuff! :)

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #11 on: January 22, 2014, 06:53:33 am »
Great stuff! :)

Thank you. :)

I double post to notify you of an error I got while compiling the lib with CMake :

include/featherkit/rendering/textsurface.h:5:39: fatal error: featherkit/rendering/text.h: No such file or directory
#include <featherkit/rendering/text.h>

And indeed there is no file with such a name in the rendering folder. I managed to compile the lib by commenting this line. Was just to warn you.


Ah, dang there is always something you miss no matter how much you try haha. Thanks for pointing it out! I have fixed it now. It was a leftover from before and that file is indeed removed.

Hey zagabar! Awesome work, your library is looking really neat!

I was mesmerized to see it running on emscripten! So much I really want to do the same myself! Would you be able to elaborate a little more on what it took to make it happen?

Thanks :)

Thanks! Cool that you liked it running on emscripten. I was actually unsure on if people would care about that feature or not haha.

Well, some of the work with emscripten was to learn how to build things with it, especially with external dependencies. Which I think is easier these days because they seem to have updated their wiki to be easier to understand. Then I had to rewrite my rendering engine a bit to make it OpenGL ES2 compliant since that's what is supported by emscripten, and that took quite a lot of time, since I had to test a lot and work out the error messages in the browser etc. And finally, since the web is asynchronous designed, you can't have a blocking main loop since that would freeze the browser. So I added some emscripten specific code in the Application class to make it emulate a main loop using a timed approach. It isn't that complicated since emscripten has functions for it.

That is pretty much what I had to do. Not _too_ much, but it is nice to have it done hehe. :)

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #12 on: January 22, 2014, 04:37:47 pm »
Cool! Since my code already supports all those requirements it shouldn't be too hard I believe!

I will try and achieve the same! Did SFML's windowing system work out of the box? I heard only SDL was working with emscripten..

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #13 on: January 22, 2014, 06:31:38 pm »
I'm not sure if you realise it, but, there are serious constraints placed on the set of types which can be used as attributes. This is due to the use of memcpy in both of the 'EntityBackend' implementations. In short, any attribute type must be trivially copyable. I strongly suggest that you either rewrite the code to avoid memcpy, or at the very least statically assert that the attribute type being registered/queried is in fact trivially copyable. It isn't difficult to come up with worst case scenarios here (i.e. this is a real and serious issue).

The implementation of 'AlignedEntityBackend' imposes the further constraint that attribute objects cannot contain pointers to other attribute objects because the pointer value will become invalid if the array containing the pointee is resized.

It should also be documented that conversions are unsafe. That is, the type of the object being retrieved/set must *exactly* match the registered type to avoid undefined behaviour. About the best you could do here is a runtime type check (because of the use of strings to identify attributes).

I have some idea to avoid/mitigate the above situations if you get stumped.

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #14 on: January 23, 2014, 04:00:00 am »
Cool! Since my code already supports all those requirements it shouldn't be too hard I believe!

I will try and achieve the same! Did SFML's windowing system work out of the box? I heard only SDL was working with emscripten..

Nice!

Yeah, I don't think SFML works out of the box. But I think it could be easier now when SFML has Android/IOS stuff going on because I think that means that SFML would support open GL ES2. But I am not exactly sure. And you would still have to make a bridge from the browser events to the SFML events I think (but don't take my word for it). SDL is indeed supported out of the box by emscripten so that is the easiest way to go.

I'm not sure if you realise it, but, there are serious constraints placed on the set of types which can be used as attributes. This is due to the use of memcpy in both of the 'EntityBackend' implementations. In short, any attribute type must be trivially copyable. I strongly suggest that you either rewrite the code to avoid memcpy, or at the very least statically assert that the attribute type being registered/queried is in fact trivially copyable. It isn't difficult to come up with worst case scenarios here (i.e. this is a real and serious issue).

The implementation of 'AlignedEntityBackend' imposes the further constraint that attribute objects cannot contain pointers to other attribute objects because the pointer value will become invalid if the array containing the pointee is resized.

It should also be documented that conversions are unsafe. That is, the type of the object being retrieved/set must *exactly* match the registered type to avoid undefined behaviour. About the best you could do here is a runtime type check (because of the use of strings to identify attributes).

I have some idea to avoid/mitigate the above situations if you get stumped.

Ah, thanks for the feedback. :)

I am aware of those constraints although I had kind of forgot about them, so it is a good reminder. The entity system (and actually the whole AlignedEntityBackend class) is the first thing of the framework that I started to write and I have levelled up a lot as a programmer since then so the ugliest code in the framework will doubtlessly be there. I have even been wanting to rewrite big parts of the entity system but haven't gotten around to it yet.

But yes, that is an issue that should be addressed indeed. The reason why I used byte-pet-byte copying is due to the AlignedEntityBackend which stores all entity attributes in the end as char arrays, and I did that to achieve general storage of any data type. But of course this is limiting as you say. There is even the fact that if you try to store an object which has a non-default destructor, the stored object will be destructed whenever the copied instance goes out of scope.

I look over the old code and see if I can come up with a nice way to fix it. Feel free to post your ideas on how to do this the best way possible. :) Depending on things I actually might remove the aligned entity backend if I can't figure out a way to do what I wanted to do with it in a good way. Is is quite a special case component. Although the idea is nice.