Skip to content

backgrounds

alemart edited this page Jan 6, 2025 · 2 revisions

Backgrounds

Overview

In Open Surge a background is composed of two elements: the background script and the background image.

The background image contains all the visual elements of the background, while the background script contains the definitions of the background such as dimensions, layers, and behaviors.

A background image is nothing without the script, even if you want to have a static background. There is a very simple reason for this. Even though making a static background looks easy as 123, the very same static background can be assembled in hundreds of different ways just by specifying different source points for the image, layering the background parts differently, or even by playing around with the scrolling speeds.

So, to summarize it, the most basic elements of a background are:

  • The background image (an image in the .png format stored in the images/ folder)
  • the background script (a plain text file with .bg extension stored in the themes/ folder)

My first background

Starting a background script

Assuming you have already chosen an image for your background, we will use the one below as reference:

images/sunshinesky.png (design by KZR)

Now open your text editor, start a new file, and you may want to add this to the start:

// Open Surge Background  
// by User001  
// Background theme for My Zone  

The // is the symbol that notes a line as a comment, and this means the engine will not read this line, as it is only meant to inform you, "the creator", or other people, "the modders", of important details about the background script.

Having this at the start of the file informs:

  • line one tells us this file is an open surge background.
  • line two tells us who created this file.
  • line three tells us what this background file was made for.

Also, if you are editing someone else's file, you should also add:

// Modified by user002

and this is what we call a header, even though this is a very simple one with only comments and no commands.

Simple background

Now that you are done with the header, you can leave some empty paragraphs, then start the very first layer.

Once again, the // symbol is useful here to help you identify which layer represents a certain part of the image.

This is an example of a code block for a background layer

// sky   
background  
{  
   initial_position    0 -64  
   scroll_speed        -0.01 0  
   behavior            DEFAULT  
   repeat_x            TRUE  
   repeat_y            TRUE  
   zindex              0.2  
     
   sprite  
   {  
       source_file     "images/sunshinesky.png"  
       source_rect     0 0 768 192  
       frame_size      768 192  
  
       animation  
       {  
           repeat      TRUE  
           fps         1  
           data        0  
       }  
   }  
}

Each background { ... } block represents a layer. You can have one or more layers per background script. In this example, we only have one layer.

So you start the first line with the word "background", so the engine knows it will create a background, and it will add the properties below.

The { and } symbols open and close a block. Blocks may contain commands, parameters and other blocks.

Important

You should always respect the structure shown in the example. Misplaced { } will make your background unable to load.

My second background

Here is a more advanced background with parallax scrolling and rain:

Images
images/rain.png
images/darkforestbg.png
images/darkforestsky.png
// Open Surge Background  
// by Mateus Reis (KZR)
// Background theme for Dark Forest Prototype  
  
// sky 0  
background  
{  
   initial_position    0 0  
   scroll_speed        0 0  
   behavior            DEFAULT  
   repeat_x            TRUE  
   repeat_y            true  
   zindex              0  
  
   sprite  
   {  
       source_file     "images/darkforestsky.png"  
       source_rect     0 0 16 16  
       frame_size      16 16  
  
       animation  
       {  
           repeat      TRUE  
           fps         1  
           data        0  
       }  
   }  
}  
  
  
// sky 1  
background  
{  
   initial_position    0 128  
   scroll_speed        -0.0 -0.04  
   behavior            DEFAULT  
   repeat_x            TRUE  
   repeat_y            FALSE  
   zindex              0.1  
     
   sprite  
   {  
       source_file     "images/darkforestsky.png"  
       source_rect     0 0 768 256  
       frame_size      256 256  
  
       animation  
       {  
           repeat      TRUE  
           fps         15  
           data        0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 2  
       }  
   }  
}  
  
// mountains 1  
background  
{  
   initial_position    0 160  
   scroll_speed        -0.10 -0.04  
   behavior            DEFAULT  
   repeat_x            TRUE  
   repeat_y            FALSE  
   zindex              0.2  
     
   sprite  
   {  
       source_file     "images/darkforestbg.png"  
       source_rect     0 0 640 256  
       frame_size      640 256  
  
       animation  
       {  
           repeat      TRUE  
           fps         8  
           data        0  
       }  
   }  
}  
  
// riverside forest 1  
background  
{  
   initial_position    0 384  
   scroll_speed        -0.30 -0.05  
   behavior            DEFAULT  
   repeat_x            TRUE  
   repeat_y            FALSE  
   zindex              0.5  
     
   sprite  
   {  
       source_file     "images/darkforestbg.png"  
       source_rect     0 256 640 288  
       frame_size      640 288  
       animation  
       {  
           repeat      TRUE  
           fps         8  
           data        0  
       }  
   }  
}  
  
// rain 1  
background  
{  
   initial_position    0 0  
   scroll_speed        10 20  
   behavior            linear -50 150  
   repeat_x            TRUE  
   repeat_y            true  
   zindex              1  
  
   sprite  
   {  
       source_file     "images/rain.png"  
       source_rect     0 0 64 64  
       frame_size      64 64  
       animation  
       {  
           repeat      TRUE  
           fps         8  
           data        0  
       }  
   }  
}  
  
// rain 2  
background  
{  
   initial_position    0 0  
   scroll_speed        15 25  
   behavior            linear -100 200  
   repeat_x            TRUE  
   repeat_y            true  
   zindex              1  
  
   sprite  
   {  
       source_file     "images/rain.png"  
       source_rect     0 0 64 64  
       frame_size      64 64  
       animation  
       {  
           repeat      TRUE  
           fps         8  
           data        0  
       }  
   }  
}  

Command reference

initial_position

Syntax: initial_position x_position y_position

Receives two parameters: X position and Y position. both counting from the top left edge of the level. higher X values mean to the right, higher Y values mean downwards.

scroll_speed

Syntax: scroll_speed x_speed y_speed

Receives two parameters: X speed and Y speed. Positive values mean the background will be moving in the same direction you are, which looks unnatural, but can be used to create a different effect. Negative values scroll the background in the opposite direction of movement, which is how things work in real life.

If the (horizontal or vertical) speed is close to zero, then the layer becomes very slow (good for distant backgrounds). If it's not close to zero, then it gets faster. If the number is negative, then it moves in the opposite direction of the camera (useful on most cases). If the number is positive, then it moves in the same direction of the camera (which would be very strange in most cases). Finally, if the horizontal (vertical) speed is zero, then it doesn't move horizontally (vertically).

behavior

Syntax: behavior behavior_name [parameter1 [parameter2 ... [parameterN] ... ]]

Specify a behavior with zero or more parameters.

Available behaviors are:

DEFAULT

  • Syntax: behavior DEFAULT
  • This default behavior is meant to only scroll the background on player movement.

LINEAR

  • Syntax: behavor LINEAR x_speed y_speed
  • This behavior makes the background scroll with constant speed, in addition of camera or player movements. x_speed and y_speed are given in pixels per second.

CIRCULAR

  • Syntax: CIRCULAR x_amplitude y_amplitude x_speed y_speed [x_initialphase [y_initialphase]]
  • This behavior makes the background describe a circular or elliptical movement. The center of the movement is the position of the background. x_amplitude and y_amplitude are given in pixels; x_speed and y_speed, in cycles per second, and x_initialphase and y_initialphase are optional parameters ranging from 0 to 359, inclusive (the default value is zero).

repeat-x

Syntax: repeat-x VALUE

VALUE is TRUE if the layer must be repeated horizontally, or FALSE otherwise.

repeat-y

Syntax: repeat-y VALUE

VALUE is TRUE if the layer must be repeated vertically, or FALSE otherwise.

sprite

The sprite section in a background { ... } block is used to tell the game engine how the layer looks like graphically. Refer to: Sprites

zindex

Syntax: zindex VALUE

VALUE is a number between 0 and 1 (inclusive) specifying the order in which background layers must be rendered. Layers with higher z-index will be rendered after layers with lower z-index.

If no zindex property is specified, the order in which the layers are rendered (printed to the screen) are given according to the order of their declaration in the .bg file. However, you can change this behavior by specifying a zindex value. If no zindex is declared, layers have zindex equal to zero.

Let's see an example:

  • Let A, B, C and D be layers with z-indexes equal to 0.0, 0.5, 0.7 and 1.0, respectively.
  • Then, layer A will be displayed behind layer B, which will be displayed behind layer C, which will finally be displayed behind layer D.
  • This would be the same as declaring A, B, C and D in alphabetical order in the .bg file, but there's more: layers with zindex greater than 0.5 are foregrounds - they are rendered after other level elements like bricks, items and the player itself.
    • This means that layers C and D are foregrounds, while A and B are regular backgrounds.

Formulas

You don't need to know this, but in case you're curious, the position of a layer with no attached movement behaviors in the screen is given by:

xpos = initial_xpos + topleft_xpos * speed_x
ypos = initial_ypos + topleft_ypos * speed_y

Where topleft is the position of the top-left corner of the screen related to the level. If you're making a foreground, these formulas can be useful to know where you should position your layer.