Skip to content

bricksets

Alexandre Martins edited this page Jan 6, 2025 · 5 revisions

Bricksets

Definitions

In Open Surge, levels are built using elements called bricks. A brick is a reusable scenery element. Bricks may be: blocks, floors, walls, ceilings, movable platforms, trees, plants, decorative objects, and so on. Bricks are like tiles, but more flexible:

  • Bricks can be of varying sizes (whereas tiles have a fixed size)
  • Bricks may be placed anywhere in space, even on top of each other
  • Bricks may be endowed with special behavior & movement

Bricks are imported into Open Surge via a brickset. If you want to create new scenery for new levels, you must first create a brickset. A brickset is composed of three elements: image, script and collision mask.

Bricks being displayed in the level editor

The brickset image

No brickset would ever exist without the image in which the bricks are drawn. This image features the artwork and may be organized in many ways. It's recommended to align the bricks to a 16x16 grid. This makes things convenient when designing levels and when creating the brickset script.

Note

To ensure maximum compatibility with most video cards, brickset images must not exceed 4096x4096 pixels. That's more than enough for most cases, but if you ever run out of space, split the artwork into two or more images. Previously, the limit was 2048x2048 pixels. It was increased in Open Surge 0.5.2. Open Surge 0.2.0 (legacy) had no hard limit, but it was not hardware accelerated.

A brickset image

The brickset script

The brickset script specifies how the bricks get put into the game for your use. It connects the artwork with the game. A brickset script is a .brk file in the themes/ folder. The engine reads this script to know what exactly the bricks are. The physics subsystem take care of the rest once you're done placing the bricks in your levels.

The brickset script references the brickset image. It specifies how big the bricks are, what part of the image to use as their "face", the animation sequence (if any), the collision mask (if any), and their behavior: whether they react as a plain stepping stone, collapse beneath you once touched, act as a "cloud" (we will discuss this soon), move around in mid-air to make jumping challenges, and so on.

The collision mask

In addition to the artwork, you may specify a collision mask, which is an image that specifies the solidity of each pixel of the bricks. A collision mask gives you a finer amount of control regarding how the collisions should be handled. Though optional, having a collision mask is highly recommended. Sometimes collisions require manual inspection, so it's better to create a mask.

Art and collision mask are split into different files. Once the artwork is ready, the mask can be created easily by copying the image and deciding which parts are solid and which aren't. A mask has two basic colors: magenta rgb(255,0,255) or transparent rgba(0,0,0,0) means non-solid. You may use black rgb(0,0,0) as solid. Artwork and mask must be aligned (i.e., share the same position in image space).

Collision masks must be smooth and should have no "holes" in it. Pay attention if your artwork is irregular: in this case you need to adjust the mask. Examples:

  1. if you have a grass brick with lots of "spikes" on top of it, smooth it out: you don't really want "spiky" artifacts affecting the collisions.
  2. if your artwork includes metallic grids or other features with holes in them, fill in the gaps: these artistic features must not affect the collisions.

See also: mask.

Creating & finding artwork

Creating new scenery is related to creating new artwork. You may create the artwork yourself, work with an artist, or find it online. There are many pixel art tutorials on the Internet. Additionally, OpenGameArt provides freely licensed art that you can use and remix.

Tip

When creating your artwork, you may find inspiration in the artwork that is shipped with Open Surge (explore the images/ folder). You can use that as a base to help you get started with your own artwork.

Design guidelines

While you have great flexibility to design your brickset, experience shows that certain approaches work better than others. We present guidelines that increase the likelihood of creating a brickset that easy to use and easy to create.

Divide the brickset into 3 parts (this division is conceptual):

1) Blocks (you may use bricks numbered from 0 to 127)

These are 128x128 bricks that represent: walls, platforms, ceilings, parts of a loop, and so on. They are the building blocks of your level and will help you build its structure. Make sure that they are tileable (repeatable).

2) Things (you may use bricks numbered from 128 upwards)

These are generally passable/decorative bricks like: flowers, trees, rocks, pipes, and so on. All such bricks must be built within a 16x16 grid (width and height must be divisible by 16, like 64x64, 32x64, etc.)

3) Special (you may use bricks numbered from 255 downwards)

These are special bricks such as: movable platforms, breakable walls, and so on. All such bricks must fit a 16x16 grid (width and height must be divisible by 16).

The brickset image may be a .png image of size 1024x1024, 1024x2048, 2048x2048 or even 4096x4096 pixels (depending on your needs). To make things easier, work with two grids simultaneously:

  • A basic grid of 16x16
  • A block-level grid of 128x128

Tip

Imaging software (such as GIMP) have the ability to work with grids. Enable the 16x16 grid in your software. Activate the option snap to grid, so that your grid becomes "magnetic". You may create a separate grid of 128x128 pixels by drawing a custom image and display it on top of your brickset - in a separate layer - while you're working on your art.

If you follow these guidelines, writing the brickset script (.brk file) will be a piece of cake and shouldn't take more than a few minutes. You may either write the brickset script yourself or use automated tools.

A brickset created using these guidelines

Using automated tools

Brickset scripts can be written manually or can be generated automatically using tools such as the Quick Brickset Editor. Although written years ago, JBlocks and the Brickset Editor Tool can still be used today.

Writing the brickset

A brickset script is a text file that has one or more brick definitions.

brick

In the brickset script, every brick definition starts with brick and is followed by its number. Following a logical sequence is highly advisable. After the brick number comes a block containing a set of parameters that describe what the brick is.

A brick is defined like this:

brick 16  
{  
    type                SOLID  
    behavior            DEFAULT  
    mask                "images/brickset_mask.png"     // optional  
    zindex              0.5                            // optional  
  
    sprite  
    {  
        source_file     "images/brickset.png"  
        source_rect     16 224 64 64  
        frame_size      64 64  
  
        animation  
        {  
            repeat      TRUE  
            fps         8  
            data        0  
        }  
    }  
}

We'll now cover the brick parameters.

sprite

The sprite block describes the graphical properties of the brick - how it's going to be displayed on the screen. For more information, read the Sprites page.

type

The type will tell the physics core how to handle collisions with this brick.

SOLID

SOLID means: a solid brick. You can't go through them.

Solid brick You can't go through it

Note

In versions of the engine prior to 0.5.0, the solid brick type was called OBSTACLE.

PASSABLE

PASSABLE means: you can pass through it. It's a non-solid brick, meaning that it doesn't affect collisions. Many scenery elements are passable bricks.

The bushes are passable bricks

CLOUD

CLOUD means: you can go to the top of it from below, but not the opposite. Cloud bricks are also known as "one-way platforms".

The rock is a cloud brick See? You can step on top of it

mask

A collision mask is a mechanism that specifies which parts of the bricks are solid and which parts aren't. This gives you a finer amount of control regarding how the collisions should be handled. Example: if you have a "grass" brick with lots of "spikes" on the top, most likely you don't want the "spiky" artifacts to affect the collisions. Collision masks must always be smooth and should not have any "holes".

Usually, a collision mask is represented by a .png image with two colors only: magenta rgb(255,0,255) or transparent rgba(0,0,0,0) (if the pixel is non-solid) and black rgb(0,0,0) (if the pixel is solid). The collision mask image must be aligned with the brick image, so that the brick and its mask get to be on the same position (although they are on different images, they share the same position). If the brick is animated, the collision mask of the brick must be at the location of the first frame of the animation.

Even though creating a collision mask is optional, it's highly recommended to do so. If this parameter is not specified, the engine will create a collision mask automatically: pixels will be solid if they are not transparent / magenta. Depending on your artwork, this may not be desirable, so creating your own mask is a good idea.

// path to the mask image
mask "images/brickset_mask.png"

Collision mask

zindex

Usually a value between 0.0 and 1.0, zindex specifies the order in which bricks are rendered to the screen. Bricks with a large zindex will be displayed in front of others. Bricks with a small zindex will be rendered behind others. Finally, a brick will be drawn behind the player if, and only if, its zindex is lower or equal to 0.5.

This is an optional parameter. If not specified, it defaults to 0.5.

// the brick will be rendered in front of others that have a lower zindex  
zindex 1.0

// bricks with a higher zindex will be rendered in front of this one  
zindex 0.1

behavior

The behavior specifies the kind of movement or behavior the brick will adopt.

DEFAULT

DEFAULT means: a brick that stands still, with no special behavior. This is the behavior that is likely to be used in most cases. Example:

// a regular brick
type SOLID
behavior DEFAULT

The syntax above shows just the type and the behavior of a brick; a more complete brick definition would be as follows:

// This is just an example  
brick 154  
{  
    type                SOLID  
    behavior            DEFAULT  
    zindex              0.5  
    mask                "images/waterworks_mask.png"  
  
    sprite  
    {  
        source_file     "images/waterworks.png"  
        source_rect     512 768 32 32  
        frame_size      32 32  
  
        animation  
        {  
            repeat      TRUE  
            fps         8  
            data        0  
        }  
    }  
}

FALL

FALL means: the brick will collapse and be destroyed upon being stepped on. Example:

// syntax: behavior FALL horizontal-pieces vertical-pieces [orientation]  
// whenever the player steps on the brick, it will collapse into (horizontal-pieces x vertical-pieces) parts  
type SOLID  
behavior FALL 8 2

An optional orientation parameter may be specified:

  • If orientation is non-negative (e.g., orientation = 1), the brick collapses from the right to the left (default)
  • If orientation is negative (e.g., orientation = -1), the brick collapses from the left to the right

The brick collapses

BREAKABLE

BREAKABLE means: the player can destroy the brick by rolling on it. Example:

// syntax: behavior BREAKABLE horizontal-pieces vertical-pieces  
// the brick will be broken in 25 pieces (5x5) of equal size  
type SOLID  
behavior BREAKABLE 5 5

Breakable bricks

SMASHABLE

SMASHABLE means: a brick that can be smashed when the player jumps on top of it. Similar to BREAKABLE.

Since: 0.5.0

// syntax: behavior SMASHABLE horizontal-pieces vertical-pieces  
// a smashable brick that will be broken in 2 pieces, horizontally  
type SOLID  
behavior SMASHABLE 2 1

Smashable brick

FLOAT

FLOAT means: a brick that goes slightly down when the player steps on top of it. An optional modifier parameter may be specified:

  • If no modifier is specified: the floating brick does nothing special
  • If modifier is 1: the floating brick falls down after the player steps on top of it

Since: 0.5.0

// syntax: behavior FLOAT [modifier]  
type SOLID  
behavior FLOAT

Floating platform

CIRCULAR

CIRCULAR specifies a movable platform that moves along an ellipse.

//  
// syntax: behavior CIRCULAR x-dist y-dist x-speed y-speed [initial-phase]  
//  
// x-dist and y-dist specify how wide/tall is the movement of the brick, in pixels  
// x-speed and y-speed specify the cycles per second rate  
// (try setting both to 0.25; the larger the value, the faster the brick)  
// initial-phase is an optional value in degrees typically set to 0 (default) or 180 (opposite phase)  
//  
  
// Example 1: the brick will move horizontally. The trajectory has an amplitude  
// of 128 pixels (to left and to right, meaning that it is 256 pixels wide), and  
// the brick completes 25% of a cycle in a second (meaning it takes 4 seconds  
// to complete a cycle).  
type CLOUD  
behavior CIRCULAR 128 0 0.25 0 0  
  
// Example 2: the brick will move along a circle of radius 128 pixels,  
// at a rate of 0.25 cycles per second  
type CLOUD  
behavior CIRCULAR 128 128 0.25 0.25 0  
  
// Example 3: a brick like example 2, but in the opposite phase  
type CLOUD  
behavior CIRCULAR 128 128 0.25 0.25 180

Moving platform Another example

PENDULAR

PENDULAR specifies a brick that swings like a pendulum.

Since: 0.5.0

//  
// syntax: behavior PENDULAR radius cycles-per-second [initial-phase [angular-offset [amplitude-offset]]]  
//  
// radius is the distance between the brick (e.g., the weight of the pendulum) and the pivot, in pixels  
// cycles-per-second is typically set to 0.25 (meaning it takes 4 seconds to complete one cycle)  
// initial-phase is a value in degrees typically set to 0 (default) or 180 (opposite phase)  
// angular-offset controls the direction of the swing and is typically set to 0 (default) or 180 degrees  
// amplitude-offset controls the amplitude of the swing and may be set to 0 (default), -30, -45, -60, -90...  
//  
  
// the following is a standard pendular brick with a radius of 128 pixels  
// moving at a rate of 0.25 cycles per second (one cycle takes 4 seconds)  
type CLOUD  
behavior PENDULAR 128 0.25  
  
// a similar pendular brick, but in the opposite phase  
type CLOUD  
behavior PENDULAR 128 0.25 180

Pendular brick Can you see the movement?

MARKER

A MARKER is a brick that is only rendered in the editor. It's used to complement collisions.

Since: 0.5.0

// a marker won't be rendered during gameplay  
type SOLID  
behavior MARKER

angle

The angle parameter is deprecated and should no longer be used. It's ignored by current versions of the engine. It was used in the legacy version of Open Surge, 0.2.0.

The angle parameter told the engine whether the brick was a floor, a wall, a ceiling, or a slope. 0º was usually flat ground, 90º a right wall, 180º a ceiling and 270º a left wall. Anything in between these values were slopes.

Now, to calculate the angle, you used some basic math. The angle was measured from the positive x-axis. A plain floor would have an angle of 0º. Simple walls/blocks (on which the player can't run through them, vertically) would also have an angle of 0º. For slopes, function atan2(y,x) would return the angle.