Sunday, January 23, 2011

Moving to A New Blog

I’ve registered a new domain, and I've moved to a new blog.
Future posts will be posted there.

Friday, January 7, 2011

Stardust 1.3 Released!



Stardust project homepage

Finally! Stardust version 1.3 is released!

I've updated all the examples, so they all work perfectly with the new particle handlers.

I'm currently working on the integration of Stardust and Minko, a new 3D engine that will support the Molehill APIs. Paq is working on the integration with Alternativa3D and Away3D, whilch will also support the Molehill APIs. I'm really looking forward to Stardust being used in Molehill-powered applications (especially games, of course), enriching the visual experience with 3D particles!.

Monday, January 3, 2011

Particle Handlers for Stardust 1.3



Stardust project homepage

As a quick notice, Paq has joined the Stardust development team. He'll be working on plugins for Alternativa3D and Away3D, and Japanese localization. Horray!!

I'm currently working on the most important new features of Stardust 1.3, switching from renderers to particle handlers.

Previously, the particle data in Stardust are read and visually presented by the Renderer class, whose particlesAdded, particlesRemoved, and render methods take in ParticleCollection objects as parameters, and traverse them to retrieve particle data, resulting in almost twice the processing overhead for particle traversal.

I've found this extra traversal effort quite unnecessary. Since a complete traversal of the internal particle collection of each emitter is already done in each emitter step, so why not "embed" the rendering process into the emitter step? This is how I came up with the idea for particle handlers.

The skeleton of the ParticleHandler class looks like this:


The stepBegin method is invoked at the beginning of each emitter step.
The stepEnd method is invoked at the end of each emitter step.
The particlesAdded method is invoked when a new particle is added to the emitter.
The particlesRemoved method is invoked when a dead particle is removed from the emitter.
The readParticle method is invoked when a particle is fully updated by all actions.

You may override these methods to create your own handlers. The concept is quite similar to that of the renderers, only that particle handlers do not require extra (and unnecessary) particle collection traversal. Everything is done in one single traversal.

A particle handler is assigned to an emitter through the Emitter.particleHandler property, which is quite straightforward:


You may find the similarity between the code above and the use of its renderer counterpart:


Not until I finished the ParticleHandler class did I realize how easy it is to implement a polling station as a particle handler, favoring those developers preferring polling over events.

For your information, a polling station is like a passive database. You access the data only when you need to, which is the opposite to an event system. An event system, as most Flash developers are already familiar with, is an active database, "pushing" data to you whenever there is new data available.

Some framework is designed to better work with polling stations rather than event systems. Thus, I've written a PollingStation class that works as a polling station, recording all the relevant particles in each emitter step, and exposing an interface for data polling.

Friday, October 22, 2010

MicroPlanet Game Concepts

Currently I'm training in the School of Political Warfare, since I've passed the test for political officers. After two more months of training, I'll be working in the army as a political officer, hopefully having a much better and easier life than other ordinary soldiers.

In case you don't follow me on Twitter, I'm accepted into DigiPen's Bachelor of Science in Game Design program. This means I'm going to learn some real hard-core game development skills from the professionals after I get out of the army. I think I shouldn't waste my time on the boring and hollow training classes in the School of Political Warfare, so I've been constantly sketching game concepts in classes.

Recently, I've come up with this game concept, called MicroPlanet. The story takes place on a galaxy of microscopic planets, where there are bunny-like fungus creatures trying to expand their territory and fighting against opposing tribes.

Here's the first concept art I've drawn.
(Click on the image for larger view)


Basically, it's a 2D real-time strategy game. The player can only control the creatures, making them gather resources and building stuff, in order to expand the colony and destroy opposing tribes. The creatures cannot directly attack those from the opposing tribes, and vice versa. They can only build weapons, such as tanks and missile silos, to destroy enemy structures. Each tribe has a main building that produces new fungus creatures. When this building is destroyed, the game is over.

Below are some concept arts for the main menu screen. The smaller two on the bottom are two different designs for the main menu options.

Here are some quick sketches for various units, resources, and buildings.

And below are some more sketches. So far I've come up with three different types of resources: thermo energy, water, and metal. Thermo energy core are like miniature suns floating in the air; the Thermo Absorber is a ring-like structure that absorbers the thermo energy radiating from the core. On micro planets, water appears as floating blobs; the Water Station gathers water resource from below using an erect pipe.

There are two types of planets: solid planets and gas planets. There are some planet-specific buildings and resources, which I'm still working on.

On the top left you can see a quick concept sketch of the in-game screen, where a minimap is present and the character is selected.

That's it for MicroPlanet concept so far. I'll go as far as I can when I'm in the army, and I'll try get directly down to some coding when I'm home. Or at least I could do some CG concept arts.

Saturday, August 7, 2010

My One-Year Compulsory Military Service

I'm about to fulfill my compulsory military service tomorrow (August 9), and it ends in mid-July 2011. During my service, I can only have web access perhaps every one or two weeks, or even longer. So the updates and fixes to my projects will become far less frequent than normal. You may still email me if you've got any problems with the projects. I don't guarantee a quick response, but I'll reply as soon as possible.

I've applied for the "Bachelor of Science in Game Design (Fall 2011)" program in DigiPen. The result will come out several weeks later. I hope I could make it :)

P.S. I've shaved my head for the army, and it takes only 10 seconds to dry it after shower!

Sunday, August 1, 2010

Using MVC Pattern in Rusher



Rusher project homepage

Rusher is now version 0.6 Beta. One of the most important changes is the extraction of entity-related code from the Engine class into the EntityManager class. So instead of writing things like:

you write:

I've also added a new MVC Pattern example. Actually, it was one of my experiments to try implementing the MVC Patern in Rusher. This one turned out nice, so I've committed it to the repository. This example is simply a proof of concept, and I might find out other better approaches to using the MVC Pattern in Rusher.

View example demo
View example source

This example is a very simple painter application, consisted of a color chooser, a clear button, and a bitmap canvas where you can draw with your cursor.

The entire application is represented by the Context class, which extends the Entity class. There are four components added to this entity: Signaller, Model, View, and Controller.

Context


The Context class is pretty simple. It creates four components and adds it to itself. Another important modification to Rusher in version 0.6 is the one-clock-cycle-delayed invocation to the Component.onAdd() method. In this way, the order in which the components are added to the entity does not affect whether accessing other components in a component's onAdd() method yields a null value.


Signaller


The Signaller component is pretty much a "signal hub" consisted of several CJSignals signal objects. These signal objects dispatch application events listened by other components. Also, other components can cause these signal objects to dispatch events.


Model


The Model component contains the underlying application data, a BitmapData object representing the canvas. Also, this component defines several public methods that modifies the bitmap data. These methods allow users to change the line color, move the drawing pen position, draw a line, and clear the entire canvas.


View


The View component constructs and displays the visual representation of the application. In addition, this component listens for the mouse event dispatched by these display objects and relays these events to the signal objects in the Signaller component.


Controller


The Controller component listens the signal objects in the Signaller component and maps them to command objects. These command objects invokes the public methods provided by the Model class to modify the underlying bitmap data.


Finally, below are the command classes.

This is the LineColor command that changes the line color.


This is the MoveTo command that moves the position of the drawing pen.


This is the LineTo command that draws a line.


And this is the Clear command that clears the entire bitmap data.


You may view the source of this example in its entirety here.

Wednesday, July 7, 2010

Performance-Improving Techniques Employed in CJSignals



CJSignals project homepage

CJSignals is an observer framework I released a couple of days ago, based on Robert Penner's AS3 Signals.

For some performance comparison of the native event system, CJSignals, and AS3 Signals, you may check out my previous post. Here I'm going to describe the performance-improving techniques employed in CJSignals.

This technique can also be employed elsewhere when massive objects are added and removed from an array very rapidly, where the array must be sorted and performance is vital. Rusher also uses this technique to manage prioritized active components.

Listener Array


For each listener functions added, a corresponding ListenerData object is created and stored in the internal array, which contains a reference to the listener, a boolean variable indicating whether the listener is a one-time listener, and an integer variable for keeping track of the index of the ListenerData object in the array. Also, a mapping relation between the listener and the ListenerData object is added to an internal dictionary for fast lookup.

Adding Listeners


CJSignals keeps track of the index of the first empty cell of the listener array with an integer variable, i.e. keeping track of the first null element. When a new listener is added, its corresponding ListenerData object is inserted to the array cell corresponding to the index, and then the index is incremented by 1. If the array is full, then its size is doubled. This approach assigns elements directly to an array cell by index, instead of invoking Array.push() every time a new listener is added.

Removing Listeners


Listeners can be removed from the array very efficiently. When a listener is removed from a signal, the listener dictionary is used to quickly retrieve the listener's corresponding ListenerData object. From the ListenerData object, the index of the object in the array can then be obtained (A). The index of the first empty cell is decremented by 1, thus pointing to the last non-null element (B). Cell A's content is replaced by cell B's, and cell B's content is replaced with a null value, so the first-null-element index is now keeping track of the new first null element.

Priority Sorting


Adding and removing listeners sets a listener-array-dirty flag to true, indicating the necessity to sort the listener array according to the listener priorities. The sorting is not necessary until the next signal dispatch or retrieval of the internal listener array through the public getter method get listeners(), the flag set back to false afterwards. Thus, multiple calls to the Signal.add() and Signals.remove() methods do not cause the array to be re-sorted; it is deferred to the point when the sorting is really necessary. After the array is sorted, the ListenerData objects are informed of and updated with their new indices.

I guess the native event system sorts the array every time a new listener is added, resulting in the huge performance difference between the system and CJSignals.

One good thing about the Array.sort() method is that it always pushes null elements to the tail of the array, so it's okay to keep a sparse array, as long as the index of the first null element is kept track of.