# How to use the Level Editor
The game has a level editor to create your own levels.

To start the editor, punch the book labelled “Level editor”
in the main menu ship or enter the “`/editor`” chat command.
To exit the editor, use the “Exit” button in the inventory
or enter the “`/ship`” chat command.

If you enter the editor, you start with an empty room,
a larger inventory, and a couple of basic items.
In the inventory menu, you can access all items with the
“Get items” button.

## Creating a level

When you start to create a new level, you should first
choose a size and the level boundaries (the blocks that surround
the level on the floor, walls and ceiling). You can do this
in the “Level settings” in your inventory menu.

The level boundaries need to be specified as itemstrings like
`lzr_core:wood`. Invalid values will be automatically replaced
by a default.

**WARNING**: Reducing the level size will remove all nodes
that would no longer fit into the level!

When you look around in the world, you will see 8 white crosses.
These are the 8 corners of the level. Only the blocks enclosed
by these symbols will be saved. Every level will be automatically
surrounded by the boundary blocks (ceiling, wall, floor) which
are *not* part of the `.mts` level file.

You can now proceed to build the level.

Use the Ultra Pickaxe to remove blocks, and the Ultra Bucket to
remove liquids.

### Level rules

The minimal requirements for every level are:

* Have at least one closed treasure chest (locked or unlocked)
* Have a way to obtain all treasures (which is the goal of every level)
* Have exactly **one** start block (`lzr_teleporter:teleporter_off`)
  (The player starts here)

## Triggers

### Overview

Triggers are very important to proceed in levels. Triggers
are the only method to open locked chests, so they are required
for every level.

The most basic way to add a trigger is to make a detector
send signals to a locked chest. Once the detector is triggered,
it breaks the lock.

### Quick start

Here’s a quick example on how to add a simple trigger
into your level:

1. Place a detector and a locked chest
2. Give yourself the trigger tool in your inventory
   and select it
3. Make sure that “Sender Mode” is active of that
   tool (you can switch modes with the [Place] key)
4. Punch the detector (there should be now a message
   and a marking at the locked chest)
5. Switch to Receiver Mode
6. Punch the chest

Now when the detector is activated by a laser, it will
send a signal to the locked chest, causing it to
break open in the game.

(note that locks never break while in the editor.)


### Description

Triggers are blocks that send signals towards other blocks to make
them do something. Signals are instantaneous and wireless.

There are two types of triggers: Senders and receivers.
Senders send signals to receivers. A sender can send
to multiple receivers at once, and a receiver can receive
signals from multiple senders at once. This is a n:m relation.

This are senders:

* Detector: May send signals to receivers when toggled
* Lever: May send signals to receivers when pulled

These are receivers:

* Emitter: May toggle the laser when it receives a signal
* Locked chest: May break the lock when it receives a signal.
  The lock will be broken forever.
* Light box: May toggle the lamp when it receives a signal
* Locked door/trapdoor: May break when it receives a signal
* (possibly others)



### Signal types, sender types and receiver types

The trigger system is quite complex and has a lot of hidden logic.
First of all, when a signal is sent, it is one of 3 possible types:
ON, OFF and TOGGLE. The ON signal normally activates the receiver,
the OFF normally deactivates it and TOGGLE normally toggles it.

Each sender has a sender type, which determines which signal type
(ON, OFF or TOGGLE) is sent (if any) to its receivers, and when.
The signal type depends on the sender's state (active or inactive).

Also, each receiver has a receiver type, which determines how it
will react to an incoming signal.

#### Sender types

The most basic sender type is *Synchronized*. If the sender was
activated, it sends an ON signal. If it was deactivated, it sends
an OFF signal. Thus “synchronizing” the sender with the receiver.
It also has a special meaning in combination with the
synchronized receiver types.

The following table lists all sender types:

    +-----------------------+----------+------------+
    | Sender type           | Activate | Deactivate |
    +-----------------------+----------+------------+
    | Synchronized          | ON       | OFF        |
    | Synchronized inverted | OFF      | ON         |
    | Toggle                | TOGGLE   | TOGGLE     |
    | Toggle ON             | ON       | ON         |
    | Toggle OFF            | OFF      | OFF        |
    | Activate TOGGLE       | TOGGLE   | (none)     |
    | Activate ON           | ON       | (none)     |
    | Activate OFF          | OFF      | (none)     |
    | Deactivate TOGGLE     | (none)   | TOGGLE     |
    | Deactivate ON         | (none)   | ON         |
    | Deactivate OFF        | (none)   | OFF        |
    +-----------------------+----------+------------+

Explanation: The cells show which signal a sender must
send when it activates or deactivates.
The “Activate” column shows which signal is sent when the
sender is deactivated, the “Deactivate” shows which signal
is sent when the sender was deactivated.
“(none)” means that no signal is sent at all (which is
different than sending an OFF signal).

#### Receiver types

These are the receiver types:

* **Any**: The receiver will react on any incoming signal.
  It will turn on, off or toggle, when the incoming signal
  was ON, OFF or TOGGLE, respectively.
* **Synchronized AND**: Receiver activates when it receives any
  signal and all its associated senders of type *Synchronized*
  are active and those of type *Synchronized inverted* are
  inactive.
* **Synchronized NAND**: Same as *Synchronized AND*, but negated.
  It would deactivate when *Synchronized AND* would activate
  and vice-versa
* **Synchronized OR**: Receiver activates when it receives any
  signal and any its associated senders of type *Synchronized*
  are active or any of those of type *Synchronized inverted* are
  inactive.
* **Synchronized NOR**: Same as *Synchronized OR*, but negated.
  It will deactivate when *Synchronized OR* would activate
  and vice-versa

The *Any* type is the simplest one, as it just does what the
incoming signal says. It is most useful for receivers with
only one sender. It works with multiple senders, too,
but things may get complicated fast.

The *Synchronized AND* type is useful if you want a number of
detectors to be activated (or deactivated) at the same time.
Just make sure that all senders are of type *Synchronized*
or *Synchronized inverted*.

Note that all receiver types are compatible with all sender
types, but not all combinations may be useful.



## Saving and loading

When you're happy with the level, use the “Save level” button in your
inventory.

Your level will be saved in the **world directory** in two files:

* The level schematic goes to `levels/<level name>.mts`
* The level settings go to `levels/<level name>.csv`

The `.mts` file is a Minetest schematic which is where all the blocks go.
It may also be edited by other tools that support this file format.

**WARNING**: If you delete the world, you will also lose all custom levels
stored in the world!

Loading the level works in a similar fashion with “Load level”.

You may also use the commands `editor_save` and `editor_load` instead.

### Auto-save

To prevent loss of work, the editor will automatically save the level
into `_AUTOSAVE_` at the following events:

* Leave the game
* Leave the editor
* Change level size or boundary nodes

`_AUTOSAVE_` will be overwritten whenever one of these events happen,
so make sure to save your work into other files.

## Testing the level

All levels created in the editor (except `_AUTOSAVE_`) will be available
to play in the main menu ship as a custom level.
You can start playtesting the level here.


## Adding the level to the game

If you think you made a nice level, send it to Wuzzy per e-mail at
Wuzzy@disroot.org.

If you have multiple levels, you may construct a level pack. See
`LEVEL_PACKS.md` for details.


### Adding a level to the core levels

To add a new level to the core level set, the following technical
steps are performed:

First, copy the level `.mts` file to `mods/lzr_levels_core/schematics`.

Then open the `.csv` file from the `levels` folder in the world directory
and copy the single line of text. Add this line to
`mods/lzr_levels_core/data/level_data.csv`.

Now just restart the game and the level should appear!




## Appendix

### Syntax of `level_data.csv`

Although not strictly necessary to understand this, here is the syntax
of `level_data.csv`. This is a comma-separated values
file (compliant with RFC 4180) where each record represents a level.
Note that a single record may have *multiple* lines!

Each record contains multiple values, in this order:

* `<file name>`: File name of the level `.mts` file
* `<level name>`: Name of the level as shown to the player, in English
* `<border list>`: List of border blocks, see below
* `<ambience>`: Background music. See the mod `lzr_ambience` for available tracks
* `<sky>`: Sky ID. See the mod `lzr_sky` for available skies. (optional)
* `<npc_texts>`: This is the text that will show when the player interacts with Goldie the Parrot. It may contain line breaks (CR LF). (optional)
* `<weather>`: Weather ID. See the mod `lzr_weather` for available weathers. (optional)
* `<backdrop>`: Backdrop ID. This is the environment that surrounds the playable level area. One of `ocean`, `islands`, `underground`, `sky`. (optional)
* `<backdrop_position>`: Backdrop position, written in format (x,y,z). Only relevant for the `islands` backdrop. (optional)
  A coordinate within a given backdrop to put the level in. The bottom left front corner of the level will be at that position. (optional)
* `<triggers>`: Serialized metadata for triggers, generated automatically by the game. The exact syntax can be found in the `lzr_lasers` mod. (optional)
* `<flags>`: List of level flags. This is a list of words that each activate a special behavior for the level. Flags are separated with `|`. These level flags exist:
  * `show_controls_<TYPE>`: Display game controls on screen. `<TYPE>` is one of:
    * `basic`: basic controls: look, move, interact, punch, menu
    * `punch`: punch controls: punch, interact, menu
    * `select_item`: item selection controls: select item, punch, place/interact, inventory, menu
  * `mark_parrot_talk`: Show a message/icon above parrot NPC (non-hidden) to indicate that you should talk to it
  * `parrot_hint`: The parrot will first ask if the player wants a hint before showing the parrot speech. Should not be used in tutorial levels
  * `hide_items`: Hide the inventory. Meant for early tutorial levels only, before the player receives items
  * `remove_plants_above`: Remove nodes in the `tree`, `leaves` or `plant` group above the level ceiling (up to 24 node lengths) (useful to remove floating palms)

Border list is a list of nodes used for the level border.
It contains 1-4 node names, separated by `|`. The border nodes are, in this order:

* Wall|Ignored|Floor|Ceiling

Wall is mandatory, the rest is optional. Ignored can be any text and will be
ignored. If floor or ceiling are missing, they will the same as wall.

Note: The same syntax is also used for the `.csv` files created by the level
editor, the only difference is that these files only contain 1 CSV record,
namely for the level they apply to.



### Using the level editor with WorldEdit

If you use the WorldEdit mod, it must be used with care.

The recommended use is to use WorldEdit *before* you configure the
triggers.

If you used WorldEdit commands to change any trigger node, this invalidates
the triggers of the level, leading to an invalid state and you can’t
properly work with the triggers anymore and the level might be
saved incorrectly.

Thus, whenever you changed any trigger node with WorldEdit, you *must*
manually call `/reset_triggers` after that. This puts the level editor
back in a valid state. The downside is that you lose all triggers
and you have to add them back from scratch.



### List of HUD icons

The editor has many icon overlays. This is a reference of all of them:

Trigger icons:

* **Green arrows pointing outwards**: Sender
* **Red arrows pointing inwards**: Receiver
* **Square corners**: The sender currently selected by the trigger tool
* **Small yellow dots**: A relation between sender and receiver

Sender type icons:

* **White equals sign**: Synchronized
* **Black unequals sign**: Synchronized inverted
* **Yellow octagon with half-filled circle**: Toggle
* **Yellow octagon with filled circle**: Toggle ON
* **Yellow octagon with empty circle**: Toggle OFF
* **Green square with half-filled circle**: Activate TOGGLE
* **Green square with filled circle**: Activate ON
* **Green square with empty circle**: Activate OFF
* **Red circle with half-filled circle**: Deactivate TOGGLE
* **Red circle Yellow with filled circle**: Deactivate ON
* **Red circle Yellow with empty circle**: Deactivate OFF

Receiver type icons:

* **Vertical line**: Any
* **Ampersand**: Synchronized AND
* **Exclamation mark with plus**: Synchronized NAND
* **Plus**: Synchronized OR
* **Exclamation mark with plus**: Synchronized NOR

Level icons:

* **Tiny white plus sign**: One of the corners of the level area
