[Top] | [Contents] | [Index] | [ ? ]

# Enigma Reference Manual

This manual describes the internals of Enigma, in particular how to build new levels using Lua and how to interact with the game engine. It describes Enigma version 0.81.

1. Introduction |  | General remarks on creating new levels
2. Objects |  | Description of all objects in Enigma
3. Variables |  | Per-level settings
4. Functions |  |
Object Index |  |
Variable Index |  |
Function Index |  |

# 1. Introduction

This chapter explains how Enigma works internally and how you can create your own levels. First some bad news: there is no graphical level editor for Enigma, so creating levels is more complicated than pressing a few buttons. But the good news is that Enigma's level format is extremely flexible and allows you to create very dynamic and interactive levels. Enigma's level descriptions are basically small programs, written in a programming language called Lua. Here are a few examples of levels that make heavy use of Lua, both when preparing the level and during the game:

- Flood Gates (``nat8.lua`') Was one of the first levels to use Lua for more than simply building the level and then handing it over to the game engine. The flowing water is controlled by a small function written in Lua--there is no built-in suppport for flowing water in the game engine.

- Enigris (``ralf04.lua`') lets you play Tetris inside Enigma.

- Mourning Palace (``ant08.lua`') moving platforms, also controlled by a Lua function.

- Finally, some of the maze levels and most of the levels in the Sokoban pack are dynamically generated: They look a little different every time you play them.

Our focus is on Lua as the interface to Enigma's game engine, so you won't learn much about Lua as a language in this chapter. Many simple things, like function calls or `if` statements, will appear familiar to anyone having a little programming experience: In many ways Lua is similar to programming languages like Basic or Pascal. But for most of Lua's finer points you will have to reach for the official Lua documentation, which you can download from lua.org.

1.1 Creating New Levels |  |
1.2 A Simple Level |  |
1.3 Registering Levels |  |
1.4 Where to go from here |  |

## 1.1 Creating New Levels

Creating a new level basically consists of the following steps

1. Writing the level description, for example a file named ``daniel01.lua`'.
2. Inserting the new level into a level pack of your choice
3. Creating a preview image for the level
4. Testing the level in Enigma

## 1.2 A Simple Level

Here is a very simple level description that can also serve as a starting-point for new landscapes. (In fact, this is the first level in Enigma, so you can try it out right away.)

     1   CreateWorld(20, 13)
     2   draw_border("st-brownie")
     3   fill_floor("fl-hay", 0,0, level_width,level_height)
     4
     5   set_stone("st-fart", level_width-1,0, {name="fart"})
     6   set_stone("st-timer", 0,0, {action="trigger", target="fart",
     7             interval=10})
     8
     9   oxyd(3,3)
    10   oxyd(level_width-4,level_height-4)
    11   oxyd(level_width-4, 3)
    12   oxyd(3,level_height-4)
    13   oxyd_shuffle()
    14
    15   set_actor("ac-blackball", 10,6.5, {player=0})

The resulting level looks like this inside the game:

Let's now turn to a line-by-line analysis of this program:

     1   CreateWorld(20, 13)
     2   draw_border("st-brownie")
     3   fill_floor("fl-hay", 0,0, level_width,level_height)

The level begins with a call to `CreateWorld`, which creates a new world that is 20 blocks wide and 13 blocks high. Every block in the world can be accessed with a pair of coordinates: The upper left corner has coordinates (0,0), the lower right one has coordinates (19,12). Every block contains a floor tile, an (optional) item, and an (optional) stone.

A frame of stones is drawn around the newly created landscape with the `draw_border` command. Its argument, `"st-brownie"`, is the name of a stone. By convention, all stones have `"st-"` prefixed to their name, similarly all item names begin with `"it-"` and all floor names with `"fl-"`.

The `fill_floor` command in line 3 fills the complete floor with tiles of type `"fl-hay"`. The other arguments are the upper left corner and the width and height of the rectangle to be filled.

     5   set_stone("st-fart", level_width-1,0, {name="fart"})
     6   set_stone("st-timer", 0,0, {action="trigger", target="fart",
     7             interval=10})

Lines 5 to 7 demonstrate how to create individual stones. The `set_stone` command takes a stone name, the desired coordinates, and an (optional) list of attributes as arguments. Note the use of curly braces `{`, `}` to enclose the attribute list.

Attributes are the key to customizing the behaviour of objects in a landscape. Here, we first give a name to the first stone we create. It's a fart stone that has the unpleasant habit of "blowing off" when triggered. Triggering this fart stone is done by the timer stone we create in line 6--7. This stone performs a predefined action at regular intervals. In this case we want to send a "trigger" message every ten seconds to the object named "fart".

     9   oxyd(3,3)
    10   oxyd(level_width-4,level_height-4)
    11   oxyd(level_width-4, 3)
    12   oxyd(3,level_height-4)
    13   oxyd_shuffle()

These commands place a couple of oxyd stones in the level. The `oxyd` command internally uses `set_stone("st-oxyd", x,y, ...)` to create the stones, but it additionally assigns sensible values to some of the oxyd stones' attributes (most notably the color). The command on line 14 permutes the colors on the oxyd stones currently in the landscape.

    15   set_actor("ac-blackball", 10,6.5, {player=0})

This final line creates the black marble controlled by the player. Objects that can move around freely are called "actors" in Enigma. Unlike stones and items, actors are not restricted to integer coordinates, as you can see in this example. The last parameter is, as usual, a list of attributes. In single-player levels this is always `{player=0}` for the black marble, in two-player levels you can use this attribute to assign actors to either the first or second player.

## 1.3 Registering Levels

After writing the level description you have to tell Enigma where to find your brand new landscape. That's really two separate steps:

1. Move the ``.lua`'-File where Enigma can find it;
2. Insert a new entry into the appropriate level index.

The ``.lua`'-Files and the corresponding level index usually reside in the same directory. For the levels that come with Enigma, for example, this is the ``levels`' directory inside. For your own levels you can either use the same directory (currently your only choice if you use the Windows version of Enigma) or the ``.enigma/levels`' directory in your home folder (only if you use the Unix version).

A level index is a file that contains the list of landscapes that comprise a level pack in Enigma. Here is an excerpt from ``index_enigma.txt`', which defines the "Enigma" level pack:

    welcome                     | Welcome                | Daniel Heck
    martin06                    | Is It Easy?            | Martin Hawlisch
    lasers101                   | Lasers 101             | Daniel Heck
    level3a                     | Feel Your Way          | Siegfried Fennig
    martin04                    | Sokoban Revival        | Martin Hawlisch

Every line in this file describes one landscape in the level pack. There are up to three entries in every line, separated by vertical bars `|`:

1. The file name of the level (excluding the ``.lua`' extension). This entry mandatory!
2. The full name of the level. This is the name the player will see in the level menu. You can leave this field empty if you prefer to leave your level unnamed.
3. The landscape's author.

When Enigma starts up it automatically tries to load an index file called ``index_user.txt`', where you can store all your personal levels. This file is not included in Enigma distributions, you have to create it yourself. The levels listed in this file will show up in a new level pack called "User Levels".

## 1.4 Where to go from here

The example level from the first section of this chapter was hopefully enough to give you an impression how level descriptions look like in Enigma. Of course, that level was extremely simple, and most interesting levels will be more complicated. The rest of this reference manual tries to document the available game objects and how to interact with the Enigma game engine, both when preparing the level (before the game starts) and during the game.

This manual only describes the low-level interface to Enigma's game engine, which is as flexible as it is inconvenient to use by hand. Petr Machata has written a comprehensive set of helper routines that greatly simplify the creation of new levels. You can use the package by including the line `Require("levels/ant.lua")` in your level descriptions. There is extensive documentation for ``ant.lua`' in file ``ant_lua.txt`' in the documentation directory.

Before you read on, please be aware that this manual is far from complete. We are working on it and it will be ready for the (glorious) 1.0 release. For the moment, the available level descriptions are the best "documentation" available.

# 2. Objects

2.1 Items |  |
2.2 Stones |  |
2.3 Actors |  |

## 2.1 Items

2.1.1 it-document: Scrolls of Paper |  | Scrolls of Paper

### 2.1.1 it-document: Scrolls of Paper

This item looks like a piece of paper and contains text messages that can be displayed by activating the item. It has the following attributes:

`text`
  The message to be displayed.

    set_item("it-document", 1,1, {text="Hello World!"})

    Document(1,1, "Hello World")

## 2.2 Stones

2.2.1 st-actorimpulse: Bumper Stones |  | Bumper Stones
2.2.2 st-chameleon: Chameleon Stone |  |
2.2.3 st-coinslot |  | Coin Slot Switch
2.2.4 st-death: Skull Stones |  | Skull Stones
2.2.5 st-disco: Disco Stones |  | Disco Stones
2.2.6 st-easymode: Easy Mode Stone |  |
2.2.7 st-fart: Fart Stone |  | Fart Stone
2.2.8 st-floppy: Floppy Switch |  | Floppy Switch
2.2.9 st-grate: Grates |  | Various Grates
2.2.10 st-knight: Knight Stone |  | Black Knights
2.2.11 st-oneway: One-way Stones |  |
2.2.12 st-oxyd: Oxyd Stones |  | The Famous Oxyd Stones
2.2.13 st-rubberband: Rubberband Stone |  |
2.2.14 st-scissors: Scissors Stone |  |
2.2.15 st-stone_break: Breakable Stone |  |
2.2.16 st-swap: Swap Stone |  | Swap Stones
2.2.17 st-thief: Thief Stone |  | Thiefs
2.2.18 st-timer: Timer Stone |  | Timers
2.2.19 st-window: Breakable Stone |  | Breakable Window
2.2.20 st-wood: Wooden Stone |  | Wooden Stones

### 2.2.1 st-actorimpulse: Bumper Stones

These stones apply an impulse to actors that touch them. The amount of force applied can be controlled by setting `enigma.BumperForce` accordingly (the default is 800). Alternatively, the `force` attribute can be used to set this factor for individual bumper stones.

The invisible variant, `st-actorimpulse_invisible` can "painted" with a brush.

### 2.2.2 st-chameleon: Chameleon Stone

This stone takes on the look of the floor beneath it. Actors can move through it, so these stones are perfect for hiding stuff under them...

### 2.2.3 st-coinslot

A switch that can be activated with coins. The more coins you put in, the longer the switch will stay activated.

It has the following attributes:

`target, action`
  As usual

### 2.2.4 st-death: Skull Stones

Simply kills all marbles that touch it (except when protected by an umbrella). There is an invisible variant, `st-death_invisible`.

### 2.2.5 st-disco: Disco Stones

Darkens everything that is underneath the stone (much like tinted glass). Can be switched on and off (hence the name).

#### 2.2.5.1 Messages

`signal`
  With parameter 1, lighten the stone and (recursively) all neighboring disco stones; with parameter smaller than 1, darken them.
`lighten`
`darken`

#### 2.2.5.2 Variants

`st-disco-light`
`st-disco-medium`
`st-disco-dark`

### 2.2.6 st-easymode: Easy Mode Stone

In easy game mode this stone converts the floor at its position to `fl-normal`. In normal game mode the stone removes any item at its position. The stone itself never appears in either game mode; it removes itself immediately after performing its job.

This stone is commonly used to hide danger areas (water holes, abyss) or to insert helper items (umbrellas, seeds, etc.) that make the level easier in easy game mode.

### 2.2.7 st-fart: Fart Stone

The fart stone has the unpleasant habit of "blowing off" when triggered (by actor hit or signal) and will close all Oxyd stones.

#### 2.2.7.1 Messages

`trigger`
  blow off

### 2.2.8 st-floppy: Floppy Switch

A switch that is activated by inserting a floppy disk.

#### 2.2.8.1 Attributes

`on`
  1 or 0
`target`
`action`

### 2.2.9 st-grate: Grates

Floating grates, mainly decorative. Flying objects (jumping marbles, rotors, etc.) cannot pass, objects moving on the floor can.

#### 2.2.9.1 Variants

`st-grate1`
`st-grate2`
`st-grate3`

### 2.2.10 st-knight: Knight Stone

See user manual for a description.

### 2.2.11 st-oneway: One-way Stones

This stone can be passed by the marble in only one direction. (Or, to be more exact, the arrow on the stone points to the one side of the stone through which it can't be entered. Hard to explain, try it yourself :-)

There are three different variants of the one-way stone: the standard one, `st-oneway`, which both the black and the white marble can pass, and two colored ones, `st-oneway_black` and `st-oneway_white`, which completely block marbles of the other color.

#### 2.2.11.1 Variants

`st-oneway`
`st-oneway-[nesw]`
`st-oneway_black`
`st-oneway_black-[nesw]`
`st-oneway_white`
`st-oneway_white-[nesw]`

#### 2.2.11.2 Attributes

`orientation`
  One of `NORTH`, `EAST`, `SOUTH`, or `WEST`. This determines the orientation of the stone when the level is loaded. You need to use the `direction` message for changing the orientation during the game. Note that it is usually easier to use one of the alternative names, like `st-oneway-north` instead of explicitly setting this attribute.

#### 2.2.11.3 Messages

`direction`
  Set the direction of the arrow during the game. Simply setting the attribute `orientation` is not enough, since this does not update the stone's model on the screen.
`signal`
`flip`
  Both these messages flip the direction of the arrow.

### 2.2.12 st-oxyd: Oxyd Stones

Oxyd stones are characterized by two attributes: Their flavor and their color. The `flavor` only affects the visual representation of the stone; it can be either `a' (opening like a flower), `b' (displaying a fade-in animation), `c', or `d'. The `color` attribute determines the color on the oxyd stone.

Note: You should rarely need to create Oxyd stones manually with `set_stone()`. Use the predefined `oxyd()` function instead. It will automatically take care of creating two Oxyd stones of every color.

#### 2.2.12.1 Attributes

`flavor`
  `a', `b', `c', or `d'
`color`
  a number between 0 and 7

#### 2.2.12.2 Messages

`closeall`
  Close all oxyd stones
`shuffle`
`Interchange the colors of the oxyd stones in the current`
  landscape. Use the `oxyd_shuffle` function.
`trigger`
  Open the stone (useful for opening Oxyd stones using switches)

### 2.2.13 st-rubberband: Rubberband Stone

If hit by a marble, this stone first removes existing connections with other rubberband stones and then attaches a new elastic between the marble and itself. Nothing happens if the marble was already attached to this particular stone.

This stone can be moved if hit with a magic wand.

#### 2.2.13.1 Attributes

`length`
  The natural length of the rubberband (default: 1)
`strength`
  The strength of the rubberband (default: 10)

### 2.2.14 st-scissors: Scissors Stone

This stone cuts all rubber bands attached to an actor that touches it.

### 2.2.15 st-stone_break: Breakable Stone

This stone can be destroyed by an actor having a hammer and by laser, dynamite, bombs and bombstones.

### 2.2.16 st-swap: Swap Stone

This stone can exchange its position with other neighboring stones if it is hit hard enough. In a way, this makes swap stones a kind of "movable stone", except that they can be only exchanged with other stones and may not be moved on empty fields.

### 2.2.17 st-thief: Thief Stone

Takes one item from inventory after when hit by the player's marble. Umbrellas protect against thievery.

### 2.2.18 st-timer: Timer Stone

This stone can be used to trigger periodic events or to trigger one single event after a certain amount of time.

#### 2.2.18.1 Attributes

`on`
  1 if the timer is running
`interval`
  number of seconds before `action` is performed
`loop`
  if 1, restart the timer after performing `action`
`action`
  as usual
`target`
  as usual
`invisible`
  if 1, stone is invisible

#### 2.2.18.2 Messages

`on`
`off`
`onoff`

#### 2.2.18.3 Example

    -- activate a laser after 5 seconds
    set_stone("st-laser", 10,11, {name="laser"})
    set_stone("st-timer", 10,10,
              {loop=0, action="onoff", target="laser", interval=5})

### 2.2.19 st-window: Breakable Stone

Hit this window heavily with your marble to blast it into smithereens.

### 2.2.20 st-wood: Wooden Stone

This stone is movable. If moved into abyss, water or swamp it builds a wooden plank.

Note: There are two flavors of `st-wood` which may be specified by using `st-wood1` or `st-wood2`.

## 2.3 Actors

Movable objects are called "actors" in Enigma. The commonest actor is, of course, the black marble, but there are a others, including the white marble, the killerball and a few more.

2.3.1 Actor Attributes |  |

### 2.3.1 Actor Attributes

All actors share a set of common attributes that determine their general behaviour:

`player`
  The player "owning" this actor. This is either 0 or 1 for the first or second player respectively. Actors attached to a player can pick up items and can be respawned when they are killed.
`mouseforce`
  A factor that determines how much the actor accelerates when the mouse is moved. Default is 1, use higher values for fast moving actors. If set to 0, the actor cannot be moved with the mouse (but external forces can still exert a force on it).
`controllers`
  Determines which players may move this actor: 1=Player 1, 2=Player 2, 3=both. By default, `ac-blackball`, `ac-whiteball` and `ac-whiteball-small` have their `controllers` attribute set to 1,2, and 3 respectively.
`whiteball, blackball`
  Used by color-sensitive stones (black/white switches for example) to determine whether the actor is the black or the white marble. These attributes may disappear in future versions, please avoid using them if possible.

# 3. Variables

This chapter describes the Lua variables that can be accessed from level descriptions

Variable: enigma.AllowTogglePlayer
  `TRUE` or `FALSE`

Variable: enigma.Brittleness
  A value between 0 and 1, denoting the probability that a brittle floor plate desintegrates further when an actor enters or leaves it. 1 means that the floor will always crack, 0 that it is indestructible.

Variable: enigma.BumperForce
  The amount of force applied to an actor that hits an `st-actorimpulse` stone. 2.2.1 st-actorimpulse: Bumper Stones.

Variable: enigma.ConserveLevel
  `TRUE` or `FALSE`. If `FALSE`, reload the level whenever the an actor that is controlled by a player (i.e., one that has the `player` attribute set) dies. Often used in meditation landscapes or landscapes that are intended to be solved in one go.

Variable: enigma.ElectricForce

Variable: enigma.FrictionFactor

Variable: enigma.ShowMoves
  TRUE or FALSE. This is only used in the Sokoban level pack.

Variable: enigma.SlopeForce

Variable: enigma.SlopeForce2

# 4. Functions

4.1 AddRubberBand |  |
4.2 CreateWorld |  |

## 4.1 AddRubberBand

Function: AddRubberBand (actor, object, strength, length)

  This function connects two objects with a rubber band: The first object is always an actor, the second object can be either another actor or a stone.

  The first argument actor is always a reference to an actor created earlier with the `set_actor` function. The second parameter object may be either an actor or a stone created earlier. The last two parameters define the properties of the rubber band: strength denotes the force factor of the elastic and length its natural length. No force is exerted on the actor if the rubber band is shorter than its natural length.

### 4.1.1 Example

    local ac=set_actor("ac-blackball", 1.5,7.5, {player=0})
    local st=set_stone("st-brownie", 10,6)
    AddRubberBand(ac, st, 50, 10)

## 4.2 CreateWorld

Function: CreateWorld (width, heigth)

  This function creates a new level. Because objects can only be added to the level after `CreateWorld` has been called, you should usually do so near the beginning of your level description.

  The width and height denote the size of the size of the new level. All levels with only one screen have the minimum size of 20x13 blocks.

  Note that level fields are indexed from zero, i.e, the field indices for a 20x13 level are in the range (0..19)x(0..12). Also note that the screens in Enigma overlap by one line or column: A level that fits on a single screen has size of 20x13, but two a level that is two screens wide 39x13 or 20x25, three screens 58x13 or 20x37.

# Object Index

# Variable Index

Jump to: | E

| Index Entry | Section
E |  |
| `enigma.AllowTogglePlayer` | 3. Variables
| `enigma.Brittleness` | 3. Variables
| `enigma.BumperForce` | 3. Variables
| `enigma.ConserveLevel` | 3. Variables
| `enigma.ElectricForce` | 3. Variables
| `enigma.FrictionFactor` | 3. Variables
| `enigma.ShowMoves` | 3. Variables
| `enigma.SlopeForce` | 3. Variables
| `enigma.SlopeForce2` | 3. Variables

Jump to: | E

# Function Index

Jump to: | A C

| Index Entry | Section
A |  |
| `AddRubberBand` | 4.1 AddRubberBand
C |  |
| `CreateWorld` | 4.2 CreateWorld

Jump to: | A C

[Top] | [Contents] | [Index] | [ ? ]

# Table of Contents

> 1. Introduction

> > 1.1 Creating New Levels
> > 1.2 A Simple Level
> > 1.3 Registering Levels
> > 1.4 Where to go from here

> 2. Objects

> > 2.1 Items

> > > 2.1.1 it-document: Scrolls of Paper

> > 2.2 Stones

> > > 2.2.1 st-actorimpulse: Bumper Stones
> > > 2.2.2 st-chameleon: Chameleon Stone
> > > 2.2.3 st-coinslot
> > > 2.2.4 st-death: Skull Stones
> > > 2.2.5 st-disco: Disco Stones

> > > > 2.2.5.1 Messages
> > > > 2.2.5.2 Variants

> > > 2.2.6 st-easymode: Easy Mode Stone
> > > 2.2.7 st-fart: Fart Stone

> > > > 2.2.7.1 Messages

> > > 2.2.8 st-floppy: Floppy Switch

> > > > 2.2.8.1 Attributes

> > > 2.2.9 st-grate: Grates

> > > > 2.2.9.1 Variants

> > > 2.2.10 st-knight: Knight Stone
> > > 2.2.11 st-oneway: One-way Stones

> > > > 2.2.11.1 Variants
> > > > 2.2.11.2 Attributes
> > > > 2.2.11.3 Messages

> > > 2.2.12 st-oxyd: Oxyd Stones

> > > > 2.2.12.1 Attributes
> > > > 2.2.12.2 Messages

> > > 2.2.13 st-rubberband: Rubberband Stone

> > > > 2.2.13.1 Attributes

> > > 2.2.14 st-scissors: Scissors Stone
> > > 2.2.15 st-stone_break: Breakable Stone
> > > 2.2.16 st-swap: Swap Stone
> > > 2.2.17 st-thief: Thief Stone
> > > 2.2.18 st-timer: Timer Stone

> > > > 2.2.18.1 Attributes
> > > > 2.2.18.2 Messages
> > > > 2.2.18.3 Example

> > > 2.2.19 st-window: Breakable Stone
> > > 2.2.20 st-wood: Wooden Stone

> > 2.3 Actors

> > > 2.3.1 Actor Attributes

> 3. Variables
> 4. Functions

> > 4.1 AddRubberBand

> > > 4.1.1 Example

> > 4.2 CreateWorld

> Object Index
> Variable Index
> Function Index

[Top] | [Contents] | [Index] | [ ? ]

# Short Table of Contents

> 1. Introduction
> 2. Objects
> 3. Variables
> 4. Functions
> Object Index
> Variable Index
> Function Index

[Top] | [Contents] | [Index] | [ ? ]

# About this document

This document was generated by using texi2html

The buttons in the navigation panels have the following meaning:

Button | Name | Go to | From 1.2.3 go to
--- | --- | --- | ---
[ < ] | Back | previous section in reading order | 1.2.2
[ > ] | Forward | next section in reading order | 1.2.4
[ << ] | FastBack | beginning of this chapter or previous chapter | 1
[ Up ] | Up | up section | 1.2
[ >> ] | FastForward | next chapter | 2
[Top] | Top | cover (top) of document |
[Contents] | Contents | table of contents |
[Index] | Index | concept index |
[ ? ] | About | this page |

where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:

- 1. Section One
  - 1.1 Subsection One-One
    - ...
  - 1.2 Subsection One-Two
    - 1.2.1 Subsubsection One-Two-One
    - 1.2.2 Subsubsection One-Two-Two
    - 1.2.3 Subsubsection One-Two-Three <== Current Position
    - 1.2.4 Subsubsection One-Two-Four
  - 1.3 Subsection One-Three
    - ...
  - 1.4 Subsection One-Four

This document was generated by Daniel Heck on October, 11 2003 using texi2html