Delta Engine Blog

All about multiplatform and game development

Running Unit Tests Visually and confirming via Screenshots

We keep our engine and internal projects 100% covered with unit tests, almost all of it is reachable from NCrunch (95%+), which we use continuously to make sure we do not break anything when doing changes (which we do every day, even when working on other projects). Anyway, this only covers the logical rules and whatever we wrote in the unit tests. We used functional testing in the past and constantly tested our samples and tests manually to see if things still work as they should, but after reaching several thousand tests over the years and a much smaller team now, we don't have time to constantly test rendering functionality or sample games. Almost all of the sample games had to be removed because we just did not have the time to constantly adjust them and test them. We probably also had way too many, so we reduced it to the bare minimum plus the current project we are working on.

To help out testing the frameworks, graphics and rendering features we used approval tests in the past, which is accomplished by simply adding an extra attribute to visual tests (any test can be visual in our engine as long as the test class derives from TestWithMocksOrVisually). In the past we also integrated this into our nightly builds in TeamCity, but we had constantly problems with NUnit crashing or the whole TeamCity process freezing up after hundreds of tests (many minutes later), which was impossible to reproduce locally, thus we disabled this 2 years ago :(

Now with our new Editor Viewport technology, which works similar to how Unity3D loads and unloads .NET code (we just do it from inside our engine, not like Unity3D from native code and with some super old mono runtime), I could finally reactivate approval tests on TeamCity and this is what it looks like (pretty proud of myself, does not look like much, but this took a long time to get working):

  • Currently tests about 150 visual tests
  • Runs each of them to the 0.4s time (which is done in less than 20ms for each in reality)
  • Makes a screenshot (1280x720, takes up most time together with comparing it, around 50ms)
  • Compares it to be almost pixel perfect with the approved screenshot (either from before or what we specify)
  • 0.1% difference is allowed (not all frameworks render things the same way pixel perfectly)
  • Repeats this for all of our now 12 frameworks to make sure it looks correct on all support platforms (more on that in a later post)

Early Alpha of Towers with Hand Gestures and Voice Recognition

We are currently implementing support for Intel's RealSense SDK, which works similar to Microsoft Kinect, but is more suitable for PCs and has a ton of cool features like Voice Recognition, Speech Synthesizing, Hand Gestures, Face Detection, and a ton of other Augmented Reality stuff.

In our early build of Towers not much works get as we focused on cleaning up our code base from previous projects and improving the Editor to visually assemble entities (like for Towers, so players can build their own levels). Anyway, Hand Gestures and Voice Recognition works already and is pretty fun. Using Mouse/Touch/GamePad/Keyboard/etc. is of course still an option ^^

Keep in mind these screenshots contain visual bugs and the alpha is not yet done, earliest beta release is February 2015. More updates about the Editor and the Towers game are coming in 2015. Have nice holidays and a happy new year.



Delta Engine Editor exhibited at the Prototypenparty

Yesterday, the Delta Engine participated as a "prototyper" in an event called Prototypenparty (engl. "Prototype Party"). It is meant as an opportunity to let product developers test their creation by a variety of people of different backgrounds.















You can either attend as "prototyper" showcasing your product, or as a "feedbacker" who tries the stuff out and gives criticism. The Delta Engine, among 5 other prototypers, exhibited the editor to the ~ 40 feedbackers. 



By the way, the Prototypenparty itself is also a prototype, since it was hold for the first time. :) . Besides other software prototypes, service-, furniture- and product-prototypes where shown.



At the end of the evening, every feedbacker voted for his/her two favorite prototypes. The winner´s prize was a whole lot of bottles of this prototype beer, brewed by a "Kreativbrauerei" (= creative brewery) from Hamburg: 


(Photo taken from the Prototypenparty Facebook Page)


Sadly, we were not the winner :( . Nonetheless, we are happy about the interest we received. A warm "Thank you" to all feedbackers who took the time to try out the editor, talk to us and stated us their opinion. The next blog entry will show some more cool editor stuff. Stay tuned! :)


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);
       
}
}

New Editor in Delta Engine


A few weeks ago we started boosting development of the Editor again and we are now catching up to expose new DeltaEngine features. Since the new content and entity systems have been built with the goal to enable easy editing via the Editor, we now see the new design coming together.
The properties of Templates and Entities can be changed via a few clicks and adding new content is as easy as a drag and drop.
The ContentManager of the Editor enables to see scenes and their nested content of other public projects and simply preview them so you can see how we did it or later even re-use some content in your projects. The sole purpose of the Editor is to make developing your games much easier and straight forward.
We are looking forward to see how you will use it and hear your feedback after the next release.