The unusually useless case of loadCompressedDataFromByteArray

As you might probably know Tetragon uses zipped resource packages that are used by it’s AIR builds. These resource packages contain all the asset files, which can be images, XML files, SWF files, etc. etc. and also MP3 files. The only way to load MP3 files directly with AS3 so far has been to use Sound.load() but in the case of Tetragon MP3 files need to be loaded as raw byte data since this is the only way how it works to read  MP3 files that are stored in a packed zip file (remember Tetragon streams in data from zip files via random access, which is quite cool and something I explained here).

Since the AS3 Sound class had no methods to accept any byte data the workaround to load MP3 files as raw byte data so far has been to load them with URLLoader and then wrap the MP3 data into an in-memory SWF that is created with the help of AS3SWF. This works fine on desktop- and on Android builds. But enter iOS where it’s strictly forbidden to execute any non-native scripts and the whole idea falls apart as not even the creation of an in-memory SWF structure is allowed there, you will simply get an exception thrown and end up with no sound in your application.

However with the release of Flash Player 11 and AIR 3 there was a promising solution for this problem glittering at the horizon of Flash development: two new methods for the AS3 Sound class named loadCompressedDataFromByteArray and loadPCMFromByteArray! This new API was something I’m sure many audio-related Flash devs have been looking forward to since a long time and so I too was looking forward to finally be able to change the audio file loading in Tetragon to something that is natively supported and works on all supported platforms.

The disappointment was great when I sat down to implement the new sound API, in particular loadCompressedDataFromByteArray which as the (very terse) API documentation claims can be used to load MP3 files into the Sound class as byte data, just as we need it. In truth this obviously means that an MP3 file can be streamed in with this method and it’s audio played back only IF it’s played right after a call to the method. Trying to keep the loaded audio and play it back later results in an invalid Bytearray. This is how it’s done here. Check the onComplete handler in the script and you see how loadCompressedDataFromByteArray() is called and right after it sound playback is started. If you would try to play the sound later it’s not going to work. The audio data is lost!

UPDATE: I have filed this bug on Adobe’s new bug base! Please follow the link and vote for it! https://bugbase.adobe.com/index.cfm?event=bug&id=3072682

So either the new sound API is completely bugged or way too limited to make good use of it. There has been similar complaints from Andre Michelle about the other new method, loadPCMFromByteArray which seems to be quite buggy. Read more about it here http://bugs.adobe.com/jira/browse/ASL-281 (and please do log in and vote for the issue, if you can!). Unfortunately Adobe’s so called Bug and Issue Management System seems to be quite bugged by itself. I’ve been trying to register there, by now with three different Email addresses but never got any confirmation Email back from them, so I can’t log in. Trying to contact the admins doesn’t work either. Clicking the “contact the administrators” link will result in the following adequately useless page:

Find any admin link there? Right, me neither. Seems Adobe doesn’t want to be bugged about bugs, haha.

This is all a very sad state of affairs! whoever implemented (unplemented suits better here) the new sound API was either not given any time to finish it, or had absolutely no sense or concept on how to do this right. Seems it wasn’t even tested properly. If you can please go to Adobe’s Bug report site and make some noise about this! There is a lot of potential in the new sound API, if it only would work!

The Future of Tetragon

As you know, Adobe dropped the Flash Player for mobile platforms last week which caused a great uproar in the Flash community and in part in the wider technology community so I think it’s important to let you know where Tetragon is heading from now and what my thoughts are about the whole mess that Adobe has caused with their announcement.

The problem isn’t really that the mobile Flash Player was terminated, it’s the loss of trust in Adobe that comes with it. Adobe’s de facto monopoly claim on the Flash platform has always been a risk lurking at the horizon and now it has come close enough to bite us in the rear end. Adobe, keen on HTML5 like the rest of the internet committee, by now seems quite willing to throw Flash out of the window easily in exchange for jumping on the bandwagon of HTML5 hype. The signs that they are giving are quite clear. But have they asked the Flash programmers if we actually want to have Flash exchanged with HTML5. Of course they didn’t! All of a sudden some Flash devs seem to be strangely attracted by HTML5 and Javascript while others have a more exotic view toward the nature of the internet. I however have to be completely honest with you, I never will be attracted by HTML5 as a programming solution.

For the last ten years I have been a Flash developer, Flash made me learn programming, it made me learn OOP, then it made me learn to hate the Spaghetti coding of ActionScript 1 and love ActionScript 2 and then it made me learn to love ActionScript 3 a loathe ActionScript 2. Flash gave me easy access to learn a professional programming language for creating games. That’s what I always wanted to do. I learned to love ActionScript’s clean and typed syntax and it’s compact distribution form as compiled and compressed binaries. Flash and in particular AIR provided everything I ever wanted for game development, sans hardware 3D but we got that recently, too.

Now enter HTML5 and Javascript! It’s a bunch of untyped, loose and inconsistent stuff at best. It’s the most farthest away thing from a classic programming paradigm and it’s everything I never wanted to touch since I learned programming. With Javascript you get something that is at the level of ActionScript 1 without strong typing, loads of dynamic object access and a clutter of files that lie around openly on your server. HTML isn’t even a programming language, it’s a markup that reminds me back in horror on the early days of the internet where there was an era during that I used this stuff. I don’t really care whether the code files are easily accessible and can be stolen, that can be done with Flash too. I just don’t like the awkwardness and fragmentation of HTML5′s and Javascript’s nature.

Instead, the reason why I love working with Flash is because of the clearness of ActionScript 3 and because it’s a brilliant write-once distribute anywhere multi-platform approach with a nicely compiled release format. You don’t get this with HTML5, nor with any other platform.

Another big deal is the Open-Sourcing of the Flex framework. Quite honestly I’m not sure what to make of this one. Flex for the web is clearly unsuitable by now. HTML5 is taking over the RIA world and I have no problem with it. The Flash platform isn’t accessible enough to provide well integrated apps on the web. It’s strength are clearly defined in other areas. But the Flex framework is a very attractive solution for building desktop and mobile apps via AIR and Adobe has added several mobile-optimized UI components to the framework just recently. The open-sourcing of the Flex framework in my opinion is far more concerning than the end of the Mobile Flash Player.

How will all this affect Tetragon? For now this doesn’t affect the development of Tetragon at all. The Desktop Flash Player is still with us and hopefully for quite a while longer. But it’s easy to see where Adobe is heading with this. They are following suit with the popularity of the HTML5 dictate and want to jump on the band-wagon as quick as possible. Collateral damage doesn’t seem to matter for them. Neither does it seem to matter for their CEOs and marketing managers that JS and HTML is one giant jumble of incoherent, unoptimzed mess that lacks any OOP structure and that no decent game developer on earth wants to code with.

After that we still have the AIR platform for desktop and mobile apps and as long as the AIR platform continues to exist there is absolutely nothing in the way of Tetragon’s development. AIR is extremely attractive for game developers who want to deploy to the desktop and mobile platforms with the same code base and that is clearly one of Tetragon’s goals. Time will tell how Adobe progresses with the AIR platform but I hope they don’t spoil that one too.

But what if Adobe messes up completely and kills AIR and with that the whole Flash platform (as stupid as this may seem)? In that case I guess for me it’s either time to step back from this all for a while and concentrate on some other game design- and game development-related things or concentrate wholly onto another technology like C#, C++, haXe or even Objective-C, maybe even Python. The problem however remains: None of these technologies provide an attractive and compact multi-platform solution like the Flash platform does.

There is one thing that I can guarantee you that is never going to happen: me starting to develop with HTML or Javascript.

Tetragon website moved to new domain and a quick hint regarding the development state

Just a quick note for anyone who is linking or following this website or it’s RSS feed … this site has now been moved to it’s official URL www.tetragonengine.com so I recommend to update your bookmarks.

A quick info on the development state of the engine in case you’re wondering why it’s so quiet over on the engine’s GIThub repository … Do not worry! The engine is under constant development, however the dev build is – for the time being – under private hosting. For one, this is because with this we have a trac coming along with it where we can more easily track issues, bugs and feature todos. And the second reason is that Eclipse’s Egit plugin is shaky at best when it comes to merging repository branches.

There’s still quite a bit of work ahead to get Centauri ready so please be patient, we’re working on it!

Layered Architecture Diagram

This diagram provides an overview of the architecture layers that tetragon’s runtime engine follows. It shows all the major components that tetragon consists of. Upper layers depend on lower layers, but not vice versa.What follows is a brief overview of the layers and their various components, from bottom to top.

  1. OS: This one is obvious. The underlying operating system.
  2. Flash Player / AIR Runtime: tetragon is fully written in AS3 and so the Flash Player or AIR runtime act as a layer between engine and operating system. All compability intricacies for the various supported platforms are handled by the Flash runtime so here is nothing we need to (or can) take care of.
  3. Third-party Libraries: tetragon makes use of third-party libraries and frameworks where it makes sense. For example all 3D rendering is provided by any of the supported 3D engines. tetragon provides API layers that conveniently integrate these engines.
  4. tetragon Base Engine: This represents the base engine of tetragon which – if required – can be used on it’s own without the Gameplay Foundation or any of the other add-ons. The base engine is further divided into the following layers:
    1. Core Systems: This layer contains all the core systems of the engine.
    2. Resource Management: This layer represents tetragon’s resource manager which is responsible for loading and conditioning all the supported resource files and making them available for use inside the engine (some of the supported resources are listed as examples, but this shows only a part of eventually supported media resources).
    3. Additional Base Systems: These are systems that belong to the base engine but are built on top of the core functionality. This includes the audio system, GUI and front-end facilities, networking systems and the (almighty) entity system.
  5. tetragon Gameplay Foundation: This layer covers the game add-on that ships with tetragon by default. It provides standard functionality to be able to develop basic games with tetragon, such as standard render systems, entity systems and entity components that provide a default set of supported entity definitions, as well as standard data parsers and data processors.
  6. Game-specific Subsystems: This layer represents a set of subsystems for a specific game or game type add-on. tetragon will ultimately provide some of these add-ons, named for example rpg (role-playing game) and tbs (turn-based strategy). These are extra add-ons that may be added on top of the base engine and gameplay foundation to provide specific systems for a specific type of game. Such a subsystem can for example provide their own data- and entity definitions, custom entity systems that might manage the game A.I., custom render systems, etc.

This diagram is a work in progress and will be updated when required.

tetragon Desktop Builds and Window Bounds

When launching an AIR desktop build of tetragon the position and size of it’s main window will automatically be stored and recalled the next time the application is launched. Additionally the system chrome extra width and height are being calculated and the stage size is adjusted accordingly.

The reason for this is that the stage size of an AIR desktop application comprises the width and height of the system chrome which means that you typically end up with a smaller stage size than expected. To that problem adds that the system chrome can have different sizes depending on the OS and the visual theme. To solve this problem tetragon calculates the size difference and adjusts the stage size accordingly during startup. Imagine you define your application stage size to be 640 x 400. By default your stage size on web builds would be still 640 x 400 but on desktop builds (that use the system chrome) the actual stage size would be smaller because the whole window incl. the chrome would be 640 x 400. However thanks to tetragon’s adjustment the AIR stage size remains 640 x 400 and not 630someting x 380something. This is great because you don’t have to fumble around with this issue.

However there is a pitfall to be aware of: Be sure to set your AIR window minSizes to something large enough that can handle your application’s default width and height! By default tetragon’s build properties set the AIR window minSizes to the same as the default sizes so it will work alright but be wary if you change the minSizes! Setting this to anything below the default sizes will give you wrong window sizes and not only that, the window size will grow with each launch.

If you want to reset the window bounds to it’s defaults tetragon provides a console command to do just that. Open tetragon’s console and type in resetwinbounds (or the shortcut rwb) and the position and size of the window will be reset.

Ultimately there might be situations where you want to remove the file where window bounds are stored. This file is a Local Shared Object residing in the application’s application storage directory. On Windows this path is for example:

C:/Users/username/AppData/Roaming/com.hexagonstar.tetragon/Local Store/#SharedObjects/tetragon.swf/localSettings.sol

After removing this file the application’s window will be reset to it’s default bounds at the next launch. Keep in mind however that, depending on the application, the window bounds might not be the only data the sol file stores.

Casted Lookup Performance Test

There’s an interesting tidbit of information on jacksondunstan.com about using casts when accessing data from a data structure to gain performance. As tests show this is true for all tested structures (Array, Vector, Dictionary, Object and Dynamic Class) but what is even more impressive is the difference of how to cast. As the results below will show it’s always significantly faster to use the “as” operator for casting than the conventional method of using braces “()”. This comes as somewhat of a surprise for me as I’ve been always under the impression that the opposite is true. However that might have been still based on outdated tests done on older Flash runtimes.

Note that this performance gain will only show in the release Flash Player. In the Debug player you will likely get the opposite result that using the “as” operator is slower so be sure you are testing in the release runtime.

Here are my results:

*** Casted Lookup Performance Test ***
Runtime: 11.0.1 (60), PlugIn, WIN, Debugger: false
Click to begin test!
Running 10000000 iterations ...
Finished! All results in milliseconds, smaller is better.
TYPE             NO CAST    CAST AS    CAST ()
----------------------------------------------
Array            75         42         249
Vector           71         37         244
Dictionary       219        182        382
Object           202        172        380
Dynamic Class    212        178        377
SUM              779        611        1632

The tetragon Display List Hierarchy

This article will explain how the display list in tetragon is organized. There are some differences about how the structure looks between web builds and AIR builds but usually you don’t need to worry about these as long as you don’t mess with the display structure and nicely stick to using your Displays inside Screens as it is supposed to be.

Web Builds

For tetragon web builds a preloader is used which extends a MovieClip. This preloader acts as the context view and ultimately becomes the wrapper for the whole rest of the display list chain. The preloader MovieClip has two frames, the first for the preload display (which is disposed after preloading has finished) and the second keeps the screen container and optionally the utility container (see below).

AIR Builds

For AIR builds (desktop, Android, iOS) the structure looks slightly different. As these builds don’t require a preloader they are just using the Entry class as the context view. The Entry class for AIR builds extends Sprite so the hierarchy is more simple here than for web builds. The Entry class then directly contains the screen container and optionally the utility container.

The Screen Container

The screen container is a Sprite that holds any screens that you are going to use in your game. Since there can ever be only one screen open at a time the screen container will only contain one screen at a time. If a new screen is opened the former screen is removed from the screen container and the new screen is added.

In your screens you then have any number of displays (extending the Display class) which in turn can contain any number of other display objects (Sprites, Shapes, MovieClips, Bitmaps, ViewPorts, etc.).

The Background is an optional display object for screens. It can be used to place a background behind screens. This background can contain an image, animation or any other kind of display object and is displayed underneath any screen that is opened. The Background is created lazily, i.e. if you don’t use it it’s display object will not be there. In that case the screen container will only contain a screen and no background.

The Utility Container

The utility container is used to hold such things like the Console and the FPSMonitor. It sits on top of the screen container so that debugging displays are never obstructed by screens. The Console and FPSMonitor as well as the utility container are wholly optional.  If you disable the Console or FPSMonitor they aren’t created and therefore don’t exist as a display object. If you choose to disable both the Console and FPSMonitor (through the app config or wherever) the whole utility container isn’t created because we don’t need an empty container hanging around on the display list. In this case the screen container would be the only object wrapped by the context view.

The Entity System

The Entity System that will be part of tetragon from version 1.1.0 (Centauri) on is a solution to get a consistent and flexible architecture into the engine that will manage all game objects. If you’re unfamiliar with Entity Systems (ES) I recommend to read these articles posted by T=Machine which explains the approach behind an ES very well. If on the other side you’ve already worked with a tool like Unity or another engine like PBE then you already used an Entity System because they are exactly that, with the difference that Entities are just called Game Objects in Unity and that the system works somewhat different in PBE.

tetragon’s ES follows a truly separated architecture between entities, components and systems. It essentially follows the rationale that “A game is just a real time database with a graphical front end”. What this means is best explained by describing the three major parts of an ES and what they do …

Entities

An entity is a game object that has a role somewhere in your game (or application). Many things can be defined as an entity, here are some examples: a player or non-player character, an enemy space ship, a weapon, a med pack, a vehicle, a building, a country, a world, a galaxy, a magic spell, a skill (e.g in a role-playing game), a quest, a graphical user interface element … you see there’s almost no limit to what might be defined as an entity.

However there are sometimes decisions to make about what should be an entity and what not. Take for example a tile-based game. Would you want to make every tile an entity? You could but you have to ask yourself if this is really necessary. In tetragon there are several ‘intermediate’ objects that are not entities, for example SpriteSets and SpriteFrames.

The way how entities are designed in tetragon makes them almost essentially into flyweights because an entity is nothing more than a dynamic object with a unique ID, a few very small helper methods and a list of components which define the type of the entity (over at T=Machine he calls this ‘aspect’ though I’m not really happy with that term in this relation). All the logic that processes entities are in the systems (more about them below).

Entities are purely dynamic and don’t exist as classes. You have to somewhat rethink your OOP practices for them as there is absolutely no strong-typed implementation for any of an entity’s properties. The only place where you ever define entities (actually entity definitions) is in your entity data files. More about this later.

Components

Entity components are the parts that define an entity so any entity has to possess one or more entity components. Components define what characteristics an entity has and by that they ultimately define what an entity can do and how it behaves. In most cases one component is responsible for only one aspect of an entity (uh, now I’m using that word too. Maybe it makes sense after all) but this is not a rule that is set in stone. Depending on the purpose there can be components that fulfill multiple aspects at once or are only used for a specific type of entity.

Some very basic examples for entity components would be for example the Spacial2DComponent that simply tells that an entity can have a two-dimensional position and rotation or a GraphicsComponent that determines that the entity has renderable graphics.

More specific types of components in tetragon are for example the WorldSpaceComponent and the CellComponent. These describe properties that really only adhere to worldspace or cell entities.

Just like entities, components do not possess any logic. The only implementation they possess are properties for a specific aspect of an entity. They may of course have getter and setter methods though. Every entity component of a specific type also has a unique ID.

Systems

Systems are the most complex parts of an ES because they contain all the logic that processes the data of entities. A system often has a one-to-one relationship with a specific type of component but again this isn’t mandatory. A Render2DSystem is only able to render entities to the screen that possess a Graphics2DComponent whereas a Render3DSystem might be specific to only entities that represent a 3D graphics object. Another example would be an AIComponent and an AISystem that only cares about processing the A.I. of all entities that possess an AIComponent.

Most of the systems run permanently as long as they game runs but not all necessarily have something to do all the time (if that would be the case we’d be running into performance issues real quick). Rendering-related systems are triggered by the render loop while non-rendering-related systems are triggered by the game loop, for example A.I. processing which needs a lot less frequent updating than rendering.

Application Settings

The Application Settings (or Game Settings) are a domain of settings in tetragon that are exclusively related to the nature of the project for that tetragon is used for. This means that all settings that are used to configure the specifics of a game or application are best placed in the Settings, contrary to the Application Config in which only basic, engine-related settings are stored.

On the API side of things the Settings are referenced in the Registry and therefore can be reached via Main.instance.registry.settings. Unlike the Config, the Settings is a Hashmap that stores key-value pairs so knowing the key name for a specific settings value is vital. By default the engine loads settings from an XML-based resource file …

The Settings Resource File

On the file side of things the Settings are part of the resource data files and reside in a file named settings.xml which is located in the resources/data path. Keep in mind that because the Settings are part of the resource files it also means that for AIR builds they are packed and compressed into a resource archive just like all other resource files.

The Settings file structure is straightforward with key names that are defined as XML tags and their value is wrapped by them. Like in all other resource data files complex types are supported for settings values as well. Consider the following example settings XML …

<?xml version="1.0" encoding="UTF-8"?>
<settings>
	<screenScale>1.0</screenScale>
	<splashStateID>splashState</splashStateID>
	<initialStateID>emptyState</initialStateID>
	<splashBackgroundColors ctype="Array">0x002C3F, 0x0181B8</splashBackgroundColors>
	<splashLogoColor>0xFFBF00</splashLogoColor>
	<splashScreenWaitTime>6</splashScreenWaitTime>
	<showSplashScreen>true</showSplashScreen>
	<allowSplashAbort>true</allowSplashAbort>
</settings>

Depending on your application or game you add any and as many settings to the file as your project might require. Fetching a specific settings value in the engine is then a simple matter of calling the getSettings() method. However it’s a good practice to check whether a settings value is really available …

var colors:Array = Main.instance.registry.settings.getSettings("splashBackgroundColors");
if (colors)
{
	// Do something with colors...
}
else
{
	// fall back on default colors...
}

Application Config

The Application Config is an object used by tetragon that stores engine-related configuration data. It’s a class named Config that is located in the tetragon.data package and a reference of it is stored in the Registry class so it can easily be reached via Main.instance.registry.config.

The Config class contains various public properties that are directly related to basic features of the engine like Console and logging preferences, graphic options, IO and Updater settings etc. It may be accessed from anywhere else in the engine but the class should not be changed or extended. Project-specific settings instead should be stored in the Settings. New config properties are bound to be added to the Config class (or changed) as development progress on the engine move on.

The Config File (app.ini)

The configuration file is a text file with key-value pairs which is loaded and parsed into the Config object during the init phase. The file is named automatically after the filename of the respective application’s SWF file. For example if the project’s app.shortname (in the build.properties) is defined as yourgame, the resulting SWF file will be named yourgame.swf and the application config file will be named yourgame.ini automatically. After building, the file is located in the application’s base folder.

In tetragon v1.1.0 and later, AIR-based builds of tetragon will check if the config file exists in the user data folder of the respective platform the app is run on (for example C:/Users/username/Documents/PublisherName/YourGameName/settings/yourgame.ini). If the file was found there it will also be loaded and parsed from there. If the file was not found in the user data folder a copy of it will be created there and loaded next time the app is started.

The template file for the configuration file is located in the project folder under bld/templates/shared/app.ini.