1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-11 17:51:04 +00:00

Rename “Minimal development test” to “Development Test” (#9928)

This commit is contained in:
Wuzzy 2020-05-26 00:17:52 +02:00 committed by GitHub
parent b546e8938d
commit 083b285f43
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
371 changed files with 25 additions and 25 deletions

View file

@ -0,0 +1,4 @@
License information for Development Test
----------------------------------------
The same license as for Minetest applies.

52
games/devtest/README.md Normal file
View file

@ -0,0 +1,52 @@
# Development Test (devtest)
This is a basic testing environment that contains a bunch of things to test the engine, but it could also be used as a minimal testbed for testing out mods.
## Features
* Basic nodes for mapgen
* Basic, minimal map generator
* Lots of example nodes for testing drawtypes, param2, light level, and many other node properties
* Example entities
* Other example items
* Formspec test (via `/test_formspec` command)
* Automated unit tests (disabled by default)
* Tools for manipulating nodes and entities, like the "Param2 Tool"
## Getting started
Basically, just create a world and start. A few important things to note:
* Items are gotten from the “Chest of Everything” (`chest_of_everything:chest`)
* When you lost your initial items, type in `/stuff` command to get them back
* By default, Creative Mode activates infinite node placement. This behavior can be changed with the `devtest_infplace` setting
* Use the `/infplace` command to toggle infinite node placement in-game
* Use the Param2 Tool to change the param2 of nodes; it's useful to experiment with the various drawtype test nodes
* Check out the game settings and server commands for additional tests and features
* Creative Mode does nothing (apart from default engine behavior)
Confused by a certain node or item? Check out for inline code comments.
### Example tests
* You can use this to test what happens if a player is simultaneously in 2 nodes with `damage_per_second` but with a different value.
* Or use the Falling Node Tool on various test nodes to see how they behave when falling.
* You could also use this as a testbed for dependency-free mods, e.g. to test out how your formspecs behave without theming.
## Random notes
* Experimental/strange/unstructured tests can be found in the `experimental` mod
* Textures of drawtype test nodes have a red dot at the top left corner. This is to see whether the textures are oriented properly
## Design philosophy
This should loosely follow the following principles:
* Engine testing: The main focus of this is to aid testing of *engine* features, such as mapgen or node drawtypes
* Mod testing: The secondary focus is to help modders as well, either as a minimal testbed for mods or even as a code example
* Minimal interference: Under default settings, it shall not interfere with APIs except on explicit user wish. Non-trivial tests and features need to be enabled by a setting first
* Convenience: Have various tools to make usage easier and more convenient
* Reproducing engine bugs: When an engine bug was found, consider creating a test case
* Clarity: Textures and names need to be designed to keep different things clearly visually apart at a glance
* Low loading time: It must load blazing-fast so stuff can be tested quickly

2
games/devtest/game.conf Normal file
View file

@ -0,0 +1,2 @@
name = Development Test
description = Testing environment to help with testing the engine features of Minetest. It can also be helpful in mod development.

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

BIN
games/devtest/menu/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

View file

@ -0,0 +1,334 @@
local WATER_ALPHA = 160
local WATER_VISC = 1
local LAVA_VISC = 7
--
-- Node definitions
--
-- Register nodes
minetest.register_node("basenodes:stone", {
description = "Stone",
tiles = {"default_stone.png"},
groups = {cracky=3},
})
minetest.register_node("basenodes:desert_stone", {
description = "Desert Stone",
tiles = {"default_desert_stone.png"},
groups = {cracky=3},
})
minetest.register_node("basenodes:dirt_with_grass", {
description = "Dirt with Grass",
tiles ={"default_grass.png",
-- a little dot on the bottom to distinguish it from dirt
"default_dirt.png^basenodes_dirt_with_grass_bottom.png",
{name = "default_dirt.png^default_grass_side.png",
tileable_vertical = false}},
groups = {crumbly=3, soil=1},
})
minetest.register_node("basenodes:dirt_with_snow", {
description = "Dirt with Snow",
tiles ={"basenodes_dirt_with_snow.png",
-- a little dot on the bottom to distinguish it from dirt
"default_dirt.png^basenodes_dirt_with_snow_bottom.png",
{name = "default_dirt.png^default_snow_side.png",
tileable_vertical = false}},
groups = {crumbly=3, soil=1},
})
minetest.register_node("basenodes:dirt", {
description = "Dirt",
tiles ={"default_dirt.png"},
groups = {crumbly=3, soil=1},
})
minetest.register_node("basenodes:sand", {
description = "Sand",
tiles ={"default_sand.png"},
groups = {crumbly=3},
})
minetest.register_node("basenodes:desert_sand", {
description = "Desert Sand",
tiles ={"default_desert_sand.png"},
groups = {crumbly=3},
})
minetest.register_node("basenodes:gravel", {
description = "Gravel",
tiles ={"default_gravel.png"},
groups = {crumbly=2},
})
minetest.register_node("basenodes:junglegrass", {
description = "Jungle Grass",
drawtype = "plantlike",
tiles ={"default_junglegrass.png"},
inventory_image = "default_junglegrass.png",
wield_image = "default_junglegrass.png",
paramtype = "light",
walkable = false,
groups = {snappy=3},
})
minetest.register_node("basenodes:tree", {
description = "Normal Tree Trunk",
tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
is_ground_content = false,
groups = {choppy=2,oddly_breakable_by_hand=1},
})
minetest.register_node("basenodes:leaves", {
description = "Normal Leaves",
drawtype = "allfaces_optional",
tiles = {"default_leaves.png"},
paramtype = "light",
is_ground_content = false,
groups = {snappy=3},
})
minetest.register_node("basenodes:jungletree", {
description = "Jungle Tree Trunk",
tiles = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
is_ground_content = false,
groups = {choppy=2,oddly_breakable_by_hand=1},
})
minetest.register_node("basenodes:jungleleaves", {
description = "Jungle Leaves",
drawtype = "allfaces_optional",
tiles = {"default_jungleleaves.png"},
paramtype = "light",
is_ground_content = false,
groups = {snappy=3},
})
minetest.register_node("basenodes:pine_tree", {
description = "Pine Tree Trunk",
tiles = {"default_pine_tree_top.png", "default_pine_tree_top.png", "default_pine_tree.png"},
is_ground_content = false,
groups = {choppy=2,oddly_breakable_by_hand=1},
})
minetest.register_node("basenodes:pine_needles", {
description = "Pine Needles",
drawtype = "allfaces_optional",
tiles = {"default_pine_needles.png"},
paramtype = "light",
is_ground_content = false,
groups = {snappy=3},
})
minetest.register_node("basenodes:water_source", {
description = "Water Source",
drawtype = "liquid",
tiles = {"default_water.png"},
special_tiles = {
{name = "default_water.png", backface_culling = false},
{name = "default_water.png", backface_culling = true},
},
alpha = WATER_ALPHA,
paramtype = "light",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drowning = 1,
liquidtype = "source",
liquid_alternative_flowing = "basenodes:water_flowing",
liquid_alternative_source = "basenodes:water_source",
liquid_viscosity = WATER_VISC,
post_effect_color = {a = 64, r = 100, g = 100, b = 200},
groups = {water = 3, liquid = 3},
})
minetest.register_node("basenodes:water_flowing", {
description = "Flowing Water",
drawtype = "flowingliquid",
tiles = {"default_water_flowing.png"},
special_tiles = {
{name = "default_water_flowing.png", backface_culling = false},
{name = "default_water_flowing.png", backface_culling = false},
},
alpha = WATER_ALPHA,
paramtype = "light",
paramtype2 = "flowingliquid",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drowning = 1,
liquidtype = "flowing",
liquid_alternative_flowing = "basenodes:water_flowing",
liquid_alternative_source = "basenodes:water_source",
liquid_viscosity = WATER_VISC,
post_effect_color = {a = 64, r = 100, g = 100, b = 200},
groups = {water = 3, liquid = 3},
})
minetest.register_node("basenodes:river_water_source", {
description = "River Water Source",
drawtype = "liquid",
tiles = { "default_river_water.png" },
special_tiles = {
{name = "default_river_water.png", backface_culling = false},
{name = "default_river_water.png", backface_culling = true},
},
alpha = WATER_ALPHA,
paramtype = "light",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drowning = 1,
liquidtype = "source",
liquid_alternative_flowing = "basenodes:river_water_flowing",
liquid_alternative_source = "basenodes:river_water_source",
liquid_viscosity = 1,
liquid_renewable = false,
liquid_range = 2,
post_effect_color = {a = 103, r = 30, g = 76, b = 90},
groups = {water = 3, liquid = 3, },
})
minetest.register_node("basenodes:river_water_flowing", {
description = "Flowing River Water",
drawtype = "flowingliquid",
tiles = {"default_river_water_flowing.png"},
special_tiles = {
{name = "default_river_water_flowing.png", backface_culling = false},
{name = "default_river_water_flowing.png", backface_culling = false},
},
alpha = WATER_ALPHA,
paramtype = "light",
paramtype2 = "flowingliquid",
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drowning = 1,
liquidtype = "flowing",
liquid_alternative_flowing = "basenodes:river_water_flowing",
liquid_alternative_source = "basenodes:river_water_source",
liquid_viscosity = 1,
liquid_renewable = false,
liquid_range = 2,
post_effect_color = {a = 103, r = 30, g = 76, b = 90},
groups = {water = 3, liquid = 3, },
})
minetest.register_node("basenodes:lava_flowing", {
description = "Flowing Lava",
drawtype = "flowingliquid",
tiles = {"default_lava_flowing.png"},
special_tiles = {
{name="default_lava_flowing.png", backface_culling = false},
{name="default_lava_flowing.png", backface_culling = false},
},
paramtype = "light",
light_source = minetest.LIGHT_MAX,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drowning = 1,
damage_per_second = 4,
liquidtype = "flowing",
liquid_alternative_flowing = "basenodes:lava_flowing",
liquid_alternative_source = "basenodes:lava_source",
liquid_viscosity = LAVA_VISC,
post_effect_color = {a=192, r=255, g=64, b=0},
groups = {lava=3, liquid=1},
})
minetest.register_node("basenodes:lava_source", {
description = "Lava Source",
drawtype = "liquid",
tiles = { "default_lava.png" },
special_tiles = {
{name = "default_lava.png", backface_culling = false},
{name = "default_lava.png", backface_culling = true},
},
paramtype = "light",
light_source = minetest.LIGHT_MAX,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drowning = 1,
damage_per_second = 4,
liquidtype = "source",
liquid_alternative_flowing = "basenodes:lava_flowing",
liquid_alternative_source = "basenodes:lava_source",
liquid_viscosity = LAVA_VISC,
post_effect_color = {a=192, r=255, g=64, b=0},
groups = {lava=3, liquid=1},
})
minetest.register_node("basenodes:cobble", {
description = "Cobblestone",
tiles ={"default_cobble.png"},
is_ground_content = false,
groups = {cracky=3},
})
minetest.register_node("basenodes:mossycobble", {
description = "Mossy Cobblestone",
tiles ={"default_mossycobble.png"},
is_ground_content = false,
groups = {cracky=3},
})
minetest.register_node("basenodes:apple", {
description = "Apple",
drawtype = "plantlike",
tiles ={"default_apple.png"},
inventory_image = "default_apple.png",
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
groups = {dig_immediate=3},
-- Make eatable because why not?
on_use = minetest.item_eat(2),
})
minetest.register_node("basenodes:ice", {
description = "Ice",
tiles ={"default_ice.png"},
groups = {cracky=3},
})
-- The snow nodes intentionally have different tints to make them more
-- distinguishable
minetest.register_node("basenodes:snow", {
description = "Snow Sheet",
tiles = {"basenodes_snow_sheet.png"},
groups = {crumbly=3},
walkable = false,
paramtype = "light",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5},
},
})
minetest.register_node("basenodes:snowblock", {
description = "Snow Block",
tiles ={"default_snow.png"},
groups = {crumbly=3},
})

View file

@ -0,0 +1,2 @@
name = basenodes
description = Contains basic nodes for mapgen

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 790 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 B

View file

@ -0,0 +1,295 @@
--
-- Tool definitions
--
--[[ TOOLS SUMMARY:
Tool types:
* Hand: basic tool/weapon (just for convenience, not optimized for testing)
* Pickaxe: dig cracky
* Axe: dig choppy
* Shovel: dig crumbly
* Shears: dig snappy
* Sword: deal damage
* Dagger: deal damage, but faster
Tool materials:
* Dirt: dig nodes of rating 3, one use only
* Wood: dig nodes of rating 3
* Stone: dig nodes of rating 3 or 2
* Steel: dig nodes of rating 3, 2 or 1
* Mese: dig "everything" instantly
]]
-- The hand
minetest.register_item(":", {
type = "none",
wield_image = "wieldhand.png",
wield_scale = {x=1,y=1,z=2.5},
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level = 0,
groupcaps = {
crumbly = {times={[3]=1.50}, uses=0, maxlevel=0},
snappy = {times={[3]=1.50}, uses=0, maxlevel=0},
oddly_breakable_by_hand = {times={[1]=7.00,[2]=4.00,[3]=2.00}, uses=0, maxlevel=0},
},
damage_groups = {fleshy=1},
}
})
-- Mese Pickaxe: special tool that digs "everything" instantly
minetest.register_tool("basetools:pick_mese", {
description = "Mese Pickaxe",
inventory_image = "basetools_mesepick.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=3,
groupcaps={
cracky={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
crumbly={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
snappy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
choppy={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
dig_immediate={times={[1]=0.0, [2]=0.0, [3]=0.0}, maxlevel=255},
},
},
})
--
-- Pickaxes: Dig cracky
--
-- This should break after only 1 use
minetest.register_tool("basetools:pick_dirt", {
description = "Dirt Pickaxe",
inventory_image = "basetools_dirtpick.png",
tool_capabilities = {
max_drop_level=0,
groupcaps={
cracky={times={[3]=2.00}, uses=1, maxlevel=0}
},
},
})
minetest.register_tool("basetools:pick_wood", {
description = "Wooden Pickaxe",
inventory_image = "basetools_woodpick.png",
tool_capabilities = {
max_drop_level=0,
groupcaps={
cracky={times={[3]=2.00}, uses=30, maxlevel=0}
},
},
})
minetest.register_tool("basetools:pick_stone", {
description = "Stone Pickaxe",
inventory_image = "basetools_stonepick.png",
tool_capabilities = {
max_drop_level=0,
groupcaps={
cracky={times={[2]=1.20, [3]=0.80}, uses=60, maxlevel=0}
},
},
})
minetest.register_tool("basetools:pick_steel", {
description = "Steel Pickaxe",
inventory_image = "basetools_steelpick.png",
tool_capabilities = {
max_drop_level=1,
groupcaps={
cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=0}
},
},
})
minetest.register_tool("basetools:pick_steel_l1", {
description = "Steel Pickaxe Level 1",
inventory_image = "basetools_steelpick_l1.png",
tool_capabilities = {
max_drop_level=1,
groupcaps={
cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=1}
},
},
})
minetest.register_tool("basetools:pick_steel_l2", {
description = "Steel Pickaxe Level 2",
inventory_image = "basetools_steelpick_l2.png",
tool_capabilities = {
max_drop_level=1,
groupcaps={
cracky={times={[1]=4.00, [2]=1.60, [3]=1.00}, uses=90, maxlevel=2}
},
},
})
--
-- Shovels (dig crumbly)
--
minetest.register_tool("basetools:shovel_wood", {
description = "Wooden Shovel",
inventory_image = "basetools_woodshovel.png",
tool_capabilities = {
max_drop_level=0,
groupcaps={
crumbly={times={[3]=0.50}, uses=30, maxlevel=0}
},
},
})
minetest.register_tool("basetools:shovel_stone", {
description = "Stone Shovel",
inventory_image = "basetools_stoneshovel.png",
tool_capabilities = {
max_drop_level=0,
groupcaps={
crumbly={times={[2]=0.50, [3]=0.30}, uses=60, maxlevel=0}
},
},
})
minetest.register_tool("basetools:shovel_steel", {
description = "Steel Shovel",
inventory_image = "basetools_steelshovel.png",
tool_capabilities = {
max_drop_level=1,
groupcaps={
crumbly={times={[1]=1.00, [2]=0.70, [3]=0.60}, uses=90, maxlevel=0}
},
},
})
--
-- Axes (dig choppy)
--
minetest.register_tool("basetools:axe_wood", {
description = "Wooden Axe",
inventory_image = "basetools_woodaxe.png",
tool_capabilities = {
max_drop_level=0,
groupcaps={
choppy={times={[3]=0.80}, uses=30, maxlevel=0},
},
},
})
minetest.register_tool("basetools:axe_stone", {
description = "Stone Axe",
inventory_image = "basetools_stoneaxe.png",
tool_capabilities = {
max_drop_level=0,
groupcaps={
choppy={times={[2]=1.00, [3]=0.60}, uses=60, maxlevel=0},
},
},
})
minetest.register_tool("basetools:axe_steel", {
description = "Steel Axe",
inventory_image = "basetools_steelaxe.png",
tool_capabilities = {
max_drop_level=1,
groupcaps={
choppy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=90, maxlevel=0},
},
},
})
--
-- Shears (dig snappy)
--
minetest.register_tool("basetools:shears_wood", {
description = "Wooden Shears",
inventory_image = "basetools_woodshears.png",
tool_capabilities = {
max_drop_level=0,
groupcaps={
snappy={times={[3]=1.00}, uses=30, maxlevel=0},
},
},
})
minetest.register_tool("basetools:shears_stone", {
description = "Stone Shears",
inventory_image = "basetools_stoneshears.png",
tool_capabilities = {
max_drop_level=0,
groupcaps={
snappy={times={[2]=1.00, [3]=0.50}, uses=60, maxlevel=0},
},
},
})
minetest.register_tool("basetools:shears_steel", {
description = "Steel Shears",
inventory_image = "basetools_steelshears.png",
tool_capabilities = {
max_drop_level=1,
groupcaps={
snappy={times={[1]=1.00, [2]=0.50, [3]=0.25}, uses=90, maxlevel=0},
},
},
})
--
-- Swords (deal damage)
--
minetest.register_tool("basetools:sword_wood", {
description = "Wooden Sword",
inventory_image = "basetools_woodsword.png",
tool_capabilities = {
full_punch_interval = 1.0,
damage_groups = {fleshy=2},
}
})
minetest.register_tool("basetools:sword_stone", {
description = "Stone Sword",
inventory_image = "basetools_stonesword.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=0,
damage_groups = {fleshy=4},
}
})
minetest.register_tool("basetools:sword_steel", {
description = "Steel Sword",
inventory_image = "basetools_steelsword.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
damage_groups = {fleshy=6},
}
})
-- Fire/Ice sword: Deal damage to non-fleshy damage groups
minetest.register_tool("basetools:sword_fire", {
description = "Fire Sword",
inventory_image = "basetools_firesword.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=0,
damage_groups = {icy=6},
}
})
minetest.register_tool("basetools:sword_ice", {
description = "Ice Sword",
inventory_image = "basetools_icesword.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=0,
damage_groups = {firy=6},
}
})
--
-- Dagger: Low damage, fast punch interval
--
minetest.register_tool("basetools:dagger_steel", {
description = "Steel Dagger",
inventory_image = "basetools_steeldagger.png",
tool_capabilities = {
full_punch_interval = 0.5,
max_drop_level=0,
damage_groups = {fleshy=2},
}
})

View file

@ -0,0 +1,2 @@
name = basetools
description = Contains basic digging tools

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

View file

@ -0,0 +1,26 @@
-- Bucket: Punch liquid source or flowing liquid to collect it
minetest.register_tool("bucket:bucket", {
description = "Bucket",
inventory_image = "bucket.png",
stack_max = 1,
liquids_pointable = true,
groups = { disable_repair = 1 },
on_use = function(itemstack, user, pointed_thing)
-- Must be pointing to node
if pointed_thing.type ~= "node" then
return
end
-- Check if pointing to a liquid
local n = minetest.get_node(pointed_thing.under)
local def = minetest.registered_nodes[n.name]
if def ~= nil and (def.liquidtype == "source" or def.liquidtype == "flowing") then
minetest.add_node(pointed_thing.under, {name="air"})
local inv = user:get_inventory()
if inv then
inv:add_item("main", ItemStack(n.name))
end
end
end,
})

View file

@ -0,0 +1,2 @@
name = bucket
description = Minimal bucket to pick up liquids

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

View file

@ -0,0 +1,27 @@
minetest.register_node("chest:chest", {
description = "Chest",
tiles ={"chest_chest.png^[sheet:2x2:0,0", "chest_chest.png^[sheet:2x2:0,0",
"chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:1,0",
"chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:0,1"},
paramtype2 = "facedir",
groups = {dig_immediate=2,choppy=3},
is_ground_content = false,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec",
"size[8,9]"..
"list[current_name;main;0,0;8,4;]"..
"list[current_player;main;0,5;8,4;]" ..
"listring[]")
meta:set_string("infotext", "Chest")
local inv = meta:get_inventory()
inv:set_size("main", 8*4)
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("main")
end,
})

View file

@ -0,0 +1,2 @@
name = chest
description = A simple chest to store items

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

View file

@ -0,0 +1,135 @@
local F = minetest.formspec_escape
-- Create a detached inventory
local inv_everything = minetest.create_detached_inventory("everything", {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
return 0
end,
allow_put = function(inv, listname, index, stack, player)
return 0
end,
allow_take = function(inv, listname, index, stack, player)
return -1
end,
})
local inv_trash = minetest.create_detached_inventory("trash", {
allow_take = function(inv, listname, index, stack, player)
return 0
end,
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
return 0
end,
on_put = function(inv, listname, index, stack, player)
inv:set_list("main", {})
end,
})
inv_trash:set_size("main", 1)
local max_page = 1
local function get_chest_formspec(page)
local start = 0 + (page-1)*32
return "size[8,9]"..
"list[detached:everything;main;0,0;8,4;"..start.."]"..
"list[current_player;main;0,5;8,4;]" ..
"label[6,4;Trash:]" ..
"list[detached:trash;main;7,4;1,1]" ..
"button[0,4;1,1;chest_of_everything_prev;"..F("<").."]"..
"button[1,4;1,1;chest_of_everything_next;"..F(">").."]"..
"label[2,4;"..F("Page: "..page).."]"..
"listring[detached:everything;main]"..
"listring[current_player;main]"..
"listring[detached:trash;main]"
end
minetest.register_node("chest_of_everything:chest", {
description = "Chest of Everything",
tiles ={"chest_of_everything_chest.png^[sheet:2x2:0,0", "chest_of_everything_chest.png^[sheet:2x2:0,0",
"chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:1,0",
"chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:0,1"},
paramtype2 = "facedir",
groups = {dig_immediate=2,choppy=3},
is_ground_content = false,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", "Chest of Everything")
meta:set_int("page", 1)
meta:set_string("formspec", get_chest_formspec(1))
end,
on_receive_fields = function(pos, formname, fields, sender)
if formname == "" then
local meta = minetest.get_meta(pos)
local page = meta:get_int("page")
if fields.chest_of_everything_prev then
page = page - 1
elseif fields.chest_of_everything_next then
page = page + 1
end
if page < 1 then
page = 1
end
if page > max_page then
page = max_page
end
meta:set_int("page", page)
meta:set_string("formspec", get_chest_formspec(page))
end
end,
})
minetest.register_on_mods_loaded(function()
local items = {}
for itemstring,_ in pairs(minetest.registered_items) do
if itemstring ~= "" and itemstring ~= "unknown" and itemstring ~= "ignore" then
table.insert(items, itemstring)
end
end
--[[ Sort items in this order:
* Chest of Everything
* Test tools
* Other tools
* Craftitems
* Other items
* Dummy items ]]
local function compare(item1, item2)
local def1 = minetest.registered_items[item1]
local def2 = minetest.registered_items[item2]
local tool1 = def1.type == "tool"
local tool2 = def2.type == "tool"
local testtool1 = minetest.get_item_group(item1, "testtool") == 1
local testtool2 = minetest.get_item_group(item2, "testtool") == 1
local dummy1 = minetest.get_item_group(item1, "dummy") == 1
local dummy2 = minetest.get_item_group(item2, "dummy") == 1
local craftitem1 = def1.type == "craft"
local craftitem2 = def2.type == "craft"
if item1 == "chest_of_everything:chest" then
return true
elseif item2 == "chest_of_everything:chest" then
return false
elseif dummy1 and not dummy2 then
return false
elseif not dummy1 and dummy2 then
return true
elseif testtool1 and not testtool2 then
return true
elseif not testtool1 and testtool2 then
return false
elseif tool1 and not tool2 then
return true
elseif not tool1 and tool2 then
return false
elseif craftitem1 and not craftitem2 then
return true
elseif not craftitem1 and craftitem2 then
return false
else
return item1 < item2
end
end
table.sort(items, compare)
inv_everything:set_size("main", #items)
max_page = math.ceil(#items / 32)
for i=1, #items do
inv_everything:add_item("main", items[i])
end
end)

View file

@ -0,0 +1,2 @@
name = chest_of_everything
description = Adds the chest of everything from which you can take all items

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

View file

@ -0,0 +1,37 @@
local groups = {
"cracky", "dig_immediate"
}
-- Register dig nodes with 1 digging group, a rating between 1-3 and a level between 0-2
for g=1, #groups do
local gr = groups[g]
for r=1, 3 do
for l=0, 2 do
if not (gr=="dig_immediate" and (l>0 or r==1)) then
local d
if l > 0 then
d = string.format("Dig Test Node: %s=%d, level=%d", gr, r, l)
else
d = string.format("Dig Test Node: %s=%d", gr, r)
end
local tile = "dignodes_"..gr..".png^dignodes_rating"..r..".png"
if l==1 then
tile = tile .. "^[colorize:#FFFF00:127"
elseif l==2 then
tile = tile .. "^[colorize:#FF0000:127"
end
minetest.register_node("dignodes:"..gr.."_"..r.."_"..l, {
description = d,
tiles = { tile },
groups = { [gr] = r, level = l },
})
end
end
end
end
-- Node without any digging groups
minetest.register_node("dignodes:none", {
description = "Dig Test Node: groupless",
tiles = {"dignodes_none.png"},
})

View file

@ -0,0 +1,2 @@
name = dignodes
description = Nodes with different digging groups

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 B

View file

@ -0,0 +1,215 @@
minetest.register_chatcommand("test_inv", {
params = "",
description = "Test: Modify player's inventory formspec",
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player then
return false, "No player."
end
player:set_inventory_formspec(
"size[13,7.5]"..
"image[6,0.6;1,2;player.png]"..
"list[current_player;main;5,3.5;8,4;]"..
"list[current_player;craft;8,0;3,3;]"..
"list[current_player;craftpreview;12,1;1,1;]"..
"list[detached:test_inventory;main;0,0;4,6;0]"..
"button[0.5,7;2,1;button1;Button 1]"..
"button_exit[2.5,7;2,1;button2;Exit Button]")
return true, "Done."
end,
})
minetest.register_chatcommand("test_bulk_set_node", {
params = "",
description = "Test: Bulk-set 9×9×9 stone nodes",
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player then
return false, "No player."
end
local pos_list = {}
local ppos = player:get_pos()
local i = 1
for x=2,10 do
for y=2,10 do
for z=2,10 do
pos_list[i] = {x=ppos.x + x,y = ppos.y + y,z = ppos.z + z}
i = i + 1
end
end
end
minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
return true, "Done."
end,
})
minetest.register_chatcommand("bench_bulk_set_node", {
params = "",
description = "Benchmark: Bulk-set 99×99×99 stone nodes",
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player then
return false, "No player."
end
local pos_list = {}
local ppos = player:get_pos()
local i = 1
for x=2,100 do
for y=2,100 do
for z=2,100 do
pos_list[i] = {x=ppos.x + x,y = ppos.y + y,z = ppos.z + z}
i = i + 1
end
end
end
minetest.chat_send_player(name, "Benchmarking minetest.bulk_set_node. Warming up ...");
-- warm up with stone to prevent having different callbacks
-- due to different node topology
minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
minetest.chat_send_player(name, "Warming up finished, now benchmarking ...");
local start_time = minetest.get_us_time()
for i=1,#pos_list do
minetest.set_node(pos_list[i], {name = "mapgen_stone"})
end
local middle_time = minetest.get_us_time()
minetest.bulk_set_node(pos_list, {name = "mapgen_stone"})
local end_time = minetest.get_us_time()
local msg = string.format("Benchmark results: minetest.set_node loop: %.2f ms; minetest.bulk_set_node: %.2f ms",
((middle_time - start_time)) / 1000,
((end_time - middle_time)) / 1000
)
return true, msg
end,
})
local function advance_pos(pos, start_pos, advance_z)
if advance_z then
pos.z = pos.z + 2
pos.x = start_pos.x
else
pos.x = pos.x + 2
end
if pos.x > 30900 or pos.x - start_pos.x > 46 then
pos.x = start_pos.x
pos.z = pos.z + 2
end
if pos.z > 30900 then
-- We ran out of space! Aborting
aborted = true
return false
end
return pos
end
local function place_nodes(param)
local nodes = param.nodes
local name = param.name
local pos = param.pos
local start_pos = param.start_pos
table.sort(nodes)
minetest.chat_send_player(name, "Placing nodes …")
local nodes_placed = 0
for n=1, #nodes do
local itemstring = nodes[n]
local def = minetest.registered_nodes[itemstring]
local p2_max = 0
if param.param ~= "no_param2" then
-- Also test the param2 values of the nodes
-- ... but we only use permissible param2 values
if def.paramtype2 == "wallmounted" then
p2_max = 5
elseif def.paramtype2 == "facedir" then
p2_max = 23
elseif def.paramtype2 == "glasslikeliquidlevel" then
p2_max = 63
elseif def.paramtype2 == "meshoptions" and def.drawtype == "plantlike" then
p2_max = 63
elseif def.paramtype2 == "leveled" then
p2_max = 127
elseif def.paramtype2 == "degrotate" and def.drawtype == "plantlike" then
p2_max = 179
elseif def.paramtype2 == "colorfacedir" or
def.paramtype2 == "colorwallmounted" or
def.paramtype2 == "color" then
p2_max = 255
end
end
for p2 = 0, p2_max do
-- Skip undefined param2 values
if not ((def.paramtype2 == "meshoptions" and p2 % 8 > 4) or
(def.paramtype2 == "colorwallmounted" and p2 % 8 > 5) or
(def.paramtype2 == "colorfacedir" and p2 % 32 > 23)) then
minetest.set_node(pos, { name = itemstring, param2 = p2 })
nodes_placed = nodes_placed + 1
pos = advance_pos(pos, start_pos)
if not pos then
aborted = true
break
end
end
end
if aborted then
break
end
end
if aborted then
minetest.chat_send_player(name, "Not all nodes could be placed, please move further away from the world boundary. Nodes placed: "..nodes_placed)
end
minetest.chat_send_player(name, "Nodes placed: "..nodes_placed..".")
end
local function after_emerge(blockpos, action, calls_remaining, param)
if calls_remaining == 0 then
place_nodes(param)
end
end
minetest.register_chatcommand("test_place_nodes", {
params = "[ no_param2 ]",
description = "Test: Place all non-experimental nodes and optionally their permissible param2 variants",
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player then
return false, "No player."
end
local pos = vector.floor(player:get_pos())
pos.x = math.ceil(pos.x + 3)
pos.z = math.ceil(pos.z + 3)
pos.y = math.ceil(pos.y + 1)
local start_pos = table.copy(pos)
if pos.x > 30800 then
return false, "Too close to world boundary (+X). Please move to X < 30800."
end
if pos.z > 30800 then
return false, "Too close to world boundary (+Z). Please move to Z < 30800."
end
local aborted = false
local nodes = {}
local emerge_estimate = 0
for itemstring, def in pairs(minetest.registered_nodes) do
if itemstring ~= "ignore" and string.sub(itemstring, 1, 13) ~= "experimental:" then
table.insert(nodes, itemstring)
if def.paramtype2 == 0 then
emerge_estimate = emerge_estimate + 1
else
emerge_estimate = emerge_estimate + 255
end
end
end
-- Emerge area to make sure that all nodes are being placed.
-- Note we will emerge much more than we need to (overestimation),
-- the estimation code could be improved performance-wise …
local length = 16 + math.ceil(emerge_estimate / 24) * 2
minetest.emerge_area(start_pos,
{ x = start_pos.x + 46, y = start_pos.y, z = start_pos.z + length },
after_emerge, { nodes = nodes, name = name, pos = pos, start_pos = start_pos, param = param })
return true, "Emerging area …"
end,
})

View file

@ -0,0 +1,29 @@
-- Create a detached inventory
local inv = minetest.create_detached_inventory("test_inventory", {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
experimental.print_to_everything("allow move asked")
return count -- Allow all
end,
allow_put = function(inv, listname, index, stack, player)
experimental.print_to_everything("allow put asked")
return 1 -- Allow only 1
end,
allow_take = function(inv, listname, index, stack, player)
experimental.print_to_everything("allow take asked")
return 4 -- Allow 4 at max
end,
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
experimental.print_to_everything(player:get_player_name().." moved items")
end,
on_put = function(inv, listname, index, stack, player)
experimental.print_to_everything(player:get_player_name().." put items")
end,
on_take = function(inv, listname, index, stack, player)
experimental.print_to_everything(player:get_player_name().." took items")
end,
})
inv:set_size("main", 4*6)
inv:add_item("main", "experimental:callback_node")
inv:add_item("main", "experimental:particle_spawner")

View file

@ -0,0 +1,23 @@
--
-- Experimental things
--
experimental = {}
dofile(minetest.get_modpath("experimental").."/detached.lua")
dofile(minetest.get_modpath("experimental").."/items.lua")
dofile(minetest.get_modpath("experimental").."/commands.lua")
function experimental.print_to_everything(msg)
minetest.log("action", msg)
minetest.chat_send_all(msg)
end
minetest.log("info", "[experimental] modname="..dump(minetest.get_current_modname()))
minetest.log("info", "[experimental] modpath="..dump(minetest.get_modpath("experimental")))
minetest.log("info", "[experimental] worldpath="..dump(minetest.get_worldpath()))
minetest.register_on_mods_loaded(function()
minetest.log("action", "[experimental] on_mods_loaded()")
end)

View file

@ -0,0 +1,103 @@
minetest.register_node("experimental:callback_node", {
description = "Callback Test Node (construct/destruct/timer)",
tiles = {"experimental_callback_node.png"},
groups = {dig_immediate=3},
-- This was known to cause a bug in minetest.item_place_node() when used
-- via minetest.place_node(), causing a placer with no position
paramtype2 = "facedir",
drop = "",
on_construct = function(pos)
experimental.print_to_everything("experimental:callback_node:on_construct("..minetest.pos_to_string(pos)..")")
local meta = minetest.get_meta(pos)
meta:set_string("mine", "test")
local timer = minetest.get_node_timer(pos)
timer:start(4, 3)
end,
after_place_node = function(pos, placer)
experimental.print_to_everything("experimental:callback_node:after_place_node("..minetest.pos_to_string(pos)..")")
local meta = minetest.get_meta(pos)
if meta:get_string("mine") == "test" then
experimental.print_to_everything("correct metadata found")
else
experimental.print_to_everything("incorrect metadata found")
end
end,
on_destruct = function(pos)
experimental.print_to_everything("experimental:callback_node:on_destruct("..minetest.pos_to_string(pos)..")")
end,
after_destruct = function(pos)
experimental.print_to_everything("experimental:callback_node:after_destruct("..minetest.pos_to_string(pos)..")")
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
experimental.print_to_everything("experimental:callback_node:after_dig_node("..minetest.pos_to_string(pos)..")")
end,
on_timer = function(pos, elapsed)
experimental.print_to_everything("on_timer(): elapsed="..dump(elapsed))
return true
end,
})
minetest.register_tool("experimental:privatizer", {
description = "Node Meta Privatizer",
inventory_image = "experimental_tester_tool_1.png",
groups = { testtool = 1, disable_repair = 1 },
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type == "node" then
local node = minetest.get_node(pointed_thing.under)
if node.name == "chest:chest" then
local p = pointed_thing.under
minetest.log("action", "Privatizer used at "..minetest.pos_to_string(p))
minetest.get_meta(p):mark_as_private({"infotext", "formspec"})
if user and user:is_player() then
minetest.chat_send_player(user:get_player_name(), "Chest metadata (infotext, formspec) set private!")
end
return
end
end
if user and user:is_player() then
minetest.chat_send_player(user:get_player_name(), "Privatizer can only be used on chest!")
end
end,
})
minetest.register_tool("experimental:particle_spawner", {
description = "Particle Spawner",
inventory_image = "experimental_tester_tool_1.png^[invert:g",
groups = { testtool = 1, disable_repair = 1 },
on_use = function(itemstack, user, pointed_thing)
local pos = minetest.get_pointed_thing_position(pointed_thing, true)
if pos == nil then
if user then
pos = user:get_pos()
end
end
pos = vector.add(pos, {x=0, y=0.5, z=0})
local tex, anim
if math.random(0, 1) == 0 then
tex = "experimental_particle_sheet.png"
anim = {type="sheet_2d", frames_w=3, frames_h=2, frame_length=0.5}
else
tex = "experimental_particle_vertical.png"
anim = {type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3}
end
minetest.add_particle({
pos = pos,
velocity = {x=0, y=0, z=0},
acceleration = {x=0, y=0.04, z=0},
expirationtime = 6,
collisiondetection = true,
texture = tex,
animation = anim,
size = 4,
glow = math.random(0, 5),
})
end,
})

View file

@ -0,0 +1,2 @@
name = experimental
description = Chaotic mod containing unstructured tests for testing out engine features. The features in this mod should be moved to other mods.

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

View file

@ -0,0 +1,37 @@
local give_if_not_gotten_already = function(inv, list, item)
if not inv:contains_item(list, item) then
inv:add_item(list, item)
end
end
local give_initial_stuff = function(player)
local inv = player:get_inventory()
give_if_not_gotten_already(inv, "main", "basetools:pick_mese")
give_if_not_gotten_already(inv, "main", "basetools:axe_steel")
give_if_not_gotten_already(inv, "main", "basetools:shovel_steel")
give_if_not_gotten_already(inv, "main", "bucket:bucket")
give_if_not_gotten_already(inv, "main", "testnodes:light14")
give_if_not_gotten_already(inv, "main", "chest_of_everything:chest")
minetest.log("action", "[give_initial_stuff] Giving initial stuff to "..player:get_player_name())
end
minetest.register_on_newplayer(function(player)
if minetest.settings:get_bool("give_initial_stuff", true) then
give_initial_stuff(player)
end
end)
minetest.register_chatcommand("stuff", {
params = "",
privs = { give = true },
description = "Give yourself initial items",
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player or not player:is_player() then
return false, "No player."
end
give_initial_stuff(player)
return true
end,
})

View file

@ -0,0 +1,3 @@
name = give_initial_stuff
description = Gives items to players on join
depends = basetools, bucket, chest_of_everything, testnodes

View file

@ -0,0 +1,9 @@
minetest.register_on_joinplayer(function(player)
local cb = function(player)
if not player or not player:is_player() then
return
end
minetest.chat_send_player(player:get_player_name(), "This is the \"Development Test\" [devtest], meant only for testing and development. Use Minetest Game for the real thing.")
end
minetest.after(2.0, cb, player)
end)

View file

@ -0,0 +1,2 @@
name = initial_message
description = Show message to joining players explaining what this testing game is about

Some files were not shown because too many files have changed in this diff Show more