Archive for the ‘Testing’ tag

Brain Melt

I’ve been writing and re-writing a lot of code lately. Somewhere between the work to be done and the work I want to see done, there are dozens of thoughts and discoveries that are worth sharing. Some are puzzling, others are simply brain melting.

Behaviors

A long time goal: behaviors! What is it? How does it work? Well… imagine you write this line of code in a Bold Pixel Engine entity:

1
entity.behaviors.face.mouse();

And from that moment on, the entity will always rotate to the mouse position. That’s a behavior.

Imagine that you could say that instead of facing you’d want it to rotate to the mouse position at a given speed, or with a tween, or that you want it to evade another entity or to find the path to a certain point. Now imagine that behaviors could applied to time… that you could tell your engine time would slow down so you could see all in slow motion…

Well… I wrote two behaviors and it works like a charm!

Flash Player is somewhat smart

I’ve noticed that if you copyPixels() or draw() outside the target bitmapData area, it won’t render anything. Having thousands of objects outside the rectangle area is absolutely meaningless, even if you apply a transformation matrix and draw.

I thought about the possibility of creating a camera object… suddenly this possibility became obviously closer since there will be no need to verify if an object is supposed to be rendered, Flash Player does that for me, I just have to pass the right rectangle… awesome! or at least I’m thinking it will be!

Filters

I really needed a rest a couple of nights ago… so nothing better than writing some new functionalities! My goal was to write filters to apply in layers. After noticing that most flash filters need a BlurFilter applied on top of it, I decided to make it simple and just work with one BlurFilter and one ColorTransform in each layer.

BlurFilter is a huge performance killer, so I played around with only applying the filter to whatever the area the filter needed to be applied to and it works great! The bigger the area, the bigger the performance impact that’s for sure!

ColorTransform seems to have no impact. I’m betting that the pixel color is calculated directly when drawing… if this is true… it’s quite smart!

All in all and since I didn’t want to use any other filters for performance issues, I noticed that with just a little tiny bit of patience, blur and color transform can do most of the cute effects we might need, from shadows to glows to motion blur.

Brain melting the possibilities

A camera with behaviors, like moving to an area with tweening. Flames coming out of a structure and then exploding in thousands of particles flying around with fire trails. Zillions of projectiles flying around in a huge map… wow… this weekend really caused a brain melt.

Need to finish the tutorials to Bold Pixel Engine v1 because v2 is already shaping.

Posted: February 16th, 2010
at 1:00pm by Vlad

Tagged with , , , , ,


Categories: The code of VGS

Comments: 2 comments


A small fighting AI test

Although me and finite state machines are good friends for sometime, implementing a more in-depth artificial inteligence algorithm is something I’ve been looking forward to test for some time. I did manage to take sometime to do some learning and testing and I’d like to share the results with you.

What you see below is a simple FSM ruling the behavior of two fighters. Each fighter selects one of six attacks randomly, moves into position, attacks and steps back. If the fighter is attacked before starting his own attack, it has a 50% chance of dodging and then proceed to attack. If hit, after being in slight pain, it steps back. Everytime it steps back, a new attack is chosen.

The discussion I had with myself is if it would make sense to make a round based combat disguised to create the illusion of real time combat or a real time combat directly. Funny enough, I found it easier to make it real time directly.

More can be done in terms of complexity layering, but as a learning experience done with just some hours, I’m more than happy, so see you all later! Vlad is out!

p.s.: oh and cheer Marco for this character! It’s a long time favorite of ours, waiting for the right opportunity to pop up into the web! :)

The Flash plugin is required to view this object.

Posted: January 25th, 2010
at 12:33am by Vlad

Tagged with , , ,


Categories: The code of VGS

Comments: 3 comments


Handling local high-scoring

Hi folks, Vlad here.

We just tackled a code problem that is as complicated in nature as simple in resolution.

Problem

To have a high-scoring table that works not only on websites, but also localy, in our case, while ran from a DVD. The second issue is that we need a custom high score table, not the standard one size fits all ’showboard()’ solution that most APIs offer.

Original approach

Our first thought was to communicate directly with a web service using AMFPHP. This works indeed, but the user must allow the local Flash Player to access outside content. We didn’t like this… on one hand, security warnings and the software asking to confirm security stuff scares the common user, on the other hand many of the players of these games are kids, so this would be a pain!

Further investigation

But we know that there are a lot of APIs that allow a lot of off-site communication, even localy! There are security protocols that Flash Player enforces, so how are they dealt with? If someone else has done it, it is possible…

The answer is: the APIs communicate with a swf that lies in the same server where data communication is handled. The APIs connection methods are in most part the download of that specific swf and it is the swf that holds all the ‘inteligence’, does making the whole process more troublesome, but more secure…

Solution

We investigated this because of a thread I created at FGL’s forums. I explained what we needed and the answer was: try Mochi’s APIs. Which we did, easily. Mochi’s API does exactly that: it connects to the webserver where it downloads a swf that holds all the methods to communicate with their databases, so there’s no security issue here. As long as there is a internet connection, it will work.

Code

And here is the code to handle the custom table. I’m not including the standard stuff, like connecting or sending scores, that’s pretty straight forward. The only weird and somewhat confusing and somewhat oddly documented feature is the request for high scoring data from Mochi’s servers.

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
private function getScores(e:MouseEvent)
{
	MochiScores.requestList(this, "onScoresReceived");
}
 
public function onScoresReceived (args:Object)
{
	if (args.scores != null)
	{
		nameTable.text = ""; // Textfield for names
		scoreTable.text = ""; // Textfield for scores
 
		var newScores:Object = MochiScores.scoresArrayToObjects(args.scores);
 
		for (var index = 0; index < 10; index++)
		{
			nameTable.text += newScores.alltime[index].name + "\n";
			scoreTable.text += newScores.alltime[index].score + "\n";
		}
	}
	else
	{
		if (args.error)
		{
			trace("Error: " + args.errorCode);
		}
	}
}

Hope this helps! See you all soon!

Posted: January 16th, 2010
at 11:16am by Vlad

Tagged with ,


Categories: The code of VGS

Comments: 3 comments


More testing on Actionscript’s Math class

As you may have noticed I’m somewhat critical regarding the AS3 Math class. I’m a bit sick to be honest and work was flowing as I wanted to so I took 30 minutes off to test some stuff.

Flooring a number

Getting the nearest low integer of a number is usually achieved with Math.floor(number). If we didn’t have it, we would probably typecast the number to an integer and get the same result. So I looped both methods one million times and measured the results.

Math.floor(number) performed around 150 milliseconds
int(number) performed around 5 miliseconds

Now the bad news is that this works for positive numbers, using int(number) for negative signed numbers doesn’t produce a floored integer. For example int(-2.4) returns -2 where it should return -3.

Rounding a number

Rounding a number will return the closest integer of that number. Again this is usually achieved with Math.round(number) but we can also do this:

One million iterations after the results are as follow:

Math.round(number) took around 165 milliseconds
int(number + 0.5) took around 5 miliseconds

Same issue applies regarding negative signed numbers though, so keep that in mind, but the question is…

Are you feeling the urge of writing a new Math class?

This way we could deal with both performance and doing some arrangements to make negatives work correctly. Problem with this is that we will be calling a static method from an external class. A full working rounding method called one million times took 180 milliseconds against the 165 milliseconds from Math.round(number) method, so there’s loss instead of gain.

Bottom line is that this kind of stuff is a bit like using multiplications over divisions. Depends on a lot of stuff. If your display objects move on a positive x and y axis, you can do it like there’s not tomorrow, just typecast to integer whatever you need to round, but all in all, unless you have millions of Math class operations to do, you won’t even notice the difference.

See you soon,
Vlad

Posted: August 9th, 2009
at 12:00am by Vlad

Tagged with , ,


Categories: The code of VGS

Comments: No comments


The “make it fast” demo

Yesterday I wrote about making code work then nice then fast. I believe that the fast part was not that obvious on how it can impact your overall game performance. So I decided to put up a simple test that is a demonstration of a real world example.

We will be dealing with two of the finest cpu-cycle hogs in the Actionscript world and you can pretty much apply it to every thing game development related.

The main code

I defined this as the document class of some flash file and then started to add methods to test. Each method was a variation of the previous. At each test I simply added the function call to the constructor. Simple and fast, here’s the first method…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package
{
    import flash.display.MovieClip;
    import flash.geom.Point;
    import flash.utils.getTimer;
 
    public class PerfTest extends MovieClip
    {
        public function PerfTest()
        {
            // The start time
            var startTime:int = getTimer();
 
            // Test method call goes here
 
            // Traces the test results
            trace("Test concluded in " + String(getTimer() - startTime) + " miliseconds");
        }
    }
}

Calculating a distance: 1750ms

The basic test is to calculate the distance between two points. I simply wrote every single detail of code I needed inside a 1 million iteration ‘for’ loop. I created new points, calculated the right triangle legs and then the hypotenuse. Every thing should be crystal clear. One million distances calculated got an average time of around 1750 miliseconds.

1
2
3
4
5
6
7
8
9
10
11
12
13
private function DistanceTest1()
{
    for (var test:int = 1; test <= 1000000; test++)
    {
        var point1:Point = new Point(100, 100);
        var point2:Point = new Point(200, 200);
 
        var leg1Length:Number = Math.pow(point1.x - point2.x, 2);
        var leg2Length:Number = Math.pow(point1.y - point2.y, 2);
 
        var distance:Number = Math.sqrt(leg1Length + leg2Length);
    }
}

Skipping object creation: 505ms

This is one of the biggest issues, one that is often a problem. I’ve read about it, I’ve even defended that object pooling is not that important in many games and then once my code created around 200 objects in less than a second I had to rethink it. Add to that that the objects created had things to do on their own, like moving, colliding and sorts and I got myself a bit of a performance issue.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private function DistanceTest2()
{
    var point1:Point = new Point(); // Created outside the loop
    var point2:Point = new Point(); // Created outside the loop
 
    for (var test:int = 1; test <= 1000000; test++)
    {
        point1.x = point1.y = 100; // Reused object
        point2.x = point2.y = 200; // Reused object
 
        var leg1Length:Number = Math.pow(point1.x - point2.x, 2);
        var leg2Length:Number = Math.pow(point1.y - point2.y, 2);
 
        var distance:Number = Math.sqrt(leg1Length + leg2Length);
    }
}

The only thing done is here to take the creation of new objects from the loop. Note that I’m not reusing Numbers because the impact is on the creation of an object with the ‘new’ operator.

Other ways to do math: 180ms

The result is the same but the time taken to do it isn’t. Math.pow(x,y) and other methods from the Math static class are very heavy. There are times where it is too troublesome not to use it, but if you can avoid it, do so.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private function DistanceTest3()
{
    var point1:Point = new Point();
    var point2:Point = new Point();
 
    for (var test:int = 1; test <= 1000000; test++)
    {
        point1.x = point1.y = 100;
        point2.x = point2.y = 200;
 
        // Math.pow(x,y) substituted with a simple multiplication
        var leg1Length:Number = (point1.x - point2.x) * (point1.x - point2.x);
        var leg2Length:Number = (point1.y - point2.y) * (point1.y - point2.y);
 
        var distance:Number = Math.sqrt(leg1Length + leg2Length);
    }
}

One last math optimiztion: 20ms

Calculating square roots is heavy stuff, really heavy stuff. This is not the exact same case as the one pointed previously, but it is very similar. The main difference here is that if you are returning the distance, that is not the correct distance at all. It is the distance powered by two. If you want to use this distance to check against something, you’ll need to power that something also to keep it fast.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private function DistanceTest4()
{
    var point1:Point = new Point();
    var point2:Point = new Point();
 
    for (var test:int = 1; test <= 1000000; test++)
    {
        point1.x = point1.y = 100;
        point2.x = point2.y = 200;
 
        var leg1Length:Number = (point1.x - point2.x) * (point1.x - point2.x);
        var leg2Length:Number = (point1.y - point2.y) * (point1.y - point2.y);
 
        // No square root is calculated, you need to take this into consideration
        var distance:Number = leg1Length + leg2Length;
    }
}

Conclusions

I tried to address some common performance downfalls that happen very easily but that can be dealt with very easily also. We can argue that this is over one million iterations, but if you are using this kind of code for collision detection, that amount of iterations can happen sooner than you’d expect.

The real problem with performance in game development is not at all a matter of having millions of operations in one spot of your game loop like it is demonstrated here, but having several minor performance issues all around your code that is called from the game loop.

This is just a demo of the kind of things you should look for and solve. There are many others, some of it very game specific. When your game is working as intended, when the design is implemented, it’s time to make it fast because the game should be as smooth as possible and because you’ll probably and hopefully polish the game. That polishing often adds something to the game and that something needs breathing room to work out well.

Hope this helps,
Vlad

Posted: August 5th, 2009
at 12:00am by Vlad

Tagged with ,


Categories: The code of VGS

Comments: 5 comments