This manual describes the internals of Enigma, i.e., how to build new levels using Lua and how to interact with the game engine.  It corresponds to Enigma version 0.80.

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--the game engine knows nothing about it.

  * 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 (http://www.lua.org).

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.

Objects
*******

Stones
======

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...

st-death: Skull Stone
---------------------

Simply kills all marbles that touch it (except when protected by an umbrella).  st-death_invisible.

st-death_invisible: Invivible Skull Stone
-----------------------------------------

Simply kills all marbles that touch it (except when protected by an umbrella).  This variant is invisible.  st-death.

st-disco: Disco Stones
----------------------

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

Messages
........

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

Variants
........

st-disco-light

st-disco-medium

st-disco-dark

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.

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.

Messages
........

trigger
     blow off

st-floppy: Floppy Switch
------------------------

A switch that is activated by inserting a floppy disk.

Attributes
..........

on
     1 or 0

target

action

st-grate: Grates
----------------

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

Variants
........

st-grate1

st-grate2

st-grate3

st-knight: Knight Stone
-----------------------

See user manual for a description.

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.

Attributes
..........

length
     The natural length of the rubberband (default: 1)

strength
     The strength of the rubberband (default: 10)

st-scissors: Scissors stone
---------------------------

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

st-stone_break: Breakable Stone
-------------------------------

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

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.

st-thief: Thief Stone
---------------------

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

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.

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

Messages
........

on

off

onoff

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})

st-window: Breakable Stone
--------------------------

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

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.

Variables
*********

Functions
*********