Log In
Name:
Pass:
Online Members (0)
No members are currently online.
Current Interguild Time:
Fri Mar 29 2024 9:17 am
Member Chat Box  [click here to enlarge]
Recent Posts and Comments
ShareThis
« Blogs Index < Aeon Project
« Livio's Blog

The new demo really changed a lot of things with how the game handles customization options. In this post, I'm going to introduce you to these changes while also considering ways that these options could be improved for future updates. I'm going to split this into two parts. Part 2 will focus on the styles system, which part 1 will focus on everything else.

Table of Contents:
( 1 ) Version Number
( 2 ) Title
( 3 ) Level Properties
( 4 ) Keys
( 5 ) External Assets
( 6 ) Custom Content

  ( 6.A ) Drawing Shapes
  ( 6.B ) Borders
  ( 6.C ) Solid Fills
  ( 6.D ) Image Fills
  ( 6.E ) Coming Soon
( 7 ) Animation
( 8 ) Declaring Object Types

  ( 8.A ) Inheritance and Classes
( 9 ) Level Code

Let's start by looking at the level code for the default level, because it contains a full level code, without relying on any of the built in settings:
http://www.interguild.org/levels/index.php?id=3741
I recommend switching back to this level as you read this guide as a way of seeing examples. It's also good to open the game and make small changes to the level in order to play around with some of the options.

Like the previous demos, the level code is written in XML format. You don't have to fully understand how XML works, but it's fairly self explanatory. What's important is that you don't accidentally make an XML syntax error, which would render your code unreadable to the game. Because I'm using Flash Player's built-in XML parser, as far as I know, I have no way of finding which line number you made your error in.

Version Number:
Code:
<level demo="VERSION_NUMBER">

While there are plenty of Aeon levels in the database so far, the game doesn't load any of the ones that have been posted before this year, because none of them are compatible with the current build. Since I might be making many smalller updates in the future, It's good to keep track of which version a certain level was built for. Right now, the game forces you to set the version number to 4.0. You can get away with not doing it, but it'll annoy you with a pop-up every time that level is loaded.

I'm not sure if I'll go through the trouble of making everything backwards-compatible, though. Just remember that you're making levels for a game that's not finished yet.


Title:
Code:
<title><![CDATA[TITLE GOES HERE]]></title>

That CDATA thing is a feature of XML that allows you to write mostly anything without interfering with the syntax and structure of the rest of the XML. While you may be tempted to separate the actual title from the ugly syntax with line breaks, those line breaks will actually appear in your title. Perhaps in a future version, I'll make it more user-friendly by removing any immediately surrounding line-breaks. But I'm not sure if that's necessary since you'll most likely be editing your options through a user-interface in the final game.


Level Properties:
Code:
<level size="WIDTH HEIGHT" framerate="FRAMERATE" windowSize="WIDTH HEIGHT" loadDefaultSettings="TRUE/FALSE" background="IMAGE_ID" />

Most of these options are just workarounds until the real level properties customization settings are implemented. It's likely that this entire line might be omitted from future versions of the level code.

The options for size and windowSize work similarly. You give it two numbers (width and height) separated by a space. The units for "size" are the number of grid tiles (which are 32x32 each), and the units for windowsize are pixels. When you set the window size, the game window will actually resize itself to what you set. But you can't tell the game to stop players from resizing the window themselves, yet.

The loadDefaultSettings option determines whether or not to load all of the game's built-in specifications. In future versions of the game, you should be able to determine which default settings you want and which you don't want. But until then, it's either all or nothing. The default level code can be found in full in the default level. The default settings include everything mentioned under the following tags: keys, assets, content, animation, objects, and styles.

The background setting takes the id of any image (which is defined later in the code) and makes a crude, static, background for your level. Like I said, the "real" version of these customization options are to be added later.


Keys:
Code:
<keys>...<key key="KEY_CODE">ACTION_ID</key>...</keys>

Here you can map different keyboard presses to different actions. You can find the KeyCodes that you need on this page:
http://www.dakmm.com/?p=272

And here's a list of the different Action ID's:
Code:
1	LEFT
2 RIGHT
3 UP
4 DOWN
5 JUMP
6 PAUSE
7 QUIT
8 RESTART
I don't know why I didn't just make you write out the full name as opposed to relying on these IDs. That's definitely something to fix for a future demo.

The Esc key is always mapped to the PAUSE action, and you are not allowed to re-map it to anything else.

The pause screen is different in this build. You can open it from anywhere while playing a level, including the jump-to-start screen. This allows players to leave a level even if that level has no keys set or links for how to exit it.


External Assets:
Code:
<assets>...<image id="ID" src="URL" />...</assets>

This is where you define the external assets that you want to load into the game, and you must assign an id name to each of them. Right now you can only load in images.

I mentioned how you can load in sprite sheets, so I made two sprite sheets to help you get started:
http://interguild.org/aeon/images/aeon_sprite_sheet.png
http://interguild.org/aeon/images/interguild_sprite_sheet.png

You can also find some of the other images used in the demo, and in past demos, here:
http://interguild.org/aeon/images/


Custom Content:
Code:
<content>...<drawing id="ID" ...>...</drawning>...</content>

This is where things start to get complicated. I have to admit that this isn't necessarily the most intuitive feature ever, and that there's a lot of polishing to be done here. The purpose of the content section is to manipulate any assets that you have in order to create new assets. Since all we can do is import images, there's only one type of content, which is the drawing. Because you're creating new assets, the ID name cannot be the same as any of the other asset ID's that you've already defined.

Drawing Shapes

Unfortunately, the current version of the content system does not you allow you to directly instantiate another asset yet, but you can, however, draw a shape that will use that asset as its fill.

At this point you can only draw two shapes: circles, and rectangles:
Code:
<drawing id="circle-with-box">
<circle radius="RADIUS" center="CENTER_X CENTER_Y">
...options go here...
</circle>
<rectangle box="X Y WIDTH HEIGHT" rounding="ROUNDING_X ROUNDING_Y">
...options go here...
</rectangle>
<rectangle box="X Y WIDTH HEIGHT" rounding="ROUNDING">
...options go here...
</rectangle>
<drawing>
You can put as many elements into a single drawing as you want, with little cost to performance, because it all gets compressed into pixel data later.

When drawing circles you specify where you want the center of the circle to be and its radius. You can't make ellipses yet, because that's complicated enough to be an entirely different shape. Although, you could probably get away with making ellipses by abusing some of the rectangle's rounding options.

When drawing rectangles, you specify its size by using the "box" property (which is a little misleading in context with another option we'll discuss later). You can also define a rounding radius in order to create a rounded corner. This property will accept either one or two numbers. Use one number to define a standard rounded corner, or by defining two numbers, you can make the horizontal rounding different from the vertical rounding, so that your corners look more like ellipses than circles.

Next, we'll look at the different options that you can give your drawings:

Code:
<drawing id="circle-with-box">
<rectangle box="X Y WIDTH HEIGHT" rounding="ROUNDING">
<border ... />
<solidFill ... />
<imageFill ... />
</rectangle>
<drawing>

Borders:
Code:
<border color="COLOR_HEX" alpha="TRANSPARENCY_%" size="BORDER_WIDTH" />


If I remember correctly, you can write numbers in three valid formats: #FFFFFF, 0xFFFFFF, or simply FFFFFF. You cannot use keywords like "red" or "blue", but maybe I'll add that feature someday.

The alpha property takes in a number from 0 to 100, and it determines how transparent the border is.

The size property specifies the number of pixels wide that you want the border to be. According to the ActionScript 3.0 API, a border width of 0 will result in a "hairline" border to be applied, which I don't understand because I've never actually seen this hairline border anywhere.

Solid Fills:
Code:
<solidFill color="COLOR_HEX" alpha="TRANSPARENCY_%" />

See above section for more info on these properties.

Image Fills:
Code:
<imageFill assetid="IMAGE_ID" box="CROP_X CROP_Y CROP_WIDTH CROP_HEIGHT" angle="DEGREES" scale="SCALE_X% SCALE_Y%" alpha="TRANSPARENCY_%" tintColor="COLOR_HEX" tintAlpha="TRANSPARENCY_%" />

See above section for more info on some of these properties.

This is where the term "box" gets confusing, as I mentioned earlier. In this context, I'm using the word "box" to represent what is really "crop". What this does is define a region within the image that you're referencing from. This allows you to treat that region as though it was its own original image, which you can alter, distort, and even make repeating patterns out of.

The scale property takes either one or two numbers. Having two numbers allows you to stretch your image horizontally or vertically. Put in a percentage between 0-100 to shrink, anything larger than 100 will expand, and negative numbers will flip the image around, like a mirror.

I probably should've named that as "tintStrength" rather than tintAlpha, but it does convey the fact that, like regular alpha, you're limited to a range from 0-100. The tint settings allow you to tint your image towards a specific color. For example, you could take an image of fire and make it green.

Coming Soon:
Like I said before, it stinks that you can't directly instantiate an image and manipulate it yet, but it also stinks that I forgot to add features that will let you manipulate the drawing itself. For instance, you can't rotate any of these shapes, or stretch them, or do much else with them aside from editing their fills and borders.

I would also like to add a new shape called "text" which will allow you to write things into your level. For now, you can sort of add text to your levels by importing it as an image, but this would be so much more convenient. And I want to add a "mask" feature that will let you create effects similar to the terrain fills from the previous demos.


Animation:
Code:
<animation> ... <frame>...</frame> ... </animation>

This area really needs some work done on it, because many of its settings overlap with the responsibilities that <content> should have, but for some reason, doesn't.

Before you can use any of the fancy assets that you've imported and created up until this point, you'll have to create a frame for it:
Code:
<animation>
<frame id="FRAME_ID" next="FRAME_ID" delay="INTEGER">
<image id="ID" position="X Y" box="CROP_X CROP_Y CROP_WIDTH CROP_HEIGHT" flipX="TRUE/FALSE" flipY="TRUE/FALSE" />
<image id="ID" ... />
</frame>
</animation
You can place any number of assets into a single frame, but at this point we only have image assets to work with. The only new image properties here are the flipX and flipY options, which were crudely added in order to make life easier. Hopefully I'll make this system easier to work with by the next demo.

Each frame gets a unique id, and you're not allowed to reuse any of the IDs that you might have named image assets with. You can specify an animation sequence by setting the "next" property to another frame id. You can make long animations by having a lot of frames link to each other, and you can create a loop by linking to a past frame in the sequence.

Unless you want a really detailed, 30-fps animation, you'll most likely use the "delay" option, which lets you specify the number of frames that you want to repeat the current frame for. For example, an 8-bit animation might demand a delay of about 5, which makes the animation 5 times slower than what it would have normally been. If you want to make a stand-by animation for when the character isn't doing much, you could set the delay to something long, like 90 frames which is 3 seconds.


Declaring Object Types:
Code:
<objects> ... <obj /> ... </objects>

Ah, we're finally getting into concrete stuff. The purpose of the objects tag is to define all of the objects that you want to use in your level. For example, if you wanted to create a new tile, you would have to define its tile ID and name here.

Code:
<objects>
<obj id="TILE_ID" name="NAME" behavior="BEHAVIOR_ID" inheritsFrom="TILE_ID" />
</objects>

The name property is really just a formality at this point, but it will be used by the level editor later. There's also supposed to be an "editorIcon" property for the editor, but I digress.

The behavior thing is a feature that hasn't been implemented yet, and right now there's only one possible value ("player") used for denoting which object needs to be attached to the game's player controls.

The tile id is supposed to be only one character long, because it's the representation of your object in the code that draws the map. But there are some reserved characters that you are not allowed to use: space, tab, line-break or return, '.' (period), ';' (semicolon), '=' (equals sign), and '$' (dollar sign). These reserved characters have special meaning when drawing the map and they help compress the file size of your levels.

You can also specify a two-character id, if you the first character is a '$' (this is why the '$' is reserved). The only reason why you'd want a two-character id is in the very unlikely case when you've already gone through all of the other ASCII values.

Inheritance and Classes

The "inheritsFrom" property allows you to make objects that inherit all of the styles from another object type. For example, a steel arrow might inherit from a steel crate. This feature is mainly for convenience, as it really just makes the game more inefficient, and you're not allowed to inherit from more than one object..

The other case where you're allowed to have a two-character id is when your first character is a period. This denotes that object type as a class type instead. Classes can have the same style properties and settings as objects, but they cannot be instantiated. Rather, you can attach classes to individual objects in the level code (discussed below). For example, if this sequence was in the level code: "xxx.axxx", it will create 6 terrain blocks, but the third block will have the class ".a" attached to it, meaning it will inherit all of the properties of its core object type, as well as its class type. This is my solution to the fact that you can't have multiple inheritance.

Now, working with inheritance can be pretty confusing. The problem is that rather than having all of these rules merge seamlessly together, the way it's really done is that the game takes all of the rules from the parent type, applies those, then it goes to the child type and applies those, then when it has reached the end of the inheritance chain, it applies the class's rules. The problem with this is that it causes the styles system to act in unintuitive ways.


Level Code:
Code:
<levelcode><![CDATA[...]]></levelcode>

The purpose of the levelcode (which probably should've been called mapcode or something), is to define which objects are instantiated in your level and where. It's very similar to HATPC's level code system, which is why I recommend using CSD's CaveMaker to make levels. Basically, think of the whole level as a grid, and the level code is a sequence of characters where each character represents what's in each grid element. This is why the game object id's are one-character long.

You can compress your level code by using the following syntax:
x=20;
. When the level loader comes across the equals sign, it scans the following text up to the nearest semicolon and parses it as a number. In this case, this tells the level to create 20 instances of the object type "x" (terrain). Without this feature, this line would've taken us twenty characters, but now we only need 5.

Spaces in the level code represent empty grid elements, Tabs represent 4 spaces, and New-Lines represent a jump to the start of the next grid row. Again, you might be tempted to separate your actual level code from the CDATA with linebreaks, but those line breaks will actually be counted as indications that you want to skip to the next line in the grid.

As mentioned in the previous section, "$a" is read as one tile, and ".a" will add that class to the last-visited tile.


To be continued...

By now, you've learned how to declare an object type and make instances of it in the code, but how do you tell the game how you want these objects to behave? The styles system is designed to give you a simplified interface to editing the dozens of options and features that objects have. This system really merits guide of its own, which is why I split this guide into two parts.

EDIT: Click here for Part Two!
[?] Karma: 0
User Comments (8)
« Forum Index < The Aeon Development Board

canadianstickdeath
[?] Karma: 0 | Quote - Link
Thursday, January 12 2012, 1:19 am EST

Age: 35
Karma: 350
Posts: 2990
Gender: Male
pm | email
I don't like the one or two character object id restriction and I think you should switch from a level code string to an array.
Livio
[?] Karma: 0 | Quote - Link
Thursday, January 12 2012, 1:25 am EST

Age: 31
Karma: 470
Posts: 9620
Gender: Male
Location: Arizona, USA
pm | email
It's just that strings provide for much smaller level codes than arrays. The biggest factor in loading times is the size of the level code, and if the game had to parse an array of x-length string id's, the loading times would take a serious hit, along with the amount of memory needed to store each level. I suppose we could alternatively have a list of coordinates or something, but that would have a similar effect, especially for maps with a lot of objects in them.
canadianstickdeath
[?] Karma: 0 | Quote - Link
Thursday, January 12 2012, 1:59 am EST

Age: 35
Karma: 350
Posts: 2990
Gender: Male
pm | email
Really, the parsing the text is the slowest thing? I mean, it seems like initializing the objects themselves should take more time than just parsing through the code...

Why would it take more memory to store the level? Obviously the level code itself becomes about 3x bigger (at least if you only use 1-character ids), but it's not like storing a string of that size is especially labour intensive?
Livio
[?] Karma: 0 | Quote - Link
Thursday, January 12 2012, 2:41 am EST

Age: 31
Karma: 470
Posts: 9620
Gender: Male
Location: Arizona, USA
pm | email
I was referring to memory on the server needed to store all of the bigger level codes that get uploaded to the database.

Well, that was definitely an exaggeration. What I meant was that it was one of the areas of the level loading process that I found the most room to optimize loading times from. A compressed level code loads significantly faster than an uncompressed one. Part of the reason why Quirvy's level takes so long isn't just because it has a lot of objects but because he has a lot of empty spaces that need to be parsed through.
canadianstickdeath
[?] Karma: 0 | Quote - Link
Thursday, January 12 2012, 2:46 am EST

Age: 35
Karma: 350
Posts: 2990
Gender: Male
pm | email
Which fine on github has the text parsing in it... >_>
Livio
[?] Karma: 0 | Quote - Link
Thursday, January 12 2012, 2:50 am EST

Age: 31
Karma: 470
Posts: 9620
Gender: Male
Location: Arizona, USA
pm | email
canadianstickdeath
[?] Karma: 0 | Quote - Link
Thursday, January 12 2012, 3:05 am EST

Age: 35
Karma: 350
Posts: 2990
Gender: Male
pm | email
I was thinking you wouldn't manually parse the array, but that you could define the array in XML, if that's possible? I know way less about this sort of thing than I should. :p
Livio
[?] Karma: 0 | Quote - Link
Thursday, January 12 2012, 3:15 am EST

Age: 31
Karma: 470
Posts: 9620
Gender: Male
Location: Arizona, USA
pm | email
Maybe something like:
Code:
<array>
    <el objectID="X-length ID" />
    <el objectID="X-length ID" />
    <el objectID="X-length ID" />
    <el objectID="X-length ID" />
    <el objectID="X-length ID" />
</array>
But would we include blank spaces in there? And the game would also know to switch to the new line when it reaches the end of the level width. I dunno, this just sounds like a real pain to work with, especially now that we don't have a level editor for the game. And I don't think the advance in loading times would be worth all of the extra memory demanded on the server.

« Forum Index < The Aeon Development Board

In order to post in the forums, you must be logged into your account.
Click here to login.

© 2024 The Interguild | About & Links | Contact: [email protected]
All games copyrighted to their respective owners.