ReTux


Editing Levels

Levels are, of course, the meat of any levelset. They are what you will spend the most of your time on. Levels are stored in Tiled JSON files found under the data/levels directory.

Table of Contents

Level Properties

When you create a new copy of data/levels/base.json, you will have an empty level with a size of one screen, the "arctis" background, and the music set to "chipdisko.ogg". Of course, you don't want every level you create to be in this configuration.

Changing the size of a level is simple enough: simply resize the map to the desired size. Each screen is 25 tiles wide by 14 tiles tall, so keep this in mind when choosing your level's size.

The background used for the level is specified by the custom "background" (string) map property. The following background names can be entered:

To see what each of these backgrounds look like, see the images in data/images/backgrounds. You can also append "_castle" to any of these background names to get a castle background with the chosen background name visible out the windows; for example "arctis_castle" will create a castle background, with windows showing the arctis background outside.

You can also control the positioning of the background within the level. This is especially useful if your level is taller than one screen; it allows you to align the background with the bottom of the level, for instance. The positioning of the background is controlled with the custom "background_x" (int) and "background_y" (int) map properties, which indicate the number of pixels (not tiles) to reposition the background to the right and down, respectively. For example, to align the background to the bottom of the level when the level's height is 24 tiles, you can set "background_y" to 320 (that's the height of the tiles multiplied by the difference between the level's height and the height of one screen).

The music used for the level is specified by the custom "music" (string) map property. This should be the exact file name of one of the files found in data/music. If another file exists with the same name, but with "-start" at the end of the base file name (before the extension), then ReTux considers that file to be the start of the music and plays it once before playing the indicated file.

It is possible to include a custom music file with a level set. If you do this, please make sure the file name is reasonably unique so that your custom music is not likely to conflict with another level set's custom music, and place it in your data/music directory. It is also possible to make the level not play music by deleting the existing "music" custom property.

The name of the level is indicated by the custom "name" (string) map property. This can be anything you like; it will be displayed when the player is on the level's worldmap space. If this is not specified, something like "Level 1" (indicating the appropriate level number) will be shown instead.

There are also a few other map properties you can specify. A list of all available custom map properties follows:

Sub-Levels

In some cases, it can be desirable to have multiple areas in a level. For example, you may want to add a bonus area, or you may want to create a series of rooms in a castle. To achieve this, any level can have multiple sub-levels.

Sub-levels are exactly the same as regular levels, with only two key differences:

  1. The "name" and "time_bonus" properties have no effect.
  2. They cannot be entered directly from the worldmap and are not listed in the levelset's list of levels; instead, the main level provides a warp pipe or door which leads to the sub-level.

We will discuss Spawning-related Objects and Warp Pipes which can be used to warp between sub-levels later on.

Level Construction

Constructing a level consists of two tasks: designing the look of the level, and specifying the behavior of the level.

The look of the level is generally customized by placing tiles. Tiles are found in any tileset which is not defined as a particular object. They have no effect on the game other than appearance. data/levels/base.json comes with three tile layers, but you can add more tile layers if needed.

The behavior of the level is controlled by various collision objects. The types of collision objects are:

To create any of these collision objects, simply draw a rectangle object and set its type to the appropriate type listed above. In general, it is suggested to put these objects in the "Collision Objects" layer, but there is no particular requirement for you to do this. Alternatively, as a convenience, you can draw a rectangle in the "solid" layer without specifying a type, and it will be implicitly defined as a "solid" collision object.

The timeline switched to by "timeline_switcher" collision objects is defined by the custom "timeline" (string) property. This should be the name of a timeline file located in data/timelines.

The spawn point used for "checkpoint" collision objects is defined by the custom "dest" property. This should be the ID of a spawn point within this level file, or alternatively a string in the form "levelname:id", where "levelname" is the file name of the sub-level located in data/levels, and "id" is the ID of a spawn point within that sub-level.

Objects

Of course, a level without objects, such as the player and enemies, would not be very fun. There are several different types of objects that can be placed in a ReTux level.

Each of these objects is technically a particular tile in a particular tileset. Simply place the appropriate tile in the level as an object. Any object layer other than the ones with all-lowercase names can be used, and you can create new object layers if desired. However, to maintain consistency, you should generally layer objects the following way, from front to back:

  1. Players
  2. Enemies and other NPCs
  3. Items and special blocks

base.json comes with three layers named "Players", "NPCs", and "Items" for use in layering objects the proper way.

Tux

Tux is the first tile found in the "creatures" tileset. Its type name is "player". One Tux object must exist in every level for it to be playable.

A Tux object can optionally have the following custom properties defined:

While "human" is False, Tux can be controlled by a timeline in the following ways (see Creating Timelines for more information about timelines):

Basic Enemies

ReTux has a variety of enemies that can be placed in a level. Most of the basic enemies are tiles found in the "creatures" tileset. If they touch the player from the side or bottom, the player is hurt. Many enemies can be "stomped" by the player landing on top of them; those that cannot be "stomped" instead hurt the player in this case.

Snowman

The snowman is the only tile found in the "snowman" tileset. His type name is "snowman". This is a boss consisting of four stages:

  1. Prior to stage 1, he is dormant and does nothing.
  2. Prior to the "strong" stage, he simply constantly chases Tux at a slow speed.
  3. Starting on the "strong" stage and prior to the "final" stage, he constantly chases Tux at a slightly faster speed, but if Tux is above him, he jumps 7 tiles.
  4. During the "final" stage, he simply constantly chases Tux at a fast speed.

In between stages is the stunned phase, in which he simply runs back and forth at a very fast speed for a brief moment. During this time, he cannot be damaged or killed. After the stunned phase, he dies if currently on the "final" stage, or advances to the next stage otherwise.

Outside of the stunned phase, being stomped, knocked, or blasted causes him to immediately enter the stunned phase. He also enters the stunned phase if his hitpoints reach 0. Any time the stunned phase is entered, his hitpoints are reset to their original value. When knocked by another object, the responsible object is also knocked. When burned, his hitpoints reduce by 1. He cannot be frozen.

This boss is similar to Boom-Boom from Super Mario Bros 3.

A snowman object can optionally have the following custom properties defined:

Raccot

Raccot is the only tile found in the "raccot" tileset. His type name is "raccot". This is a boss which alternates between using the icicle attack ("hopping"), which causes Raccot icicles above Tux to fall, and charging at Tux. While charging, if Tux is above him or he cannot get closer to Tux, he jumps 5 tiles. While in the air, if he is above Tux, he ceases horizontal movement and comes crashing down at a high speed ("crushing"), destroying any crates he lands on. He is unaffected by stomping. When knocked, he is unaffected and the responsible object, if applicable, is also knocked. He cannot be burned or frozen. When blasted, his hitpoints reduce by 1. If his hitpoints reach 0, he dies.

This boss is similar to Bowser from Super Mario Bros 3.

Raccot has three major stages:

  1. In stage 0, he is dormant and does nothing.
  2. In stage 1, he does not do anything on his own, but can be controlled by the currently active timeline.
  3. In stage 2, he fights normally.

During stage 1, Raccot can be controlled by a timeline in the following ways:

A Raccot object can optionally have the following custom properties defined:

Hittable Blocks

Hittable blocks are blocks which can be "hit". This can be done by Tux bumping into the block with his head, by hitting the bottom or one of the sides of the block with a flat walking iceblock, or by blasting the block. When any hittable block is hit, all knockable objects standing on the hittable block are knocked.

Basic Items

Some objects are provided for the player to collect or use in some way.

Other Special Blocks

Spawning-related Objects

Moving Object Paths

Moving object paths are polylines which define motion for a particular object.

A moving object path is created by drawing a polyline and setting its type to the appropriate type name. The path implicitly creates the object it defines the movement of in the same layer as the path.

Any moving object path can optionally have the following custom properties defined:

The types of moving object paths are:

Circoflame Paths

Circoflames are fireballs which circle around a point. They hurt the player on contact and are destroyed when frozen. This enemy is similar to the rotodisk from Super Mario Bros 3, although multiple circoflames can also be used together to create something like the firebar from Super Mario Bros.

To place a circoflame, draw a line from the top-left corner of the tile the circoflame should circle around to the top-left corner of the tile the circoflame should start in. Set the type of this line to "circoflame".

A circoflame path can optionally have the "rvelocity" custom property defined. This is a number indicating how much the circoflame's angle in degrees relative to the center changes every frame (a frame is 1/56 of a second). Clockwise rotation is positive and counterclockwise rotation is negative. Default is 2.

A circoflame path is actually a shortcut to creating a "circoflame center". If you want, you can place a circoflame center directly, or you can spawn circoflame centers with an object warp spawn. The circoflame center is the 14th tile found in the "creatures" tileset. Its type name is "circoflame_center". A circoflame center can optionally have the "radius" (int) property, which indicates the distance of the circoflame from the center in pixels, and the "pos" (float) property, which indicates the initial angle of the circoflame in degrees relative to the center (where 0 is pointing directly to the right and positive rotation is clockwise). The default values of these properties are 128 (4 tiles) and 180 (pointing directly to the left), respectively.

Warp Pipes

Warp pipes are defined in ReTux as paths. There are two kinds of paths: warp paths, which should be drawn in the "warp" layer, and warp spawn paths, which should be drawn in the "warp_spawn" layer. Both kinds of paths should be drawn as polylines beginning and/or ending in the middle of the two-tile pipes they correspond to.

Warp paths indicate paths for the player to warp into. When the player warps into a warp pipe, the warp path is followed to the end. If the custom "dest" property is defined, this indicates the spawn point that the player is sent to when the end of the warp path is reached. This should be the ID of a spawn point within this level file, or alternatively a string in the form "levelname:id", where "levelname" is the file name of the sub-level located in data/levels, and "id" is the ID of a spawn point within that sub-level. "levelname" can also be "__main__" to specify that the main level should be warped to; this can be useful for bonus areas used by multiple levels. If the "dest" property is undefined, when the end of the warp path is reached, the player simply exits out of the warp from the end of the path in the direction it is pointing.

A warp path's "dest" property can also be specified as "__map__". In this case, the pipe will not warp the player to another level, but instead will cause the player to return to the map. This generally should only be done for levels that exist between warp spaces on worldmaps. Note that if the level set does not have a worldmap, this will instead cause the game to end.

Warp spawn paths indicate paths for the player to warp out of. They are a form of spawn point. A warp spawn path's ID is indicated by the "spawn_id" custom property. When Tux spawns into a warp spawn path, he is positioned at the beginning of the path and follows it to the end. When the end of the warp spawn path is reached, Tux exits the warp from the end of the path in the direction it is pointing.

Object Warp Spawns

An object warp spawn is a special kind of warp spawn path which is used to spawn objects, such as enemies, instead of the player. The path should be drawn the same way as a regular warp spawn, but in the appropriate layer for the object it will spawn (for example, the NPCs layer if it will spawn enemies) and given the "object_warp_spawn" type. The "cls" (string) custom property should be defined to indicate the type name of the object it should spawn.

An object warp spawn path can optionally have the following custom properties defined:

All other custom properties will be passed on to the objects when they are spawned.