I was taking a siesta in my girlfriend's house, and I had this very weird dream. The story of the dream was bizarre yet inspirational. It might serve as a game or movie concept. I thought I should type it down before I forget it.
So here goes my dream.
My girlfriend and I were some sort of secret agents sent by the government to investigate a mafia overload. We managed to get invited to his party held at his mansion, as undercover guests of course. His mansion was located in a small remote village in deep mountains, so it took us hours to drive there.
It was a very dark night. The mansion was extraordinary, like the ones you see in most movies. Most of the guests consisted of mafia members, and so began our investigation throughout the mansion.
Somehow I was noticed by a guard. He gave me a full tap-down and found my concealed gun, so our secret operation was blown. My girlfriend and I were held and watched by guards in a small room, with their boss standing aside planning how to torture and interrogate us. Both of us could simply thought about our hopeless future.
Suddenly, that was when something really wrong went on.
Without any warning, the entire village experienced a complete black-out. We could hear the screaming form the guests from everywhere in the mansion. We could even hear the shrieking voices from the entire village in the mountains, as if they were chased and attacked by some unidentified beings.
Then the lights came back.
The mansion was a mess. Shattered glasses, plates, and furnitures were scattered everywhere. Most of the guests were gone, and the rest were just too terrified to even say a word, with their mind completely left blank, not knowing what exactly to do next. People who managed to get to the garage and tried to drive away from the mansion, from the village, all mysteriously ended up either crashing into obstacles or falling into cliffs, with no survivors.
The mafia boss, my girlfriend and I, and the guards watching us, were the only people left who had remained conscious and were all thinking what to do next. Then we heard the sound.
Like thousands of high-pitched squeaking mice all coming at once, we can feel a swarm of unknown beings approaching extremely fast from outside of the mansion window.
"Quick! Shut the windows!" I yelled.
Two of the guards rushed to the open window and slammed it closed. But they were not fast enough. Some of the creatures leaked into the room. They were huge bats, or at least I thought they were. Those black-winged creatures soared in the room, attacking all the people inside, trying to bite us with their fangs and mauling us with claws.
I told the boss and the guards that this was not the time for making enemies. They should free us immediately so that we could work out a way to survive. And so my girlfriend and I were untied. Each of us picked up what we could find as a weapon in the room.
After a lot of yelling and wielding, all of us managed to kill every single flying creature in the room, shivering and panting.
"So, I think we DO need to cooperate in order to live." said the mafia boss.
It seemed that the the entire village had been wiped out, and we were the only survivors, for we could hear not a single voice from the village outside of the mansion.
"Yeah, I think so." I said.
And so began our escape from the mansion.
This is where my dream ended.
I can still remember us fighting our way through some unearthly and carnivorous creatures in my dream. It was as if those creatures were kind of manifestation of the fear and nightmare of each of us.
This can be some inspiration to a thriller adventure game. I hope more idea could come along.
Saturday, November 27, 2010
I was taking a siesta in my girlfriend's house, and I had this very weird dream. The story of the dream was bizarre yet inspirational. It might serve as a game or movie concept. I thought I should type it down before I forget it.
Friday, October 22, 2010
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)
Saturday, August 7, 2010
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
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:
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:
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 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 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 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
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
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.
For each listener functions added, a corresponding
ListenerDataobject 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
ListenerDataobject in the array. Also, a mapping relation between the listener and the
ListenerDataobject is added to an internal dictionary for fast lookup.
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
ListenerDataobject 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.
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
ListenerDataobject. From the
ListenerDataobject, 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.
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
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
ListenerDataobjects 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.
Sunday, July 4, 2010
CJSignals project homepage
You might be able to tell from the project name that this project is inspired by Robert Penner's AS3 Signals. Yes, this is the case, indeed.
I've studied C# before, and played with Qt in the last semester. I felt the same thing Robert felt about the Event System in C# and the Signals/Slots System in Qt. It makes much more sense to extend an observer framework with composition rather than inheritance, and it makes code cleaner and more comprehensible if an object dispatches events of just one type, which is not the case for the ActionScript 3.0 native event dispatchers, for they can dispatch multiple types of events.
With CJSignals, each type of event corresponds to a
Signal object "owned", a term for composition, by the subject. For instance, you can write code like this.
The parameter types of the listener matches those specified in the signal constructor. For information on the actual usage, you may check out the tutorial wiki page.
I built CJSignals from the ground up, using my own implementation of signals to boost performance, mainly performance concerning listener priority management and listener removal. I used the fast-splicing array technique I mentioned in this post, which is also employed by Rusher for active component priority management. And the priority sorting is only executed upon signal dispatch and if necessary.
Here's a comparison chart of the performance for the native event system, CJSignals, and AS3 Signals. Although CJSignals places second or third in some tests, the actual numerical results do not pose as bottleneck. What is more important is that CJSignals has the best worst-case performance: the worst test result for CJSignals is merely 13ms, whereas that for the native event system is 681ms, and AS3 Signals 5717ms.
Tuesday, June 22, 2010
I've started a new project called Shintaz, also named after one of my character from the same series as Rusher. Shintaz is a scripting engine, consisted of a compiler and a virtual machine. As you may know, the virtual machine behind Flash Player is called ActionScript Virtual Machine (AVM), and the Shintaz Virtual Machine (SVM) is going to be running on AVM. That's right, a VM running on another VM.
Actually, I took a compiler course this semester in order to help me understand how to develop a compiler and a virtual machine. It really helps a lot!
The main purpose of developing Shintaz is to integrate it with Rusher, making Rusher a game engine equipped with a scripting engine capable of compiling and running scripts at run-time. This helps the debugging process and may allow people to do lots of dynamic stuff with the game.
Shintaz's compiler is half-complete, and its virtual machine, SVM, is almost done. SVM is already capable of executing bytecode consisted of opcodes. Same as Java Virtual Machine (JVM), SVM is a stack machine, meaning its memory takes the form of one or more stacks.
Here are some code snippets for generating an opcode array, converting it to Shintaz-compatible bytecode object, and executing the bytecode with SVM.
The following code declares a variable "x", and assigns it a value of 10. Note how the value 10 is first pushed to the memory stack and then popped to be assigned to "x".
There're also some opcodes for program counter jumping and branching. The following code skips the assignment of a value 20 to "x".
The code below does exactly the same thing as the first code snippet, declaring a variable "x" and assigning a value 10 to it, but with high-level scripts.
Function declaration and class declaration are on its way. I'm trying to find more information on these topics, and then I'll start working on it.
Lastly, and one of the most important feature of Shintaz, although still work in progress, is symbol linking. What's a scripting worth if it cannot communicate with other objects and functions outside of the virtual machine? Shintaz provides a way to link symbols in the scripts with other ActionScript objects and functions.
The following code shows how. The trace function is linked to the symbol "print", so any occurrence of the identifier "print" in the script is regarded as a reference to the trace function.
Oh, I almost forgot. I'm also planning on adding serialization and deserialization features to Shintaz, allowing conversion between compiled Bytecode objects and ByteArray objects. In this way, people can save compiled bytecode to files, and later load and execute them during run-time, saving the time of compilation.
That's it. I hope I can finish Shintaz before my presentation for the PTT Flash Workshop this year on July 24.
Monday, June 7, 2010
Stardust project homepage
Paq from WonderFL made a quick performance test with different particle collection types provided by Stardust, and the result turned out to be quite different from my own previous tests. I think the difference is due to the fact that we conducted the tests with different numbers of particles. Hence, it's reasonable to choose which particle collection type to use according to the roughly estimated number of particles that will be present.
For this reason, also as one of the new feature of Stardust version 1.1.161, I've added the
Emitter.particleCollectionType getter/setter to allow users to switch between different particle collection types. Valid types are mapped by integers defined in the
Emitter constructor accepts a second parameter for the integer corresponding to a particle collection type, which is the
ParticleFastArray class by default.
This is how you set the underlying particle collection type of an emitter to a linked list.
And this is how you switch an emitter's particle collection to a different type, say, an array.
There's no specific rule in deciding whether a collection type is the best for your specific particle system. In terms of performance, fast arrays are approximately as good as linked lists. However, if you insist on finding the exact best one, you just have to try them all and then determine which works the best.
Tuesday, May 25, 2010
Stardust project homepage
(example source can be found on the project homepage)
You heard it. Stardust Particle Engine now supports Flare3D, a brand new 3D engine just released a couple of days ago. Awesome!
Flare3D includes a 3DS Max exporter that can export much, much more than just mesh data, such as complex materials (environment map, texture map, etc), animations, and bone animations. For the first example, I exported the star model and gold material entirely in 3DS Max, and the data can be correctly rendered in Flare, without writing a single line of code. The Flare3D team really has the love for 3DS Max users :)
The Flare3D extension for Stardust mainly consists of three initializers,
Flare3DSprite3D, and two renderers,
Flare3DPivot3DClone initializers work pretty much like the original
DisplayObjectClass initializer, only that they assign
Pivot3D objects from Flare3D to the
Particle.target property, and they have to be used along with the
Flare3DPivot3DRenderer. The first initializer creates new
Pivot3D objects from a reference to a
Pivot3D subclass, while the second initializer creates
Pivot3D objects by cloning an existing one. The
Flare3DSprite3D initializer creates 3D sprites and has to be used with the
I hope you enjoy playing Stardust with Flare3D :)
Friday, May 21, 2010
Stardust project homepage
The initial release of Stardust Particle Engine version 1.1 is now available (yep, no more betas). The major difference of the current revision from the previous one is the use of fast-splicing arrays (I made up this name, because I don't know if there's a formal or correct name for it).
Before Stardust employs linked-lists as default internal particle collections, ordinary arrays are used. Arrays are known to be fast to traverse and sort; however, arrays are also notoriously known to be ultra-slow when it comes to splicing large arrays. This is why I switched to linked-lists, which can perform much faster splicing operations by simple node-link manipulation.
I've come back to arrays and use a new method to perform splicing, and this turns the tables again. Now Stardust uses fast-splicing arrays as internal particle collections.
So, what are fast-splicing arrays anyway? Well, they're are no different from ordinary arrays except that they perform splicing quite differently. As any programmer familiar with ordinary array splicing knows, ordinary splicing first creates a new array of the size one-cell-smaller than the original one, and then copies the original elements, except for the spliced out one, into the new array. This is very CPU-consuming when dealing with large arrays, since a new large array is created every time a large array is to be spliced, not to mention the fact that rapid splicing is a fundamental nature of particle engines.
The figure below illustrates the splicing process for ordinary arrays.
Fast-splicing arrays do the job differently. Each of them always keeps the last cell empty, to allow iterators to tell whether they have reached the "tail" of the array, and it double its size when the last empty cell is to be used. Also, each array keeps track of the index of the last occupied cell. When a particle is to be removed from a cell, the last particle is then moved to the now-empty cell, and then the index indicator is decremented, i.e. moved left. No new arrays are ever created for splicing.
The order of the array has been disrupted you say? As long as no mutual action is in place, the order of the array is of no significance. Even if mutual actions are involved, requiring the particles to be sorted according to their x-coordinates, the emitter sorts the array automatically before further processing in this case, so the order is still not problem.
This splicing approach is even faster than linked-list splicing, since it only involves two assignment operations and one integer decrement operation, as opposed to four assignment operations for linked-lists (or maybe more...argh, you do the math).
Moreover, arrays are faster for adding particles, because they simply assign references to their cells, and, on the other hand, linked-lists have to create new nodes to hold references to particles added and subsequent nodes.
I think I don't have to say anything more about the sorting operations. Arrays are the fastest, 'nuff said.
Here's a table that compares the performance of particle adding, traversal, splicing, and sorting operations for different particle containers. I believe that you can clearly understand why I prefer fast-splicing arrays over linked-lists.
Wednesday, May 19, 2010
Monica WINS by ~cjcat2266 on deviantART
Play Monica: Nightmare
It's been too long since I got the third place in the Creative Game Design Contest held by Gamer. Today the finally sent me the certificate for the award. I felt like drawing Monica being excited about the certificate, so here it is :p
Tuesday, May 11, 2010
ZedBox project homepage
I'm happily informed by Milkmidi from Medialand that Mark Vann, also from Medialand, has built a Heineken website using ZedBox, my 2.5D billboard engine.
I've never imagined I could use ZedBox to create such stunning visual experience with massive cans of Heineken beer, although at some points the website does consume a lot of CPU resource. I think the performance could be improved by caching, or pre-rendering, the bitmaps, accounting for their different rotation angles, instead of changing their rotations directly at run-time. Anyway, Mark's definitely done a pretty darn good job on this one.
Nice job, Mark. And thanks a lot for supporting ZedBox :)
I've seen a lot of most-wanted-Flash-features articles. So I decided that I might as well write one :p
Full GPU Rendering Support
Currently, Flash Player 10.1 only supports hardware acceleration for the full-screen feature and video playback. I've always wanted to see Flash Player being capable of rendering all the display objects with full GPU acceleration. It'll be a huge boost on the performance. I believe lots of people out there also want this feature very badly.
ActionScript is the only one among the object-oriented languages I use that does not support function overloading. This can sometimes lead to frustrating experiences while designing frameworks. Sometimes I just want to provide functions with different sets of parameters that do the same job; however, due to Flash's lack of support for function overloading, I have no choice but to use lots of optional wild-card-typed parameters and depend on their types to perform differently in a single function.
Complete Generics Support
Vector class supports generics. However, I'm talking about COMPLETE generics support. That is, developers are able to write classes with whatever class templates they want, instead of only playing with the little
Vector class provided by Adobe.
It is so tempting to write classes with generics. Just imagine if you could write a following generic class:
There'll be no more type casting issues, and the following code is definitely legal.
Data Container Framework
What naturally comes after the generics support shall be a data container framework like that in Java. I hope Adobe can provide a set of containers of basic data structures, such as linked lists, stacks, hash maps, hash sets, etc. Currently the
Dictionary class acts like a object-to-object hash map, and is not strongly typed, which requires lots of casting being done. With a generic data container framework, we are able to write code like this:
And it's guaranteed to be type-safe, so you don't have to cast the evaluated value of
I like the Java container framework very much, especially the support for iterators. Iterators make traversing abstract containers even extremely easy and intuitive. I hope Adobe do consider adding a container framework seriously. I know there are already some neat container frameworks out there, like as3ds, but it's always nice to have official support, isn't it?
That's all I've got for now. I'm sure I'll come up with more wanted Flash features.
Friday, May 7, 2010
This is a sequel to my previous tutorial, Thinking in Commands part 1 and part 2.
This time I talked about how to encapsulate external data loading functionalities into commands, so that they can be arranged together with other commands. Also, I've introduced the
DataManager class, which essentially acts like a global variable aggregator. However, as Rich pointed out in the comment. This class is not type-safe, thus requiring type casting through the entire application. Actually, I also think this could be a problem for large applications. When I was writing the class, I was thinking of the
Proxy class from PureMVC. The class also acts like a global variable aggregator that is not type-safe, since this is how you obtain a reference to a custom proxy object.
Not type-safe as it is, it actually served me quite well in most applications. But yet I agree with Rich that it's not friendly in large applications. Unfortunately, this is the best solution I can come up with right now. I'll see if I can conceive something better in handling data.
Saturday, May 1, 2010
Yup, I'm currently working on a scripting engine, named Shintaz, which is the name of another character in Rusher's series. You can check out the complete character lineup here.
The motivation is twofold: first, it is my term project for the compiler course I'm taking this semester; second, my ultimate purpose is to integrate this scripting engine with Rusher Game Framework, so that you may open a console, like those where you can enter cheat codes in many Valve games, and enter scripts. This is mostly for testing and debugging purposes.
The project SVN is already opened on Google Code. Here's the source folder and the documentation. I use the ASUnit framework for unit testing Shintaz. You can check out the testing project here.
The scripting engine is still a work in progress. So far, I've finished the scanner. There's still a long way to go, with the parser and virtual machine to be finished.
Here I'll show some code snippets for the scanner.
This is how a scanner is initialized. The parameter passed to the constructor is a string of script, or code.
Tokens of the code can be obtained by repeatedly calling the
IScanner.getToken() method until the method returns null. Each token is consisted of a token type, an integer value, and a token value, whose data type depends of the token type. Here's what a piece of actual scanner code would look like.
Token.toString() method is overridden to show both the token type and token value. This is what will be displayed on the output panel.
That's it. This is my current progress on Shintaz. I'll begin to work on the parser as soon as I can. Hopefully, the entire engine can be completed by the end of this month.
Sunday, April 18, 2010
Run Rusher Run by ~cjcat2266 on deviantART
This is Rusher, the character Rusher Game Engine is named after. I haven't been drawing him for a very long while, and I felt like trying to draw him in a different style. So here it is, run Rusher run!
Monday, March 29, 2010
View part 1 of 2
View part 2 of 2
As I developed the Command Utility for Rusher Game Framework, I have come up with this idea of spreading the love for Command Pattern :p
I've already delivered three presentations on this topic, and written a two-part tutorial for ActiveTuts+. In the tutorial I've briefly covered the Command Pattern and showed how to build a minimalistic command framework, which is kind of a lite version of the Command Utility in Rusher. Also, you can find in this tutorial about how to further make use of this command framework to create a scene management framework, which is also a lite version of one of Rusher's features, the State Machine.
The concept of commands would really simplify things out when working on huge projects. If you've got problems dealing with large applications, such as messing up with complicated code that is hard to maintain, just go check out the tutorial. It's gonna help you a lot. I promise :)
Tuesday, March 23, 2010
Play Monica: Nightmare
View all entries
That's right. Monica: Nightmare got the third place in the Creative Game Design Contest held by Gamer. I'm pretty glad that the first game created by Rusher Game Framework could make it this far. Being involved in this contest was the main driving force for me on the development of Rusher. Had it not been for this contest, I think Rusher would have been still a mere idea in my mind by now.
However, I've still got several things to complain about. The graphics and music aspects make up 20% of the total score, and yet the runner-up still got 85 out of 100? I'm not unable to afford to lose. There are reasons why I'm saying this. Come on, the drawing skill is obviously...primitive, consisted of line segments and simple geometric shapes, let alone the fact that the framerate is 12FPS (that's eye-killing, really). And the music is nowhere near original, its background music for the menu scene is from Star Wars; how could Gamer not notice that? After all, use of proprietary assets is prohibited in this contest! I've sent Gamer a mail, requesting that they reveal the score every entry has got on each aspect. I hope they take this seriously; otherwise, just showing the final total score is far from convincing.
Alright, enough with the complaining. At least Monica: Nightmare gets the third place and is being displayed in the first row. This means Rusher is going to get more exposure, which is my ultimate purpose :)
Monday, March 8, 2010
Play Monica: Nightmare
Finally! My first game built with Rusher Game Framework! Escape from Monica's nightmare as fast as you can!
Monica: Nightmare is a 2D side-scroller evasive action game. You're right, no fancy attack moves. Just run! This is an entry to the Creative Game Design Contest held by Gamer. The theme of the contest is "Escape", hence the absence of attack moves. I tried to make the opening and ending look like it is SOME console game :p
I used Box2D for collision handling. The game flow control is heavily making use of the Scene Manager (now State Machine) feature of Rusher.
You can press the "+ (plus sign)" key to toggle the console panel to view debugging messages, and press the "- (minus sign)" key to toggle the Box2D debug view.
It's still quite buggy, I know. I had been working very hard to eliminate all the bugs, but the deadline did not allow me to do so. I slept at 6 in the morning on the due date and woke up at 8:30 to mail the disk to Gamer. I apologize if the bugs bother you during the gameplay.
Next time I'm gonna use all of my game-related frameworks: Rusher, Stardust, and ZedBox!
Friday, March 5, 2010
I've written another Stardust tutorial on ActiveTuts+. This time it's about how to create 3D particle effects with Stardust's native 3D engine and Papervision3D.
To combine Stardust with different 3D engines, all you need to do is use a different engine-specific renderer and initializer for particle appearance. It's well explained in the tutorial. So what are you waiting for? Just go check it out!
Thursday, February 25, 2010
I showed one of my classmates the Command Utility for Rusher Game Framework. He gave me a quick thought about conditional commands, which execute different commands depending of different conditions. I thought the idea was great, so when I turned on my laptop I directly rushed into creating conditional commands for Rusher.
Below are the conditional commands that are now available in Rusher, which is now version 0.5 Alpha.
The If command executes a "true subcommand" if the return value of the test function is true, otherwise the alternative "false subcommand" is executed. Additional parameters for the test function can be passed as an array.
The While command repeatedly executes a subcommand until the test function returns false.
Pretty much like the While command, the DoWhile command repeatedly executes a subcommand until the test function returns false, except that for the first time the subcommand is always executed regardless of the test function.
The For command is consisted of two subcommands: the "initCommand" is executed first, then the "loopCommand" is executed repeatedly until the test function returns false.
The Switch command contains a index function, which returns an integer, and an array of subcommands. It executes the subcommand in the array corresponding to the index returned by the index function.
The Repeat command repeatedly executes a subcommand for a specified number of times. This command basically does not count as a conditional command, but it certainly is equally useful.
Tuesday, February 23, 2010
The scene manager for Rusher Game Framework is now complete. It makes use of Rusher's Command Utility to achieve scene transitions, i.e. intro and outro.
One engine core contains one scene manager, which is accessed from the Engine.sceneManager property. The SceneManager.setScene() method sets the current scene for the engine core. The scene transition is handled by the Scene.introCommand and Scene.outroCommand properties. When the engine core is switching from scene A to scene B, the outro command of scene A is executed, the intro command of scene B is executed, and then finally the scene transition is complete. This scene transition command structure was inspired by Progression Framework.
Here are some code snippets for the scene transition. You can view the final result here. Click the black square and watch the scene manager do its work.
The document class is quite simple. It starts up the engine core and sets the scene to a HomeScene object.
And below is the code for the HomeScene class. It extends the Scene class and assigns two command objects to the introCommand and outroCommand properties. The _block property simply holds a reference to a Sprite with a square appearance.
The intro command makes the block fade in from zero alpha and a random position to another random position, while the outro command fades out the block to zero alpha and another random position.
The AddChild command adds the block to the container sprite. The TweenNanoFrom command is making use of the from() method of the TweenNano class from GreenSock Tweening Platform. The Trace, SetProperties, AddEventListener, RemoveEventListener commands do what their name suggest: tracing messages, setting properties, adding event listeners, and removing event listeners, respectively.
When the block is clicked, the scene tells the SceneManager to switch to another scene, in this case, still another HomeScene instance.
There are more commands integrated with GreenSock Tweening Platform not shown in this example: TweenLiteFrom, TweenLiteTo, TweenMaxFrom, and TweenMaxTo. I believe their names tell you everything about what they do.
I'm quite happy with how the Command Utility turned out. Managing how the program flow by using parallel and serial commands is very easy, and, more importantly, it is achieved with simple, clean, and readily maintainable code.
Sunday, February 21, 2010
I've added a Command Utility to Rusher Game Framework. Each engine core now has a reference to a CommandManager object; this object allows you to execute commands, be it single commands or composite commands.
There are two types of composite commands: ParallelCommand and SerialCommand. The parallel command executes all its subcommands simultaneously, while the serial command executes its subcommands sequentially. Also, each command has a delay property (the time a command "waits" before execution), which you may make use of to have advanced control over the command execution timing.
Here are some code snippets for Rusher's Command Utility.
This TraceCommand class is a very simple command consisted of a delay time and a trace message. Note that the execute() method is where all your command goes, and the complete() method should be called when the command is finished.
Here's the document class. The two commands "ps" and "sp" are a parallel command with a serial subcommand and a serial command with a parallel subcommand, respectively. The first constructor parameter of the parallel and serial commands is the delay time, and the subsequent parameters are subcommands.
This shall trace out "ps0", "ps1", "ps2", "ps3", "sp0", "sp1", "sp2", and "sp3" sequentially with a time gap of one second. The complete source code for this example can be found here.
One engine core is supposed to be used for one game level, or one scene in a game. I'm aiming for creating a utility for handling the entire game, including opening, menu screen, main game, ending, credits, etc. The Command Utility is just one part of it. You can think of it as something similar to Progression Framework.
Friday, February 12, 2010
Oooh. Look at the fresh new logo I made :p
I've written a tutorial on the basic usage of PushButton Engine. It demonstrates how to create a simple 2D arrow-key-controlled game character (well, if you'd call an arrow a character).
This time I'm going to recreate the exact same example, but using Rusher Game Framework, which is my own experimental game engine inspired by PushButton Engine.
This is the document class. The Player entity is the keyboard-controlled character, and the Scene entity is in charge of update the arrow display object's position and rotation according to the Player entity's 2D spatial data.
The engine core with the key "main" is obtained through the Engine.getInstance() method. Entities are added to the engine through the Engine.addEntity() method. The Engine.stage property must be set to a valid Stage reference in order to enable keyboard and mouse signal capture. And the engine core's main loop is invoked repeatedly through the Engine.clock.tick() method, by the enter-frame event.
This is the Player entity class, consisted of three components: 2D spatial data, render target, and controller.
The 2D spatial component contains data for position, rotation, and scale, while the scale data is not used in this example.
The render target component holds a reference to a target display object whose position and rotation will be updated according to the spatial data, accomplished by setting the render target component's positionRef and rotationRef properties to PropertyReference objects that reference the spatial data by name. The useOwnContainer property is set to true, so the display object remains in its original container set up in Flash IDE, instead of being added to the renderer's internal container sprite.
The controller component listens for keyboard signals and updates the 2D spatial data accordingly.
This is the Scene entity, which is pretty much consisted of a single component: the renderer component. This component updates the spatial value of display objects referenced by render target components.
Here's the Controller component that updates the arrow's position. The onTick() method declared in the ActiveComponent superclass is invoked on each main loop call. The engine property is a reference to the engine the owner entity is added to.
Note that the s variable is set the a value of SPEED * time. The time parameter passed to the onTick() method is the elapsed time between two main loop calls in seconds. Multiplying the SPEED constant by time, the arrow will be moved at the speed of 400 pixels per second, independent of the frame rate. So if the frame rate is set to, say, 30 fps, instead of the original 60 fps, the arrow will still move at the speed of 400 pixels per second.
Okay, this is kind of the basic usage of 2D spatial data, render targets, renderers, and active components for Rusher Game Framework. Next time I think I'll post some sample code for using Rusher's Box2D package.
I have been very quiet lately. That's because my friends and I are busy preparing for the Creative Game Design Contest held by Gamer. The theme of the contest is "Escape", and that's the only limitation. There's no limit on the game genre and gameplay.
Originally, I was thinking of using PushButton Engine. However, as Ben Garney, the creator of PushButton Engine, points out in the forum, that he is still working on transforming the engine from single-core to multi-core. My game requires a multi-core game engine, so I decided to develop a light-weight component-based experimental game engine myself. This is the advent of Rusher Game Framework. There's no stable build available in the Downloads section, but you can grab the latest revision from the SVN repository. There are two primitive examples available in the "tests" folder.
The name Rusher comes from a character I designed when I was in high school. Here's what Rusher looks like. Rusher is still in alpha, and I think it'll become beta after we release our game.
Since Rusher is component-based, it's rather easy to extend custom functionalities. Rusher already has a built-in Box2D component package, which works with Box2D 2.1a, the latest version. I developed this Box2D package because we're working on a 2D platformer.
Here I'll briefly demonstrate some code snippets for Rusher.
Similar to the Multicore version of PureMVC, each core is referenced by a key. The Engine class servers as the facade of the game framework, pretty much like the Facade class in PureMVC. The getInstance() method is how you get a reference to an engine core.
Instead of providing something like a start() method, I'd prefer make the user call the main loop function manually, just like what I did for Stardust. Each engine core has a reference to a Clock object. The Clock.tick() method must be called repeatedly to keep the engine running. This method can be directly used as an event listener, just like the Emitter.step() method in Stardust.
The Entity class represents a game entity, be it concrete as a character or abstract as a game scene. An entity is consisted of multiple components, each representing a basic module of data or behavior. The ActiveComponent class represents a behavioral component that is to update the entity repeatedly. The ActiveComponent.tick() method is called in each main loop iteration. For this to work, the entity must be added to the engine.
Each component has a name property, so that it can be referenced by name. One entity cannot possess two or more components with the same name. To reference the data (or properties) of a component from another component, the PropertyReference class is used. The concept of the PropertyReference class is actually from PushButton Engine. Referencing components and properties by name is very convenient and flexible. For instance, you can swap a component containing 2D spatial data with another special component with 2D spatial data, which works with Box2D, not interrupting the 2D rendering components which reference the 2D position data by name.
Alright, this is pretty much I can say about Rusher so far. I'll post more details about Rusher once it's matured.
Monday, January 25, 2010
Stardust project homepage
Finally, my Stardust tutorial article has been published on ActiveTuts+. They must have been very busy there at ActiveTuts+, since I had waited one week after the submission of the article for an acknowledgement and another week before it got published.
If you are interested in Stardust and are too lazy to go through the nearly 50-page PDF manual, you might want to check this article out. It's short, and yet after reading it you'll be able to create particle effects with Stardust!
I'm planning on writing more articles in the future about custom initializers/actions/renderers, 3D particle effects, and XML serialization.
Friday, January 15, 2010
View Blog Post
I just came across two Stardust demos that are pretty neat. The first one was made by Hasegawa (name spelling corrected, sorry about that :p), using a circle deflector to simulate umbrella blocking snow. The deflection looks quite nice. It's the first demo I've found to use objects other than just a boring circle to make circle deflectors look tasty. By the way, there's somehow a huge performance difference for Stardust deflectors between the Release version and Debug version of Flash Player. The Release version performs better than the Debug version. On my laptop, the performance difference for this demo is almost 50%.
View SWF & Source
The other demo is created by paq on WonderFL. This demo uses plane deflector in combination with Papervision3D to create this bouncing-planes-with-depth-of-field effect. Note that the main class extends the ReflectionView class provided by Papervision3D, which makes the demo even more beautiful.