# Monospace Engine Manual

Written for Monospace Engine Version 0.1.0.

For more information and the latest updates, visit monospace.games/engine.

Copyright © 2024 Monospace Games

## Intro

Hello!

Thank you for your interest in Monospace Engine.

Monospace Engine is a 2D game engine designed to make making games simple and fun. This manual contains everything you need to know to make games with it, or modify any Monospace Engine game you want. It is split into three sections: Basics, Reference, and Tutorials.

- The Basics section explains the central ideas behind the engine and how it works. It's a relatively short tutorial for anyone looking to get started.

- The Reference section contains a complete list of all engine features, alongside examples and explanations.

- And finally the Tutorials section contains a few useful tutorials that show how to use the engine's various features to implement some common use cases.

This manual is written for Monospace Engine Version 0.1.0. To keep up with the development of Monospace Engine visit monospace.games/engine.

If you have any suggestions or need any help feel free to send me an email at monodev@monospace.games.

I hope you like the engine and have fun creating things with it!

## Basics

The central idea of Monospace Engine is that games are made up of files that anyone can access and edit. These files can be things like images, sounds, plaintext files, or Lua code, but the important thing is that it's all user configurable. Anyone can take any game and edit, remove or replace any part of it, or add new things as they want.

Let's take a look at a Monospace Engine game to see how this works. Open the directory in which you have the engine installed, and you'll see that it contains the following:

monospace.exe
  The engine executable
user-manual.html
  This manual
games
  A directory containing installed games
common
  A directory containing common data

Now open the games directory, and you'll see that it contains a directory for each game you have installed. There is one thing that is common across these directories: they all must have a main.txt file in them. These main.txt files are plaintext files that can be opened (and edited!) with any text editor, such as Notepad. Let's go into the samplonia directory, and take a look at its main.txt file:

    GAME OBJECT

    [Samplonia]
        FILES:
            tilesets.txt
            maps.txt
            actors.txt
            keymaps.txt
        PLAYER:
            Sample_Duck
            CONTROLS: Player_Keymap

You already know what this describes! A game called Samplonia, that's made up of the listed files, where the player controls a character named Sample_Duck, and the controls are determined by Player_Keymap. You could add another file to that list and it'd become part of the game. Or you could go into any of the files listed and change them to your liking. Or you could change the player character, or the controls, etc. It's all configurable!

But before we get ahead of ourselves let's create our first game, so we'll have an independent project to work on. Go back to the games directory, and create a copy of the samplonia directory by copy-pasting it. Then open the main.txt of the new directory and change the name of the game (the [Samplonia] part) to something new, e.g. [Samplonia 2].

Congratulations! You just made your first game! That's all it takes to create a game in Monospace Engine: a directory under the games directory, which contains a main.txt file, which describes a GAME OBJECT as shown above. Launch the engine and you'll see that your new game is now listed in the games menu. However it's still identical to Samplonia, and to change that we need to know what Elements are.

### Elements

The main.txt file we looked at in the previous section started with the words GAME OBJECT and contained the description of a game named Samplonia. Take a look at any other text file listed in that description, such as tilesets.txt and maps.txt, and you'll notice that they have a similar form. They also start with a type declaration at the top ( TILESET OBJECTS or MAP OBJECTS ) and contain definitions of tilesets and maps that are used by the engine. These assets are all called elements, and they provide Monospace Engine everything it needs to know to run games.

All elements have a name, a type, and a description. The available types are the following:

GAME OBJECTS
  Games that can be run by the engine.
MAP OBJECTS
  Maps which make up game worlds.
TILESET OBJECTS
  Tilesets, used in maps.
FONT OBJECTS
  Fonts used to display text.
MENU OBJECTS
  Menus for user interaction and HUD.
CAMERA OBJECTS
  Cameras determine how players are tracked.
KEYMAP OBJECTS
  Keymaps define how characters are controlled.
ACTOR OBJECTS
  Actor objects determine the types of characters in the game.
ACTOR INSTANCES
  Actor instances are specific characters in the game world.

We build our games out of elements belonging to these types. There are many rules that determine how an element of each type is described, but the good thing is that you don't need to know them all! That's what the Reference section is for. As long as you know what each type of element does you'll be able to look up how to edit them easily.

### How Elements Are Built

Remember that the central idea of Monospace Engine is that it loads all assets from files that are accessible and editable by users. We now know these files to contain elements. But how does the engine know which files to load? And what types of files can it work with? We'll explain these in this section.

When you launch the engine it starts looking for files in the following manner:

1. First it looks at the directory named common next to the executable.

   This directory is expected to contain a main.txt similar to the game directories we've talked about in the previous sections. But the game object found in this file is special: it's named COMMONS, and as its name suggests it contains not a game but the common assets that are required for basic functionality, such as the main menu and the fonts used in it. The files belonging to this game object are loaded immediately.

2. Then the engine looks at each directory in the games directory, and loads their main.txt files. These files contain game objects, and the files belonging to these games are not loaded until the game they belong to is launched.

Aside from the main.txt files in the special locations listed above, a file is only loaded if it's part of a GAME OBJECT. And there are two kinds of files that a GAME OBJECT can contain: plaintext files and Lua scripts.

The files we've looked at so far have been plaintext files. They're just regular text files that you can open and edit with any text editor, and the description of an element in them looks like this:

    [ELEMENT_NAME]
        PROPERTY_1: VALUE_1
        PROPERTY_2:
            VALUE_2
            VALUE_3

We can load elements from Lua scripts as well. These scripts are also regular text files that you can open with any text editor, they just have the ".lua" extension to signify that the text they contain is Lua code. Lua is a programming language, but don't worry if you're not familiar with programming, it's notoriously small and straightforward. As an example here's how the above element definition looks like in Lua:

    CreateElement("ELEMENT_NAME", "ELEMENT TYPE",
                  {PROPERTY_1 = "VALUE_1",
                   PROPERTY_2 = {
                       "VALUE_2",
                       "VALUE_3" }})

### Return to Samplonia

Let's go back to the game we created at the beginning of this tutorial to put our new knowledge to use. We'll do something simple, but not too simple: we'll create a menu that launches when the player presses a button.

To figure out how to do this let's think back to the element types we've seen. You may recall the types MENU OBJECT and KEYMAP OBJECT. Since we want to create a menu, we'll create a new element of type MENU OBJECT. And since we want this menu to launch whenever a key is pressed, we'll edit a KEYMAP OBJECT. It usually pays to think in terms of elements.

Let's start with the menu. It'll be a simple one: a fullscreen menu with a button that says "Hello!", and when you press it the menu closes and the game resumes. Create a new empty text file in our game's folder, e.g. mymenu.txt, and insert the element's type and name into it:

    MENU OBJECT

    [MY_MENU]

We now need to write the description. For that let's take a look at the Reference section of the manual, I'll link to the relevant part here. Feel free to take a moment here to read a bit into how menus are described.

The necessary information we want to provide in the description is the following:

1. We want our menu to be fullscreen, so we'll use the IS_FULLSCREEN property.

2. A button mint. A mint is something that you can interact with in a menu, and its name is a portmanteau of menu + interaction. These are usually called widgets in other programs.

   For the mint itself we need the following information:

   1. Type - A mint's type determines how it can be interacted with. We want a button.

   2. Position and dimensions - Where to place the mint, and its width and height.

   3. Text - We want the button to say "Hello!".

   4. A command that executes when we press the button.

Putting all this together, here's what our menu looks like:

    MENU OBJECT

    [MY_MENU]
        IS_FULLSCREEN
        MINTS:
            MY_BUTTON:
                TYPE: BUTTON
                POSITION: (0 PIXELS, 0 PIXELS)
                DIMENSIONS: (4 TILES x 1 TILE)
                TEXT: Hello!
                PRESS_SCRIPT: CloseSelf()

In the position and dimension values we've used PIXELS and TILES, which are length units similar to centimeters and inches in real life. You can read more about the available length units here. Our button is 4 tiles wide and 1 tile long, and to keep things simple I've chosen to set the position of our mint to the origin, which corresponds to the upper left of our screen. After you finish this section feel free to experiment with these values!

Now that our menu object is ready, it's time to make the file it's in a part of our game. Open the main.txt file of the game and add mymenu.txt to FILES. Take note of the PLAYER section as well: you'll see that the value associated with the CONTROLS property is the name of a keymap object. This is the element we'll need to edit to make our new menu launch when the player presses a button. We'll find that element in the keymaps.txt file.

Open the keymaps.txt file and look for the KEYMAP OBJECT named Player_Keymap. Then add the following line to its description:

        X: LaunchMenu("MY_MENU")

And that's it! This line instructs the keymap to run the LaunchMenu("MY_MENU") command when it detects an X keypress. And since the keymap is used by the player, whenever the player presses X our menu will launch.

### Wrapping Up

We've covered the core concepts of Monospace Engine in this tutorial. What games are, what elements are, how elements are built, how to create new elements or edit existing ones - these make up our big picture. Now it's time to start looking into the finer details, which are explained in the Reference section. But before you go I'd like to make a few suggestions.

First, remember that the Reference section aims to be complete. This means that it's pretty long and written more to be consulted than read front to back. You should skim it so that you have a general idea of what's available, read the bits you find interesting, and consult it when you're actively working on things.

Second, start small and learn by doing. Make minor tweaks to other games. Samplonia in particular has been written to be as small and instructive as possible, so feel free to continue experimenting with it.

Finally you may benefit from installing a fully featured text editor if you're not already using one. Default text editors such as Notepad on Windows and Gedit on Linux are fine but very lightweight. They lack helpful features like syntax highlighting and code completion. This will not matter much at first when you're mostly dealing with plaintext files, but as you move on to working with Lua scripts the difference these features make will be night and day. There's a wide variety of text editors, each with differing capabilities. More technically inclined people tend to prefer Emacs or Neovim, but be aware that these can take a fair bit of time and effort to learn. If you're new to programming I'd suggest using NotePad++ on Windows and Kate on Linux.

And that's it for this section of the manual! Thank you for reading, and I hope you have fun creating things with the engine.

## Reference

### Initialization

Each time the engine is launched it goes through an initialization process. During this process the engine parses files found in certain locations relative to the engine executable, with the purpose of building elements. These files are the following:

1. First the file common/main.txt is parsed. This file is expected to contain a GAME OBJECT named COMMONS. This game object is intended to contain essential information such as the main menu and the fonts used in it, and the files associated with it are loaded immediately.

2. Afterwards the engine looks at each directory in the games directory, and parses their main.txt files. These directories are expected to contain assets belonging to individual games, and their main.txt files are expected to contain elements of type GAME OBJECT. Unlike COMMONS, the files belonging to these game objects are not loaded immediately, but are loaded only when the game they represent is launched.

After this process the engine will look for a menu object named MAIN_MENU, and launch an instance of it. This menu is where user interaction begins.

The existence of a menu object with the name MAIN_MENU is required for the engine to launch successfully. This menu object is included in COMMONS by default, but as with anything else in Monospace Engine you're free to modify COMMONS as you wish, so make sure to include a MAIN_MENU if you do so.

Outside of the initialization process mentioned above, the engine will only parse files when a game is launched. It is capable of parsing two types of files: Plaintext Files and Lua Scripts.

#### Plaintext Files

Plaintext files use the .txt extension and contain element descriptions in the following basic form:

    TYPE DESCRIPTION

    [ELEMENT_1_NAME]
        TYPE DESCRIPTION
        property1: value1
        property2:
            value2
            property3: value3
            property4:
                property5:
                    value4

    [ELEMENT_2_NAME]
        ...

##### Type Descriptions

The first non-whitespace, non-comment line of a plaintext file can be a type description, such as ACTOR OBJECTS. This type description can also be incomplete (e.g. just OBJECTS, or ACTOR), or can simply be omitted.

Elements can also have type descriptions on their first lines, and these can also be incomplete or omitted. The main rule is that the combination of file and element type descriptions must provide a full type for the element, and must not conflict.

Some examples:

- If the type description of a file is ACTOR OBJECTS, none of the elements in that file need to have type descriptions, they'll all be interpreted as describing actor objects. They can still have the type description ACTOR OBJECT, as it will not conflict with the file type.

- If the type description of a file is OBJECTS, elements in that file need to have type descriptions that provide the missing part of the type, e.g. ACTOR, MAP. Elements in the file can have different types provided that they're all objects. They can also specify that they are objects, but it's not necessary.

- If a file has no type description at the top, all elements in that file must have full type descriptions. These type descriptions can differ from each other, and there are no restrictions to what type of elements such a file can contain.

Plaintext files with full type descriptions at the top have less parsing overhead.

##### Element Descriptions

Element descriptions in plaintext files begin with unindented lines that contain the element's name in brackets. They end when a new description starts, or the file ends, so they can contain empty or commented out lines.

These descriptions contain the properties that describe the element according to the syntax its type requires (see elements). These properties can be nested through indentation, or be provided on the same line by being separated by colons. Omitting colons after a property indicates that it expects no nested elements after it, and an increase in indentation in such a case will result in an error. More than one colon on a single line will also result in an error. These rules are intended to make the tree structure of descriptions obvious at a glance:

    [ELEMENT_1]
        foo: bar: baz           # Wrong, multiple colons on the same line
        foo: bar:
            baz                 # Wrong, same reason

    [ELEMENT_2]
        foo:
            bar: baz            # Correct
        foo:
            bar:
                baz             # Correct

Both tabs and spaces can be used for indentation. Combining them is not a good idea, but if they are combined tabs are interpreted as a skip to the next tab stop with the tab width of eight.

##### Comments

Plaintext files support single line comments using the # character.

##### Escape Sequences

The characters : and # have special significance in plaintext files: as described above colons are treated as separators, and hashes are used for comments. But sometimes we want to turn off this behavior and just have a regular colon or hash sign in our text. This is done by preceding them with a backslash ( \ ), and such sequences of characters such as \: or \# are called escape sequences.

The full list of escape sequences in Monospace Engine are as follows:

\:
  Escapes colon, which is otherwise used as a separator.
\#
  Escapes hash, which is otherwise used as a comment delimiter.
\\
  Escapes backslash, which is otherwise used to construct escape sequences.
\n
  Represents a newline.
\t
  Represents a tab.

Additionally, if a line ends with a backslash, it'll be parsed together with the line below as if they form a single line (in other words the line break will be escaped).

If a backslash follows a character that is not listed above (such as \z) it will have no special significance, and both characters will be included in the text.

To see an example of escape sequences in action, see Font Object examples.

#### Lua Scripts

Lua scripts use the .lua extension and contain Lua code. These scripts can use the basic functionality of the Lua programming language such as variables, loops, if/else statements and functions, and they also have access to Lua's basic library and the string, table and math libraries.

Similar to plaintext files, the main purpose of Lua scripts is to create elements. Thus they are evaluated once during engine initialization or when a game is launched, and have access to a restricted subset of the engine's overall scripting functionality. See initialization contexts for details.

Lua scripts are evaluated in the same global environment, and in the order they appear in the game object that contains them. This means that definitions from file A will be visible to file B granted that file A is listed before file B in the game object. (This feature can be useful, but for readability purposes its a good idea to not rely on it too much, and prefer lexical scoping and variables declared local whenever possible)

The engine uses LuaJIT, so the scripts should be compatible with Lua version 5.1.

### Elements

TODO: Draft, improve

Elements are parsed during initialization and make up everything.

Some elements are objects, some are instances.

Object types are not modifiable at runtime.

Instances are modifiable at runtime.

All instance types are based on an object counterpart, but not all objects have instance counterparts.

Some objects have instance counterparts that are created at runtime but cannot be parsed during initialization. These are not considered elements.

#### Game Objects

Game objects represent games that can be run by the engine. The main information they contain is a list of files that make up the game, and they also specify how the game is to be displayed on the screen and the players that exist in it.

##### Scripting

Games are launched via the LaunchGame function, which creates a game instance variable named ActiveGame in the global environment. See game instances for the scripting interface of this variable.

##### Syntax

###### FILES

Paths to files containing elements that make up the game. These files can either be plaintext files or Lua scripts.

File paths must be relative to the main.txt that contains the game object, e.g. for the following directory structure:

    example_game
    ├── main.txt
    ├── file1.txt
    ├── script1.lua
    └── directory
        └── file2.txt

The expected file paths in main.txt would be:

    [EXAMPLE_GAME]
        FILES:
            file1.txt
            script1.lua
            directory/file2.txt

###### SCREENS

Monospace Engine is capable of split-screen up to four screens, and the following properties control how each screen behaves, as well as how many screens there are, and how to split the screen.

If you wish to have a single screen that tracks the player, use this property as follows:

    [EXAMPLE_GAME]
        SCREENS:
            SCREEN1:
                TRACKS: <PLAYER_NAME>

This property is optional; if no screen information is provided there will be a single screen using the camera object with the name DEFAULT_CAMERA. This screen will not render anything until its camera is attached to something, or explicitly moved to a specific position in the game world (through the camera instance API).

1. COUNT

   1/2/3/4

   Number of screens the game will be split into.

   Optional; if unprovided will default to the number of the screen with the highest number for which information has been provided (e.g. with COUNT unprovided, if any information is registered for SCREEN4, COUNT will be set to 4). If no screen information is provided for any of the individual screens, count will default to 1.

   Count is always strictly obeyed, so if you set COUNT to 2 any information provided for SCREEN3 and SCREEN4 will be discarded. Likewise setting COUNT to 4 will always result in four screens, even if no information is provided for screens SCREEN1-4.

2. SPLIT

   HORIZONTAL/VERTICAL

   The direction in which the screen will be split in.

   Optional; will default to VERTICAL if unprovided. Only matters when COUNT is 2 or 3.

3. SCREEN1/SCREEN2/SCREEN3/SCREEN4

   Screens are numbered first from left to right and then top to down. For example if there are four screens, top left will be screen 1 and bottom right will be screen 4.

   1. TRACKS

      <PLAYER OR ACTOR INSTANCE NAME>

      Determines what the camera belonging to the screen will be tracking.

      Optional; if unprovided the screen will not render anything until its camera is attached to an instance or a player, or moved to a specific position in the game world.

   2. CAMERA

      <CAMERA OBJECT NAME>

      Name of the camera object to be used by the screen.

      Optional; if unprovided will default to DEFAULT_CAMERA.

###### PLAYER/PLAYERS

Optional. There is no upper or lower limit on the number of players a game can have; you can provide no players at all, or as many as you want.

1. <PLAYER_NAME>

   Name of the player.

   1. <INSTANCE_NAME>

      Name of the actor instance that will be controlled by the player.

      Optional, players that don't control any instance are valid; they will still be able to use their keymaps.

      Multiple players can control the same instance, but one player cannot control multiple instances.

   2. CONTROLS

      See keymap parsing.

      Optional; providing no keymap information will result in a player with an empty keymap. Controls can still be registered at runtime through the scripting interface.

      Scripts associated with player keymaps will be evaluated in player contexts.

      Overlapping controls between different players should be avoided (e.g. an A press having meaning for two different players). In case of such overlaps there are no guarantees on who gets to capture the overlapping input.

###### ART

A tileset object intended to contain game art such as the cover image, optional. See tileset objects for the syntax of tileset objects.

The tile in this tileset named COVER will be displayed in the games menu if available. See game object examples/games menu for details.

###### SCRIPTS

Scripts belonging to the game, optional. See script parsing.

These scripts will be evaluated in game instance contexts.

1. INIT

   Evaluated as the last step of game initialization, after all files belonging to the game have been parsed and evaluated, and the arguments passed to the game have been loaded into its environment.

2. ACTIVE

   Evaluated each frame the game progresses.

3. RETURN

   Evaluated when the game is returned to via a CloseUntil call.

4. EXIT

   Evaluated as the first step of game exit, before the game world and the elements belonging to the game start being unloaded.

###### METADATA

Metadata for the game object, optional. See metadata for details.

The DESCRIPTION information provided in the metadata will be displayed in the games menu if available. See game object examples/games menu for more information.

##### Examples

###### Games Menu

The engine uses a menu named GAMES_MENU to list the installed games. If your game object has a tile named COVER in its art tileset, and a DESCRIPTION in its metadata, these will be used by the menu to present your game. For example:

    [MY_GAME]
        ART:
            COVER:
                TEXTURE_PATH: my_cover.png
        METADATA:
            DESCRIPTION: My first game

The cover image should be 5x7 in tiles (or 80x112 in pixels). The available space for the game name is 27 characters, and the available space for the description text is 3 lines of 26 characters.

COVER and DESCRIPTION information is optional, and if unavailable the menu will use a default cover image and description.

GAMES_MENU is not an integral part of the engine, but is just another menu object defined in the file common/menus/games.lua. As with anything else in Monospace Engine you're free to alter, delete, or replace it as you wish. The information provided here regarding COVER and DESCRIPTION applies to the default GAMES_MENU shipped with the engine.

#### Map Objects

Map objects represent individual environments of the game world. They contain information about their size, their bounds, and have canvases on which tiles are placed to determine the appearance and physical environment of the map. They can also specify how they connect to other maps to build interconnected game worlds.

##### Scripting

When a game is launched, a game world containing all maps available in the game is created. This game world can be accessed through the ActiveGame.world table containing map instances. See map instances for the scripting interface of these variables.

##### Examples

TODO: Insert examples

##### Syntax

###### DIMENSIONS

( <WIDTH> x <HEIGHT> )

Dimensions of the map. Width and height must be integers in tile units.

###### GRAVITY

<GRAVITY>

Gravity to be applied within the map. Must be an integer value in subpixel units.

Optional; defaults to 0.

###### CAMERA_BOUNDS

See rectangle parsing.

Optional; will default to map size.

Camera bound rectangles tolerate unbound rectangles and omitted values. Omitted values will default to appropriate map dimensions. Integer values provided within the definition are interpreted as being in tile units.

###### MOVEMENT_BOUNDS

See rectangle parsing.

Optional; will default to map size.

Movement bound rectangles tolerate unbound rectangles and omitted values. Omitted values will default to appropriate map dimensions. Integer values provided within the definition are interpreted as being in tile units.

###### CANVAS

See canvas parsing.

###### BACKGROUND_COLOR

See color parsing.

Optional; will default to WHITE.

If provided in RGB format, does not expect an alpha value to be provided.

###### METADATA

Metadata for the map object, optional. See metadata for details.

#### Tileset Objects

Tileset objects contain tiles, which can be placed on the canvases of maps and menus. When used in menu canvases, tiles are purely decorational. When used in map canvases, tiles are used to generate the physical environments of maps through the SOLIDITY information they contain.

Tilesets can contain two types of tiles: static tiles and animated tiles.

##### Syntax

###### DEFAULT_SOLIDITY

SOLID / NONSOLID / LIQUID / PLATFORM

Default solidity setting to be used by the tiles in the tileset if their SOLIDITY information is not provided.

Optional, if unprovided will default to NONSOLID.

The solidity of a tile determines how actor instances physically interact with it when it is placed on a map. The available options have the following behavior:

SOLID
  The tile will be solid, so that actor instances in maps will not be able to pass through it.
NONSOLID
  The tile will be non-solid.
LIQUID
  (Currently unused) The tile will be non-solid, but have a drag coefficient.
PLATFORM
  (Currently unused) Actor instances will be able to stand on the tile, but it will otherwise behave as non-solid.

Note that for solidity information to have effect, the tile must be placed on a canvas layer that has base parallax speed (see canvas layers).

###### <STATIC_TILE_NAME>

Name of a tile in the tileset. Tile names must not include whitespace.

1. TEXTURE_PATH

   <PATH>

   Path to the image containing the appearance of the tile, required.

   TEXTURE_PATH information can be provided directly after the character, e.g.:

       [MY_TILESET]
           TILE_1:
               TEXTURE_PATH: my_tileset/tile1.png

   is equivalent to:

       [MY_TILESET]
           TILE_1: my_tileset/tile1.png

2. SOLIDITY

   SOLID / NONSOLID / LIQUID / PLATFORM

   Solidity of the tile. Optional; if unprovided will default to the tileset's DEFAULT_SOLIDITY value.

###### <ANIMATED_TILE_NAME>

Name of a tile in the tileset. Tile names must must not include whitespace.

1. <STATIC_TILE_NAME>

   Name of a static tile in the tileset.

   1. <FRAME_COUNT>

      Number of frames the static tile will be displayed in the animation sequence. Must be an integer. For the last static tile in the sequence can also be the keyword REPEAT.

2. SOLIDITY

   SOLID / NONSOLID / LIQUID / PLATFORM

   Solidity of the tile. Optional; if unprovided will default to the tileset's DEFAULT_SOLIDITY value.

##### Examples

A tileset can have any number of tiles. For example, below tileset has two:

    [MY_TILESET]
        TILE_1:
            TEXTURE_PATH: my_tileset/tile1.png
        TILE_2:
            TEXTURE_PATH: my_tileset/tile2.png

Tile names must not include whitespace (e.g. TILE_1 instead of TILE 1).

TILE_1 and TILE_2 are static - their appearance does not change. Tilesets can use such static tiles to build animated tiles as follows:

    [MY_TILESET]
        TILE_1:
            TEXTURE_PATH: my_tileset/tile1.png
        TILE_2:
            TEXTURE_PATH: my_tileset/tile2.png
        ANIMATED_TILE:
            TILE_1: 30
            TILE_2: 30
            # Shows TILE_1 for half a second (30 frames),
            #   TILE_2, repeats.

We can include solidity information in our tiles by using the SOLIDITY property:

    [MY_TILESET]
        TILE_1:
            SOLIDITY: SOLID
            TEXTURE_PATH: my_tileset/tile1.png
        TILE_2:
            TEXTURE_PATH: my_tileset/tile2.png
        ANIMATED_TILE:
            TILE_1: 30
            TILE_2: 30

When such a tileset is used in a map object, TILE_1 will be solid while TILE_2 and ANIMATED_TILE will default to non-solid due to not having solidity information. We can use the DEFAULT_SOLIDITY property of a tileset to alter this behavior:

    [MY_TILESET]
        DEFAULT_SOLIDITY: SOLID
        TILE_1:
            TEXTURE_PATH: my_tileset/tile1.png
        TILE_2:
            TEXTURE_PATH: my_tileset/tile2.png
        ANIMATED_TILE:
            TILE_1: 30
            TILE_2: 30

Now all tiles in our tileset will be solid. If a tile in such a tileset includes the SOLIDITY property, it'll override the default. For example:

    [MY_TILESET]
        DEFAULT_SOLIDITY: SOLID
        TILE_1:
            TEXTURE_PATH: my_tileset/tile1.png
        TILE_2:
            TEXTURE_PATH: my_tileset/tile2.png
        ANIMATED_TILE:
            SOLIDITY: NONSOLID
            TILE_1: 30
            TILE_2: 30

In this tileset TILE_1 and TILE_2 will be solid, while ANIMATED_TILE will be nonsolid.

As a shorthand, the TEXTURE_PATH property of static tiles can be provided directly after the tile name. So the above tileset can also be expressed as:

    [MY_TILESET]
        DEFAULT_SOLIDITY: SOLID
        TILE_1: my_tileset/tile1.png
        TILE_2: my_tileset/tile2.png
        ANIMATED_TILE:
            SOLIDITY: NONSOLID
            TILE_1: 30
            TILE_2: 30

Like all other elements, tilesets can also contain metadata:

    [MY_TILESET]
        TILE_1:
            TEXTURE_PATH: my_tileset/tile1.png
        TILE_2:
            TEXTURE_PATH: my_tileset/tile2.png
        METADATA:
            AUTHOR: Pablo Picasso

#### Font Objects

Font objects determine the appearance of text. They contain information regarding the characters available in the font and how each character is to be displayed, and are used in the appearance settings of menus and mints.

Monospace Engine uses its own font format and text rendering functionality - this means that it does not use other fonts that may be found on your computer, but instead expects to find fonts in the form of FONT OBJECTS. Just like other element types, FONT OBJECTS allow users to easily create or configure fonts.

The engine ships with three fonts by default: C64, ARCADE and BUBBLES. C64 and ARCADE are general purpose fonts, and BUBBLES is for stylized text. All three are included in the COMMONS game object.

##### Syntax

###### DEFAULT_SIZE

( <WIDTH> x <HEIGHT> )

Default size for the characters in the font. Width and height must be integers in scaled pixel units.

Required, sets the dimensions of the default whitespace characters, as well as any explicitly provided whitespace characters that lack dimensions.

###### CHARACTERS

Characters in the font.

1. <CHARACTER>

   A character in the font. Can be any character, e.g. a, b, ç, 啊. Compatible with ASCII and UTF-8 encodings.

   The following are two special character names:

   UNKNOWN
     Used to represent characters that are not in the font.
   CURSOR
     Used to represent the cursor when the font is used to render text that is being edited.

   Both UNKNOWN and CURSOR are optional. If UNKNOWN is unprovided unknown characters will be displayed as whitespace, and if CURSOR is unprovided the cursor will be displayed as a block that swaps the foreground and background colors of the text at point.

   Whitespace characters space, tab, newline are inserted to all fonts by default and don't have to be explicitly provided. Tabs have tabstop behavior and a maximum length of 8 spaces.

   A font character does not strictly have to be a single character, e.g. the string ab can be registered as a font character. The reason for this is that the engine is actually encoding-agnostic - it does not care what a font character is as long as its size is less than or equal to four bytes. In the ASCII and UTF-8 encodings the string ab takes up two bytes, thus it satisfies this requirement.

   However if you register ab as a character in the font, and also register a, the text rendering will detect a before ab. As a consequence a will be given precedence and b will be rendered separately.

   1. TEXTURE_PATH

      <PATH> or WHITESPACE

      Path to the image containing the appearance of the font character. Optional; if unprovided character is assumed to be whitespace.

      TEXTURE_PATH information can be provided directly after the character, e.g.:

          [EXAMPLE_FONT]
              CHARACTERS:
                  A:
                      TEXTURE_PATH: example-font/uppercase/A.png

      is equivalent to:

          [EXAMPLE_FONT]
              CHARACTERS:
                  A: example-font/uppercase/A.png

   2. SIZE

      ( <WIDTH> x <HEIGHT> )

      Size of the font character. Width and height must be integers in scaled pixel units.

      Optional; if TEXTURE_PATH is provided will default to the detected dimensions of the given image. If not will default to DEFAULT_SIZE.

   3. OFFSET

      ( <X> , <Y> )

      Offset of the font character. X and Y must be integers in scaled pixel units.

      Optional; will default to zero.

      Offset is used during rendering to adjust character position, can be negative or positive. Offsets do not interfere with the "normal flow" of text rendering, meaning that they have no effect on the positioning of other characters.

###### METADATA

Metadata for the font object, optional. See metadata for details.

##### Examples

Here's how the font C64 is defined in common/fonts/c64.txt, abbreviated for the sake of the example:

    FONT OBJECT

    [C64]
        DEFAULT_SIZE: (8x8)
        CHARACTERS:
            # Uppercase characters
            A: fonts/c64/uppercase/A.png
            B: fonts/c64/uppercase/B.png
            # ...
            Z: fonts/c64/uppercase/Z.png

            # Lowercase characters
            a: fonts/c64/lowercase/a.png
            # ...

            # Numbers
            0: fonts/c64/numbers/0.png
            # ...

            # Punctuation
            &: fonts/c64/punct/ampersand.png
            =: fonts/c64/punct/equal.png
            !: fonts/c64/punct/exclamation.png
            _: fonts/c64/punct/underscore.png
            \\: fonts/c64/punct/bslash.png
            \:: fonts/c64/punct/colon.png
            \#: fonts/c64/punct/hash.png
            # ...

            # Special characters
            CURSOR: fonts/c64/cursor.png
            UNKNOWN: fonts/c64/unknown.png

This is pretty straightforward, but there are two things to note:

- The backslash ( \ ), colon ( : ) and hash ( # ) characters are each preceded with a backslash to turn off their syntactic significance and treat them as regular text characters. (See escape sequences)

- Instead of putting all textures in the same folder, they're sorted into subfolders such as uppercase and lowercase. This is not just for the sake of organization - Windows has trouble distinguishing path names that only differ due to capitalization, e.g. A.png and a.png, so it's necessary to put such files into different folders for them to be accurately accessed by the engine.

#### Menu Objects

Menu objects represent menus, which provide a generic way to display information and provide user interactivity. Menus can be fullscreen or windowed, interactive or non-interactive, and their appearance can be customized through their APPEARANCE and CANVAS settings.

User interaction in menus happens primarily through mints, which represent menu items such as buttons and text boxes. Menus can also contain keymaps that associate key presses with scripts.

##### Scripting

Menus are launched via the LaunchMenu function, which takes a menu object and creates a menu instance. This menu instance can then be accessed through the variable named self in the menu's scripting context.

##### Syntax

###### POSITION

( <X> , <Y> )

Position of the menu. X and Y must be viewport lengths.

Providing POSITION and DIMENSIONS information to a menu makes it windowed. Providing one makes the other a requirement, and providing neither will make the menu fullscreen, which is the default. If the menu is explicitly set to be fullscreen (via the IS_FULLSCREEN property), providing POSITION or DIMENSIONS will result in an error.

###### DIMENSIONS

( <WIDTH> x <HEIGHT> )

Dimensions of the menu. WIDTH and HEIGHT must be viewport lengths.

Providing POSITION and DIMENSIONS information to a menu makes it windowed. Providing one makes the other a requirement, and providing neither will make the menu fullscreen, which is the default. If the menu is explicitly set to be fullscreen (via the IS_FULLSCREEN property), providing POSITION or DIMENSIONS will result in an error.

###### IS_FULLSCREEN

Makes the menu fullscreen.

Menus with the IS_FULLSCREEN property should not be provided POSITION or DIMENSIONS information.

If a menu is not provided any POSITION, DIMENSIONS or IS_FULLSCREEN information it'll default to fullscreen.

###### IS_OVERLAY

Makes the menu an overlay menu, so that it will not stop the input capture and evaluation of the menu, game or stage that exists before it.

Simple explanation: When a menu is launched while a game is active, the game pauses. Overlay menus don't pause the game, so are useful for "overlays" like HUDs.

For a more detailed explanation see window stack.

Overlay menus can have keymaps, but are otherwise uninteractable, meaning they have the following restrictions compared to regular menus:

- their button and input mints are not interactable, and will behave as labels

- they do not use the default menu controls (arrow keys, enter, ESC)

###### HIDES_WHEN_INACTIVE

Makes the menu hide when it is inactive.

Simple explanation: When a menu with a transparent background is rendered on top of another menu, the text can overlap and become illegible. Making the menu below hide when it's inactive solves this problem.

A menu is inactive when there is a window newer than it on the window stack that prevents the user from interacting with it (i.e. anything that's not an overlay menu). Inactive windows are usually not rendered, but if the newer window is a menu that's not fullscreen or has a transparent background they will still render. Normally this is intended behavior, but in certain cases (e.g. overlapping text) it may make sense to hide the older menu while the newer menu exists. This option enables the hiding behavior.

###### APPEARANCE

See menu appearance.

Optinal; missing appearance information will be inherited from MAIN_MENU.

###### CANVAS

See canvas parsing.

Optional.

###### MINTS

Mints in the menu, optional.

1. <NAME>

   Name of a mint in the menu. See mints.

###### SCRIPTS

Scripts belonging to the menu, optional. See script parsing.

These scripts will be evaluated in menu instance contexts.

1. INIT

   Evaluated after the menu is initialized, and the menu's arguments have been loaded into its environment.

2. ACTIVE

   Evaluated each frame the menu is active.

3. RETURN

   Evaluated when the menu is returned to via a CloseUntil call.

4. EXIT

   Evaluated when the menu is closed.

###### KEYMAP

See keymap parsing.

Optional; all menus have the following controls by default:

Arrow Keys
  Change selected mint
Esc
  Close menu

Additional default controls can also be available depending on the type of the currently selected mint - see mint types for details.

Keymap bindings will capture input events before the default controls, meaning that in case of overlap default controls will be overshadowed.

Scripts associated with menu keymaps will be evaluated in menu instance contexts.

###### CAMERA

Camera information for the menu, optional.

All menus have their own cameras; the camera can either be attached to the menu, in which case it will automatically track the center of its active mint, or it can be detached and set to point to a specific coordinate. See camera instances for details.

Menu cameras start as attached to their menu by default, but unless the camera is provided custom bounds they will appear as static.

1. NAME

   <CAMERA NAME>

   Name of the camera object to be used by the menu.

   Optional; if unprovided will default to DEFAULT_CAMERA.

2. BOUNDS

   See rectangle parsing.

   Movement bounds for the menu's camera. Optional; will default to menu dimensions.

   Camera bound rectangles tolerate unbound rectangles and omitted values. Omitted values will default to appropriate menu dimensions. Given values must be viewport lengths.

###### METADATA

Metadata for the menu object, optional. See metadata for details.

##### Mints

Mints are things in menus that the user can interact with. There are three types of mints:

1. Label mints, which can display text.

2. Button mints, which can display text, and can be pressed.

3. Input mints, which can display text, can be pressed, and can capture text input.

The name mint is a portmanteau of menu + interaction. Mints are usually called widgets in other programs, but I did not find that name appealing so chose not to use it. Mints also have a slightly different paradigm compared to usual widgets - a mint's type can be freely changed at runtime. See mint scripting for details.

###### Scripting

When a menu instance is created, its mints are initialized as Lua variables and stored in the menuInstance.mints table. See mint scripting for the scripting interface of mints.

New mints can also be created at runtime independent of menus through the CreateMint function.

###### Syntax

1. TYPE

   LABEL/BUTTON/INPUT

   Type of the mint, required.

   Labels
     Only serve to display text; cannot be selected or pressed.
   Buttons
     Can be selected and pressed.
   Input
     Can be selected, pressed, and can capture text input.

   Pressing happens by clicking on a mint, or pressing ENTER when it's selected.

   While an input mint is selected, the following additional default controls are available:

   BACKSPACE
     Remove character before cursor
   DELETE
     Remove character at cursor
   SHIFT + ENTER
     Enter newline
   SHIFT + ARROW KEYS
     Move cursor

2. POSITION

   ( <X> , <Y> )

   Position of the mint. X and Y must be viewport lengths.

   Required.

3. DIMENSIONS

   ( <WIDTH> x <HEIGHT> )

   Dimensions of the mint. WIDTH and HEIGHT must be viewport lengths.

   Required.

4. TEXT

   <TEXT CONTENT>

   Text to be rendered by the mint, optional.

   1. PLACEHOLDER

      <PLACEHOLDER TEXT>

      Placeholder text to be rendered when mint text is empty. Optional.

5. SCRIPTS

   Scripts belonging to the mint, optional. See script parsing.

   These scripts will be evaluated in menu instance contexts.

   1. PRESS

      Evaluated when the mint is pressed. A press can be either an enter keypress or a right click.

   2. SELECTION

      Evaluated when the mint is selected.

   3. DESELECTION

      Evaluated when the mint is deselected.

   4. ACTIVE

      Evaluated each frame the mint is available and the menu it's in is active.

6. APPEARANCE

   See mint appearance.

   Optional; missing appearance information will be inherited from the parent menu.

###### Examples

TODO: Insert examples

##### Appearance

Below properties can be provided in the APPEARANCE settings of menus to customize their appearance. They can also be used in mints, but with one distinction; only the appearance settings concerning mints (which are listed after the MINTS property below) can be provided to mints. For example:

    [MY_MENU]
        APPEARANCE:
            MINTS:
                ACTIVE_COLOR: WHITE

This makes the mints in MY_MENU use WHITE as their color when active. To achieve this using the appearance setting of a mint, we would do:

    [MY_MENU]
        MINTS:
            MY_MINT:
                APPEARANCE:
                    ACTIVE_COLOR: WHITE

Such appearance settings that are directly provided to mints have precedence over the appearance settings of menus.

If a menu is missing any of its appearance information, it is inherited from the MAIN_MENU. The required/optional behavior of properties stated below is only applicable after inheritance - for example FONT is required, but if MAIN_MENU includes a FONT in its appearance settings (and it does by default) you don't have to specify it for your menus, as they'll inherit the information. In practice this means that all properties listed below are optional, unless you change the default MAIN_MENU included in the COMMONS.

If you include a menu named MAIN_MENU in your game, all menus in your game will inherit their appearance settings from your MAIN_MENU instead of the one in COMMONS.

###### Syntax

1. BACKGROUND_COLOR

   <COLOR>

   Background color of the menu. See color parsing.

   Optional, will default to transparent.

2. BORDER

   Border appearance information for the menu.

   Borders are only visible if the menu is windowed - fullscreen menus do not display borders.

   Border appearance information can be provided both for all sides, and for individual sides. Information defined for an individual side has precedence over information defined for all sides. For example:

       [MY_MENU]
           APPEARANCE:
               BORDER:
                   WIDTH: 1 PIXEL
                   ACTIVE_COLOR: RED
                   LEFT:
                       ACTIVE_COLOR: BLUE

   This defines a menu with red borders, except for the left border, which will appear blue.

   1. ACTIVE_COLOR

      <COLOR>

      The color of menu borders when the menu is active. See color parsing.

      Optional.

   2. INACTIVE_COLOR

      <COLOR>

      The color of menu borders when the menu is inactive. See color parsing.

      Optional.

   3. WIDTH

      <WIDTH>

      Width of the menu's borders. Must be a viewport length.

      Optional.

   4. <LEFT/RIGHT/UP/DOWN>

      Appearance information for an individual side of the border.

      1. ACTIVE_COLOR

         <COLOR>

         Border color when the menu is active. See color parsing.

         Optional.

      2. INACTIVE_COLOR

         <COLOR>

         Border color when the menu is inactive. See color parsing.

         Optional.

      3. WIDTH

         <WIDTH>

         Width of the border. Must be a viewport length.

         Optional.

3. MINTS

   Appearance settings for the mints in the menu.

   The settings listed here can also be provided in the APPEARANCE settings of mints directly.

   1. ACTIVE_COLOR

      <COLOR>

      The color of the mint when it is selected. See color parsing.

      Optional, will default to transparent.

   2. INACTIVE_COLOR

      <COLOR>

      The color of the mint when it is not selected. See color parsing.

      Optional, will default to transparent.

   3. TEXT

      Appearance settings for text to be rendered by mints.

      1. ACTIVE_COLOR

         <COLOR>

         Text color when the mint is selected. See color parsing.

         Optional, if unprovided will render the font's textures as-is.

      2. INACTIVE_COLOR

         <COLOR>

         Text color when the mint is not selected. See color parsing.

         Optional, if unprovided will render the font's textures as-is.

      3. PLACEHOLDER_COLOR

         <COLOR>

         The color to render placeholder text with. See color parsing.

         Optional, if unprovided will use the INACTIVE_COLOR value.

      4. FONT

         <FONT OBJECT NAME>

         Name of the font object to be used by the text.

         Required if the relevant mint has text to be rendered.

      5. POSITION

         ( <X> , <Y> )

         Position of text within the mint. X and Y must be viewport lengths. Viewport lengths in this context have scaled pixel resolution.

         Optional. For menu appearance settings, omitting this value will make it default to zero. For mint apperance settings, omitting this value will either make it default to zero (in absence of a MARGIN value), or make it default to the calculated position of the text within the mint (when a MARGIN value exists).

         If the mint has type INPUT, this value will get updated as the cursor moves around to ensure that the cursor remains visible at all times.

      6. MARGIN

         <MARGIN VALUE>

         The distance the text renderer will seek to maintain between the edges of the mint and the text rendering area. Must be a viewport length.

         Optional, if unprovided will default to zero.

         If a POSITION value is present, MARGIN will be ignored in favor of POSITION. This setting is particularly useful for input mints - as the cursor moves around POSITION will be altered accordingly, but MARGIN will stay the same, and the text renderer will try to obey it.

      7. ALIGNMENT

         LEFT/RIGHT/CENTER

         How to align lines. Optional, will default to LEFT.

      8. WRAP

         NONE/LINES/WORDS

         Determines how to display lines that are too large for their rendering area. Has the following options:

         NONE
           No text wrapping, if a line gets too large it will simply overflow horizontally.
         LINES
           Text is wrapped at the first character that overflows.
         WORDS
           Text is wrapped, and the renderer will try to do the wrapping at spaces to avoid breaking within words.

         Optional, if unprovided will default to NONE.

      9. LINE_HEIGHT

         <HEIGHT>

         Minimum height of a line of text in the mint. Must be a positive integer in scaled pixel units.

         Optional. By default the height of a text line is determined by the tallest font character in that line. If there are no characters the font's DEFAULT_SIZE property is used.

         Note that LINE_HEIGHT represents the minimum: if it is exceeded by the height of any font character in the line, or the font's DEFAULT_SIZE property, it'll be ignored for that line in favor of the larger value.

      10. CURSOR

          Appearance settings for the cursor.

          Note that a mint's cursor will only be visible if it is currently selected, and it has the type INPUT.

          1. TYPE

             BLOCK/CHARACTER

             Type of the cursor. Optional, if unprovided will default to CHARACTER.

             Cursors with the CHARACTER type are rendered using the special CURSOR character defined in font objects, and cursors with the BLOCK type are rendered by swapping the foreground and background colors of the text at point.

             If the font does not have a CURSOR character the cursor rendering will use block type rendering regardless of this setting.

          2. COLOR

             <COLOR>

             Cursor color. See color parsing.

             Optional, will default to the mint's ACTIVE_COLOR if unprovided.

          3. BLINK

             <ON-DURATION> <OFF-DURATION>

             The blinking pattern for the cursor. Both ON-DURATION and OFF-DURATION must be non-negative integers, and at least one of them must be positive. They represent the number of frames the cursor will be shown and hidden.

             Some example values:

             1 0
               The cursor will constantly be shown.
             0 1
               The cursor will never be shown.
             30 30
               The cursor will be displayed for 30 frames, and be hidden for 30 frames.

      11. REGIONS

          List of regions within the text. Each region can have its own font, foreground/background colors, and positioning offset.

          1. <REGION_NAME>

             Name of a text region.

             1. RANGE

                [<BEGIN-INDEX>, <END-INDEX>)

                The range of the region. Both BEGIN-INDEX and END-INDEX are expected to be positive integer values representing character indices, with BEGIN-INDEX being inclusive and END-INDEX being exclusive.

                For example if the text is ABCDE, the region [1,2) selects the character A, the region [1,3) selects AB, the region [2,4) selects BC and so on.

                Optional, if unprovided the region will be inactive.

                In case of overlaps, regions with higher BEGIN-INDEX values are preferred. If BEGIN-INDEX values are equal, newer regions are preferred.

                In case you are curious about the mixed use of square brackets and parentheses, this is a common notation for intervals in math. Square brackets signify that an endpoint is included, and parentheses signify that an endpoint is excluded. See wikipedia for more info.

             2. FONT

                <FONT OBJECT NAME>

                Name of the font object to be used by text within the region.

                Optional, if unprovided will default to the general FONT value of the text appearance.

             3. OFFSET

                ( <X> , <Y> )

                Offset to use when positioning the text within the region. X and Y must be integers in scaled pixel units.

                Optional; will default to zero.

                Offset is used during rendering to adjust character positions, and can be negative or positive. Offsets do not interfere with the "normal flow" of text rendering, meaning that they have no effect on the positioning of other characters.

             4. ACTIVE_COLOR

                <COLOR>

                Text color for the region when the mint is selected. See color parsing.

                Optional, if unprovided will default to the general ACTIVE_COLOR value of the text appearance.

             5. ACTIVE_BG_COLOR

                <COLOR>

                Background color for the text in region when the mint is selected. See color parsing.

                Optional.

             6. INACTIVE_COLOR

                <COLOR>

                Text color for the region when the mint is not selected. See color parsing.

                Optional, if unprovided will default to the general INACTIVE_COLOR value of the text appearance.

             7. INACTIVE_BG_COLOR

                <COLOR>

                Background color for the text in region when the mint is not selected. See color parsing.

                Optional.

   4. BORDER

      Border appearance information for mints.

      Border appearance information can be provided both for all sides, and for individual sides. Information defined for an individual side has precedence over information defined for all sides. For example:

          [MY_MENU]
              MINTS:
                  MY_MINT:
                      APPEARANCE:
                          BORDER:
                              WIDTH: 1 PIXEL
                              ACTIVE_COLOR: RED
                              LEFT:
                                  ACTIVE_COLOR: BLUE

      This defines a mint with red borders, except for the left border, which will appear blue.

      1. ACTIVE_COLOR

         <COLOR>

         The color of mint borders when the mint is active. See color parsing.

         Optional.

      2. INACTIVE_COLOR

         <COLOR>

         The color of mint borders when the mint is inactive. See color parsing.

         Optional.

      3. WIDTH

         <WIDTH>

         Width of the mint's borders. Must be a viewport length.

         Optional.

      4. <LEFT/RIGHT/UP/DOWN>

         Appearance information for an individual side of the border.

         1. ACTIVE_COLOR

            <COLOR>

            Border color when the mint is active. See color parsing.

            Optional.

         2. INACTIVE_COLOR

            <COLOR>

            Border color when the mint is inactive. See color parsing.

            Optional.

         3. WIDTH

            <WIDTH>

            Width of the border. Must be a viewport length.

            Optional.

##### Examples

TODO: Insert examples

#### Camera Objects

Camera objects define how screens track their targets. They do this using the following concepts:

Easers
  Which determine how an initial value approaches a target value.
Definitions
  Rules about where the camera seeks to place its target on the screen.
Trackers
  Collections of definitions.

##### Scripting

Camera objects are used to generate camera instances - which are used by menu instances, game screens and stages. Camera instances behave according to the rules of the camera object associated with them, and they also have a scripting interface capable of operations such as changing the target they're tracking, or being moved to specific positions. See camera instances for details.

##### Syntax

###### RESOLUTION

SCREEN_PIXELS/SCALED_PIXELS

The smallest distance which the camera is capable of moving. Screen pixel resolution results in smoother motion, while scaled pixel resolution gives a more consistent pixelated appearance.

For more information on screen & scaled pixels see lengths.

Optional; will default to SCREEN_PIXELS.

###### DEFINITION_EASING

<EASER>

Easer to be used when an active definition changes, see easers.

Required.

###### POSITION_EASING

<EASER>

Easer to be used when the target of the camera is out of focus according to the rules of the camera's tracker, see easers.

Required.

###### POINT_TRACKER

[IF (<CONDITION>)] ( <X> , <Y> )

Conditions are optional, see conditions for details. X, Y must be viewport lengths. Viewport lengths in this context use relative slices.

Point trackers seek to keep their target on a single point on the screen. For example, a point tracker with a definition of ( 180 SLICES, 180 SLICES ) will seek to keep its target in the center of the screen. When the target moves, the camera will follow it according to the easer given in the POSITION_EASING property.

Point trackers can have multiple definitions, e.g.

    [EXAMPLE_CAMERA]
        POINT_TRACKER:
            IF ( FACING_RIGHT ) ( 120 SLICES, 180 SLICES )
            IF ( FACING_LEFT ) ( 240 SLICES, 180 SLICES )
            ( 180 SLICES, 180 SLICES )

In each frame the conditions associated with these definitions will be sequentially tested, and the first one that holds will be used. Omitting the condition will make the definition always applicable.

When the active definition changes from one frame to another, the easer given in the DEFINITION_EASING property will be used.

###### REGION_TRACKER

Region trackers keep their target within the bounds of a region on the screen.

TODO: To be implemented

###### METADATA

Metadata for the camera object, optional. See metadata for details.

##### Easers

Easers determine how an initial value approaches a target value. There are three types of easers: INSTANT, CONSTANT and BERNSTEIN:

1. INSTANT

   Instant easers go from initial value to target value instantly.

2. CONSTANT

   <VALUE>

   Value is expected to be an integer in range [1,100].

   Constant easers go from initial value to target value by the given constant amount each frame. For example a constant easer with value 25 would go from 0 to 100 as 0 -> 25 -> 50 -> 75 -> 100

3. BERNSTEIN

   Bernstein easers go from an initial value to a target value using Bernstein polynomials, which makes it possible to create easers of arbitrary complexity. Such easers can display ease-in, ease-out, ease-in-out behavior and more.

   1. FORMULA

      (<STEP-VAL> [(<COEFF-VAL-1> <COEFF-VAL-2> ...)])

      Given values are expected to be floating point numbers.

      A step value is mandatory and has range (0,1]. The easing is done by incrementing from 0 to 1 by step value each frame, so it determines the duration (e.g. with a step value of 0.1, the easing process takes 10 frames to complete). Coefficient values can be omitted entirely.

      If there are n coefficients, a Bernstein polynomial that is a combination of n + 2 basis polynomials with degree n + 1 will be generated. The basis polynomials b 0,n+1 and b n+1,n+1 will have coefficients 0 and 1. These only exist to guarantee that the easing process begins from source, and ends at destination. For more information on Bernstein polynomials see wikipedia.

      This stuff sounds complicated but you can easily get an intuitive sense of it by plotting the results.

      Enter a list of coefficients in below and press the View Graph button.Coefficient List:

      I suggest trying the following values: 0.5 (linear increase), 0 (ease in), 1 (ease out), 0 1 (ease in out), 0 1 2 (overshoot). You'll quickly realize that the coefficients are basically points that the curve tries to reach on the interval between 0 and 1.

      E.g. for a formula of (0.1 (0.5)), the coefficient list is (0.5), and the resulting Bernstein polynomial is

      0⋅(1-x)2+0.5⋅2⋅x⋅(1-x)+1⋅x 2

      The FORMULA value can be provided directly after BERNSTEIN, e.g.

          [MY_CAMERA_OBJECT]
              POSITION_EASING:
                  BERNSTEIN:
                      FORMULA:
                          (0.1 (0 1))

      is equivalent to

          [MY_CAMERA_OBJECT]
              POSITION_EASING:
                  BERNSTEIN:
                      (0.1 (0 1))

   2. TIME_REVERSAL

      YES/NO/TRUE/FALSE

      Optional; will default to false.

      Easing processes have an initial and target value. If the target value changes while the process is ongoing, the process is normally interrupted and restarted with the new value. But if this option is set to true, such an interruption will result in the process reversing rather than restarting IF the new target value equals the initial value with which the process started.

      This can be useful in places like cameras with point trackers that have two definitions and have an ease in-out formula like (0.1 (0 1)).

##### Examples

TODO: Insert examples

#### Keymap Objects

Keymap objects bind input signals such as keys and mouse events to game buttons and scripts. They're used to specify the controls of players and menus.

It is possible to provide keymap objects within other elements instead of as standalone ones - such keymaps are said to be inlined. See keymap inlining for details.

##### Scripting

Keymaps have a highly flexible scripting interface - everything about a keymap can be redefined at runtime. See keymap scripting for more information.

##### Syntax

###### <KEYMAP NAME>

Name of a keymap object to inherit bindings from.

This feature is only available to inlined keymaps (see inlining). Keymaps defined as standalone elements cannot inherit.

Inheriting from multiple keymaps is not possible, and inheritance must happen before the registration of any bindings.

If any bindings provided to a keymap conflict with bindings that have been inherited, directly provided bindings will have precedence.

###### <INPUT SIGNAL>

See input signals.

An input signal can only be assigned to one thing, whether it's a script or a game button.

1. <SCRIPT>

   See scripts.

   If the input signal is a mouse event, the x and y positions of the mouse are passed to the script as arguments. The passed positions are in scaled pixels, and with respect to the upper left position of the context that has evaluated the script. (See keymap examples/mouse event)

   The context in which these scripts are evaluated depends on the keymap's role: e.g. keymaps that belong to menus will be evaluated in menu instance contexts, while keymaps that belong to players will be evaluated in player contexts.

2. <GAMEBUTTON>

   See game buttons.

   Multiple input signals can not be assigned to the same game button.

   Not all game buttons can be used here; the FORWARD and BACKWARD buttons are considered "virtual" (they don't just reflect key presses, but also depend on the direction of the controlled instance), thus are not allowed to be inserted into keymaps.

###### METADATA

Metadata for the keymap object, optional. See metadata for details.

This feature is only available to keymaps defined as standalone elements. Inlined keymaps cannot have metadata (see inlining).

##### Input Signals

Input signals represent various types of input that the user can provide. They are divided into two main categories: keys and mouse events.

###### Keys

1. Number Keys

   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

2. Alphabetical Keys

   A | B | C | D | E | F | G | H | I | J
   K | L | M | N | O | P | Q | R | S | T
   U | V | W | X | Y | Z

3. Arrow Keys

   LEFT | RIGHT | UP | DOWN

4. Other Keys

   ENTER | SPACE | TAB | BACKSPACE | DELETE
   HOME | END | ESCAPE

5. Modifier Keys

   CTRL | ALT | SHIFT

   Modifier keys can be combined with other keys using the plus sign, e.g. CTRL+S, CTRL+ALT+S.

###### Mouse Events

MOTION | LPRESS | LRELEASE | RPRESS | RRELEASE

Which correspond to the following:

MOTION
  Mouse motion
LPRESS
  Left mouse button press
LRELEASE
  Left mouse button release
RPRESS
  Right mouse button press
RRELEASE
  Right mouse button release

##### Inlining

Keymap objects are capable of being inlined - they can be provided as part of other elements as well as on their own. For example:

    [MY_KEYMAP]
        KEYMAP OBJECT
        X: Foo()

    [MY_MENU]
        MENU OBJECT
        KEYMAP: MY_KEYMAP

is equivalent to:

    [MY_MENU]
        MENU OBJECT
        KEYMAP:
            # Inlined keymap
            X: Foo()

As stated in the keymap syntax section, inlined keymaps differ from standalone keymaps in that they're capable of inheritance. For example:

    [MY_KEYMAP]
        KEYMAP OBJECT
        X: Foo()

    [MY_MENU]
        MENU OBJECT
        KEYMAP:
            MY_KEYMAP
            Y: Bar()

In this example the keymap of MY_MENU will have all bindings of MY_KEYMAP, as well as the bindings defined in its own body.

##### Examples

TODO: Insert examples

###### Mouse Event

#### Actor Objects

Actor objects define the types of characters in the game world. They describe what characters look like, how they move in the game world, and how they can be controlled. To do this they contain sprites, animations, actions, and controls that can be associated with those actions.

Note that actor objects represent the types of characters and not characters themselves - to place specific characters in the game world use actor instances.

##### Syntax

###### SPRITES

Sprites belonging to the actor object.

Actor objects can contain any number of sprites, which are in turn used to make up their animation sequences.

1. <SPRITE_NAME>

   See sprite parsing.

###### ANIMATION_SEQUENCES

Animations belonging to the actor object.

Actor objects can contain any number of animations, which are in turn used by actions to determine what characters look like as they move in the game world.

1. <ANIMATION_NAME>

   See sequence parsing.

   Sequences should be made of sprites.

###### ACTIONS

Actions belonging to the actor object.

Actor objects can contain any number of actions, and there are no restrictions on the types of actions they may contain.

1. <ACTION_NAME>

   See action parsing.

###### CONTROLS

Controls of the actor object.

Optional; no controls being provided for an actor is valid.

1. <CONTROL_NAME>

   The name of the control.

   1. INPUT

      <GAMEBUTTON(S)>

      See game button parsing.

      Can be a single button, or a combination of buttons composed through the operators + and >.

      Buttons combined with + need to be pressed in the same frame. Buttons combined with > need to be pressed consecutively, within 10 frames of each other.

   2. ACTION

      <ACTION_NAME>

      The name of the action to start.

      This shouldn't be a response or an idle action, but currently there are no checks.

   3. SET_DIRECTION

      LEFT/RIGHT/UP/DOWN/FRONT/BACK/HORIZONTAL/VERTICAL

      Sets the new direction of the actor instance. Optional.

###### AI

TODO: To be implemented

###### METADATA

Metadata for the actor object, optional. See metadata for details.

##### Examples

TODO: Insert examples

#### Actor Instances

Actor instances are individual characters in the game world. They specify which actor object they're an instance of, and where the character is located in the game world.

Unlike any other element type actor instances cannot be provided in COMMONS. This is because they require an active game world to function.

##### Scripting

The scripting interface of actor instances is currently under development. The features available at the moment are their scripting contexts, and the SearchWorld function which can look up actor instances in the game world. See actor instance scripting for details.

##### Syntax

###### INSTANCE_OF

<ACTOR OBJECT NAME>

Name of the actor object which the actor instance is an instance of.

Required, must be the first property registered.

###### DIRECTION

LEFT/RIGHT/UP/DOWN/FRONT/BACK/HORIZONTAL/VERTICAL

Direction of the actor instance.

Optional, will default to RIGHT.

###### IN_MAP

<MAP OBJECT NAME>

Name of the map the actor is in. Required.

###### POSITION

( <X> , <Y> )

Position of the actor instance. Given values must be in scaled pixel units. Required.

###### VELOCITY

( <X> , <Y> )

Velocity of the actor instance. Given values must be integers in subpixel units.

Optional; will default to zero.

The effect of velocity on position is as follows: each frame (60 times a second) the velocity value is added to the position value. So for example:

- A velocity value of (1, 0) adds 1 subpixel to the X position each frame, and in one second (60 frames) a total of 60 subpixels (equal to 1 scaled pixel as described in the units section) will be added, causing the instance to move one pixel to the right each second.

- A velocity value of (60, 0) adds 60 subpixels to the X position each frame, causing the instance to move one pixel each frame and 60 pixels each second.

So the velocity value can both be seen as subpixels per frame and pixels per second.

###### ACCELERATION

( <X> , <Y> )

Acceleration of the actor instance. Given values must integers be in subpixel units.

Optional; will default to zero.

Acceleration's effect on velocity is the same as velocity's effect on position: each frame the acceleration value is added to the velocity value. So for example an acceleration value of (1, 0) adds 1 subpixel to the horizontal velocity each frame, and in 60 frames the instance will go from stationary to moving at a velocity of (60, 0).

###### METADATA

Metadata for the actor instance, optional. See metadata for details.

##### Examples

TODO: Insert examples

#### Common Syntax

This section lists syntax rules for components that are used in multiple elements.

##### Colors

Colors can be specified in two ways: RGB values and color names.

###### RGB Values

As RGB values, colors can be expressed using the following syntax:

(<R>, <G>, <B> [, <A>])

R, G, B, A are expected to be integer values within range [0,255]. A is optional, if unprovided will default to 255, which corresponds to zero transparency. For more information about the RGBA model see wikipedia.

In certain contexts providing an alpha value is not allowed. These contexts (such as the BACKGROUND_COLOR setting of map objects) will explicitly state this restriction in their documentation.

###### Color Names

The following color names can be provided to the engine in places where a color value is expected:

Name | RGB Value | Color
--- | --- | ---
BLACK | (0,0,0) |
WHITE | (255,255,255) |
RED | (255,0,0) |
GREEN | (0,255,0) |
BLUE | (0,0,255) |

##### Lengths

###### Length Units

Monospace Engine uses the following units to describe lengths:

Screen Pixels

Length of one pixel on the display device being used.

Scaled Pixels

Length of one screen pixel times the scale multiplier.

Scaled pixels are screen pixels "scaled up" - they're the larger pixels that you see in pixel art, and they provide the engine with a consistent pixelated appearance at higher resolutions.

Tiles

One tile is equivalent to a length of 16 scaled pixels.

Tiles are typically used to describe the geometry of map objects.

Subpixels

One subpixel is equal to 1/60th of a scaled pixel.

Subpixels are used to describe values that relate to the motion of instances in game worlds, such as velocity and acceleration.

Screen Slices

One screen slice is equivalent to 1/360th of the engine window's length.

Screen slices are useful in positioning UI elements such as menus and mints - they make it possible to describe lengths such as middle of the screen (180 SLICES) or bottom of the screen (360 SLICES) in a way that's independent of the actual size of the engine window.

Unlike other length units, the length of a screen slice depends on the direction in which it's used: if used in a horizontal context (e.g. as a WIDTH value) one slice will equal 1/360 of the window's width, and if used in a vertical context (e.g. HEIGHT) it'll refer to 1/360 of the window's height.

###### Viewport Lengths

Viewport lengths are lengths composed using the units listed above. The basic syntax for them is as follows:

[<SIGN>] <MAGNITUDE> <UNIT>

Where:

- Sign can be + or -. It is optional, and if unprovided assumed to be +.

- Magnitude must be an integer.

- Unit must be one of the following:

  - SCREEN_PIXELS/SCREEN_PIXEL for screen pixels

  - SCALED_PIXELS/SCALED_PIXEL/PIXELS/PIXEL for scaled pixels

  - SCREEN_SLICES/SCREEN_SLICE/SLICES/SLICE for screen slices

  - TILES/TILE for tiles

Combinations of viewport lengths are also valid viewport lengths, e.g. 360 SLICES - 10 PIXELS.

If a viewport length is stated to have scaled pixel resolution, it means that this context is not sensitive to lengths smaller than scaled pixels, and will round them to the nearest scaled pixel value.

If a viewport length is stated to use relative slices, it means that the lengths of screen slices in this context are calculated using the active rendering area and not the whole window.

##### Rectangles

((<x1>, <y1>), (<x2>, <y2>))

x1, y1 correspond to the position of the upper left edge of the rectangle, while x2, y2 correspond to the lower right.

Depending on the context, the INF keyword can be used in descriptions to create rectangles that extend to infinity, called unbound rectangles. INF can also have a sign, such as -INF, +INF. For example ((-INF, 2), (+INF, 5)) represents a rectangle that is horizontally infinite, but vertically restricted between y = 2 and y = 5 lines.

Again depending on context, values being omitted in rectangle descriptions may be tolerable. These will default to context-specific values. As an example ((,),(+INF,)) when used as camera bounds in a map will yield a camera that is bound by the edges of the map in all directions except right.

##### Canvases

Canvases are visual environments on which tiles can be placed. They're used to describe the appearances of map and menu objects, and in case of map objects they also determine the in-game physical environments.

For the scripting capabilities of canvases see canvas scripting.

###### Syntax

1. TILES

   List of tiles within the canvas.

   1. <TILE NAME>

      Name of the tile to be placed on the canvas. Has the following form:

      <TILESET_OBJECT_NAME> <TILE_NAME>

      Where TILESET_OBJECT_NAME is the name of a tileset object, and TILE_NAME is the name of a tile within the tileset.

      For example, with MY_TILESET being the name of a tileset that contains the tiles TILE_1 and TILE_2 in it (see tileset examples), valid tile names for the tileset are MY_TILESET TILE_1 and MY_TILESET TILE_2.

      If the engine fails to find a tileset object with the given name, it will look for a game object instead, and use its game art tileset.

      If the whole name is a single token, it'll be interpreted as a tileset name, and the engine will look for a tile in the tileset named DEFAULT. As an example the names MY_TILESET and MY_TILESET DEFAULT are equivalent.

      1. <PLACEMENTS>

         ( <X>, <Y>, <Z> [, <TRANSFORM>])

         Where the tile will be placed on the canvas.

         For map canvases X, Y must be integers in tile units, and for menu canvases they must be viewport lengths with scaled pixel resolution. Z must be an integer and is used to determine the canvas layer of the placement. TRANSFORM is optional, and if provided defines the transformation to be applied to the tile.

         Multiple placements can be provided on the same line, and any text outside parentheses will be ignored. For example in maps (0,0,0) hello (1,0,0) is valid placement information.

2. LAYERS

   List of layers on the canvas.

   Each layer has a Z value and a parallax speed associated with it. Z values determine the layers' order of appearance, and parallax speeds determine how fast the tiles in the layer move as the camera scrolls.

   Layers are optional - placements with Z values that are not associated with any layer automatically create new layers with that Z value and the base parallax speed of 100.

   1. <LAYER_NAME>

      Name of a layer on the canvas.

      1. Z

         <Z_VALUE>

         Z value of the layer. Must be an integer.

         Layers with higher Z values are rendered in the background compared to layers with lower Z values. Things that are not part of canvases but are rendered alongside them will render as if they are between Z values 0 and -1. This means that tiles with negative Z values can obscure players and actor instances in maps, and mints in menus.

         All layers in a canvas must have unique Z values.

         A useful convention is to set the layer with Z value 0 to have parallax speed 100, and treat it as the "surface", with positive Z values as the background and negative Z values as the foreground.

      2. PARALLAX_SPEED

         <PARALLAX_SPEED>

         Parallax speed of the layer. Must be an integer.

         Parallax speeds determine how fast the tiles in the layer move as the camera scrolls, and the base parallax speed is 100. For example in games a layer with a parallax speed of 100 will move as fast as the player, 50 will move half as fast, and 0 will be completely stationary. Higher speed values are also possible, e.g. a layer with the parallax speed of 200 will move twice as fast as the player.

###### Examples

TODO: Insert examples

##### Transformations

Transformations are visual operations that can be applied to textures. Available transformations are the following:

- NONE

- VERTICAL_FLIP / VF

- HORIZONTAL_FLIP / HF

- QUARTER_ROTATION / QR

- HALF_ROTATION / HR

- THREE_QUARTERS_ROTATION / TQR

Rotations are done clockwise.

Combinations of transformations are also valid transformations, e.g. VF QR.

###### Scripting

Transformation values are exposed to Lua as strings, e.g. "NONE", or "QR". When existing tranform values are accessed the engine will use the shorthand forms, e.g.:

    tile.transform = "VERTICAL_FLIP" -- Set the transform value
    print(tile.transform)            -- Will print VF

##### Conditions

##### Game Buttons

##### Sprites

Sprites define how actor instances look and interact with the world at a given moment.

###### PATH

<PATH>

Path to the image containing the sprite's appearance, required.

If a property given to a sprite does not match any of the properties listed here, it's interpreted as a PATH, e.g. the following are equivalent:

    [MY_ACTOR]
        SPRITES:
            TEST_SPRITE:
                PATH: path-to-sprite.png

    [MY_ACTOR]
        SPRITES:
            TEST_SPRITE:
                path-to-sprite.png

###### DIMENSIONS

( <WIDTH> x <HEIGHT> )

Dimensions of the sprite. Width and height must be integers in scaled pixel units.

Optional, if unprovided will default to the dimensions of the image given in PATH.

###### DIRECTION

LEFT/RIGHT/UP/DOWN/FRONT/BACK

Direction in which the image of the sprite is facing by default.

Used to apply transforms as necessary, e.g. a sprite with DIRECTION set to RIGHT will be horizontally flipped when it's being used to render an instance facing left.

Optional, will default to RIGHT.

###### CENTER

( <X> , <Y> )

Center of the sprite.

Center is kept consistent from frame to frame, which allows the engine to keep the positions of instances consistent when they shape change and size during animations. You can think of it as the "heart" of the sprite.

Optional, will default to the center of the sprite's dimensions.

###### HITBOX

See rectangle parsing.

Hitbox of the sprite. The instance will take damage if its hitbox comes into contact with another instance's hurtbox.

Optional, none or multiple can be provided.

###### HURTBOX

See rectangle parsing.

Hurtbox of the sprite. The instance will inflict damage if its hurtbox comes into contact with another instance's hitbox.

Optional, none or multiple can be provided.

###### COLLISIONBOX

See rectangle parsing.

Collisionbox of the sprite. Used in interactions with map geometry, and represents the "solid" part of the sprite that can't go through tiles.

Optional, and unlike HITBOX and HURTBOX at most one COLLISIONBOX is allowed per sprite.

##### Sequences

##### Actions

Actions are things that actor instances can do. Actor instances always have an active action - whether it's one initiated at will (either by the player or through the AI), one that happens in response to something (like being hit), or just an idle action.

###### Syntax

1. TYPE

   RESPONSE/IDLE/MOVEMENT/ATTACK/DEFEND

   Type of the action. Determines whether the action can be started at will; RESPONSE and IDLE can't, but the others can.

   When an actor instance has no active action, the first IDLE action whose REQUIREMENTS property is satisfied is activated. Finding no suitable idle action will result in an error, so all actor objects must include at least one idle action.

2. ANIMATION

   See sequence parsing.

   Sequences should be made of animations.

3. MOTION

   1. INIT/DURING/END

      1. <MOTION MODIFIER>

         TODO: Obsoleted, replace

         [CONST/MAX/MIN/INCREMENT/DECREMENT] HORIZONTAL/VERTICAL POSITION/VELOCITY/SPEED/ACCELERATION [BY] <VALUE> [IF <CONDITION>]

         The first token is optional; will default to CONST if unprovided.

         [BY] is optional syntactic sugar for INCREMENT, DECREMENT cases, and is not expected for the other cases.

         If the motion modifier describes an effect on position, the effect types MAX/MIN/CONST are considered invalid.

         If the motion modifier is horizontal, the effect is "mirrored" when the corresponding instance is facing left, so that positive modifier values always correspond to movement towards the direction the instance is facing horizontally. No such adjustment is made for vertical modifiers.

         Value is in subpixel units.

         Optional.

4. REQUIREMENTS/TRIGGERS

   <CONDITION>

   See conditions.

   If type is response a condition is required.

   If type is not response this is optional; will default to TRUE so that the action will always be available.

5. DURATION

   INDEFINITE/ANIMATION_LENGTH/<VALUE>

   Value refers to the number of frames the action will be active.

   Optional; will default to indefinite.

6. INTERRUPTION

   1. INTERRUPTIBLE_AT_WILL

      YES/NO/TRUE/FALSE

      Optional; if not a response will default to yes, if a response will default to no.

   2. INTERRUPTIBLE_BY_RESPONSES

      YES/NO/TRUE/FALSE

      Optional; if not a response will default to yes, if a response will default to no.

   3. CONDITION

      <CONDITION>

      Optional; will default to false so that no extra interruption condition will exist.

###### Examples

TODO: Insert examples

###### Action Stacking

Actions can be stacked, meaning that multiple actions can be active at the same time. This is only possible with actions that are interruptible at will. At most five actions can be active at the same time, activation of any new actions will cause older ones to be shifted off, their ending consequences will not register.

With such stacked actions, the consequences of the latter ones are emphasized, but the consequences of earlier ones will also apply as long as they're not overshadowed by the more recent actions.

Appearance is determined by the most recent action only.

If an action is interruptible by responses, responses only kick in if it's the most recent action, and all stacked actions will be removed in such an event.

##### Scripts

##### Metadata

The METADATA property allows you to store custom information in elements. This information will then be available under the metadata field of the element's scripting API. For example:

    [EXAMPLE_ELEMENT]
        METADATA:
            Foo: Bar

registers the Foo, Bar key-value pair into the element's metadata, which can then be accessed as:

    -- Get EXAMPLE_ELEMENT
    local exampleElement = SearchObjects("EXAMPLE_ELEMENT")
    -- Access the field Foo of its metadata
    print(exampleElement.metadata.Foo) -- Will print Bar

The METADATA field is useful because it lets you embed your custom data into elements, which can then be used by your game's own logic. See the Implementing Weather tutorial for a demonstration.

There is no limit to how much information METADATA can contain, and its contents are translated to a table in the same hierarchy that they are provided in. For example:

    [EXAMPLE_ELEMENT]
        METADATA:
            Foo                     # metadata[1] = "Foo"
            Bar                     # metadata[2] = "Bar"
            Baz: Qux                # metadata.Baz = "Qux"
            Fruits:                 # metadata.Fruits will be a table
                Apples              # metadata.Fruits[1] = "Apples"
                Oranges             # metadata.Fruits[2] = "Oranges"
                Tropical:           # metadata.Fruits.Tropical will be a table
                    Papaya: 10      # metadata.Fruits.Tropical.Papaya = 10

In the scripting API, the metadata field will contain a table if the element has metadata, and will be nil if it does not. The field itself is read-only, but its contents aren't since metadata is just a regular table.

    exampleElement.metadata = 1       -- Wrong
    exampleElement.metadata.Foo = nil -- Correct, deletes Foo from the table

### Scripting

TODO: Draft, improve

Access signfiers: R/O, R/W refer to read-only and read-write access respectively. Note that a field being read-only does not mean that its fields cannot be read-write.

Lifetime signifiers: IND, BND, CND refer to independent, bound, and conditional lifetimes respectively.

#### Contexts

##### Initialization Contexts

##### Menu Instance Contexts

##### Game Instance Contexts

##### Player Contexts

##### Actor Instance Contexts

#### Global Definitions

##### ENGINE_VERSION

##### EType

##### AbsPath

##### Window

A value of type window, representing the window of the game engine.

Through this variable you can do things like resizing the engine's window, changing its title or icon, and more. See window scripting for details.

##### Storage

A value of type storage, containing the engine's persistent storage API.

Through this variable you can read and write files in the storage directory of the currently active game. See storage scripting for details.

##### CreateElement

##### SearchObjects

##### LaunchMenu

##### LaunchGame

##### LaunchStage

##### CloseSelf

##### CloseUntil

##### CloseAll

##### CreateMint

##### ActiveGame

##### SearchWorld

##### CreatePlayer

#### Types

##### Window

The window type allows you to do operations that relate to the window of the game engine.

The only value that has this type is the Window variable in the global environment.

###### .title R/W IND

A string value representing the title of the window.

This field can be set to new values of type string.

###### .icon R/W IND

A string or nil value representing the path of the image used as the window icon, relative to the currently active game.

This field can be set to new values of type string or nil.

###### .width R/W IND

An integer value representing the width of the window.

This value is in tile units. It is translated to screen pixels by multiplying it first with 16 (number of scaled pixels in a tile) and then the scale of the window. So for example a width of 24 with a scale of 3 will result in a window that's 24 * 16 * 3 = 1152 pixels wide.

This field can be set to new values of type integer. Trying to set it to a value less than one or one that results in a window larger than the the screen will result in an error.

###### .height R/W IND

An integer value representing the height of the window.

This value is in tile units. It is translated to screen pixels by multiplying it first with 16 (number of scaled pixels in a tile) and then the scale of the window. So for example a height of 24 with a scale of 3 will result in a window that's 24 * 16 * 3 = 1152 pixels tall.

This field can be set to new values of type integer. Trying to set it to a value less than one or one that results in a window larger than the the screen will result in an error.

###### .scale R/W IND

An integer value representing the scale multiplier of the window.

This field can be set to new values of type integer. Trying to set it to a value less than one or one that results in a window larger than the the screen will result in an error.

###### .letterbox R/W IND

A boolean value representing whether the window is to be letterboxed or not.

When a window is letterboxed it is made fullscreen, but the width and height of its render area is kept the same. This adds black letterboxes around the render area as necessary.

This field can be assigned to any value regardless of type - but the new value is always coerced to a boolean ( true or false ).

##### Storage

The storage type allows you to read and write files in the storage directory of the currently active game. The only value that has this type is the Storage variable in the global environment.

For example, if the currently active game is My Game, defined in the mygame folder, its storage directory will be in the following location:

    monospace.exe
    games
    └── mygame
        ├── main.txt    # Where My Game is defined
        └── storage     # Storage directory of My Game

The indices of the Storage variable represent the files in this directory, and can be used in the following way:

- Storage["file_name.txt"] - Reads the file. Returns a string if the file exists, and nil if it does not.

- Storage["file_name.txt"] = "File contents" - Writes to the file. Will create a new file or overwrite the existing file. Will create the storage directory if it does not already exist.

- Storage["file_name.txt"] = nil - Deletes the file. Will remove the storage directory if it becomes empty.

If there is no active game, this variable refers to the storage directory of the COMMONS game object, at the location common/storage.

##### Menu Instances

##### Mints

Mints are interactable UI elements in menus. For the static syntax of mints, see mint syntax.

Mints are created at runtime in two possible ways:

1. When a menu instance is created through the LaunchMenu function, the mints that exist in the corresponding menu object are initialized as Lua variables and stored in the menuInstance.mints table of the new menu.

2. Through the CreateMint function.

Despite being created alongside menu instances, mints have independent lifetimes, and can be freely inserted to and removed from menus via the menuInstance.mints table. This means that a mint can be passed from one menu to another, be in multiple menus at once, or exist outside of any menus.

Outside of the special fields listed below, mints can be used as regular tables, meaning that values can be read from and written to their arbitrary indices.

The fields of a mint can be iterated over via the pairs function.

###### Scripting Interface

1. .type R/W IND

   A string value indicating the mint's type. Is either "LABEL", "BUTTON", or "INPUT".

   This field can be set to new values that equal one of the above listed strings to change the mint's type.

2. .position R/W BND

   A viewport position value containing the position of the mint.

   This field can be set to new values of type string, viewport position, or viewport dimension. If the new value is a string, it must have the format "(<X>, <Y>)" where X and Y are viewport lengths.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

3. .dimensions R/W BND

   A viewport dimension value containing the dimensions of the mint.

   This field can be set to new values of type string, viewport position, or viewport dimension. If the new value is a string, it must have the format "( <WIDTH> x <HEIGHT>)" where WIDTH and HEIGHT are viewport lengths.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

4. .text R/W BND

   A text buffer value containing the text of the mint.

   This field can be set to new values that have the type string.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

5. .scripts R/O BND

   A script container value containing the scripts of the mint.

   This field is read-only.

6. .appearance R/O BND

   A mint appearance value containing the appearance settings of the mint.

   This field is read-only.

##### Text Buffers

Text buffers provide a scripting interface for the text content of mints. They are not independent objects - text buffers are created alongside the mints that own them, and their lifetimes are limited by their owners.

###### Scripting Interface

1. .string R/W IND

   A string value containing the text in the buffer.

   This field can be set to new values that have the type string.

2. .placeholder R/W IND

   A string value containing the placeholder text to be rendered when the buffer is empty.

   This field can be set to new values that have the type string.

3. .width R/O IND

   A number value equal to the width of the text in scaled pixel units.

   This field is read-only.

4. .height R/O IND

   A number value equal to the height of the text in scaled pixel units.

   This field is read-only.

5. .readOnly R/W IND

   A boolean value representing whether the text in the buffer is allowed to be edited or not. Intended for user input - does not disable the textBuffer:Insert and textBuffer:Delete functions.

   This field can be assigned to any value regardless of type - but the new value is always coerced to a boolean ( true or false ).

6. .cursorIndex R/W IND

   Integer value representing the index the cursor is on.

   Begins from 1. For example, with the string "ab", cursorIndex being 1 would correspond to the cursor being on "a", 2 being on "b", and 3 being at the end of the string.

   This field can be set to integer values. When being set, it has the following behavior when the index is outside of the normal range:

   - If the new value is too large (e.g. 4 for the above example), the cursor is set to the end of the string.

   - If the new value is negative, indices are counted from the end of the string with -1 corresponding to the last possible position (e.g. for the above example index -1 would be 3, -2 would be 2, -3 would be 1). If the new value is too low, the cursor is placed at the beginning of the string.

   - If the new value is zero, the cursor is set to the end of the string.

   After being set cursorIndex is always coerced into the normal range. So for the example string of "ab", setting it to -1 and then accessing it would result in it being 3.

7. :Insert(text) R/O IND

   A function that inserts the given text into the buffer at the current position of the cursor. Equivalent to entering text manually. Will move the cursor (and cursorIndex) to the right by the number of characters in the text.

   Parameter List
   Name | Type | Explanation
   --- | --- | ---
   text | String | Text to be inserted into the buffer.

8. :Delete(n) R/O IND

   A function that deletes n number of characters at the current location of the cursor. Equivalent to pressing delete n times.

   Parameter List
   Name | Type | Explanation
   --- | --- | ---
   n | Number | Number of characters to be deleted.

##### Viewport Types

This section lists the scripting interfaces for viewport lengths and various other types that build on them. For the syntax of viewport lengths, see viewport length syntax.

###### Viewport Lengths

1. .slices R/W IND

   An integer value containing the number of screen slices in the length.

   This field can be set to integer values.

2. .tiles R/W IND

   An integer value containing the number of tiles in the length.

   This field can be set to integer values.

3. .pixels R/W IND

   An integer value containing the number of scaled pixels in the length.

   This field can be set to integer values.

4. .screenPixels R/W IND

   An integer value containing the number of screen pixels in the length.

   This field can be set to integer values.

5. .absoluteLength R/O IND

   An integer value corresponding to the magnitude of the viewport length in screen pixels.

   This field is read-only.

###### Viewport Positions

1. .x R/W BND

   A viewport length value containing the x component of the position.

   This field can be set to new values of type string and viewport length. If the new value is a string, it must be in the viewport length syntax.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

2. .y R/W BND

   A viewport length value containing the y component of the position.

   This field can be set to new values of type string and viewport length. If the new value is a string, it must be in the viewport length syntax.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

###### Viewport Dimensions

1. .width R/W BND

   A viewport length value containing the width component of the dimension.

   This field can be set to new values of type string and viewport length. If the new value is a string, it must be in the viewport length syntax.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

2. .height R/W BND

   A viewport length value containing the height component of the dimension.

   This field can be set to new values of type string and viewport length. If the new value is a string, it must be in the viewport length syntax.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

###### Viewport Rectangles

1. .x1 R/W BND

   A viewport length value containing the x1 component of the dimension, which corresponds to the horizontal position of the upper left corner.

   This field can be set to new values of type string and viewport length. If the new value is a string, it must be in the viewport length syntax.

   If the rectangle allows omissions and infinite values, this index can also be set to "+INF", "-INF", "" and nil. Omitted fields will default to appropriate context-specific values.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

2. .y1 R/W BND

   A viewport length value containing the y1 component of the dimension, which corresponds to the vertical position of the upper left corner.

   This field can be set to new values of type string and viewport length. If the new value is a string, it must be in the viewport length syntax.

   If the rectangle allows omissions and infinite values, this index can also be set to "+INF", "-INF", "" and nil. Omitted fields will default to appropriate context-specific values.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

3. .x2 R/W BND

   A viewport length value containing the x2 component of the dimension, which corresponds to the horizontal position of the lower right corner.

   This field can be set to new values of type string and viewport length. If the new value is a string, it must be in the viewport length syntax.

   If the rectangle allows omissions and infinite values, this index can also be set to "+INF", "-INF", "" and nil. Omitted fields will default to appropriate context-specific values.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

4. .y2 R/W BND

   A viewport length value containing the x2 component of the dimension, which corresponds to the vertical position of the lower right corner.

   This field can be set to new values of type string and viewport length. If the new value is a string, it must be in the viewport length syntax.

   If the rectangle allows omissions and infinite values, this index can also be set to "+INF", "-INF", "" and nil. Omitted fields will default to appropriate context-specific values.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

##### Appearance Types

This section describes the Lua types that relate to the appearance settings of menu instances and mints.

The general rule with these types is that all properties listed in the menu appearance section have a corresponding field in the scripting interface, and the names of these fields are in lower camel case ( FONT becomes font, BACKGROUND_COLOR becomes backgroundColor and so on). So for example a menu appearance property set as follows:

    [MY_MENU]
        APPEARANCE:
            MINTS:
                TEXT:
                    FONT: MyCoolFont

Can be used through the scripting interface as:

    print(menuInstance.appearance.mints.text.font)  -- Prints "MyCoolFont"
    menuInstance.appearance.mints.text.font = "C64" -- Changes the menu's font

Inheritance continues to happen at runtime: setting an appearance setting of a mint to nil will make it inherit that setting from the menu instance it is in, and altering an appearance setting of a menu instance will make the mints in that menu use the new appearance setting IF they have inherited it. For example:

    -- Set the menu appearance setting
    menu.appearance.mints.text.font = "C64"

    -- Empty appearance settings of mints get inherited from menus
    mint.appearance.text.font = nil
    print(mint.appearance.text.font) -- Will print C64

    -- Inherited appearance settings are kept updated
    menu.appearance.mints.text.font = "ARCADE"
    print(mint.appearance.text.font) -- Will print ARCADE

    -- Explicitly setting an appearance setting will stop inheritance
    mint.appearance.text.font = "BUBBLES"
    menu.appearance.mints.text.font = "C64"
    print(mint.appearance.text.font) -- Will print BUBBLES

###### Menu Appearance

1. .backgroundColor R/W IND

   A string or nil value representing the background color of the menu instance.

   This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

2. .border R/O BND

   A value of type border appearance containing the border appearance settings of the menu instance.

   This field is read-only.

3. .mints R/O BND

   A value of type mint appearance containing the default appearance settings for the mints in the menu instance.

   Mints in a menu will inherit their missing appearance settings from this value, and altering this value will alter the inherited appearance settings of the mints.

   This field is read-only.

###### Mint Appearance

1. .activeColor R/W IND

   A string or nil value representing the background color of the mint when it is active (selected).

   This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

2. .inactiveColor R/W IND

   A string or nil value representing the background color of the mint when it is inactive (not selected).

   This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

3. .border R/O BND

   A value of type border appearance containing the border appearance settings of the mint.

   This field is read-only.

4. .text R/O BND

   A value of type text appearance containing the text appearance settings of the mint.

   This field is read-only.

###### Border Appearance

1. .activeColor R/W IND

   A string or nil value representing the color of the borders when mint or menu is active (mints are active when they are selected, menus are active when there is no menu newer than them blocking their evaluation).

   This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

2. .inactiveColor R/W IND

   A string or nil value representing the color of the borders when mint or menu is inactive (mints are inactive when they are not selected, menus are inactive when there is a menu newer than them that blocks their evaluation).

   This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

3. .width R/W BND

   A viewport length or nil value representing the width of the borders.

   This field can be set to new values of type string, viewport length or nil. If the new value is a string, it must be in the viewport length syntax.

   Setting this field to a new non-nil value will not replace the existing value, but will reinitialize it with the given value.

4. <left/right/up/down> R/O BND

   The fields left, right, up and down of a border appearance value contain values of type border side appearance, containing the appearance information for their respective side.

   1. .activeColor R/W IND

      A string or nil value representing the color of the border when mint or menu is active (mints are active when they are selected, menus are active when there is no menu newer than them blocking their evaluation).

      This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

   2. .inactiveColor R/W IND

      A string or nil value representing the color of the border when mint or menu is inactive (mints are inactive when they are not selected, menus are inactive when there is a menu newer than them that blocks their evaluation).

      This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

   3. .width R/W BND

      A viewport length or nil value representing the width of the border.

      This field can be set to new values of type string, viewport length or nil. If the new value is a string, it must be in the viewport length syntax.

      Setting this field to a new non-nil value will not replace the existing value, but will reinitialize it with the given value.

###### Text Appearance

1. .activeColor R/W IND

   A string or nil value representing the color of the text when its mint is active (selected).

   This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

2. .inactiveColor R/W IND

   A string or nil value representing the color of the text when its mint is inactive (not selected).

   This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

3. .placeholderColor R/W IND

   A string or nil value representing the color of the placeholder text.

   This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

4. .font R/W IND

   A string or nil value containing to the name of the font object used to render the text.

   This field can be set to new values that have the type string or nil. If the value is a string, it must be the name of a font object.

5. .position R/W BND

   A viewport position value representing the position of the text.

   This field can be set to new values of type string, viewport position, viewport dimension or nil. If the new value is a string, it must have the format "(<X>, <Y>)" where X and Y are viewport lengths.

   If the mint the text belongs to has the type INPUT, as the cursor moves around this value will automatically be altered as necessary to keep the cursor on-screen.

   Setting this field to a new value will not replace the existing value, but will reinitialize it with the given value.

6. .margin R/W BND

   A viewport length or nil value representing the distance the renderer will try to maintain between the text and the mint's borders.

   This field can be set to new values of type string, viewport length or nil. If the new value is a string, it must be in the viewport length syntax.

   Setting this field to a new non-nil value will not replace the existing value, but will reinitialize it with the given value.

7. .alignment R/W IND

   A string or nil value describing how to align the text. If a string, is either "LEFT", "RIGHT", or "CENTER".

   This field can be set to new values of type string or nil. If the new value is a string, it must equal one of the above listed strings.

8. .wrap R/W IND

   A string or nil value describing how to wrap the lines in the text that are too long for the render area. If a string, is either "NONE", "LINES", or "WORDS".

   This field can be set to new values of type string or nil. If the new value is a string, it must equal one of the above listed strings.

9. .lineHeight R/W IND

   A number or nil value determining the minimum height of text lines.

   This field can be set to new values of type number or nil.

10. .cursor R/O BND

    A value of type cursor appearance, containing the settings regarding how the cursor is to be rendered.

    1. .type R/W IND

       A string or nil value indicating the type of the cursor. If a string, is either BLOCK or CHARACTER.

       This field can be set to new values of type string or nil. If the new value is a string, it must equal one of the above listed strings.

    2. .color R/W IND

       A string or nil value representing the color of the cursor.

       This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

    3. .blink R/W IND

       A string or nil value describing how the cursor blinks.

       This field can be set to new values of type string or nil. If the new value is a string, it must be in the appropriate format of "ON_DURATION OFF_DURATION" where both ON_DURATION and OFF_DURATION are integers.

11. .regions R/O BND

    A value of type text region container.

    This is a special table-like type that allows you to:

    - Access the existing text regions by indexing their names

      regions.myRegion

    - Create new regions by inserting tables containing region information into its indices

      regions.newRegion = {RANGE = "1 10", FONT = "ARCADE"}

    - Remove existing regions by setting its fields to nil

      regions.newRegion = nil

    It can also be iterated over using the pairs function. (While iterating over the text region container avoid inserting new regions, deleting existing regions, or altering region ranges. These operations are currently not supported during iteration.)

    1. .<region_name> R/W BND

       A text region or nil value depending on whether a region with the given name exists in the container or not.

       The fields of a text region container can be set to new values of type table, text region or nil. Inserting table and text region values creates new regions in the container, and inserting nil causes the existing regions to be deleted.

       1. .range R/W IND

          A string or nil value indicating the range of the region.

          This field can be set to new values of type string or nil. If the new value is a string, it must be in the appropriate format of "[RANGE_BEGIN RANGE_END)" where both RANGE_BEGIN and RANGE_END are integers.

       2. .font R/W IND

          A string or nil value containing to the name of the font object used to render the text in the region.

          This field can be set to new values that have the type string or nil. If the value is a string, it must be the name of a font object.

       3. .offset R/W IND

          A string or nil value indicating the offset of the text in the region.

          This field can be set to new values of type string or nil. If the new value is a string, it must be in the appropriate format of "(X, Y)" where both X and Y are integers.

       4. .activeColor R/W IND

          A string or nil value representing the color of the text in the region when its mint is active (selected).

          This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

       5. .inactiveColor R/W IND

          A string or nil value representing the color of the text in the region when its mint is inactive (unselected).

          This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

       6. .activeBgColor R/W IND

          A string or nil value representing the background color of the text in the region when its mint is active (selected).

          This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

       7. .inactiveBgColor R/W IND

          A string or nil value representing the background color of the text in the region when its mint is inactive (unselected).

          This field can be set to new values that have the type string or nil. If the value is a string, it must use the color syntax.

##### Game Instances

##### Players

##### Actor Instances

##### Map Instances

##### Stages

##### Canvases

1. :Place(tileName, x, y, z [, transform]) R/O IND

   Places tile described by tileName onto canvas, at the location specified by the x, y and z parameters, with the given optional transform value. Returns a canvas tile value representing the new tile.

   tileName must be a string, see tile names for more information.

   x and y must be integers for map canvases, and strings in the viewport length format for menu canvases.

   z must be an integer and determines the canvas layer the tile is on. If no canvas layer with the given z value is found, a new layer with the base parallax speed of 100 is automatically created.

   transform is an optional parameter, and if provided must be a string corresponding to a valid transformation.

2. .tiles R/O BND

   A value of type canvas tile container.

   This value is array-like: with n tiles on the canvas its integer indices from 1 to n will contain values of type canvas tile.

   These indices are read-only: to place new tiles use canvas:Place, and to remove existing tiles use tile:Remove. When a new tile is placed on the canvas it is appended to the end of the array, and when a tile is removed from the canvas all subsequent tiles in the array are shifted below by one, so that no holes will exist.

   This value can be iterated over using the ipairs function. While iterating you can place new tiles or remove existing tiles.

3. .layers R/O BND

   A value of type canvas layer container.

   This is a special table-like type that allows you to:

   - Access the existing canvas layers by indexing their names.

     canvas.layers.myLayer

   - Create new layers by inserting tables containing layer information into its indices.

     canvas.layers.newLayer = {Z = "15", PARALLAX_SPEED = "50"}

     Note that all layers in a canvas must have unique Z values. Trying to insert a new layer with a duplicate Z value will throw an error.

   - Remove existing layers by setting its fields to nil.

     canvas.layers.newLayer = nil

     Removing a layer removes all tiles on that layer as well.

   It can also be iterated over using the pairs function. (While iterating over the canvas layer container avoid inserting new layers or deleting existing layers. These operations are currently not supported during iteration.)

4. .type R/O IND

   A string value describing the type of the canvas. Is either "MAP" or "MENU".

   The difference between map and menu canvases is that the x, y positions of tiles are integers in map canvases, and viewport lengths in menu canvases.

   This field is read-only.

###### Canvas Tiles

1. .tileName R/W IND

   A string value containing the name of the tile, which determines the tile's appearance.

   This field can be set to new values of type string that are valid tile names.

2. .x R/W CON

   X position of the tile.

   If the tile belongs to a map canvas this field contains an integer, can be set to new integer values, and the value it contains has independent lifetime.

   If the tile belongs to a menu canvas, this field contains a viewport length, can be set new values that have the type string or viewport length, and the lifetime of the value it contains is bound by the lifetime of the tile. If the new value is a string, it must be in the viewport length format.

3. .y R/W CON

   Y position of the tile.

   If the tile belongs to a map canvas this field contains an integer, can be set to new integer values, and the value it contains has independent lifetime.

   If the tile belongs to a menu canvas, this field contains a viewport length, can be set new values that have the type string or viewport length, and the lifetime of the value it contains is bound by the lifetime of the tile. If the new value is a string, it must be in the viewport length format.

4. .z R/W IND

   An integer value containing the Z value of the tile, determining the canvas layer the tile is on.

   This field can be set to new integer values. If no canvas layer with the given new Z value is found, a new layer with the base parallax speed of 100 is automatically created.

5. .transform R/W IND

   A string or nil value containing the transformation that has been applied to the tile.

   This field can be set to new values of type string and nil. If the new value is a string, it must be a valid transformation.

6. .isVisible R/W IND

   A boolean value determining whether the tile is visible or not.

   This field can be assigned to any value regardless of type - but the new value is always coerced to a boolean ( true or false ).

7. .animation R/O BND

   If the tile is an animated tile, this field contains a value of type animation with the below listed fields. If the tile is a static tile, this field is nil.

   This field is read-only.

   1. .frame R/W IND

      An integer value containing the index of the frame to be rendered. Is in the range [1-n] where n is the total number of frames in the animation.

      This field can be set to new integer values. If the new value is outside of the [1-n] range it will be brought within the range, e.g. setting this field to n+1 will result in it being 1, setting it to 0 will result in it being n and so on.

      If the animation sequence is infinite (uses the REPEAT keyword), this field will behave as if n is an arbitrary very large integer.

   2. .speed R/W IND

      A number value representing the animation's speed.

      This field can be set to new number values. Setting it to 0 makes the animation pause, setting it to 1 makes it run at its normal speed, 0.5 at half speed, -1 makes it run in reverse, and so on.

8. :Remove() R/O IND

   Removes tile from the canvas. After the removal the tile value will no longer be valid, and trying to access its indices will result in an error.

###### Canvas Layers

1. .z R/W IND

   An integer value representing the Z value of the layer.

   This field can be set to new values of type integer. Note that all layers on a canvas must have unique Z values, so trying to set this to a new value that is already used by another layer in the canvas will result in an error.

   Changing this value will also change the .z values of all tiles on the layer.

2. .parallaxSpeed R/W IND

   An integer value representing the parallax speed of the layer.

   This field can be set to new values of type integer.

##### Keymaps

##### Camera Instances

##### Script Containers

##### Objects

object.name

object.metadata

For game objects:

object.art - game art tileset

For tile objects:

tileset.tiles - a table containing the names of tiles as keys and True as values

### Other

#### Window Stack

#### Special Element Names

#### Error Messages

## Tutorials

### Implementing Weather

TODO: Draft, complete

Let's say you want to implement weather in your game, so that some maps have different looks depending on the weather, e.g. if it's snowy, sunny, rainy or windy. A possible way to do this is as follows:

1. Mark the maps that are sensitive to weather changes.

2. When the player enters such a map, go over the tiles in the map.

3. If a tile indicates that its appearance changes depending on the weather, find the tile to replace it with.

4. Do the replacement.

We can mark the maps that are sensitive to weather as:

    MAP OBJECT

    [FOREST_MAP]
        METADATA:
            WEATHER_SENSITIVE: YES

We need to note weather sensitivity for tiles as well, and we also need a way to determine which tile replaces which. A simple way to do this is to name your tiles so that their names indicate which weather conditions they respond to, e.g.

    TILESET OBJECT

    [FOREST_TREES_TILESET]
        PINETREE_SUNNY: ... # Tile info, skipped for brevity
        PINETREE_WINDY: ...
        PINETREE_SNOWY: ...
        PINETREE_RAINY: ...

Then you can just check the latter part of a tile name to see if it is sensitive to weather change, and replace the weather part to find the name of the new tile.

Our full script will then look like this: