Controls ########################################################## Crawl sneak Run special/aux1 Wallrun run + jump into a wall (requires a few of attempts to success) Edge climb touch an edge above the ground Kong run into a block Cat leap jump backwards in edge climbing Tic tac/walljump run + jump side of a wall Double wall climb hold left & right Backflip hold jump & press back/down Frontflip jump, (hold) place/RMB & press forward/up Right sideflip jump, (hold) place/RMB & press right Left sideflip jump, (hold) place/RMB & press left Roll sneak when falling from a height, causing less fall damage Dive roll place/RMB and press up, useful to dive faster forward You can use all flips to reach more height and come over obstacles on 2 blocks while running, but sideflips wont hurt on obstacles and there is no risk you breaks your neck. Commands ########################################################## /protect 1 select position 1, reselect by punch the node /protect 2 select position 2, reselect by punch the node /protect protect /protect abort (or punch a marker) /remove_area remove area /exaach Achievements /exaach_clear Clear your achievements (ban required) Privileges ########################################################## protect_unlimited -- Protection without limits protection_bypass -- can interact in all areas, exept "game rule" areas ########################################################## Modding ##################################################### ########################################################## This is a collection of functions that can be usefull by modding. Modding itemdef/nodedef ##################################################### -- No depends needed groups={ exatec_tube=1 -- exatec: is tube / used as tubes exatec_tube_connected=1 -- exatec: tubes is connected to exatec_wire=1 -- exatec: used as wire / leading exatec_wire_connected -- exatec: wire is connected to } exatec={ -- exatec: nodedef property, add to minetest.register_node input_max=1 -- exatec: max stack to put output_max=1 -- exatec: max stack to take input_list="listname", -- exatec: list to put in output_list="listname", -- exatec: list to stack take from test_input=function(pos,stack,oldpos,curpos) -- exatec: test for input return true or false/nil end, test_output=function(pos,stack,oldpos) -- exatec: test for output return true or false/nil end, on_input=function(pos,stack,oldpos,objectpos) -- while input, note objectpos is sent by entities in tubes, and are nil in other cases end, on_output=function(pos,stack,oldpos) -- while output end, on_wire = function(pos) -- while wire connected end on_data_wire = function(pos,channel,from_channel,data) -- while data wire connected end on_tube = function(pos,stack,oldpos,object) -- stack incoming to tube end } hat_properties={ -- used to define item as hat & properties used while attaching pos = {x=0, y=6, z=0}, rotation = {x=0,y=90,z=0}, size = {x=0.5,y=0.5,z=0.5} } on_item_touch=function(pos,object) -- called when an item touch the node Protect ########################################################## depends = protect # protect.add_game_rule_area(pos1,pos2,title) -- area that cant be interacted by anyone, returns id # protect.remove_game_rule_area(id) -- remove game rule area -- activate "protect:area_breaker" from exatec to break any "game rule area" it is inside Player style ########################################################## depends = player_style # player_style.players[player_name] -- player data # player_style.register_profile({ -- register player style profile, if name is nil or "default" this will be default for everyone name = "profile name", texture = {"character.png"}, visual = "mesh", visual_size = {x=1,y=1}, collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, mesh = "character.b3d", diving = true, flying = true, animation = { stand={x=1,y=39,speed=30}, walk={x=41,y=61,speed=30}, }, eye_height = 1.6, stepheight = 0.7, hotbar = "player_api_hotbar.png", hotbar_selected = "player_api_hotbar_selected.png", }) # player_style.set_profile(player,"profile name") -- set the profile # player_style.thirst_to_death(player) -- hurts until death or if the player drinks enough # player_style.player_attached[player_name] = something/nil -- deactivated player styles /animation/moves ... # player_style.register_button({ -- adds a button the players inventory type="image_button", nil , "image", "item_image" exit=true, nil , true image="default_dirt.png", nil, image, item name="dirt", button name/id label="dirt text", button label info="Dirts button", infotext / tooltip action=function(user) action end }) # player_style.register_environment_sound({ --adds sounds around nodes node="default:water_flowing", -- node required sound="default_water_stream", -- sound required gain=2, -- nil,number (default: 0.5) timeloop=4, -- nil,number (default: 1) distance = 10, -- nil,number (default: 10) min_y = -20, -- nil,number (default: -31000) max_y = 50, -- nil,number (default: 31000) count = 5, -- nil,number (default: 1) [min count of nodes] }) # player_style.get_player_skin(player) -- returns player skin # player_style.get_current_player_skin(player) -- returns the current player's basic skin (return player:get_properties().textures[1]) # player_style.add_player_skin(player,texture,layer) -- add player texture (set_properties) adds the texture to lists that will merged with other textures to avoid conflicts (layer_list1 .. layer_list2 ...). armor is added to layer 2, spacesuit 3. # player_style.remove_player_skin(player,texture,layer) -- remove the texture from the list # player_style.update_player_skin(player,newskin) -- update the texture list, "newskin" if you want to tempoary change the skin # player_style.register_skin({ -- adds skin to the skin list name = "name" required skin = "texture.png" required cost = 500 nil = "Free" info = "text" origin = "name" nil = using mod's name -- self is a table that is circuits through the skin functions on_use=function(self,player) -- when a player starts to use the skin. on_stop_using=function(self,player) -- when a player stop to use the skin on_join=function(self,player) -- called when a player joins on_use_join=function(self,player) -- called on both when a player joins and starts to use the skin, instead of make same function for on_join and on_use on_step=function(self,player,dtime) -- on global step }) player_style.register_manual_page({ -- adds an manual page name = "Name" -- required, showed in the list text = "information" -- required, text or formspec text tags = {"default:dirt","default:dirt_with_grass","snowy"} -- used when looking for page content, when the player is looking at a node, object or wieldied item label = "Page label" -- adds a label to the page itemstyle = "mod:item" -- adds an item image, label and textarea action=function(player) -- called when the page will be viewed end, }) Armor ########################################################## depends = armor # armor.register_item("type",{ -- register aror item: "chestplate"," helmet", "gloves", "boots", "leggings", "shield" type="chestplate", level=3, -- armor_group, 0 and higher, 100 = immortal item="default:steel_ingot", -- craft item groups={}, -- itemgroups, can be nil image="default_steelblock.png", -- material, auto generating textures item_image = "image.png", -- custom item image, replacing material image armor_image = "image.png", -- custom armor image, replacing material image, "shield" will use item_image here too hand_image = "image", -- custom wieldhand (used with gloves) hand_damage= 1, -- custom wieldhand damage (used with gloves) on_secondary_use = function() -- custom secondary_use (used with gloves) (right click in air) }) # armor.update(player,wear/nil) -- updates the armor items # armor.show(player) -- show the armor gui # armor.user[player_name] -- player data # armor.registered_items[item] -- get regstered item image Nitroglycerine ########################################################## depends = nitroglycerine # nitroglycerine.crush(pos) -- spawns a ice crush # nitroglycerine.freese(object) -- freese object / object to ice # nitroglycerine.explotion(pos,{ -- creates an explotion radius = 5, -- nil/9 set = "node", -- nil/"" place = {nodes}, -- nil/{"fire:not_igniter","air","air","air","air"} place_chance = 5, -- nil/5 user_name = "name", -- nil/"" drops = 1 -- nil/1 velocity = 1 -- nil/1 hurt = 1 -- nil/1 }) # nitroglycerine.cons({ -- gets connected nodes in real time pos=pos, -- required max=500, -- nil/9 distance=1, -- nil/1 (the higher number the longer between nodes + lag) name="a replacing", -- nil/random number replace={ -- required (atleast 1 option) [options] can be node or group [value] node or function ["snowy"]="default:dirt_with_grass", ["default:leaves"]="default:stone", ["spreading_dirt_type"]="dirt", ["leaves"]=function(pos) minetest.remove_node(pos) end, }, on_replace=function(pos) print(replaced,dump(pos)) end, }) Beds ########################################################## depends = beds # beds.sleeping(pos,player) -- sleep player and skip night if all players is sleeping # beds.lay_and_stand(pos,player) -- toggle lay/stand # beds.respawn(player) -- move player to bed Weather ########################################################## depends = weather # weather.while_rain(pos) -- check if it is raining at position Bones ########################################################## depends = bones # bones.drop(player) -- drop player bones Achievements ########################################################## depends = exaachievements # exaachievements.register({ type="eat", -- required, alternatives: "eat", "craft", "place", "dig", "customize" item="plants:apple", -- required: item or group (not used by "customize") name="Apples", -- required description="Eat 100 apples", -- required count=100, -- nil/10 skills=2, -- nil/1 image="plants_apple.png", -- nil/image or item min=10, -- nil/min achievements to be able hide_until=2, -- nil/ min achievements to be able and visible approve=function(player,item,pos) -- nil/ params depends by type return true or false end completed=function(player) -- nil, called while achievement completed end }) # exaachievements.customize(player,achievement_name) -- Used by "customize" # exaachievements.get_skills(user) -- Get player skills # exaachievements.if_completed(user,achievement_name) -- if completed # exaachievements.do_a(def) -- shortcut to dig a ... exaachievements.register({type="dig"... required item Carts ########################################################## depends = exacarts # exacarts.register_rail({ -- you can customize the node's properties too name = "name" -- required, adds "_rail" or full_custom_name = "name" -- name that doesn't add "_rail" texture = "texture" -- "default_ironblock.png" overlay = "texture" -- "" wood_modifer = true, -- nil/ (modifer the wood instead of the bar) all_modifer = true, -- nil/ (modifer the wood & bar) add_groups = groups -- add to groups and instead of making a whole new group set craft_recipe = def -- you can make a full craft recipe, send directly to minetest.register_craft() -- or automatically: craft_item = "item" -- "group:metalstick" craft_wood = "item" -- "group:stick" craft_count = n -- 16 on_rail=function(pos,self,velocity) -- called when a cart is using it end }) Lakes ########################################################## depends = lakes # lakes.registry_lake("name",{ -- genrating lakes, all options are required spawn_in = "default:dirt_with_grass", chance = 10, min_y = -50, max_y = 50, radius = math.random(5,20), source = "default:water_source", in_nodes = { "default:dirt", "default:dirt_with_grass", "default:sand", "default:water_source", } }) exatec ########################################################## depends = exatec # exatec.send(pos,force_send,table_to_send) -- send wire signal, force_send to send even the node are ignored # exatec.data_send(pos,to_channel,node_channel,table_of_optional_content) -- send data wire signal Multidimensions ########################################################## depends = multidimensions # multidimensions.register_dimension(name,{ -- all options are optional dim_y number/nil, -- dimension y position, do not use if you aren't sure dim_height 1000 bedrock_depth = 50 dirt_depth = 5 ground_limit = 530 -- height the ground ends water_depth = 8 enable_water = true terrain_density = 0.4 flatland = true gravity = 1 sky = {} -- player:set_sky() sun = {} -- player:set_sun() moon = {} -- player:set_moon() map = { -- map/generator properties offset = 0 scale = 1 spread = {x=100,y=15,z=100} seeddiff = 24 octaves = 5 persist = 0.7 lacunarity = 1 flags = "absvalue" } self = { -- table used by the dimension stone = "default:stone" dirt = "default:dirt" grass = "default:dirt_with_grass" air = "air" water = "default:water_source" sand = "default:sand" bedrock = "multidimensions:bedrock" } stone_ores = {["default:space_titanium_ore"] = { -- same kind of propery for all ores chunk=1 -- chunk (blob size) chance=5000 -- chanse to be generated }} dirt_ores = ... -- ores in dirt grass_ores = ... -- ores in grass ground_ores = ... -- ores in ground air_ores = ... -- ores in air water_ores = ... -- ores in water sand_ores = ... -- ores in sand on_generate=function(data,id,cdata,area,x,y,z) -- called when dimension is generating } multidimensions:bedrock -- node used as bedrock multidimensions:blocking -- node used as invisible walls multidimensions:killing -- node used as killing none walkable floor Default ########################################################## depends = default # default.register_chest({ name = "locked_chest", -- Required description = "Locked chest", locked = true, burnable = true, texture="default_wood.png", -- Required craft={{"default:chest","default:steel_ingot"}}, }) # default.register_fence({ name = "apple_wood", -- Required texture = "plants_apple_wood.png", -- Required craft={{"group:stick","group:stick","group:stick"}} }) # default.register_chair({ name = "apple_wood", -- Required description = "Apple wood chair", burnable = true, texture = "plants_apple_wood.png", -- Required craft={{"group:stick","wood",""}} }) # default.workbench.register_craft({ -- register craft recipe for a item with workbenchs output="mod:name", recipe={ {"default:steel_ingot","default:steel_ingot","default:steel_ingot"}, {"","group:stick",""}, {"","group:stick",""}, } }, }) # default.date(param,compare_time) -- param: -- "get" get current time (return os.time()) -- "s" secunds -- "m" minuts -- "h" hours -- "d" days -- example: -- local time = default.date("get") -- if default.date("h",time) > 3 then # default.register_eatable(itemtype,name,hp,gaps,def) -- itemtype "node"/"tool"/"craftitem" -- name "mod:name" -- hp number health to add at each use -- gaps number parts to eat, -- def itemdef table def.groups = { -- can be nil eatable = 2 nil/hp -- adds hp gaps = 4 nil/gaps -- gaps to eat wet = -1 nil/-0.1 -- gives thurst while eating } # default.register_door({ name="apple_wood_door", --Required: name of item description = "Apple wood door", texture="plants_apple_wood.png", burnable = true, craft={ {"plants:apple_wood","plants:apple_wood",""}, {"plants:apple_wood","plants:apple_wood",""}, {"plants:apple_wood","plants:apple_wood",""}, } }) # default.register_plant({ -- generating a nodedef with default settings, you can change all of them name="anthriscus_sylvestris" --Required: name of item description = "" tiles={"parsnip.png"} decoration={noise_params={ offset=-0.0015 scale=0.015 seed=3365 }}, groups={spreading_plant=10} visual_scale=1.1 }) default.register_tree({ name="apple", -- Required: name of items fruit={ -- Spawning fruits hp=1, gaps=4, description = "Apple", tiles={"plants_apple.png"}, inventory_image="plants_apple.png", }, tree={tiles={"tree_top.png","tree_top.png","tree.png"}}, -- tree sapling={tiles={"plants_apple_treesapling.png"}}, -- sapling wood={tiles={"plants_apple_wood.png"}}, -- wood leaves={tiles={"plants_apple_leaves.png"}}, -- leaves schematic=modpath.."tree.mts", -- Required: genrating the tree sapling_place_schematic=function(pos) -- Required: growing tree from sapling minetest.place_schematic(pos, modpat ..tree.mts) end }) ==== default.registry_mineral(def) -- auto generating mineral items: block, ore, lump, ingot, pick, shovel axe, vineyardknife, hoe and crafting -- tool craft-recipes are registered as workbench crafting -- Options: -- all options have default values, so you don't have to fill a table if you just want to add 1 value inside it except tool_capabilities, example of this in default/items.lua. -- the table of settings will be set as nodedef / itemdef # default.registry_mineral({ name "itemname", --Required: name used for all items texture "img.png", --Required: used as default texture for all items not_lump nil/true --disable lump (drop) lump={ description nil/"" inventory_image nil/"img.png" } drop={ --can be set if not_lump = true name nil/"" inventory_image nil/"img.png"/diamond/longcrystal/round(tinemeald/oval/crystal/quartz/emeald description nil/"" } not_ingot nil/true --disable ingot not_ingot_craft nil/true --disable automatic recipe ingot={ description nil/"" inventory_image nil/"img.png" }, not_block nil/true --disable block not_block_craft nil/true --disable automatic recipe block={ tiles tiles/table description nil/"" sounds nil/sounds groups nil/table } not_ore nil/true --disable block ore={ tiles tiles/table description nil/"" sounds nil/sounds groups nil/table } ore_settings nil/table can be used even not_ore = true through name name nil/string wherein nil/"node" clust_scarcity nil/number clust_num_ores nil/number clust_size nil/number y_min nil/number y_max nil/number } not_pick nil/true --disable pick pick={ description ="", nil/"" sounds = sounds nil/sounds inventory_image = "img.png" tool_capabilities = { full_punch_interval max_drop_level damage_groups groupcaps } } not_shovel nil/true --disable shovel shovel={ description nil/"" sounds nil/sounds inventory_image nil/"img.png" tool_capabilities nil or { full_punch_interval max_drop_level damage_groups groupcaps } } not_axe nil/true --disable axe axe={ description nil/"" sounds nil/sounds inventory_image nil/"img.png" tool_capabilities nil or { full_punch_interval max_drop_level damage_groups groupcaps } } not_vineyardknife nil/true --disable vineyardknife vineyardknife={ description nil/"" sounds nil/sounds inventory_image nil/"img.png" tool_capabilities nil or { full_punch_interval max_drop_level damage_groups groupcaps } } not_hoe nil/true --disable hoe hoe={ description nil/"" sounds nil/sounds inventory_image nil/"img.png" tool_capabilities nil or { full_punch_interval max_drop_level damage_groups groupcaps } } regular_additional_craft={ -- default crafting, can contain multiple recipes {output="default:coalblock", recipe={ {"default:coal_lump","default:coal_lump","default:coal_lump"}, {"default:coal_lump","default:coal_lump","default:coal_lump"}, {"default:coal_lump","default:coal_lump","default:coal_lump"}, } } } workbench_additional_craf={ -- workbench crafting, can contain multiple recipes {output="default:coalblock", recipe={ {"default:coal_lump","default:coal_lump","default:coal_lump"}, {"default:coal_lump","default:coal_lump","default:coal_lump"}, {"default:coal_lump","default:coal_lump","default:coal_lump"}, } } } }) # default.register_blockdetails({-- registers and block with texture/object above, is mostly used by flat ocean decorations, everything can be nil except name. name="name", -- required node={ -- node def block="default:sand" -- is set while dug tiles = {"default_sand.png","default_stick.png"} -- the second one is the detail on the block }, item={}, -- item/drop def ... item={type="node"} for node ddef={}, -- decoration generating def }) # default.register_pebble({ -- everything can be nil except name. name="stone", tiles={"default_stone.png","default_sand.png"}, -- the second one is used by ocean decorations block="default:sand", -- is set while dug decoration={} -- decoration generating def }) # bows.register_arrow(name,{ --everything can be nil except then name. description = "", damage = 1, on_hit_sound = "default_dig_dig_immediate", on_hit_object = function(self,target,hp,user,lastpos) end, on_hit_node = function(self,pos,user,lastpos) end, on_step = function(self,dtime,user,pos,oldpos) end, groups = {}, craft_count = 4, craft = { {"default:flint","group:stick","examobs:feather"} {"","",""}, } }) # bows.register_bow(name,{ -- everything can be nil except name. description = "", uses = 49, -- amount of uses before it breaks level = 6, -- arrow power/velocity shots = 1, -- amount of shots at same time texture = "default_wood.png" groups = {}, craft = { {"","group:stick","materials:string"}, {"group:stick","","materials:string"}, {"","group:stick","materials:string"} }, }) # bows.arrow_remove(self) -- remove the arrow # apos(pos,x,y,z) -- simply add number to position, everything can be nil except pos, eg apos(pos,0,2) # default.set_on_player_death(playername,eventname,value/function) -- run / delete value on player death/leave # default.get_on_player_death(playername,eventname) -- get event # default.defpos(pos,"buildable_to") -- safe returns minetest.registered_nodes[minetest.get_node(pos).name].subdef # default.defname(name,"buildable_to") -- same as above, but requires name insead # default.def(name) -- returns minetest.registered_nodes[node_name] without crashing while failing # default.registry_bucket("default:water_source") -- creates a bucket # default.wieldlight(user_name,wield_index,item_to_wear) -- wield light / flashlight # default.punch(target,puncher,dmg/nil) --punch object # default.punch_pos(pos,damage/nil,even_items true/nil) -- punch objects in a position (a<=1) # default.take_item(clicker) -- take wield item # default.dye_texturing(index,{ -- returns a modified string, everything can be nil opacity = 150, image_w = 16, image_h = 16, palette_w = 7, palette = "default_palette.png", }) # default.dye_coloring(pos, node, player, pointed_thing) -- used by colorable nodes, eg .on_punch=default.dye_coloring # default.treasure({ -- adds a node with treasure-listed items level = 1, -- nil to 3, (auto usage), level of treasure items = {}, -- can be nil, customized items to put in node = "default:chest", -- can be nil, node to set }) # default.pickupable(entity/self,player) -- allows player to pick up object # default.is_decoration(object,item) -- if object is meant to be a decoration / not efected by players/mobs..., checks for entitydef decoration = true # default.watersplash(pos,item true/nil) -- creates a water splash # default.flowing(object) -- makes object flowing in flowing source, use in a on_step def # Coin(player,count) -- add couns to player # num(number) -- returns if number is a number # memory_mb() -- returns curennt memory used by lua # default.respawn_player(player,drop_bones true/nil) default.node_sound_defaults() -- nodedef sounds default.node_sound_stone_defaults() default.node_sound_wood_defaults() default.node_sound_water_defaults() default.node_sound_metal_defaults() default.node_sound_dirt_defaults(a) default.node_sound_leaves_defaults() default.node_sound_gravel_defaults() default.node_sound_glass_defaults() default.node_sound_clay_defaults() default.node_sound_snow_defaults() default.node_sound_sand_defaults() default.tool_breaks_defaults(a) -- itemdef tool break sound Mobs ########################################################## depends = examobs # examobs.register_mob({ -- shows the most options, you can explore the examobs/mina.lua to find more name = "name", -- name type = "npc", -- mob type dmg = 1, -- punching damage aggressivity = 1, -- -2 to 2, -2: flee from everything, -1: flee from monsters, 0: no reaction, 1: fight monsters, 2: fight everything walk_speed = 4, run_speed = 8, hp = 20 -- health physical = true collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35} visual = "mesh" visual_size = {x=1,y=1} mesh = "character.b3d" makes_footstep_sound = true lay_on_death = -- 0/1 (off/on) textures = {"character.png"} team = "default" range = 15 -- view range reach = 4 -- can reach & punch punch_chance = 5 bottom = 0 -- checking nodes from here (pos.y+bottom) breathing = 1 -- 0/1 (breathing as fishes/drowning) resist_nodes = {} -- {["default:lava_source"]=1,["fire:basic_flame"]=true} swiming = 1 -- 0/1 (swiming/drowning while it is in water, as an deathtrap) inv = {} -- inventory/drops {["default:stick"]=2,["default:dirt"]=89} flee_from_threats_only = 0 -- 1/0 (off/on) floating = {} -- {["default:water_source"]=1,["default:gass"]=true} floating_in_group = -- alternative to above, "water" updatetime = 1 -- run/cycle time spawning = nil -- nil/false automatic spawning, false = no spawning spawn_chance = 100 spawn_on = {"group:dirt","group:sand"} spawn_in = -- node or group-name light_min = 9 light_max = 15 lifetime = 300 -- before its removed add_wear = 10000 -- adds tool wear animation = "default" -- or {stand={x=1,y=39},walk={x=41,y=61,},run={x=41,y=61,speed=60},attack={x=65,y=75},lay={x=113,y=123}} step = function(self) -- on_step on_dying = function(self) death = function(self) on_punched = function(self,puncher) on_punching = function(self) before_punching = function(self) before_spawn = function(pos) on_spawn = function(self) on_load = function(self) is_food = function(self,item_string) -- return true to use item as food on_lifedeadline = function(self) -- runned while mob lifetime expended, return true to reset it on_walk = function(self,x,y,z) on_fly = function(self,x,y,z) on_stand = function(self) on_click = function(self,clicker) }) # examobs.register_bird(def) -- as to above, adapted for birds # examobs.register_fish(def) -- fish # self:eat_item(self,item,nil or hp) # self:heal(self,hp,gaps,num) # self:pos() -- return self.object:get_pos() # self:hurt(dmg) # examobs.jump(self) # examobs.stand(self) # examobs.walk(self,run) # examobs.lookat(self,pos) # examobs.anim(self,type) # examobs.num(a) --check number # examobs.team(object) # examobs.known(self,object,type,get) # examobs.visiable(pos1,pos2) # examobs.gethp(ob,even_dead) # examobs.viewfield(self,ob2) # examobs.faceside(self,ob) # examobs.pointat(self,d) # examobs.distance(pos1,pos2) # examobs.punch(puncher,target,damage) # examobs.showtext(self,text,color) # examobs.dropall(self) # examobs.dying(self,set) # walkable(pos) # examobs.shoot_arrow(self,pos2,"examobs:arrow") ########################################################## Yet undocumentation ############################################# ########################################################## villages sign plasma paintnings