* [XYZ] refers to a section the Minetest API
* [#ABC] refers to a section in this document
+ * [pos] refers to a position table `{x = -5, y = 0, z = 200}`
Bucket API
----------
The bucket API allows registering new types of buckets for non-default liquids.
-
bucket.register_liquid(
"default:lava_source", -- name of the source node
"default:lava_flowing", -- name of the flowing node
"bucket:bucket_lava", -- name of the new bucket item (or nil if liquid is not takeable)
"bucket_lava.png", -- texture of the new bucket item (ignored if itemname == nil)
"Lava Bucket", -- text description of the bucket item
- {lava_bucket = 1} -- groups of the bucket item, OPTIONAL
+ {lava_bucket = 1}, -- groups of the bucket item, OPTIONAL
+ false -- force-renew, OPTIONAL. Force the liquid source to renew if it has
+ -- a source neighbour, even if defined as 'liquid_renewable = false'.
+ -- Needed to avoid creating holes in sloping rivers.
)
+The filled bucket item is returned to the player that uses an empty bucket pointing to the given liquid source.
+When punching with an empty bucket pointing to an entity or a non-liquid node, the on_punch of the entity or node will be triggered.
+
Beds API
--------
}
}
+Bones API
+---------
+
+An ordered list of listnames (default: "main", "craft") of the player inventory,
+that will be placed into bones or dropped on player death can be looked up or changed
+in `bones.player_inventory_lists`.
+
+e.g. `table.insert(bones.player_inventory_lists, "backpack")`
+
Creative API
------------
-A global string called `creative.formspec_add` was added which allows mods to add additional formspec elements onto the default creative inventory formspec to be drawn after each update.
+Use `creative.register_tab(name, title, items)` to add a tab with filtered items.
+For example,
+
+ creative.register_tab("tools", "Tools", minetest.registered_tools)
+
+is used to show all tools. Name is used in the sfinv page name, title is the
+human readable title.
+
+`is_enabled_for` is used to check whether a player is in creative mode:
+
+ creative.is_enabled_for(name)
+
+Override this to allow per-player game modes.
+
+The contents of `creative.formspec_add` is appended to every creative inventory
+page. Mods can use it to add additional formspec elements onto the default
+creative inventory formspec to be drawn after each update.
+
+Chests API
+----------
+
+The chests API allows the creation of chests, which have their own inventories for holding items.
+
+`default.chest.get_chest_formspec(pos)`
+
+ * Returns a formspec for a specific chest.
+ * `pos` Location of the chest node, e.g `{x = 1, y = 1, z = 1}`
+
+`default.chest.chest_lid_obstructed(pos)`
+
+ * Returns a boolean depending on whether or not a chest has its top obstructed by a solid node.
+ * `pos` Location of the chest node, e.g `{x = 1, y = 1, z = 1}`
+
+`default.chest.chest_lid_close(pn)`
+
+ * Closes the chest that a player is currently looking in.
+ * `pn` The name of the player whose chest is going to be closed
+
+`default.chest.open_chests`
+
+ * A table indexed by player name to keep track of who opened what chest.
+ * Key: The name of the player.
+ * Value: A table containing information about the chest the player is looking at.
+ e.g `{ pos = {1, 1, 1}, sound = null, swap = "chest" }`
+
+`default.chest.register_chest(name, def)`
+
+ * Registers new chest
+ * `name` Name for chest
+ * `def` See [#Chest Definition]
+
+### Chest Definition
+
+ description = "Chest",
+ tiles = {
+ "default_chest_top.png",
+ "default_chest_top.png",
+ "default_chest_side.png",
+ "default_chest_side.png",
+ "default_chest_front.png",
+ "default_chest_inside.png"
+ }, -- Textures which are applied to the chest model.
+ sounds = default.node_sound_wood_defaults(),
+ sound_open = "default_chest_open",
+ sound_close = "default_chest_close",
+ groups = {choppy = 2, oddly_breakable_by_hand = 2},
+ protected = false, -- If true, only placer can modify chest.
Doors API
---------
### Fence gate definition
description = "Wooden Fence Gate",
- texture = "default_wood.png",
+ texture = "default_wood.png", -- `backface_culling` will automatically be
+ -- set to `true` if not specified.
material = "default:wood",
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
sounds = default.node_sound_wood_defaults(), -- optional
+Dungeon Loot API
+----------------
+
+The mod that places chests with loot in dungeons provides an API to register additional loot.
+
+`dungeon_loot.register(def)`
+
+ * Registers one or more loot items
+ * `def` Can be a single [#Loot definition] or a list of them
+
+`dungeon_loot.registered_loot`
+
+ * Table of all registered loot, not to be modified manually
+
+### Loot definition
+
+ name = "item:name",
+ chance = 0.5,
+ -- ^ chance value from 0.0 to 1.0 that the item will appear in the chest when chosen
+ -- due to an extra step in the selection process, 0.5 does not(!) mean that
+ -- on average every second chest will have this item
+ count = {1, 4},
+ -- ^ table with minimum and maximum amounts of this item
+ -- optional, defaults to always single item
+ y = {-32768, -512},
+ -- ^ table with minimum and maximum heights this item can be found at
+ -- optional, defaults to no height restrictions
+ types = {"desert"},
+ -- ^ table with types of dungeons this item can be found in
+ -- supported types: "normal" (the cobble/mossycobble one), "sandstone", "desert"
+ -- optional, defaults to no type restrictions
+
Fence API
---------
`farming.register_plant(name, Plant definition)`
* Register a new growing plant, see [#Plant definition]
+`farming.registered_plants[name] = definition`
+ * Table of registered plants, indexed by plant name
+
### Hoe Definition
* Called when fire attempts to remove a burning node.
* `pos` Position of the burning node.
+ `on_ignite(pos, igniter)`
+
+ * Called when Flint and steel (or a mod defined ignitor) is used on a node.
+ Defining it may prevent the default action (spawning flames) from triggering.
+ * `pos` Position of the ignited node.
+ * `igniter` Player that used the tool, when available.
+
+
Give Initial Stuff API
----------------------
^ Adds items to the list of items to be given
+Players API
+-----------
+
+The player API can register player models and update the player's appearence
+
+* `player_api.register_model(name, def)`
+ * Register a new model to be used by players
+ * name: model filename such as "character.x", "foo.b3d", etc.
+ * def: See [#Model definition]
+ * saved to player_api.registered_models
+
+* `player_api.registered_player_models[name]`
+ * Get a model's definition
+ * see [#Model definition]
+
+* `player_api.set_model(player, model_name)`
+ * Change a player's model
+ * `player`: PlayerRef
+ * `model_name`: model registered with player_api.register_model()
+
+* `player_api.set_animation(player, anim_name [, speed])`
+ * Applies an animation to a player
+ * anim_name: name of the animation.
+ * speed: frames per second. If nil, default from the model is used
+
+* `player_api.set_textures(player, textures)`
+ * Sets player textures
+ * `player`: PlayerRef
+ * `textures`: array of textures, If `textures` is nil the default
+ textures from the model def are used
+
+* `player_api.get_animation(player)`
+ * Returns a table containing fields `model`, `textures` and `animation`.
+ * Any of the fields of the returned table may be nil.
+ * player: PlayerRef
+
+### Model Definition
+
+ {
+ animation_speed = 30, -- Default animation speed, in FPS.
+ textures = {"character.png", }, -- Default array of textures.
+ visual_size = {x = 1, y = 1}, -- Used to scale the model.
+ animations = {
+ -- <anim_name> = {x = <start_frame>, y = <end_frame>},
+ foo = {x = 0, y = 19},
+ bar = {x = 20, y = 39},
+ -- ...
+ },
+ collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}, -- In nodes from feet position
+ stepheight = 0.6, -- In nodes
+ eye_height = 1.47, -- In nodes above feet position
+ }
+
+
TNT API
-----------
+-------
`tnt.register_tnt(definition)`
* `description` A description for your TNT.
* `radius` The radius within which the TNT can destroy nodes. The default is 3.
* `damage_radius` The radius within which the TNT can damage players and mobs. By default it is twice the `radius`.
+ * `sound` The sound played when explosion occurs. By default it is `tnt_explode`.
* `disable_drops` Disable drops. By default it is set to false.
* `ignore_protection` Don't check `minetest.is_protected` before removing a node.
* `ignore_on_blast` Don't call `on_blast` even if a node has one.
* `bottom` Bottom tile. By default the name of the tnt with a suffix of `_bottom.png`.
* `burning` Top tile when lit. By default the name of the tnt with a suffix of `_top_burning_animated.png".
-`tnt.boom(position, definition)`
+`tnt.boom(position[, definition])`
^ Create an explosion.
* `position` The center of explosion.
-* `definition` The TNT definion as passed to `tnt.register`
+* `definition` The TNT definion as passed to `tnt.register` with the following addition:
+ * `explode_center` false by default which removes TNT node on blast, when true will explode center node.
-`tnt.burn(position)`
-
-^ Ignite TNT at position
+`tnt.burn(position, [nodename])`
+^ Ignite node at position, triggering its `on_ignite` callback (see fire mod).
+If no such callback exists, fallback to turn tnt group nodes to their
+"_burning" variant.
+ nodename isn't required unless already known.
To make dropping items from node inventories easier, you can use the
following helper function from 'default':
* `new_param2` the new value of param2 that would have been set if on_rotate wasn't there
* return value: false to disallow rotation, nil to keep default behaviour, true to allow
it but to indicate that changed have already been made (so the screwdriver will wear out)
- * use `on_rotate = screwdriver.disallow` to always disallow rotation
+ * use `on_rotate = false` to always disallow rotation
* use `on_rotate = screwdriver.rotate_simple` to allow only face rotation
+
+Sethome API
+-----------
+
+The sethome API adds three global functions to allow mods to read a players home position,
+set a players home position and teleport a player to home position.
+
+`sethome.get(name)`
+
+ * `name` Player who's home position you wish to get
+ * return value: false if no player home coords exist, position table if true
+
+`sethome.set(name, pos)`
+
+ * `name` Player who's home position you wish to set
+ * `pos` Position table containing coords of home position
+ * return value: false if unable to set and save new home position, otherwise true
+
+`sethome.go(name)`
+
+ * `name` Player you wish to teleport to their home position
+ * return value: false if player cannot be sent home, otherwise true
+
+
+Sfinv API
+---------
+
+### sfinv Methods
+
+**Pages**
+
+* sfinv.set_page(player, pagename) - changes the page
+* sfinv.get_homepage_name(player) - get the page name of the first page to show to a player
+* sfinv.register_page(name, def) - register a page, see section below
+* sfinv.override_page(name, def) - overrides fields of an page registered with register_page.
+ * Note: Page must already be defined, (opt)depend on the mod defining it.
+* sfinv.set_player_inventory_formspec(player) - (re)builds page formspec
+ and calls set_inventory_formspec().
+* sfinv.get_formspec(player, context) - builds current page's formspec
+
+**Contexts**
+
+* sfinv.get_or_create_context(player) - gets the player's context
+* sfinv.set_context(player, context)
+
+**Theming**
+
+* sfinv.make_formspec(player, context, content, show_inv, size) - adds a theme to a formspec
+ * show_inv, defaults to false. Whether to show the player's main inventory
+ * size, defaults to `size[8,8.6]` if not specified
+* sfinv.get_nav_fs(player, context, nav, current_idx) - creates tabheader or ""
+
+### sfinv Members
+
+* pages - table of pages[pagename] = def
+* pages_unordered - array table of pages in order of addition (used to build navigation tabs).
+* contexts - contexts[playername] = player_context
+* enabled - set to false to disable. Good for inventory rehaul mods like unified inventory
+
+### Context
+
+A table with these keys:
+
+* page - current page name
+* nav - a list of page names
+* nav_titles - a list of page titles
+* nav_idx - current nav index (in nav and nav_titles)
+* any thing you want to store
+ * sfinv will clear the stored data on log out / log in
+
+### sfinv.register_page
+
+sfinv.register_page(name, def)
+
+def is a table containing:
+
+* `title` - human readable page name (required)
+* `get(self, player, context)` - returns a formspec string. See formspec variables. (required)
+* `is_in_nav(self, player, context)` - return true to show in the navigation (the tab header, by default)
+* `on_player_receive_fields(self, player, context, fields)` - on formspec submit.
+* `on_enter(self, player, context)` - called when the player changes pages, usually using the tabs.
+* `on_leave(self, player, context)` - when leaving this page to go to another, called before other's on_enter
+
+### get formspec
+
+Use sfinv.make_formspec to apply a layout:
+
+ return sfinv.make_formspec(player, context, [[
+ list[current_player;craft;1.75,0.5;3,3;]
+ list[current_player;craftpreview;5.75,1.5;1,1;]
+ image[4.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]
+ listring[current_player;main]
+ listring[current_player;craft]
+ image[0,4.25;1,1;gui_hb_bg.png]
+ image[1,4.25;1,1;gui_hb_bg.png]
+ image[2,4.25;1,1;gui_hb_bg.png]
+ image[3,4.25;1,1;gui_hb_bg.png]
+ image[4,4.25;1,1;gui_hb_bg.png]
+ image[5,4.25;1,1;gui_hb_bg.png]
+ image[6,4.25;1,1;gui_hb_bg.png]
+ image[7,4.25;1,1;gui_hb_bg.png]
+ ]], true)
+
+See above (methods section) for more options.
+
+### Customising themes
+
+Simply override this function to change the navigation:
+
+ function sfinv.get_nav_fs(player, context, nav, current_idx)
+ return "navformspec"
+ end
+
+And override this function to change the layout:
+
+ function sfinv.make_formspec(player, context, content, show_inv, size)
+ local tmp = {
+ size or "size[8,8.6]",
+ theme_main,
+ sfinv.get_nav_fs(player, context, context.nav_titles, context.nav_idx),
+ content
+ }
+ if show_inv then
+ tmp[4] = theme_inv
+ end
+ return table.concat(tmp, "")
+ end
+
Stairs API
----------
### Pane definition
{
- textures = {"texture_Bottom_top", "texture_left_right", "texture_front_back"}, -- More tiles aren't supported
+ textures = {"texture for sides", (unused), "texture for top and bottom"}, -- More tiles aren't supported
groups = {group = rating}, -- Uses the known node groups, see [Known damage and digging time defining groups]
sounds = SoundSpec, -- See [#Default sounds]
recipe = {{"","","","","","","","",""}}, -- Recipe field only
+ use_texture_alpha = true, -- Optional boolean (default: `false`) for colored glass panes
}
Raillike definitions
* `default.node_sound_wood_defaults()`
* `default.node_sound_leaves_defaults()`
* `default.node_sound_glass_defaults()`
+ * `default.node_sound_metal_defaults()`
Default constants
-----------------
`default.LIGHT_MAX` The maximum light level (see [Node definition] light_source)
-Player API
-----------
-The player API can register player models and update the player's appearence
+GUI and formspecs
+-----------------
-`default.player_register_model(name, def)`
+`default.get_hotbar_bg(x, y)`
- * Register a new model to be used by players.
- * name: model filename such as "character.x", "foo.b3d", etc.
- * def: See [#Model definition]
+ * Get the hotbar background as string, containing the formspec elements
+ * x: Horizontal position in the formspec
+ * y: Vertical position in the formspec
-`default.registered_player_models[name]`
+`default.gui_bg`
- * Get a model's definition
- * see [#Model definition]
+ * Background color formspec element
-`default.player_set_model(player, model_name)`
+`default.gui_bg_img`
- * Change a player's model
- * `player`: PlayerRef
- * `model_name`: model registered with player_register_model()
+ * Image overlay formspec element for the background to use in formspecs
-`default.player_set_animation(player, anim_name [, speed])`
+`default.gui_slots`
- * Applies an animation to a player
- * anim_name: name of the animation.
- * speed: frames per second. If nil, default from the model is used
+ * `listcolors` formspec element that is used to format the slots in formspecs
-`default.player_set_textures(player, textures)`
+`default.gui_survival_form`
- * Sets player textures
- * `player`: PlayerRef
- * `textures`: array of textures, If `textures` is nil, the default textures from the model def are used
+ * Entire formspec for the survival inventory
-default.player_get_animation(player)
+`default.get_furnace_active_formspec(fuel_percent, item_percent)`
- * Returns a table containing fields `model`, `textures` and `animation`.
- * Any of the fields of the returned table may be nil.
- * player: PlayerRef
+ * Get the active furnace formspec using the defined GUI elements
+ * fuel_percent: Percent of how much the fuel is used
+ * item_percent: Percent of how much the item is cooked
-### Model Definition
+`default.get_furnace_inactive_formspec()`
+
+ * Get the inactive furnace formspec using the defined GUI elements
- {
- animation_speed = 30, -- Default animation speed, in FPS.
- textures = {"character.png", }, -- Default array of textures.
- visual_size = {x = 1, y = 1}, -- Used to scale the model.
- animations = {
- -- <anim_name> = {x = <start_frame>, y = <end_frame>},
- foo = {x = 0, y = 19},
- bar = {x = 20, y = 39},
- -- ...
- },
- }
Leafdecay
---------
-To enable leaf decay for a node, add it to the `leafdecay` group.
+To enable leaf decay for leaves when a tree is cut down by a player,
+register the tree with the default.register_leafdecay(leafdecaydef)
+function.
+
+If `param2` of any registered node is ~= 0, the node will always be
+preserved. Thus, if the player places a node of that kind, you will
+want to set `param2 = 1` or so.
-The rating of the group determines how far from a node in the group `tree`
-the node can be without decaying.
+The function `default.after_place_leaves` can be set as
+`after_place_node of a node` to set param2 to 1 if the player places
+the node (should not be used for nodes that use param2 otherwise
+(e.g. facedir)).
-If `param2` of the node is ~= 0, the node will always be preserved. Thus, if
-the player places a node of that kind, you will want to set `param2 = 1` or so.
+If the node is in the `leafdecay_drop` group then it will always be
+dropped as an item.
-The function `default.after_place_leaves` can be set as `after_place_node of a node`
-to set param2 to 1 if the player places the node (should not be used for nodes
-that use param2 otherwise (e.g. facedir)).
+`default.register_leafdecay(leafdecaydef)`
+
+`leafdecaydef` is a table, with following members:
+ {
+ trunks = {"default:tree"}, -- nodes considered trunks
+ leaves = {"default:leaves", "default:apple"},
+ -- nodes considered for removal
+ radius = 3, -- radius to consider for searching
+ }
+
+Note: all the listed nodes in `trunks` have their `on_after_destruct`
+callback overridden. All the nodes listed in `leaves` have their
+`on_timer` callback overridden.
-If the node is in the `leafdecay_drop` group then it will always be dropped as an
-item.
Dyes
----
* `default.grow_new_pine_tree(pos)`
* Grows a new design pine tree at pos
+ * `default.grow_new_snowy_pine_tree(pos)`
+ * Grows a new design snowy pine tree at pos
+
* `default.grow_new_acacia_tree(pos)`
* Grows a new design acacia tree at pos
* `default.grow_new_aspen_tree(pos)`
* Grows a new design aspen tree at pos
- * `default.grow_new_snowy_pine_tree(pos)`
- * Grows a new design snowy pine tree at pos
+ * `default.grow_bush(pos)`
+ * Grows a bush at pos
+
+ * `default.grow_acacia_bush(pos)`
+ * Grows an acaia bush at pos
+
+Carts
+-----
+
+ carts.register_rail(
+ "mycarts:myrail", -- Rail name
+ nodedef, -- standard nodedef
+ railparams -- rail parameter struct (optional)
+ )
+
+ railparams = {
+ on_step(obj, dtime), -- Event handler called when
+ -- cart is on rail
+ acceleration, -- integer acceleration factor (negative
+ -- values to brake)
+ }
+
+ The event handler is called after all default calculations
+ are made, so the custom on_step handler can override things
+ like speed, acceleration, player attachment. The handler will
+ likely be called many times per second, so the function needs
+ to make sure that the event is handled properly.
+
+Key API
+-------
+
+The key API allows mods to add key functionality to nodes that have
+ownership or specific permissions. Using the API will make it so
+that a node owner can use skeleton keys on their nodes to create keys
+for that node in that location, and give that key to other players,
+allowing them some sort of access that they otherwise would not have
+due to node protection.
+
+To make your new nodes work with the key API, you need to register
+two callback functions in each nodedef:
+
+
+`on_key_use(pos, player)`
+ * Is called when a player right-clicks (uses) a normal key on your
+ * node.
+ * `pos` - position of the node
+ * `player` - PlayerRef
+ * return value: none, ignored
+
+The `on_key_use` callback should validate that the player is wielding
+a key item with the right key meta secret. If needed the code should
+deny access to the node functionality.
+
+If formspecs are used, the formspec callbacks should duplicate these
+checks in the metadata callback functions.
+
+
+`on_skeleton_key_use(pos, player, newsecret)`
+
+ * Is called when a player right-clicks (uses) a skeleton key on your
+ * node.
+ * `pos` - position of the node
+ * `player` - PlayerRef
+ * `newsecret` - a secret value(string)
+ * return values:
+ * `secret` - `nil` or the secret value that unlocks the door
+ * `name` - a string description of the node ("a locked chest")
+ * `owner` - name of the node owner
+
+The `on_skeleton_key_use` function should validate that the player has
+the right permissions to make a new key for the item. The newsecret
+value is useful if the node has no secret value. The function should
+store this secret value somewhere so that in the future it may compare
+key secrets and match them to allow access. If a node already has a
+secret value, the function should return that secret value instead
+of the newsecret value. The secret value stored for the node should
+not be overwritten, as this would invalidate existing keys.
+
+Aside from the secret value, the function should retun a descriptive
+name for the node and the owner name. The return values are all
+encoded in the key that will be given to the player in replacement
+for the wielded skeleton key.
+
+if `nil` is returned, it is assumed that the wielder did not have
+permissions to create a key for this node, and no key is created.