Sam MacPherson

Flash, Haxe, Game Dev and more…

Category Archives: java

Asset Management

Here is a quick overview of how we (My game designer and I) deal with managing assets for flash development. Due to our small team size of just 2 people we historically had a very programmer-centric setup which put a lot of pressure on me, the programmer, to hard code things into the game as they were developed. This worked fine for our previous projects which were relatively simple, but our latest project requires much more content. So naturally I had to start developing tools for my designer. Specifically an asset management tool.

Starting last November I began work on an Asset Management tool written in Java. Eight months later this is what we have come up with.

The above image is a screen shot of the asset manager with our latest game’s asset file open. Let me go over each of the sections briefly. But first some terminology:

  • A directory is basically a grouping of attributes with a (potentially empty) asset attached to it. I may use the word object or game object interchangeably with directory.
  • Assets are binary data which can be images/animations/sounds/fonts/etc.
  • Attributes are just simply key/value pairs. I will sometimes call these properties.

1. Directory Explorer

Displays the logical structure of the game elements. For example I have highlighted a directory called “regular0” which is inside the zombie directory so even with no knowledge of the game internals you can probably tell it is a common zombie.

2. Directory Preview

This is somewhat preliminary. As of now only images will display. Everything else will just display text to let the designer know there is an asset attached to this directory.

3. Directory Properties

Every directory can be assigned as many properties as it needs. As you can see in the above image this is useful for attaching game-specific meta data to the object.

4. Asset Library

The asset library stores references to all external binary data. By keeping the asset library and the directories separate we are able to separate the game logic from the raw data. This is useful if for example you want to make two different enemies but don’t want to duplicate the animation data.

5. Asset Preview

Similar to the directory preview except for the asset library.

Now for some technical details on the file structure. Everything in the above image is stored into a GigaBlast Asset Package file format (.gap extension). On the flash side I can then load everything in using an in-house resource management class. The file format is as follows:

-- GigaBlast Asset Package Format Specification V2.00 --

-- Data Types --
String - 2 byte length followed by 'length' 1 byte ascii characters  
Integer - 4 byte integer  

-- Overall structure --
[Header]  
[Library]  
[Directory]  
[Binary Data]  

-- Header --
"GAP" (3 byte file format identifier)  
Major Version (2 bytes)  
Minor Version (2 bytes)  
Flags (1 byte) {  
	1 - Compressed (All non-header data is compressed with zlib)  
	2 - Signed (All non-header data is signed with RSA after compression and signature is appended to file)  
}  
ABSOLUTE Library offset (Integer) (Does not include header)  
ABSOLUTE Directory offset (Integer) (Does not include header)  
ABSOLUTE Binary Data offset (Integer) (Does not include header)  

-- Library --
Asset Count (Integer)  
Assets {  
	Name (String)  
	Data Type (Integer) [0 = Any, 1 = Image, 2 = Animation, 3 = Sound, 4 = Font)  
	RELATIVE Binary Data offset (Integer)  
}  

-- Directory --
Name (String)  
Library ID (Integer)  
Meta Data Count (Integer)  
Meta Data {  
	Name (String)  
	Value (String)  
}  
Directory Count (Integer)  
Directories {  
	Dir (Directory)  
}

-- Binary Data --
Data Size in bytes (Integer)  
Data (Binary Data)

-- Formats Supported by GigaBlast Asset Manager --
Binary Data (Anything -- even empty data)
Images (PNG, GIF, JPEG)
Animations (SWF)
Sound (MP3)
Fonts (TTF)

Once I have a GAP, say ‘lib-sam.gap’ from above, I can then load this into flash by doing this:

Assets.setCompletionCallback(onAssetsLoaded);
Assets.load('/path/to/lib-sam.gap');

function onAssetsLoaded ():void {
	var asset:Asset = Assets.get('zombies.regular0');
	trace(asset.getProperty('speed'));                    //Will print '5:10'
	var displayObject:FlashDisplayObject = asset.get();   //Get the attached asset on the directory
	canvas.add(displayObject.newInstance());              //This will create a new instance of the animation and attach it to the canvas
}

As I was designing this, the terminology between the Java and Flash counterparts became a little fuzzy. What I am in fact calling an asset in flash is actually equivalent to a directory in the Java manager.

You are able to load as many GAP files as you want. They will all be gracefully merged into the Assets class.

But wait! There’s more!

You may have noticed in the file format structure there is the allowance for compression and package signing. The compression is completely transparent. The package signing is useful if you don’t want people tampering with the GAP file (Messing with enemy stats and bad stuff like that). I’ve also included a key generation tool.

When the keys are set (As seen in the above image) then the file will include an RSA signature at the end of the GAP file. You then hardcode the public key somewhere very hidden inside your swf file. When loading the file you do this:

var publicKey:BigInteger = BigInteger.ofString("30819F300D06092A864886F70D010101050003818D0030818902818100B79E8D7D9B538BDCBFF4EDD0E4BB0AB3031D49FFD8759F7FEDF5D171BF9969EBC148325F3FF9246A2E489F6FE7506329B72DD3477134FB6D7098487261B8F9A6E96DDF21DCB0062C9931737C9924A6CFC64DAC06A8F6DB1F363F54FBA763330EB2A8DBEB52D9DD62AB998D2C7BC63CAE2D8D4E2A5A8A13E0B362F44410134DFB0203010001", 16);
Assets.load('path/to/lib-sam.gap', publicKey);

What does this do? Without going into details it will disallow anyone but the person who knows the private key to edit the GAP file. The BigInteger class you see is provided by caffine-hx which is a haxe library.

But wait! There’s even MORE!

Included in the asset manager is a generic map editor which is capable of drawing in directories onto a map.

The map editor is in its infancy, but as of now it is capable of drawing three distinct types of images: surfaces (grass, dirt), wall-like things (walls, railings, roads) and doodads (chairs, tables). The nice thing about combining this with the asset manager is that for example as long as you add in a ‘type’ property on your directory and the directory is an image anything can be drawn onto the map.

To make things more specific to a particular game you can add in any property onto the drawn directory. For example Zed (Our zombie game) has collision areas which I’m sure is fairly common. To make any object collidable you simply add the property ‘inteact’=’collidable’ to the directory and begin drawing it in.

My flash-side library is capable of loading maps in a WYSIWYG fashion. More complicated constructs such as lighting and localized sound is achieved by having game logic pull out specific drawn-in objects instead of rendering them. You can see an example of this in the above example with all the faint blue/green/red areas. Those areas are in fact markers for lighting and event based actions.

There is a bunch more features but I won’t get into them right now. As of now our asset manager is not open to the public, but I hope to release it into the open source community soon. I am not particularly skilled at GUI design so perhaps someone out there would be willing to help out with that aspect.

Advertisements