Naturalslopeslib Lua API

Introduction

Naturalslopeslib adds the ability for given nodes to turn into slopes and back to full block shape by itself according to the surroundings and the material hardness. It creates natural landscape and smoothes movements.

Slopes can be generated in various ways. Those events can be turned on or off in settings. The shape is updated on generation, with time, by stepping on edges or when digging and placing nodes.

As Minetest main unit is the block, having half-sized blocks can break a lot of things. Thus half-blocks like slopes are still considered as a single block. A single slope can turn back to a full node and vice-versa and half-blocks are not considered buildable upon (they will transform back into full block).

Usage

You may register slopes in two ways: letting the mod generating all the stuff or getting the definitions and registering the nodes in the calling mod. With the first method, slope nodes will be registered within naturalslopeslib while with the second method, you can set the slope names from the calling mod. In both cases, the shape update behaviour is handled automatically by the library according to the settings and the availability of poschangelib and twmlib.

For the first method, just call naturalslopeslib.register_slopes. For example:

naturalslopeslib.register_slopes("default:dirt")

You can use naturalslopeslib.get_all_shapes to get the name of the slope nodes.

For the second method, get the slope definitions from naturalslopeslib.get_slope_defs and register the four nodes manually with the desired names with minetest.register_node. When done, call naturalslopeslib.set_slopes to link all the different shapes.

For example:

local slope_defs = naturalslopeslib.get_slope_defs("defaut:dirt")
local slope_names = {
    "default:dirt_slope", "default:dirt_inner_corner",
    "default:dirt_outer_corner", "default:dirt_pike"
}
for i, def in ipairs(slope_defs) do
    minetest.register_node(slope_names[i], def)
end
naturalslopeslib.set_slopes("default:dirt",
    slope_names[1], slope_names[2],
    slope_names[3], slope_names[4], factors)

Regarding dependencies, the slopes are defined by copying the current definition of the original node. This means that modifications applied to the original node after the slopes are registered are not applied to slopes. If you want the slopes to act like the original nodes no matter what happen to their definition, you can call naturalslopes.propagate_overrides() before or after registering slopes. That way all future call to minetest.override_item (even from other unknown mods) will also apply to slopes silently, removing the need to explicitely define mod requirements.

Definitions

ReplacementTable

A table containing references to various shape. The type of references can either be a name or an internal id.

{
    source         = full node reference,
    straight       = straight slope reference,
    inner          = inner corner reference,
    outer          = outer corner reference,
    pike           = pike/slab reference,
    chance         = inverted chance of happening,
    chance_factors = multiplicator for `chance` for each type
        {mapgen = w, stomp = x, time = y, place = z}.
        By default all of these factors are 1 (no effect).
}

Registration API

naturalslopeslib.default_definition

This tables holds default definition override for newly registered slopes. When using register_slope, they are added to def_changes if not already set to avoid copy/pasting a lot of things and automate some behaviours.

{
    drop_source = true/false
    -- When true, if no drop is defined, it is set to the source node 
    -- instead of the slope.
    -- For example, digging a dirt slope gives a dirt block (when true)
    -- or the dirt slope (when false)
    tiles = {{align_style="world"}}
    -- As for tile definitions, the list can hold up to 6 values,
    -- but only align_style, backface_culling and scale are read.
    groups = {not_in_creative_inventory = 1}
    -- The list of groups to add with their value.
    -- Set a group value to 0 to remove it
    other keys
    -- Override this key when no change is explicitely set.
}

Note that changes to default_definitions are not retroactives. If the defaults are changed on the run, all slopes that were previously registered are not affected.

Good practices are setting the defaults before registering your slopes, then calling naturalslopeslib.reset_defaults() to prevent your settings to effect further declarations.

naturalslopeslib.reset_defaults()

Resets naturalslopeslib.default_definition to the less-impacting values.

These defaults are as follow:

{
    drop_source = false,
    tiles = {},
    groups = {}
}

naturalslopeslib.register_slope(base_node_name, def_changes, update_chance, factors, color_convert)

Registers all slope shapes and automatic stomping for a full node.

  • base_node_name the full block node name.
  • def_changes changes to apply from the base node definition.
  • All the attributes are copied to the sloped nodes expect those ones which are replaced:
    • drawtype set to "nodebox" or "mesh" according to the rendering mode
    • nodebox or mesh is replaced
    • selection_box and collision_box matching to the according mesh
    • paramtype is set to "light", and paramtype2 to "facedir" or "colorfacedir"
    • the group "natural_slope" is added (1 = straight, 2 = inner corner, 3 = outer corner, 4 = pike)
    • the group "family:<full node name>" is added
  • Then they are changed from def_changes. Use "nil" string to explicitely erase a value (an not nil).
  • update_chance inverted chance for the node to be updated.
  • factors optional table for chance factors. By default each factor is 1.
  • color_convert optional function to convert color palettes (see below). Ignored when paramtype2 from the base node is not "color". By default, it matches the first 8 values, and other color values are set to 0.
  • returns ReplacementTable.

About color palettes: The palette for slopes can only have 8 colors while the original one can hold up to 256 colors. A reduced palette must be provided for nodes which paramtype2 is "color" even if not all colors are used. To control how the palette values are converted, you may pass a function(int, bool) as color_convert. When the second parameter is true, the first parameter is the full block color index (from 0 to 255) and it must return an index for the slope color (from 0 to 7). When false the first parameter is the slope color index (from 0 to 7) and it must return an index for the full block color index (from 0 to 255).

naturalslopeslib.set_slopes(base_node_name, straight_name, inner_name, outer_name, pike_name, update_chance, factors)

  • Link existing nodes. Same as register_slopes but without registering new nodes. Use it when the shapes are already registered from eslewhere. The node definitions are not changed at all.
  • base_node_name the full node name.
  • straight_name the straight slope node name.
  • inner_name the inner corner node name.
  • outer_name the outer corner node name.
  • pike_name the pike/slab node name.
  • update_chance the inverted chance of happening.
  • factors optional table for chance factors. By default each factor is 1.
  • returns a ReplacementTable.

naturalslopeslib.register_sloped_stomp(source_node_name, dest_node_name, stomp_desc)

Register stomp_desc from all shapes of source_node_name to dest_node_name.

It requires poschangelib. If the mod is not activated, this function will do nothing.

naturalslopeslib.propagate_overrides()

Once called, calling minetest.override_item from that point will also apply the modifications to the corresponding slopes. Once called, this behaviour cannot be disabled.

Getters

naturalslopeslib.get_slope_defs(base_node_name, def_changes)

  • base_node_name the full block node name.
  • def_changes changes to apply from the base node definition.
  • All the attributes are copied to the sloped nodes expect those ones which are replaced:
    • drawtype set to "nodebox" or "mesh" according to the rendering mode
    • nodebox or mesh is replaced
    • selection_box and collision_box matching to the according mesh
    • paramtype is set to "light", and paramtype2 to "facedir" or "colorfacedir"
    • the group "natural_slope" is added (1 = straight, 2 = inner corner, 3 = outer corner, 4 = pike)
    • the group "family:" is added
  • Then they are changed from def_changes. Use "nil" string to explicitely erase a value (an not nil).
  • returns a table of node definitions for straight slope, inner corner, outer corner and pike in that order.

Warning: The palette for slopes can only have 8 colors while the original one can hold up to 256 colors. A reduced palette must be provided for nodes which paramtype2 is "color" even if not all colors are used.

naturalslopeslib.get_regular_node_name(slope_node_name)

  • slope_node_name a node name.
  • returns the name of the regular node (the unslopped one). Nil if it is not a slope node.
  • It may be unnaccurate as it checks only if the name follows the internal pattern for slope names.

naturalslopeslib.get_replacement(source_node_name)

  • source_node_name a registered node name.
  • returns a ReplacementTable. Nil if no slopes are registered.

naturalslopeslib.get_replacement_id(source_id)

  • source_id the id of the node.
  • returns a ReplacementTable with node ids as values. Nil if no slopes are registered.

naturalslopeslib.get_all_shapes(source_node_name)

Returns all variant shape names in a table {block, straight slope, inner corner, outer corner, pike}. Returns {source_node_name} if there are no other shapes for this node.

  • source_node_name a node name, can be a full block or a slope.

naturalslopeslib.get_all_slopes(source_node_name)

Returns all sloped variant shape names in a table {straight slope, inner corner, outer corner, pike}. Returns {} if there are no slopes for this node.

  • source_node_name a node name, can be a full block or a slope.

naturalslopeslib.list_registered_nodes()

Returns the list of nodes in block shape that have slopes registered for.

Shape update API

naturalslopeslib.is_free_for_shape_update(pos)

Checks if a node is considered free for defining which shape could be picked.

  • pos the position of the node to check (probably a neighbour of a candidate to shape update).
  • returns true if the node is free, false if occupied, nil if unknown (not loaded)

naturalslopeslib.area_is_free_for_shape_update(area, data, index)

Checks if a node is considered free for defining which shape could be picked.

  • area VoxelArea to use.
  • data Data from VoxelManip.
  • index position in area.
  • returns true if the node is free, false if occupied, nil if unknown (not loaded)

Was previously named naturalslopeslib.area_is_free_for_erosion.

naturalslopeslib.get_replacement_node(pos, node, [area, data, param2_data])

Get the replacement node according to it's surroundings. This function exists in two formats, for a single position or a VoxelArea.

In both case, it returns the parameters to update the node or nil when no replacement is available.

  • For a single node
    • pos the position of the node or index with VoxelArea.
    • node the node at that position.
    • returns a node for minetest.set_node.
  • For a VoxelArea
    • index (the pos argument) the index within the area.
    • content_id (the node argument) the node at that position or content id with VoxelArea.
    • area the VoxelArea, nil for single position update (determines which type of the two previous arguments are).
    • data Data from VoxelManip, nil for single position update.
    • param2_data param2 data from VoxelManip, nil for single position update.
    • Returns a table with id and param2_data.

naturalslopeslib.chance_update_shape(pos, node, factor, type)

Do shape update when random roll passes on a single node.

  • pos the position to update.
  • node the node at pos.
  • factor optional chance factor, when > 1 it have more chances to happen
  • type optional update type for chance factors. Either "mapgen", "stomp", "place" or "time". When not set, the chance factor is ignored (as if it is 1). It is cumulative with factor.
  • returns true if an update was done, false otherwise.

naturalslopeslib.update_shape(pos, node)

Do shape update disregarding chances.

  • pos the position to update.
  • node the node at pos.
  • returns true if an update was done, false otherwise.

naturalslopeslib.update_shape_on_walk(player, pos, node, desc, trigger_meta)

Callback for poschangelib, to get the same effect as naturalslopeslib.update_shape.

Map generation

These functions allows to tweak the map generation to change the default behaviour. Which is updating an area on generation after other map generation functions.

naturalslopeslib.set_manual_map_generation()

Disables the default registration to handle the mapgen manually. Once it is called, other mods should take care of handling shape update on generation. Otherwise nothing is done.

naturalslopeslib.area_chance_update_shape(minp, maxp, factor, skip, type)

Massive shape update with VoxelManip. This is the VoxelManip on generation method.

  • minp lower boundary of area.
  • mapx higher boundary of area.
  • factor Inverted factor for chance (0.1 means 10 times more likely to update)
  • skip optional random skip, roughfly ignore skip/2 to skip nodes.
  • type optional update type for chance factors. Either "mapgen", "stomp", "place" or "time". When not set, the chance factor is ignored (as if it is 1). It is cumulative with factor.

naturalslopeslib.register_progressive_area_update(minp, maxp, factor, skip, type)

Mark an area to be updated progressively. This is the Progressive on generation method. The area is not updated instantly but added to a list.

  • minp lower boundary of area.
  • mapx higher boundary of area.
  • factor Inverted factor for chance (0.1 means 10 times more likely to update)
  • skip optional random skip, roughfly ignore skip/2 to skip nodes.
  • type optional update type for chance factors. Either "mapgen", "stomp", "place" or "time". When not set, the chance factor is ignored (as if it is 1). It is cumulative with factor.

Settings getters

These functions get the current settings with the default value if not set.

naturalslopeslib.setting_enable_surface_update()

  • Returns true or false. Always false if twmlib is not available.

naturalslopeslib.setting_enable_shape_on_walk()

  • Returns true or false. Always false if poschangelib is not available.

naturalslopeslib.setting_enable_shape_on_generation()

  • Returns true or false. It may not reflect the actual behaviour if the default mapgen behaviour was disabled by naturalslopeslib.set_manual_map_generation.

naturalslopeslib.setting_generation_method()

  • Returns "VoxelManip" or "Progressive". It may not reflect the actual behaviour if the default mapgen behaviour was disabled by naturalslopeslib.set_manual_map_generation.

naturalslopeslib.setting_generation_factor()

  • Returns the chance factor for map generation to reflect the landscape age. It is cumulative with the "mapgen" chance factor of each node if any is defined. It may not reflect the actual behaviour if the default mapgen behaviour was disabled by naturalslopeslib.set_manual_map_generation.

naturalslopeslib.setting_stomp_factor()

  • Returns the chace factor when walking on nodes. It is cumulative with the "stomp" chance factor of each node if any is defined.
  • This factor is applied upon node registration.

naturalslopeslib.setting_dig_place_factor()

  • Returns the chace factor when the neighbouring nodes change. It is cumulative with the "place" chance factor of each node if any is defined.

naturalslopeslib.setting_time_factor()

  • Returns the chace factor on timed update. It is cumulative with the "time" chance factor of each node if any is defined.
  • This factor is applied upon node registration.

naturalslopeslib.setting_generation_skip()

  • Returns the approximate number of nodes skipped for each node. It may not reflect the actual behaviour if the default mapgen behaviour was disabled by naturalslopeslib.set_manual_map_generation.

naturalslopeslib.setting_enable_shape_on_dig_place()

  • Returns true or false. This setting is read only on startup and may not reflect the actual value if it was changed while the server is running.

naturalslopeslib.setting_rendering_mode()

  • Returns Cubic, Smooth or Rough. This setting is read only when registering nodes and may not reflect the actual value if it was changed while the server is running.
  • Was previously naturalslopeslib.setting_smooth_rendering, that is now deprecated but still available and returns true for Smooth and Rough modes.

Chat commands

/updshape

  • requires server privilege.
  • Force updating the node the player is standing upon.