Full LibGDX Game Tutorial – Entities using Ashley(ECS)

Ashley ECS

Sharing is caring!

Full LibGDX Game Tutorial – Entities using Ashley the ECS

Welcome to part 10 of our Full LibGDX Game Tutorial. This part will focus on improving our current system by using Ashley an Entity Component System. If you haven’t seen the earlier parts of this tutorial I advise you to start at Full LibGDX Game Tutorial – Project setup as this tutorial continues from these earlier parts. For those of you who have come from part 9, you can continue on.

We currently have a system in place that allows us to start loading our assets, which then goes to a menu and from there we can start the game. The game so far allows us to control a player character to some extent. This current system is hard coded and makes it difficult to update with new features and new mechanics. This is where the Entity Component System (ECS) comes in handy. The ECS will allow us to break our game model down into sections that can be easier to maintain and modify. Our model will be broken down into Engine, Systems, Entities and Components. How are we going to do this? you ask. Well, we’re going to use Ashley the ECS  designed to run with Libgdx. The Ashley wiki contains more information on the ECS than this guide will go into available here.

Ashley

As mentioned earlier Ashley breaks the model down into Engine, System, Entities and Components. The Engine is the controller that will run they systems we define. It will also control the creating and destroying of systems, entities and components. In games we have different sections that require logic such as rendering images, physics, collisions etc, this is where the Systems comes in. We will use a system for each area of logic. So we will have a Rendering system which solely focuses on rendering textures. Next, we have components. Components are simple classes which store data such as an image or the position of our player and finally, we have our Entities. The Entities will be a collection of components used to define an in-game object.

For example, we have a player entity which has 2 components: ImageComponent(stores an image) and PositionComponent(stores the player position). Next, we have a RenderSystem which takes any entity that has an ImageComponent and a PositionComponent and then renders it. We tell our engine to make the entities and tell the engine that it needs to run the render system. Now When our engine runs any entity created that has an ImageComponent and a Position Component will be drawn. We can then create another entity this time an enemy with an ImageComponent and PositionComponent and it will automatically be added to the render system and rendered. We can then add new components for animations, AI, collisions and add their respective systems until we have all our game logic defined.

Adding Ashley to our project

To add Ashley to our project we are going to update our build.gradle file for our box2dtut project. In our main project box2dtut, scroll down to the build.gradle file and open it. Update the repositories to match this code:

Next, add the Ashley compile code for each platform as shown below:

Refresh Gradle Dependancies to add Ashley
Refresh Gradle Dependancies to add Ashley to our project

Refresh the grade dependencies for each project to make sure that Ashley has been added. Ashley should now be added and you can continue to add the code.

Creating A Component

The first thing we’re going to do now we have Ashley ion our project is to define our Components. Components are classes used solely for storing information for a specific set of data. Our first component will be for storing our positional data. So let’s make that now.

That’s it.  A simple class that implements the Ashley Component interface and a few values. Cool, now let’s add a component for a texture:

Yay, another easy one….Well, they’re all easy as these are only for holding bits of data for our entities. Here are all the other Components we will be using:

That’s all the Components currently needed in our game.

Systems

Let’s move on to doing a system which will be used to render our entities. Our system will loop through all entities that have the TransformComponent and TextureComponent and then use the data in these components to draw the texture in the correct location.

This code was adapted from code created by Barry @ https://github.com/RoaringCatGames to fit into this tutorial. I have added comments on all the parts I think may need explanation. Basically, this system will get all Entities that have a TextureComponent and a TransformComponent then loops through each one and draw it to the screen using the SpriteBatch.

In order for this system to work, we need to create the ZComparator system which is:

Now onto all the other systems used:

I’m sure a lot of you are thinking about how much code I just spurted out just now. But be assured this code is laying a foundation for us so we don’t have to write as much code later and our code is nicely organised into specific areas which allow us to add/remove/update new features later with minimal hassle.

Adding the Engine

Now we have all the components and systems in place we can make a start on removing the model and adding our Engine in our MainScreen. Since we are no longer using the model we need to add all the necessary parts used in the model to our main screen. this includes things like the sounds, atlas and the box2d world. Update your MainScreen constructor to match the following:

Here you can see we moved all the required items to our MainScreen and added some new stuff. The first new item we added was the RenderingSystem. This is the RenderingSystem we just added at the start of this chapter. Next, we created a PooledEngine. This is supplied by the Ashley system and the Pooled version reuses objects instead of creating new ones reducing lag from Garbage Collection. Then we continue to add all our other systems we made and finally we create some objects in our world, a player and some platforms. The code for these objects is in the next section.

Adding Entities

We got components, systems and engines, but no entities. Let’s fix that now by adding them. As you seen were adding them using these 3 methods; createPlayer(), createPlatform(x,y) and createFloor(); The createPlayer() method below shows how we add a player entity:

Here we first use the engine to create and empty Entity. We then use the Engine to create all the components that make up the player entity. We then create all the data that fills up the components such as image, position and box2d body. Next, we add the components to the Player Entity and finally add the player Entity to the engine.

The createPlatform(x,y) and createFloor() are pretty much the same as above but they require less components. Code below:

There’s one more thing to do before our game will work and that is to update our Box2dContactListener to update Entities when they contact other items. The new updated Contact Listener is:

Here you can see we got rid of all the bloat and now only need to update the entity collisionComponent when something is hit.

Before we can run this code we need to update our MainScreen’s render method to make the engine run.

 

You should now be able to run the project and control the player and make it jump on the platforms.

As usual, the code for this part can be downloaded from StorMyVids here.

In the next part we will add infinite level generation using simplex noise.

← Scene2D Contents Simplex Noise Level Gen →

 

Sharing is caring!

23 Replies to “Full LibGDX Game Tutorial – Entities using Ashley(ECS)”

  1. Don’t you need to add Pool.poolable interface to your components class? if not, info on ashley’s wiki is wrong though.

    1. Yes, you are correct. If you need to destroy Ashley entities and then recreate them you will end up with entities with properties carried over. Later in this tutorial series, we will go over this issue and fix it.

      1. Thanks for quick reply. Tutorials are really helpful. Piece by piece, fits together.

  2. Caterpillar says: Reply

    Can’t get Ashley into my IdeaJ

    1. Do you get an error message of some sort or is it unable to find the Ashley classes?

      1. Caterpillar says: Reply

        I am not sure but I think I wrote some stuff in the wrong gradle file. I restarted this time and just included Ashley and Box2Dlighting and everything it offers instead of trying to import things.

  3. The only mystery that remains is “cmTrans” in “ZComparator”. Where is it? It’s not in the scope.

    1. Ah that seems to be a typo in the code. The transformM in that section should be cmTrans. I have updated the guide.

  4. I think you missed the following in your MainScreen.render() method:

    Gdx.gl.glClearColor(0f, 0f, 0f, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    engine.update(delta);

    1. Yes, you are correct. I have added it to the guide.

  5. Hi,
    when i try to add Ashley to my Project and updating my build.gradle, i do rightclick on the project -> gradle -> refresh gradle project, then i get the following error:

    FAILURE: Build failed with an exception.

    * Where:
    Build file ‘…\core\build.gradle’ line: 60

    * What went wrong:
    A problem occurred evaluating project ‘:core’.
    > Cannot change dependencies of configuration ‘:android:natives’ after it has been resolved.

    Can you help me again?

  6. Another Question: how can i import your source code into my eclipse? i tried several times with different approaches but with no success

  7. Quick question, why not use a IntervalIteratingSystem for PhysicsSystem… it looks like that’s exactly what you’re reimplementing.
    A system that updates at a certain interval…

    Or (and this is in all honestly, not trying to sound like a dick :P) has this tutorial been written before Interval systems were added to ashley?

    1. Honestly, I didn’t know it existed. The task was simple enough that I didn’t need to look for a premade solution. In retrospect adding it would of made the tutorial a bit more complete.

  8. Hello,
    Thank your tutorials which are all very great. But I’m lost at this one. I like to understand every letters of the code, and right now, even after read the code several times I can’t understand all. Do you have any advice to understand everything ? (external links, or other)

    1. Some of The tutorial sites I used to learn Libgdx are:
      https://www.gamefromscratch.com/page/LibGDX-Tutorial-series.aspx
      https://github.com/libgdx/libgdx/wiki
      https://www.redblobgames.com/
      If you’re having issues with a particular extension E.g Ashley ECS then browse for their wiki.
      If all else fails you can always use a forum or service like StackOverflow to summon a code jedi.

  9. These are great and I really appreciate them. This one, however, was like when you’re doing a drawing tutorial:

    Step one: Draw a circle
    Me: Got it, feeling good
    Step two: Draw the rest of the dragon
    I understand the overall concept but the details only about a quarter.

    1. Hello Jesse – I found that reading the Ashley Wiki and understanding the CES architecture helped me out. Not sure if that will help you, but I feel this step in the series is a big leap, but still very useful content to be placed within it. If you spend more time understanding the concepts first (Component Entity Systems), then the Ashley System (this is basically the same as CES) and writing out every component listed above, you will grasp it much more firmly.

      Hope it helps – Cheers!

    2. Honestly, I would be completely LOST If I hadn’t read Ashley’s wiki and this article first: https://www.gamedev.net/articles/programming/general-and-gameplay-programming/understanding-component-entity-systems-r3013/

      I highly recommend spending more time understanding the core concepts of ECS before continuing the tutorial.

  10. What is the advantage of using the update method in IteratingSystem? Should we use it or just do everything in the processEntity method?

  11. hey John – Thanks for this write-up. I’ve been following along and gotten stuck.

    I was able to get the game to a running state with all the code from this Step in the series, but I couldn’t get my keyboard inputs to read or react on the player properly. While debugging, I could clearly see that the keyboard controller is not null and linked to my PlayerComponent. I thought it was the Gdx.setInputProcessor, but this is set accordingly in my show() and I’ve actually also included it in my resume (not that it made a difference). What do you think it could be?

    Any help is appreciated – Thanks in advance!

    1. ACtually I don’t know if keyboard controller is linked to my PlayerComponent.

      I am passing the KeyboardController created within my MainScreen into the PlayerControlSystem, but it doesn’t seem to pick up any of my keypresses when i check using printlns.

    2. I figured it out. I didn’t add the entity to my engine. fml.
      I’ve been looking at the screen for too long.

      Thanks.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.