Enhancing by refactoring

Two years ago I read a lot about OOP. Every time I picked a new concept in some forum or chat I’d do my best to understand and apply it. I was eager to improve my coding knowledge and skills but everything we code as a purpose and an audience and if we forget the purpose or the audience we are introducing more problems with the knowledge we have than solving problems.

That happened with Bold Pixel. At some point in time Bold Pixel became a monster to please developers instead of a tool to be more productive in my purpose to my audience: create games for players! People play games, not code!

I stopped over-engineering sometime ago and started reading about how to become a better programmer not by writing better code, but by writing the exact code to solve the exact problem. This brought a new problem: what to do with Bold Pixel and how to maintain and evolve it? First thing was to start a new package and only bring in classes that I needed but wire the classes up to be as slim and straight to the point as possible. I do that all the time to build up my code base right now, but that’s not all. Here’s the whole process I’m using right now.

Start simple

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class BlitObject {
    // Position
    public var x:Number = 0;
    public var y:Number = 0;
    // Rendering
    public var visible:Boolean = true;
    public function BlitObject():void {
        // Constructor
    }
    internal function render():void {
        // Render stuff here
    }
}

The class above can be a stub for a simple blit object. From a OOP perspective it breaks encapsulation completely since x, y and visible variables should be private but seriously, do I really need those to be private or protected and have getters and setters? No I don’t so no need to over-engineer it. The only thing I want to have contained is the render method that should only be called by the blit engine that lives in the same package.

The blit object only responsibility is to copyPixels or draw on a given world position translating camera position on the fly.

Writing a simple class like this is fast, performs fast, case closed.

Evaluate new needs

Now I need a tile map class. This class is also a blit object so following the “is a” versus “has a” rule tile map should inherit blit object. Considering the blit engine has a camera, the tile map won’t move. This brings two new problem.

1. If the tile map doesn’t move, why do I have x and y publicly accessible?
2. I want my camera to follow blit objects so blit objects must have x and y variables (or properties). How can I make tile map be recognized as a blit object, have x and y and have none of those altered?

Sounds messy…

I could write a Blittable interface that would define a render function and getter and setter methods for x and y. The problem is that if there’s something I want to keep in the package scope is the render function and interfaces define public interfaces.

The solution is to convert blit object in an abstract class and have its original functionality moved to a new graphic class.

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
39
40
41
42
43
44
45
46
47
48
49
class BlitObject {
    // Rendering
    public var visible:Boolean = true;
    internal function render():void {
        throw new Error("Abstract function called. Override render()!");
    }
    public function get x():Number {
        return NaN;
    }
    public function set x(v:Number):void {
        throw new Error("Abstract function called or property x not available.");
    }
    public function get y():Number {
        return NaN;
    }
    public function set y(v:Number):void {
        throw new Error("Abstract function called or property y not available.");
    }    
}
class Graphic extends BlitObject {
    // Position
    private var _x:Number = 0;
    private var _y:Number = 0;
    override internal function render():void {
        // Render stuff here
    }
    // Position
    override public function get x():Number { return _x }
    override public function set x(v:Number):void { _x = v }
    override public function get y():Number { return _y }
    override public function set y(v:Number):void { _y = v }
}
class TileMap extends BlitObject {
    override internal function render():void {
        // Render the tile map
    }
}

Problem solved. The class responsibilities are much better defined.

1. A blit object renders and has x and y coordinates. Since it is an abstract class everything we try to do with it directly will result in an error.
2. A graphic is a world movable blit object that renders by copyPixel or draw.
3. A tile map is a world static blit object that renders very large objects by copyPixel or draw  based on a predefined xml specification.

Conclusion

What’s the conclusion here? Well for starters by this time I’d have a couple of interfaces and probably a helpers. I’m not saying it is wrong to have interfaces and helpers, actually it is preferable, but it would be coding for the sake of coding instead of coding for the sake of making a game. It took me 10 minutes to do this and while I was at it the BlitObject class also extends a ListObject class that really speed up the iteration, addition and removal of objects from the blit engine.

Still… I did repeat my self and the code has suffered another refactoring since then. I’ll leave that for another post but I wonder if you know what’s repeated… :)

Posted: January 28th, 2012
at 2:00am by Vlad

Tagged with , , , , ,


Categories: Dev Journal: Danger Zone,The code of VGS

Comments: No comments


Application Design vs Game Design Round 1

Hi everyone, Vlad here.

Let me start by saying that the title is a bit misleading. For starters it is not an actual bout but more a decision making process. It also gives the impression I’ll write more about this or that I have some kind of plan about this subject. I don’t, it just happens that I think I’ll travel this road again.

Game Design

The game design for this game states that:

1. The player’s objective is to reach the top of the “structure” (named just to make sense) where the action rolls;
2. The “structure” has several “floors” (again just for easier comprehension);
3. The player can fall to the previous “floor”;
4. It is guaranteed that the player will see at least three “floors”;

Application Design

One thing that I know for sure is that we will be blitting all graphics and that the player token has three different blit objects and two of those rotate thus negating copyPixels and putting the dreadful draw method to work.

Another thing I know is that each “floor” is a tilemap, also blitted and that each tile is 64×64.

And now the assumptions begin. How big is each “floor”? I have no idea but let’s say that a rather large “floor” has 50×50 tiles. If the player will see at least three floors and on later stages all “floors” are rather large we are talking about 7,500 tiles to be rendered with a astonishing number of 30,720,000 pixels to be copied… each frame.

The “floor” where the player is will only render the tiles on screen (88 max) but the other two lower “floors” can potentially be fully rendered given the camera specs. Even if all three “floors” only rendered tiles on screen (which won’t happen by design) there would still be 7,500 objects to manage and that’s tiles only since we need to add to this all the remaining entities: player, enemies, decorations, effects, etc, but to make it worse the bottom two levels will be zoomed and probably in full view which means not only that all their blit objects will be visible but also that at least 5,000 of those objects will use draw instead of copyPixels… Did the headache kicked in already or is it just pure performance insanity?

Implementation

One of the great things about copyPixels is that it only renders the intersection between the target bitmapData rectangle and the source rectangle positioned at the destination point. What this means is that if we have 1,000 objects to render but only one actually has an intersecting rectangle, most of the processing time is running the array, vector or list and – more important and processor heavy – calling the functions that will in the end render.

The draw method also does this with a matrix… more on this later.

The solution was to write a BlitTileMap class that builds the tilemap in one big texture before it is used. While it uses much more RAM this class allows to address pretty much every problem stated earlier.

First and foremost the number of objects managed and therefor the performance lost with running their container (in our case, a linked list) and calling functions. From a potential 7,500+ we now have 3. The other issue that this addresses is the number of pixels it will render or try to render, from potentially 30,000,000+ to the worst case scenario of 1,050,000. And last but not least, considering the lower “floors” will be zoomed out, instead of using draw to render 5,000+ objects it will render… 2!

But the draw method also has a funny and helpful consequence. The smaller the scale, the faster draw executes which in terms of performance is relevant considering the zoom out will be achieved through scale. Less objects taking less time to render will be (I hope) quite a performance boost.

Did I just write all this? Wow!… Later!

Posted: January 25th, 2012
at 12:15am by Vlad

Tagged with , , ,


Categories: Dev Journal: Danger Zone,The code of VGS,The design of VGS

Comments: 1 comment


2012 Update

Hi everyone, Vlad here.

Yeah, I know… long time, no writing. 2011 started great, didn’t finish that well for a lot of reasons, mostly unrelated to Vortix but we are catching up and have some stuff rolling. Here’s a quick update.

As you might have noticed in the last post Marco and Pedro are working on some cool stuff that involves kicking, punching and 3D!

In the meantime I’ve been messing around with some cool stuff too. First and on top of our priorities is a new game that if it is as fun to play as it is challenging to put, should be a great game. I’ll post my thoughts on some of the challenges we will face as we walk the dev path.

But that’s not all… Doing R&D has become almost a hobby of mine. Weird to have a hobby that involves coding when I’m not coding but it’s fun and I admit that I like to maintain codebase and have codebits ready to evolve when needed.

I’ve played around with client-server stuff, dual-screen stuff, multi-platform stuff. Right now multi-platform is my main focus and haXe and NME the weapons of choice. This means that I have a lot of duplicated code but it’s getting pretty!

And this is the quick (or not) update and the promise of more blog posts with less interval.

Posted: January 23rd, 2012
at 8:16pm by Vlad

Tagged with ,


Categories: The life of VGS

Comments: 1 comment


Fighting a 3d Battle!

Hey everyone,

We’re working on a new game using a really cool 3d Engine: Flare3D.

Here are some screenshots of what we have, and I’m not going to tell you what its about, but I can tell you its not a street fighter style game or tekken or virtua fighter.

Enjoy

 

 

Tell us what you think!

 

Cya!

Marco

Posted: January 6th, 2012
at 7:22pm by Marco


Categories: Uncategorized

Comments: 4 comments


Introducing Atomik Kaos 3 Crystals

Hi everyone, Vlad here.

Time for a new game (actually two new games, more on that later August) and this time we follow our cutest franchise: Atomik Kaos! I could tell you much about it but it’s not 100% ready although it should be up for licensing in a couple of days.

Without further delay, here’s a video… by Marco!

Posted: July 22nd, 2011
at 2:44pm by Vlad

Tagged with ,


Categories: Releases

Comments: 2 comments


« Older Entries