# Level packs A level pack is a collection of levels that belong together. This is the best way to store and share custom levels, but it requires Lua programming skills to add a new level pack. To add a new level pack, a new Luanti mod must be created containing these things: 1) Level schematic (`*.mts`) files. These are for the blocks of the level 2) Level metadata in a level data CSV file. This contains all information that the schematic file cannot hold, e.g. title, boundary blocks, weather, sky, etc. The level data CSV specifies the metadata for ALL levels at once. This file also defines the level order. Levels at the top will be played first. 3) Lua code to register the level pack (see below) The mod must depend on `lzr_levels`. The mod *should* follow the naming convention `lzr_pack_`. Apart from this, the mod can be like any other mod and may add or change other things on top of just the levels themselves. ## File structure Normally, the file structure of the mod is as follows: * `mod.conf`: Must declare dependency on `lzr_levels` * `init.lua`: Lua code to register level pack (see below) * `data/level_data.csv`: CSV file for level metadata for ALL levels * `schematics/`: The level `*.mts` files go here * `solutions/`: (optional) Level solution files `*.sol.csv` go here. * `locale/`: (optional) To store the locale files, if present Some of these file locations may be changed by parameters of the function `lzr_levels.register_level_pack`. ## Register the level pack To register a level pack, you must call `lzr_levels.register_level_pack`. The definition of this function is as follows: ### `lzr_levels.register_level_pack(name, info)` Register a level pack. For this to work, the level-related data must be present in the locations defined at `level_data_file`, `schematic_path` and (optionally) `solutions_path` described below. If successful, the level pack will appear in the game under the custom levels menu. Parameters: * `name`: Level pack ID. A string. The allowed characters are `a-z`, `A-Z`, `0-9` and `_` (underscore). IDs starting with two underscores are reserved to Lazarr! * `info`: Table of optional additional information, with these fields: * `title`: human-readable level pack title * `description`: short description/explanation about this level pack. 1-3 sentences. * `textdomain_level_names`: textdomain of the translation file containing the translated level names (default: no translation) * `textdomain_npc_texts`: textdomain of the translation file containing the translated texts for NPCs like Goldie the Parrot (default: no translation) * `level_data_file`: Path to CSV file containing metadata of all levels (default: `/data/level_data.csv`) * `schematic_path`: Path to directory containing the level '.mts' schematic files (default: `/schematics`) * `solutions_path`: Path to directory containing the *optional* level '.sol.csv' solution files (default: `/solutions`) If successful, the level pack will appear in the game under the custom levels menu. #### A note about solution files Solution files exist for internal purposes, for the quality assurance and game stability of Lazarr! to ensure the levels still work after major changes to the game. This feature mainly exists for the core levels and it’s not neccessary for custom level packs to create them. ### Example A simple example with one level, translated into German. We call the mod `lzr_pack_example`. Here’s the file structure: * `mod.conf` * `init.lua` * `schematics` * `lzr_pack_example_example.mts` * `data` * `level_data.csv` * `locale` * `lzr_pack_example.pot` * `lzr_pack_example.po.de` * `lzr_pack_example_level_names.pot` * `lzr_pack_example_level_names.de.po` * `lzr_pack_example_npc_texts.pot` * `lzr_pack_example_npc_texts.de.po` The code of `init.lua`: local S = minetest.get_translator("lzr_pack_example") lzr_levels.register_level_pack("example", { title = S("My Example Levels"), description = S("Some example levels to test things."), textdomain_level_names = "lzr_pack_example_level_names", textdomain_npc_texts = "lzr_pack_example_npc_texts", })