Tuesday, 19 November 2013

Concerning component-entity systems


Recently I have been discussing component based design with a friend, and he asked me how my implementation worked out in my platformer. My description grew quite long, so I thought I would make a post out of it - I wanted to do it anyway, I was just always procrastinating. And since there is not much practical info available about it, hopefully it might be useful for others as well. My system is based on this article, and probably this post will not be too clean without reading that one first.

In my C++ implementation Entity is just a typedef to int, they can be created by entities_create(); and recycled by entities_destroy(Entity i);. Currently there are 6 components: Common, Physics, Graphics, Animation, Audio, Camera.

Components


The most basic is the Common component, it contains the position, rotation and facing of an entity. I wanted to group together all the data into one component that most entities have and most other components access.

The Graphics component assigns images to entities. It accesses the Common component to know where to draw the image. The Animation component is quite similar, but instead of static images it uses animation instances.

The Audio component is also similar to the Graphics, it maps entities to Sound instances. At first I thought that it might be a limitation that one entity can have only one sound playing, but then I realized that I can create a new entity for each sound I want to play if needed. Simple.

The Physics part is more complicated, it consists of a main component which maps entities to Box2D bodies, and a subcomponent which maps entities to foot sensors (these are used to query whether an entity is standing on something). These are separate components, but due to the underlying Box2D implementation they are intertwined (the foot sensor needs to access the body), so I just put them together. A body can be either static (for platforms) or dynamic (for moving objects), so it could be possible to handle them as two separate components. Each turn the Physics component updates the position and rotation attributes in the Common component.

The Camera component is a bit special: only one entity can have it (that is, the Camera component has an Entity target; variable instead of a mapping from entities). I don’t remember the original article mentioning such components, but I thought it was logical to do it this way. Essentially it uses OpenGL transformations to follow The Entity so that it appears in the centre of the screen. Changing it to follow other entities can be used to simply implement nice effects, e.g. following a projectile and zooming in on it.

These are the components on the C++ side, but it’s just half of the story; most of the functions of the components are exported to the embedded Lua interpreter, so other components can be implemented in scripts. The C++ components are quite general and could be used to implement many kinds of games (at least I believe so), while the components related to the actual gameplay can be done in Lua. So far I have only implemented the Bullet component, but I was planning others (e.g. AI). Maybe one day I will continue working on this project.

Technical details


For each component I have header file to make all the public functions available to other components (and, more importantly, to Lua), for example common.h contains:

void common_init();
void common_add(Entity e, float x=0, float y=0, float angle=0);
void common_delete(Entity e);

And <name_of_component>.cpp contains the implementation. Private variables and functions are static, public functions are exported in the header, and public variables are global. Yes, global, the second most evil thing after goto, and just slightly better than premature optimization. Please don’t stone me… at least until I blow this whistle. Even if I do say "global". But to be serious, I think this was one of the biggest advantages of using a component-entity system: that it taught me how to tame my globals. I was always told not to use them, because who knows which part of the program modifies them at what time, so they can cause lot’s of headache. But with this system it’s quite clear which component uses what other components, so the modifications can be easily tracked (at least I can do it since I am the only developer… this might be different in a team). And anyway, passing around one huge object containing all the game state is no better.

To provide the mappings between entities and components I use two classes (T is the type of the component, usually a struct):

template <class T> class DenseComp {...};
template <class T> class SparseComp {...};

DenseComp uses std::vector to store the component, and it is used in the Common component. It works since a mapping from Entities (which are in fact integers) to component data is needed, and that’s what a vector does. Since usually most of the entities have the Common component, it’s not wasting space, and this way accessing the Common component of an entity (which is quite frequent) happens in constant time.

SparseComp uses std::map to map entities to a component, it is used in general for other components. It is more space-efficient than a vector when just a part of the entities have the component, and usually querying the component of a specific entity is not too frequent, so the slower lookup is not a problem.

Creating two separate classes for components might have been premature optimization, since currently I just have a handful of entities, so it does not really matter. Maybe using just the one with std::map would have been enough.

Using plain C functions and structs instead of C++ classes to implement components has a big advantage: it’s much easier to bind them to scripting languages. Most scripting language implementations support binding of C functions, but binding methods of C++ classes is complicated at best and usually requires some binding generator. And since Entities are just integers, it’s straightforward to use them in scripts, no need for wrapping classes or handling them as special user-data.

On a sidenote, I was experimenting with turning the engine inside-out, that is, throwing out the Lua interpreter, compiling the code as a shared library and then loading it from Ruby or Python or LuaJIT or any other language implementation which supports it, and this way making it available for other scripting languages. It was working fine on Linux, importing shared libs is a piece of cake with LibFFI in Ruby and ctypes in Python, but unfortunately I had issues on windows: loading the dll hung. The problem was related to using the SFML library, and I could not solve it even after a few days of debugging, so I gave up. I considered migrating to SDL, but it would have been much of a hassle.

Summary


All in all the component-entity system worked out really well in my engine. My codebase is well organized, related code is contained in small, well-separated units. Adding a new feature usually means creating a new .cpp and .h file and requires very little change in existing code. Extending functionality is also easy, since modifications usually affect just one component.

This design also hands itself well for building a base engine with general functionality and creating the specific gameplay in scripts. I have no experience with building a complex engine based on OOP, I can imagine that it would work just as well.

One thing that is not clear is when to group together simple components into more complex ones, or the opposite, when should it be advantageous to cut a complicated component into several smaller ones. I suppose it needs some experience to decide this.

I did not completely throw objects out the window: I still use them as basic building blocks, and they are great for that. But on higher levels there are just entities and components. I think it’s like playing with lego. When you build a house you use the small bricks, but don’t really design it on the level of bricks; you say that the house should have a kitchen, a bedroom, and a garage, and then design those with bricks, and decide how they could fit together to make up a house.

Sunday, 25 August 2013

And remember, respect is everything

After almost a year finally a new article. I wasn't idling, but on the one hand I had lots of other things to do (changed job, moved to a new country, made many new friends and discovered new activities like wall climbing), on the other hand I could not make significant progress on any of my projects, so there was nothing to write about.

I did not abandon the platformer engine, now and then I was tinkering with it. I have implemented the audio component, so game entities can have sound effects and music can be played in the background; I have added support for joysticks; and migrated to SFML 2.1 from 1.6, which was not trivial due to api changes, but was not hard either.

After a while there was not much work to do on the engine, it was time to start creating artwork - I could not postpone it any longer. So I designed a character, painted the required body parts, scanned and processed them with Gimp, tried to make a simple walk animation, and failed miserably. It just couldn't get it look good. The main reason is that the animation system I designed did not turn out as good as I expected. Without a skeleton it was hard to keep body proportions and find the correct positions and orientations of the parts. So I designed another animation system based on a skeleton, but could not find motivation to actually implement it.

Slowly the decision reaped in me that I should change to a game which does not require much animation, and then I decided I would try my hand at a GTA style game. Not the modern 3d GTAs, but the oldschool GTA 1 and 2 with top-down view. I researched my possibilities for physics and graphics, and finally decided to modify the platformer engine to be suitable for this game style instead of implementing a new engine from scratch. I went into a three day coding spree, and in the end I had the car and pedestrian physics, pseudo 3d buildings and very basic gameplay implemented.

The physics is based on this nice Box2D car example which I reimplemented in C++. It uses a body for the car, and a number of steered and/or driven wheels. The wheels can be placed anywhere on the body, so many different vehicles are possible: cars with front, rear or all-four-driving, motorbikes with 2 or 3 wheels, trucks and limos with 6 wheels. So I did not have to reinvent the wheel.

The game logic and physics are 2d, but buildings are drawn in 3d, which gives a sense of depth; just like in the original games. Vehicles and buildings do not need animation, but I’ll have to implement it for humans. I plan an animation system based on separately drawn frames (like in The Silliness of the Lambs), nothing complicated (like my attempts for the platformer).

The gameplay should be full with action, gunfights, speeding, blood, gore, explosion, all that is fun. Maybe I’ll add RPGish features as well. But I don’t promise anything, I have many other things to do in The Outside, and I also want to experiment with some other ideas… so eventually something will happen to it.
 




Monday, 17 September 2012

Platformer - a bit more like a game

There were quite lot of improvements made in my engine, the most important is that I have implemented the animation system, working as described in a previous article. Most of the code was already written for the animation editor, so I 'just' had to port it to C++ from Java, and make the rendering work with OpenGL.

A small change that turned out to be quite important was that I have exposed some keyboard handling functions to Lua, so now it is possible to handle key events from scripts. It is important because it makes it possible (and easy) to add new gameplay features from scripts, without modifying the engine. The wizard should throw a fireball? Just add some lines to the keyboard event handling logic in the Lua script, which creates a new entity, sets up its physical properties (size, position, speed) and appearance (add an image to it), and done, there flies the fireball! As the engine becomes more and more complete, the more code will be written in Lua, and less in C++.

Now that the scripting part of the engine is capable of so much, I have added some mainly eye-candy features besides the projectiles: the camera follows the projectile and zooms on it; the camera target can be switched now, it follows either the wizard or the dog, but it could be any entity in the game; and the last new feature is shaking the camera after falling from great heights.


I have been using Bitbucket as an online backup for my projects for a while, and recently I have started to use it's issue tracker too, which is great. It helps me collect the tasks I plan to make in the engine, so when I decide to do some work, I just take a look at the issues, and I can easily decide what should be the next step. I don't have to remember all the possible improvements, and more importantly I don't forget my good ideas.

Another awesome thing is that I tried to compile the engine on Linux, and after collecting the necessary libraries and setting up the build environment, the code compiled without any warnings, and it runs fine on Linux too. I developed the whole engine with platform independence in mind, but I was glad anyway to see it compile and run without any problems on Linux too, especially since it depends on several libraries.

The engine will soon have enough features implemented to be sufficient for a simple game, so after some minor improvements my plan is to create some real artwork and a level, and make a short demo version of the game I have in my mind. Though it might be delayed a bit, because I am changing my job (even moving to another country), and I think it will keep me busy for a while.


Monday, 11 June 2012

Platformer - it's starting to look like a game

In the last two months I was busy with lots of other things, but this weekend I had time to work on my game. It was surprisingly easy to continue the development after the break, I think this signs that the code quality is not that bad. Due to the entity-component system the code-base is well separated into largely independent units (components/subsystems), so it's not hard to understand.

The new features:
  • smooth camera system, the camera can follow the movement of any entity
  • improved scripting, more and more can be done from scrips
  • graphics layers, by using perspective projection instead of orthographic
  • lots of small things under the hood which enhance the engine, but are not directly visible

I have examined the Unity and Unreal3 engines and development environments, on the first hand to see if I should use them instead of building my own engine, and on the other hand to see how real, commercial, successful engines work. I decided to continue with my own engine, and my goal is to have a single engine that can be used for different games simply by using different scripts.

The usual screenshot and video (please note that the graphics art is completely placeholder, I just drew the images in a few minutes; the game I am planning will have a completely different style):




The next step in my plan is to implement animation, then handling physical events, and meanwhile generally improve the engine. Then, when the engine is good enough, I will start building a real game with it.

BTW I have realized I love platformer games. I really enjoy jumping, shooting or solving problems in Trine 1 and 2, Limbo, Braid, American McGee's Alice and Alice: Madness Returns... I have even played Prince of Persia (the good old one, not the new version) in DOSBox. I think I will have to invest into buying Rayman: Origins too, it looks quite good. Actually I took the fancy to continue developing my game while playing Braid and Limbo... somehow I felt I shouldn't just play games, I should create them if I can.

Another thing I have realized is that how convenient it is to play games with a gamepad compared to controlling with the keyboard. It's much better leaning back in my chair or couch, resting my hands holding the controller in my laps, instead of leaning over the keyboard on my desk. So I will aim for supporting gamepads in my games.

Saturday, 7 April 2012

A basic platformer

I have started to work on the 2d platformer game I mentioned in the previous article. As the first step I am developing the engine. It is in C++, using Box2D for physics, SFML for window handling, input and audio, OpenGL for rendering (currently just old style OpenGL, later I plan to use shaders), and Lua for scripting. Box2D, OpenGL and the C++ glue code will do the heavy lifting, while the game logic and events will be scripted in Lua.

I use my own entity-component framework which is based on this article to organize the 'things' in the game. This is my first experiment with an EC system, so far it seems to work really well. It is quite different from object oriented design, it modified the way I think about structuring the code.

Building a basic platformer with Box2D is not really hard. I chose boxes as the physical representation of entities. It might not be too accurate, but I think it will be sufficient for the game I plan. But later I can extend it anyway. Platforms that do not move have a static Box2D body, other things that should be able to move and react to forces have a dynamic body.

As a platformer game, jumping has an important role in gameplay. The player should be able to jump, also enemies, but only when there is something they can jump from, that is, they are standing on something. My first approach to detect if an entity can jump was to check the forces effecting the body, and if the y component is greater than zero, then there is surely something pushing the body upwards and jumping should be allowed. I implemented this method, at first seemed to work, but then I noticed that when the player was standing on another dynamic body then sometimes it could not jump. After some examination it turned out that when two dynamic bodies are resting on each other then the value of y component varies inconsistently (at least as far as I can tell...), so this is not a good method.

My next idea was to attach sensors to the lower parts of the bodies, and use them to detect if there is something under the body. Sensors are like ghost bodies, they go through other bodies (they do not generate collisions), but they detect if they are touching something. I implemented this method too, and it works like a charm. So from now on every living thing in the game will have a thin 'foot sensor' to decide whether it can jump.

The 'living things' (the player, enemies...) have 0.0 friction to move easily, and fixed rotation because that's how they should behave in a platformer :) To move a body I just set it's velocity (e.g. v.y=30 to jump, v.x=20 to move right), and Box2D will take care of everything. Here is an image showing the simple sandbox environment I used for testing. It has 2 static platforms, 3 dynamic boxes and the player.


A picture is worth a thousand words, but since this is a game a video might be worth a thousand pictures, so here is a short one:


There is much work to do... implementing animation, particle systems, sound effects, camera... lot's of tangential stuff like menu system, starting a game, loading, saving... then programming the gameplay, creating content. So I will not be bored :)

Saturday, 3 March 2012

My experiments with 2d animation

Recently I was playing with the thought to start developing a new game, now that the previous one is finished. One of my ideas is a 2d sidescroller platformer game, similar to the 2d mode of Alice: Madness Returns, with some inspirations from Trine. After considering different options I decided that I would develop my own game engine (I like programming, so that would be the funniest part anyway:), that would use Box2D for physics, Lua for scripting and OpenGL with shaders for rendering.

While planning the game I was thinking much about animation. For The Silliness of the Lambs I have done some basic animations, but they are quite ugly, and creating them was a bit tedious. I realized that drawing animations frame by frame is not my slice of bread, so I was looking for other ways to do it. I wanted something like drawing parts of a character (like body, head, arms, legs), and then putting them together in different poses to form an animation.

Since skeletal animation is the most used method for 3d animations, as a first attempt I designed a 2d skeletal animation system. In this system every character would have:
  • a skeleton: a hierarchical set of bones, defining the main structure of the character
  • a 'skin': a set of images; each bone would have an image
  • poses: a pose would define the position of each bone related to their parents
  • animations: a sequence of poses and the interpolation times between them would form an animation
The advantages of this system would be naturally looking animations, and that the skeleton could be used for ragdoll effects. Existing tools could also be used for this, the animations could be created in a 3d editor, and an engine like Ogre could play them. But I don't have much experience with 3d editors, and I thought that Ogre would be overkill for a simple 2d game, so on paper I designed an animation program that I could use to edit skeletons, skins, poses and animations. After that I realized that I did not really want to implement a such complex program just to create animations, and that this whole system was too complicated.

So I started to think about a simpler method, and I realized that a skeleton is not really needed for an animation, so I designed a new system without a skeleton. In this system the basic structure is the 'animation'; different animations for a character are not related. An animation consists of a set of parts (images), several frames, and the interpolation times between the frames. A frame defines a transformation (translation, rotation and scale) for each image, and these transformations are interpolated between frames (by the way I have learned that interpolating angles is not just that simple...).

This new system does not have the advantages of the previous one, but it was much more appealing for me, so I implemented a simple editor for it. I used Java , because that's what I like to use to create programs with GUIs.

Adding the first part

The left area is for handling the parts. Parts can be added, deleted, named and put in order (the order is important when drawing the animation, it defines the drawing order). The upper panel is the palette. Parts can be selected from the list on the left, and the desired operation on them can be performed with the mouse.

Some more parts, named, ordered, moved and rotated

The area below the drawing canvas is for handling frames (adding, removing them, and setting the duration between them). The transformation operations on the parts always modify the current frame.

Adding and editing frames

The most exciting part of the GUI is the Play button, if it is clicked, a new window is opened which plays the animation. I have recorded a short video of the animation of the wizard that you can see in the pictures:


Yeah, it's quite simple, not really naturally looking, but much easier to create than drawing each frame manually, and easier to use than the skeletal version.

Hopefully one day you will see a game featuring animation created with this program :)

Sunday, 8 January 2012

The Silliness of the Lambs released!

I have finished The Silliness of the Lambs and released it for completely free. It is available for download from the Android Market:


It features 20 levels, sound effects, and all good things that accumulated during the 4-5 months of development. Do not hesitate to try it :) All feedback is welcome.

I used the following software to develop this game:
  • Eclipse IDE + Android SDK for coding
  • Inkscape, Gimp and IrfanView for graphics
  • Git for version control
  • SheepEditor (my own custom editor) for creating levels

Now I can finally start working on new projects :)