Delta Engine Blog

All about multiplatform and game development

How to compose entities - Build a smiley out of Ellipse2D components

This is a small tutorial article from our wiki on how to create entities via our new system, more to come soon:

This article walks you through the steps of creating a custom entity with child entities using the Ellipse2D class. Everything you see here can also be done with the Editor by just dragging components and entity templates into your entity. The Smiley entity can be reused and be combined with any other component as well (rotate, scale, outline, physics, etc.)

The Ellipse2D class combines the following components (the same will be added if you drag in an Ellipse in the Editor):

  • Ellipse2DComponent for the ellipse x and y radius
  • Polygon2DComponent for the polygon points
  • As well as Vector2D for the position, Size (automatically calculated from the points) and Color
  • Many other components can be attached via the properties available in the Entity2D base class (Rotation, Scale, Outline, Pivot, etc.) or just by attaching more components like Image, GradientColor, Rotate, Velocity, Gravity, etc.

Let's build a new entity based on just that entity. Let's start with a unit test like in the other Tutorials:

1:
2:
3:
4:
5:
6:
[Test]
public void BuildSmileyEntity()
{
       
var smileyYellow = new Color(1.0f, 0.9f, 0.2f);
       
var smiley = new Ellipse2D(Vector2D.Zero, 0.25f, smileyYellow);
}

which produces just a yellow circle:

Next we should add 2 ellipses for the eyes and connect them to the parent circle:

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
[Test]
public void BuildSmileyEntity()
{
       
var smileyYellow = new Color(1.0f, 0.9f, 0.2f);
       
var smiley = new Ellipse2D(Vector2D.Zero, 0.25f, smileyYellow);
       
var leftEye = new Ellipse2D(new Vector2D(-0.05f, 0.1f), 0.02f, 0.04f, Color.Black);
       
var rightEye = new Ellipse2D(new Vector2D(0.05f, 0.1f), 0.02f, 0.04f, Color.Black);
        leftEye
.AddParent(smiley.Entity);
        rightEye
.AddParent(smiley.Entity);
}

For the mouth a simple ellipse is not going to cut it, but we can use a trick and just render 2 ellipses with the second smaller one overwriting the first one with yellow again, leaving just the mouth part in black. We should also render the eyes next. Keep in mind that doing this kind of fine-tuning is much easier with the Editor and should not be done in code, we just want to illustrate how things work here.

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
[Test]
public void BuildSmileyEntity()
{
       
var smileyYellow = new Color(1.0f, 0.9f, 0.2f);
       
var smiley = new Ellipse2D(Vector2D.Zero, 0.25f, smileyYellow);
       
var mouth = new Ellipse2D(new Vector2D(0, -0.0225f), 0.18f, 0.165f, Color.Black);
        mouth
.AddParent(smiley.Entity);
       
var mouthOverlay = new Ellipse2D(new Vector2D(0, 0), 0.185f, 0.165f, Color.White);
        mouthOverlay
.AddParent(smiley.Entity);
       
var leftEye = new Ellipse2D(new Vector2D(-0.05f, 0.1f), 0.02f, 0.04f, Color.Black);
        leftEye
.AddParent(smiley.Entity);
       
var rightEye = new Ellipse2D(new Vector2D(0.05f, 0.1f), 0.02f, 0.04f, Color.Black);
        rightEye
.AddParent(smiley.Entity);
}

 

and we are done. Now we are free to use that entity as many times as we want. Lets put it in a method and use it as a template for many more smileys rotating and scaling around on the screen. Keep in mind we do not want to change the Smiley template entity parameters programmatically, just define it once and then change whatever you want in the derived entities based on the template.

Also notice we added a Rotate component and TapGesture trigger with a ChangeColorAction (to Orange) when clicking on a smiley. Each entity created from the template will get all these features as well and any future improvements also.

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:

21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:

34:
35:
36:
37:
38:
[Test]
public void BuildSmileyEntity()
{
       
CreateSmiley();
}

private static Ellipse2D CreateSmiley()
{
       
var smileyYellow = new Color(1.0f, 0.9f, 0.2f);
       
var smiley = new Ellipse2D(Vector2D.Zero, 0.25f, smileyYellow);
       
var mouth = new Ellipse2D(new Vector2D(0, -0.0225f), 0.18f, 0.165f, Color.Black);
        mouth
.AddParent(smiley.Entity);
       
var mouthOverlay = new Ellipse2D(new Vector2D(0, 0), 0.185f, 0.165f, Color.White);
        mouthOverlay
.AddParent(smiley.Entity);
       
var leftEye = new Ellipse2D(new Vector2D(-0.05f, 0.1f), 0.02f, 0.04f, Color.Black);
        leftEye
.AddParent(smiley.Entity);
       
var rightEye = new Ellipse2D(new Vector2D(0.05f, 0.1f), 0.02f, 0.04f, Color.Black);
        rightEye
.AddParent(smiley.Entity);
        smiley
.Entity.AddComponent(new Rotate());
       
Scene.Current.AttachCommand(smiley.Entity, new TapGesture(),
          new ChangeColorAction());
       
return smiley;
}

[Test]
public void CreateManyRotatingAndScalingSmileys()
{
       
var smileyTemplate = CreateSmiley().ConvertToTemplate();
       
var random = Resolve<Randomizer>();
       
var allSmileys = new List<Polygon2D>();
       
for (int num = 0; num < 50; num++)
       
{
               
var smiley = new Polygon2D(smileyTemplate);
                smiley
.Position = new Vector2D(random.Get(-0.45f, 0.45f),
                   random.Get(-0.3f, 0.3f));
                smiley
.Scale = new Scale(random.Get(0.05f, 0.15f));
                smiley
.Rotation = random.Get(0, 360);
                allSmileys
.Add(smiley);
       
}
}

Game Development Tool Essentials book is out

Based on the book article Kirsten and me wrote 2 years ago a new book is out. Nice to see my name on a book cover again :)

The book has 220 pages and just 13 chapters and is a bit expensive at the moment. I suggest to wait until the price drops, the ebook is at least a bit cheaper.

Source code can be found in the DeltaEngine/Samples/Labyrinth directory when the next release is is out or on the book download page. The sample game will be available on the StarterKits page as well.

Entity Component System in Delta Engine v1.2

After finishing one internal project and now working on the next project (non-game) we found some common problems with content and entities in v1.0 and v1.1, especially when things change over time and the data is not longer compatible (happened mostly in UI controls). Instead of trying to patch things over and over again we redesigned the content system earlier this month to be more data driven. Thanks to that we had some ideas to improve entities as well to be more data driven. Most simple entities have really good performance in the Delta Engine and were highly optimized for the use cases we had (Sprites, Lines, 3D models, LogoApp), but once you start adding more logic, things got slow quickly. Obviously in each case we could optimize it again, but code is not getting prettier and doing it on the build service side is too much work for our now much smaller team.

So instead I experimented around a bit over Easter Holiday and came up with a cleaner Entity System for Delta Engine v1.2 than what we had before. In v1.1 entities can have update behaviors, draw behaviors, components, lerpable render data, any other type of data and have update and draw methods build in so you can derive from them and build things in an OOP way. All the functionality for component data driven design was in there, but only used when it made a solution easier. This added a lot of complexity on the build service side were we basically take all these approaches and make normal component data driven entities out of them again (tons of code gets generated). I ignored the complaining of the platform team and now that I have worked on this myself last month and got it finally working, I have to agree, things kind of got crazy. One of the problems with v1.0 and v1.1 was to support JavaScript and C++ for Android code generation for any kind of entity. Since we allowed so much, things easily got out of hand and something was always not working. Because we had no prior experience to this, we just said this is a big problem and there seems to be no easier solution (probably still true).

Starting with v1.2 entity is just an empty sealed class, you cannot derive it or do any OOP, it just has some optional tags to find things later if needed and some entities can have children (like Buttons nested in a Panel). You can also add components to describe what an entity is about, they are not stored in the entity and can even be reused by multiple entities. Examples are Position2D, Color, Material, Rotation, PhysicsBody, Trigger, Action, etc. Entities can also be just templates, which means no logic or rendering is executed for them, but the data is all there to create new alive instances from it. And you can turn a entity invisible, which turns off the attached renderers while keeping their components and render data alive. That is pretty much it, all of it is data driven, which means we can easily safe it in the editor, there is no functionality in any of the entities or components, it is all just data (in fact we enforce it, if you put anything but public fields in components, the system will detect it and throw an exception).

To make things simple in code as well plus support old v1.1 code as well as we can, an EntityCreator class is available. Obviously not having Update or Draw methods or OOP in entities is going to break all kinds of things inside the engine and some of the games utilizing this. For example Line2D, Sprite or Model are not longer entities, but derive from EntityCreator, which internally just creates a entity and adds all the required components. This way the code stays mostly compatible, is easy to use for newbies not knowing or wanting to use or extend entities, but you are totally free to create your own entities and customize it as much as you want. This is pretty much the only way to create anything in the Delta Engine anyway (as opposed to other engines where you have a huge list of existing classes you can use that do not use the same system as you). Unreal Engine 4 Blueprint system is also an inspiration on what could be done, but we do not plan to do anything as complex and complete, we still like writing code in C#, much faster that way (both in writing and execution speed).

Here are two quick pictures I drew in the last 2 hours while explaining the new system. Maybe next time we should record it so users can benefit from our training as well :)

First whiteboard image is just a bunch of ideas from during the week (going into a more data driven "MVC" way, was changed back to "Systems" and "Renderers" for clarity later):

The next whiteboard image is about the new entity component system in all its glory with data locality explained, components and examples plus how the editor works:

If you want to know more and read additional articles about entity systems check out our wiki page on this topic.

To be a Creative Coder

Are you interested in programming and doing it in funny, creative ways? Would you like to learn coding or improve your skills? Would you like to make this passion your profession? 

Here it is a brand new initiative, called CreativeCoder. CreativeCoder is a training program for creating professional programmers through professional experience. The participants will be able to train themselves in a real working environment and to learn stuff by doing!

Delta Engine is part of this program too!

Do you want more info?

Just click on this link and take a look around!

Pump up the noise!

Can you hear it? Was that the sound of a far away explosion?

What could have caused it? Maybe it was a Fire Tower attacking a Cloth Creep... or an Impact one slamming on Iron?

Since the release is approaching, it is finally time for Creepy Towers to start being noisy! We are working together with Reflex Studio, a professional music and sound composing studio with quite some experience!

Reflex Studio is on the professional market for almost fifteen years and counts more than 60 successful projects under its belt.

Given this fact, Creepy Towers will be even more awesome than expected!

Creepy Towers Game Jam

Next week, third Delta Engine Game Jam is scheduled. However, we decided to make it a little different and more special: it will be a jam entirely devoted to Creepy Towers. For this reason, it will be a simple internal affair, closed to visitors, entirely devoted to boost our tower defense game development!

 

Here at the offices, we are pretty excited and are already making the first preparations for the event. Small teams will have to show how good they are both to compete and cooperate for a final, common goal!

 However, some fun moment might happen some now and then, like, for example, a few challanes at soccer-table!

 

Creepy Towers keeps on growing

Silently, just like an obscure unseen menace, Creepy Towers project keeps on growing.

If you are new and ask what is Creepy Towers, I can tell you that it is a 3D Tower Defense game currently under development at Delta Engine. Just like the engine itself, CT is an open source project and will be updated on regular basis. Given its nature, this game will take into careful account every suggestion and proposal made by players, so be sure to be a fan from the very beginning! Like the FaceBook page now!

I almost forgot: Creepy Towers will be released for all the platforms supported by Delta Engine and, thanks to Cloud savings, it will be possible to play it and use your data on any device you own.

 Are you wondering how it might look like? Well, this is just a sneak peek of a level... but enjoy it!