Initial checkin.
22
license.md
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
(C) 2016 Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
Licensing Terms and Conditions
|
||||
==============================
|
||||
|
||||
ATWT is licensed permissively, generally under the MIT-feh license
|
||||
(https://spdx.org/licenses/MIT-feh.html) for all ATWT code
|
||||
components. Artwork is generally CC-BY-4.0.
|
||||
|
||||
ATWT contains code and artwork that is borrowed from other mods and may
|
||||
be licensed under different license terms. You should confirm that your
|
||||
use of the code and artwork is compatible with these licenses. These
|
||||
licenses are stated in the subfolders and files of these components
|
||||
where relevant.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
90
mods/db/init.lua
Normal file
@ -0,0 +1,90 @@
|
||||
--[[
|
||||
|
||||
sqlite backend for insidethebox
|
||||
|
||||
This backend stores various persistent world data bits that are
|
||||
not properly stored by the minetest engine. This mod provides both
|
||||
persistent and performant data storage for the itb game until a
|
||||
better solution exists.
|
||||
|
||||
Major data storage parts in this db:
|
||||
|
||||
- players, player scores
|
||||
No player metadata storage exists currently. Only HP and air
|
||||
are stored in player data. We lack storage for things like
|
||||
skin choice, stamina, RPG points and skills, etc.
|
||||
|
||||
- box data
|
||||
|
||||
--]]
|
||||
|
||||
local world_path = minetest.get_worldpath()
|
||||
local sqlite3 = require("lsqlite3")
|
||||
local itb_db = sqlite3.open(world_path .. "/itb.sqlite")
|
||||
|
||||
if not itb_db then
|
||||
assert("lsqlite3 not available or non-functional. Please use e.g. luarocks to install lsqlite3")
|
||||
end
|
||||
|
||||
-- we require these tables to exist:
|
||||
assert(itb_db:exec[[
|
||||
CREATE TABLE box (id INTEGER PRIMARY KEY, data BLOB);
|
||||
CREATE TABLE series (id INTEGER PRIMARY KEY, name TEXT, meta BLOB);
|
||||
CREATE TABLE series_box (series_id INTEGER, box_id INTEGER);
|
||||
CREATE TABLE player (id INTEGER PRIMARY KEY, name TEXT, meta BLOB);
|
||||
CREATE TABLE points (player_id INTEGER, score REAL, type TEXT, box_id INTEGER);
|
||||
]])
|
||||
|
||||
-- table structure and content
|
||||
--[[
|
||||
|
||||
box table: Contain the storage of the box content (not metadata) so all blocks. (one-to-one)
|
||||
- id: box identifier
|
||||
- data: box contents (nodes)
|
||||
|
||||
series: Contains existing series
|
||||
- id: series ID
|
||||
- name: name of the series
|
||||
- meta: misc data
|
||||
|
||||
series_box: maps boxes into series (many-to-many)
|
||||
- series_id: series ID
|
||||
- box_id: box ID
|
||||
|
||||
player: player info
|
||||
- id: player number
|
||||
- name: player name
|
||||
- meta: random player data bits
|
||||
|
||||
score: player and box score data
|
||||
- player_id: player id
|
||||
- score: score value
|
||||
- type: score type (e.g. reviewed a box)
|
||||
- box: associated box ID
|
||||
--]]
|
||||
|
||||
db = {}
|
||||
|
||||
function db.player_get_meta(name)
|
||||
for row in itb_db:nrows("SELECT meta FROM player WHERE name = '" .. name .. "';") do
|
||||
return minetest.parse_json(row.meta)
|
||||
end
|
||||
|
||||
print("no such player in db", name)
|
||||
return nil
|
||||
end
|
||||
|
||||
function db.player_put_meta(name, meta)
|
||||
local r = itb_db:exec("REPLACE INTO player_meta (name, meta) VALUES ('" .. name .. "', '" ..
|
||||
minetest.write_json(meta) .. "');")
|
||||
if not r then
|
||||
print("error writing")
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
itb_db:close()
|
||||
end)
|
11
mods/mg/init.lua
Normal file
@ -0,0 +1,11 @@
|
||||
--[[
|
||||
|
||||
mapgen - none!
|
||||
|
||||
--]]
|
||||
|
||||
-- disable all mapgens
|
||||
minetest.register_on_mapgen_init(function(parms)
|
||||
minetest.set_mapgen_params({mgname = "singlenode", flags = "nolight", flagmask = "nolight"})
|
||||
end)
|
||||
|
83
mods/nodes/init.lua
Normal file
@ -0,0 +1,83 @@
|
||||
|
||||
--[[
|
||||
|
||||
nodes.lua - basic node blocks for Inside The Box
|
||||
|
||||
]]--
|
||||
|
||||
-- table format:
|
||||
-- [1] name, also used for texture
|
||||
-- [2] true for stair/slab
|
||||
-- [3] tool if diggable version needs to be added
|
||||
-- [4] color versions?
|
||||
|
||||
local nodes = {
|
||||
{"bricks_clay", true, "pickaxe"},
|
||||
{"bricks_limestone", true, "pickaxe"},
|
||||
{"bricks_marble", true, "pickaxe"},
|
||||
{"bricks_sandstone", true, "pickaxe"},
|
||||
{"bricks_stone", true, "pickaxe"},
|
||||
{"cobble", true, "pickaxe"},
|
||||
{"cobble_moss", true, "pickaxe"},
|
||||
{"limestone", true, "pickaxe"},
|
||||
{"marble", true, "pickaxe"},
|
||||
{"sandstone", true, "pickaxe"},
|
||||
{"stone", true, "pickaxe"},
|
||||
{"stone_moss", true, "pickaxe"},
|
||||
{"glass", false, "pickaxe"},
|
||||
{"bronze", false, "pickaxe"},
|
||||
{"gold", false, "pickaxe"},
|
||||
{"iron", false, "pickaxe"},
|
||||
{"clay", false, "shovel"},
|
||||
{"dirt", false, "shovel"},
|
||||
{"gravel", false, "shovel"},
|
||||
{"sand", false, "shovel"},
|
||||
{"trunk_light", false, "axe"},
|
||||
{"trunk_medium", false, "axe"},
|
||||
{"trunk_dark", false, "axe"},
|
||||
{"leaves_light", false, "axe"},
|
||||
{"leaves_medium", false, "axe"},
|
||||
{"leaves_dark", false, "axe"},
|
||||
{"wood_dark", true, "axe"},
|
||||
{"wood_light", true, "axe"},
|
||||
{"wood_medium", true, "axe"},
|
||||
{"grass", false, false},
|
||||
{"wool_*", false, false},
|
||||
}
|
||||
|
||||
for _, v in pairs(nodes) do
|
||||
local groups = {}
|
||||
if v[3] then
|
||||
groups = {[v[3]] = 3}
|
||||
end
|
||||
minetest.register_node(":a:" .. v[1], {
|
||||
Description = v[1],
|
||||
tiles = {v[1] .. ".png"},
|
||||
groups = groups,
|
||||
})
|
||||
end
|
||||
|
||||
-- diggable stuff
|
||||
|
||||
-- panes
|
||||
-- iron_pane
|
||||
-- glass_pane
|
||||
|
||||
|
||||
-- walls
|
||||
-- cobble_wall
|
||||
-- cobble_moss_wall
|
||||
|
||||
|
||||
-- special nodes
|
||||
-- water
|
||||
-- lava
|
||||
-- tnt
|
||||
-- fire
|
||||
-- fire_permanent
|
||||
|
||||
|
||||
-- chests:
|
||||
-- empty (fake) chest
|
||||
-- chest-with-key
|
||||
-- chest-with-tool
|
BIN
mods/nodes/textures/bricks_clay.png
Normal file
After Width: | Height: | Size: 434 B |
BIN
mods/nodes/textures/bricks_limestone.png
Normal file
After Width: | Height: | Size: 543 B |
BIN
mods/nodes/textures/bricks_stone.png
Normal file
After Width: | Height: | Size: 443 B |
BIN
mods/nodes/textures/bronze.png
Normal file
After Width: | Height: | Size: 629 B |
BIN
mods/nodes/textures/clay.png
Normal file
After Width: | Height: | Size: 482 B |
BIN
mods/nodes/textures/cobble.png
Normal file
After Width: | Height: | Size: 554 B |
BIN
mods/nodes/textures/cobble_moss.png
Normal file
After Width: | Height: | Size: 652 B |
BIN
mods/nodes/textures/dirt.png
Normal file
After Width: | Height: | Size: 539 B |
BIN
mods/nodes/textures/glass.png
Normal file
After Width: | Height: | Size: 310 B |
BIN
mods/nodes/textures/gold.png
Normal file
After Width: | Height: | Size: 773 B |
BIN
mods/nodes/textures/grass.png
Normal file
After Width: | Height: | Size: 919 B |
BIN
mods/nodes/textures/gravel.png
Normal file
After Width: | Height: | Size: 572 B |
BIN
mods/nodes/textures/iron.png
Normal file
After Width: | Height: | Size: 471 B |
BIN
mods/nodes/textures/leaves_dark.png
Normal file
After Width: | Height: | Size: 561 B |
BIN
mods/nodes/textures/leaves_light.png
Normal file
After Width: | Height: | Size: 704 B |
BIN
mods/nodes/textures/leaves_medium.png
Normal file
After Width: | Height: | Size: 704 B |
BIN
mods/nodes/textures/marble.png
Normal file
After Width: | Height: | Size: 506 B |
BIN
mods/nodes/textures/sand.png
Normal file
After Width: | Height: | Size: 524 B |
BIN
mods/nodes/textures/sandstone.png
Normal file
After Width: | Height: | Size: 409 B |
BIN
mods/nodes/textures/stone.png
Normal file
After Width: | Height: | Size: 275 B |
BIN
mods/nodes/textures/trunk_dark.png
Normal file
After Width: | Height: | Size: 606 B |
BIN
mods/nodes/textures/trunk_light.png
Normal file
After Width: | Height: | Size: 724 B |
BIN
mods/nodes/textures/trunk_medium.png
Normal file
After Width: | Height: | Size: 711 B |
BIN
mods/nodes/textures/wood_dark.png
Normal file
After Width: | Height: | Size: 503 B |
BIN
mods/nodes/textures/wood_light.png
Normal file
After Width: | Height: | Size: 622 B |
BIN
mods/nodes/textures/wood_medium.png
Normal file
After Width: | Height: | Size: 565 B |
48
mods/tools/init.lua
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
-- hand tool
|
||||
minetest.register_item(":", {
|
||||
type = "none",
|
||||
tool_capabilities = {
|
||||
-- can't pick up any node by hand
|
||||
groupcaps = {},
|
||||
},
|
||||
})
|
||||
|
||||
-- node tools
|
||||
minetest.register_tool(":a:shovel", {
|
||||
description = "A Shovel",
|
||||
inventory_image = "shovel.png",
|
||||
tool_capabilities = {
|
||||
groupcaps = {
|
||||
shovel = {
|
||||
times = {[1] = 3, [2] = 3, [3] = 3},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_tool(":a:axe", {
|
||||
description = "An Axe",
|
||||
inventory_image = "axe.png",
|
||||
tool_capabilities = {
|
||||
groupcaps = {
|
||||
axe = {
|
||||
times = {[1] = 3, [2] = 3, [3] = 3},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
minetest.register_tool(":a:pickaxe", {
|
||||
description = "A Pickaxe",
|
||||
inventory_image = "pickaxe.png",
|
||||
tool_capabilities = {
|
||||
groupcaps = {
|
||||
pickaxe = {
|
||||
times = {[1] = 3, [2] = 3, [3] = 3},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
minetest.register_tool(":a:sword", {})
|
||||
minetest.register_tool(":a:flint", {})
|
||||
|
BIN
mods/tools/textures/axe.png
Normal file
After Width: | Height: | Size: 255 B |
BIN
mods/tools/textures/pickaxe.png
Normal file
After Width: | Height: | Size: 248 B |
BIN
mods/tools/textures/shovel.png
Normal file
After Width: | Height: | Size: 260 B |
107
mods/torches/init.lua
Normal file
@ -0,0 +1,107 @@
|
||||
|
||||
--[[
|
||||
|
||||
Torch mod - formerly mod "Torches"
|
||||
======================
|
||||
|
||||
(c) Copyright BlockMen (2013-2015)
|
||||
(C) Copyright sofar <sofar@foo-projects.org> (2016)
|
||||
|
||||
This mod changes the default torch drawtype from "torchlike" to "mesh",
|
||||
giving the torch a three dimensional appearance. The mesh contains the
|
||||
proper pixel mapping to make the animation appear as a particle above
|
||||
the torch, while in fact the animation is just the texture of the mesh.
|
||||
|
||||
|
||||
License:
|
||||
~~~~~~~~
|
||||
(c) Copyright BlockMen (2013-2015)
|
||||
|
||||
Textures and Meshes/Models:
|
||||
CC-BY 3.0 BlockMen
|
||||
Note that the models were entirely done from scratch by sofar.
|
||||
|
||||
Code:
|
||||
Licensed under the GNU LGPL version 2.1 or higher.
|
||||
You can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation;
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt
|
||||
|
||||
--]]
|
||||
|
||||
minetest.register_node("torches:torch", {
|
||||
description = "Torch",
|
||||
drawtype = "mesh",
|
||||
mesh = "torch_floor.obj",
|
||||
inventory_image = "default_torch_on_floor.png",
|
||||
wield_image = "default_torch_on_floor.png",
|
||||
tiles = {{
|
||||
name = "default_torch_on_floor_animated.png",
|
||||
animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3}
|
||||
}},
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
liquids_pointable = false,
|
||||
light_source = 13,
|
||||
groups = {choppy=2, dig_immediate=3, flammable=1, attached_node=1, torch=1},
|
||||
drop = "torches:torch",
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
wall_bottom = {-1/8, -1/2, -1/8, 1/8, 2/16, 1/8},
|
||||
},
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = pointed_thing.under
|
||||
local node = minetest.get_node(under)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if def and def.on_rightclick and
|
||||
((not placer) or (placer and not placer:get_player_control().sneak)) then
|
||||
return def.on_rightclick(under, node, placer, itemstack,
|
||||
pointed_thing) or itemstack
|
||||
end
|
||||
|
||||
local above = pointed_thing.above
|
||||
local wdir = minetest.dir_to_wallmounted(vector.subtract(under, above))
|
||||
local fakestack = itemstack
|
||||
if wdir == 0 then
|
||||
return itemstack
|
||||
elseif wdir == 1 then
|
||||
fakestack:set_name("torches:torch")
|
||||
else
|
||||
fakestack:set_name("torches:torch_wall")
|
||||
end
|
||||
|
||||
itemstack = minetest.item_place(fakestack, placer, pointed_thing, wdir)
|
||||
itemstack:set_name("torches:torch")
|
||||
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("torches:torch_wall", {
|
||||
drawtype = "mesh",
|
||||
mesh = "torch_wall.obj",
|
||||
tiles = {{
|
||||
name = "default_torch_on_floor_animated.png",
|
||||
animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3}
|
||||
}},
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
light_source = 13,
|
||||
groups = {choppy=2, dig_immediate=3, flammable=1, not_in_creative_inventory=1, attached_node=1, torch=1},
|
||||
drop = "torches:torch",
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
wall_side = {-1/2, -1/2, -1/8, -1/8, 1/8, 1/8},
|
||||
},
|
||||
})
|
||||
|
50
mods/torches/models/torch_floor.obj
Normal file
@ -0,0 +1,50 @@
|
||||
# Blender v2.76 (sub 11) OBJ File: 'torch_floor.blend'
|
||||
# www.blender.org
|
||||
mtllib torch_floor.mtl
|
||||
o Cube_Cube.001
|
||||
v 0.062500 0.062500 -0.062500
|
||||
v 0.062500 -0.500000 -0.062500
|
||||
v 0.062500 0.062500 0.062500
|
||||
v 0.062500 -0.500000 0.062500
|
||||
v -0.062500 0.062500 -0.062500
|
||||
v -0.062500 -0.500000 -0.062500
|
||||
v -0.062500 0.062500 0.062500
|
||||
v -0.062500 -0.500000 0.062500
|
||||
v -0.353553 -0.500000 0.353553
|
||||
v -0.353553 0.500000 0.353553
|
||||
v 0.353553 -0.500000 -0.353553
|
||||
v 0.353553 0.500000 -0.353553
|
||||
v -0.353553 -0.500000 -0.353553
|
||||
v 0.353553 -0.500000 0.353553
|
||||
v -0.353553 0.500000 -0.353553
|
||||
v 0.353553 0.500000 0.353553
|
||||
vt 0.562500 0.500000
|
||||
vt 0.562500 0.625000
|
||||
vt 0.437500 0.625000
|
||||
vt 0.437500 0.500000
|
||||
vt 0.437500 0.000000
|
||||
vt 0.562500 0.000000
|
||||
vt 0.562500 0.125000
|
||||
vt 0.437500 0.125000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.000000
|
||||
vn 0.000000 1.000000 0.000000
|
||||
vn 0.000000 0.000000 -1.000000
|
||||
vn 1.000000 0.000000 0.000000
|
||||
vn -0.707100 0.000000 -0.707100
|
||||
vn -0.707100 -0.000000 0.707100
|
||||
g Cube_Cube.001_Cube_Cube.001_Material.001
|
||||
usemtl Material.001
|
||||
s off
|
||||
f 3/1/1 1/2/1 5/3/1 7/4/1
|
||||
f 8/5/1 4/6/1 2/7/1 6/8/1
|
||||
f 3/2/2 4/6/2 8/5/2 7/3/2
|
||||
f 1/3/3 3/2/3 4/6/3 2/5/3
|
||||
f 5/2/2 1/3/2 2/5/2 6/6/2
|
||||
f 7/3/3 8/5/3 6/6/3 5/2/3
|
||||
g Cube_Cube.001_Cube_Cube.001_Material.002
|
||||
usemtl Material.002
|
||||
f 9/9/4 10/10/4 12/11/4 11/12/4
|
||||
f 13/12/5 14/9/5 16/10/5 15/11/5
|
64
mods/torches/models/torch_wall.obj
Normal file
@ -0,0 +1,64 @@
|
||||
# Blender v2.76 (sub 11) OBJ File: 'torch_wall.blend'
|
||||
# www.blender.org
|
||||
mtllib torch_wall.mtl
|
||||
o Cube_Cube.001
|
||||
v 0.062469 -0.195248 0.023570
|
||||
v 0.062469 -0.476498 -0.463570
|
||||
v 0.062469 -0.303502 0.086070
|
||||
v 0.062469 -0.584752 -0.401070
|
||||
v -0.062531 -0.195248 0.023570
|
||||
v -0.062531 -0.476498 -0.463570
|
||||
v -0.062531 -0.303502 0.086070
|
||||
v -0.062531 -0.584752 -0.401070
|
||||
v -0.353584 -0.613553 0.022500
|
||||
v -0.353584 -0.613553 0.460000
|
||||
v 0.353522 0.093553 0.022500
|
||||
v 0.353522 0.093553 0.460000
|
||||
v -0.353584 0.093553 0.022500
|
||||
v 0.353522 -0.613553 0.022500
|
||||
v -0.353584 0.093553 0.460000
|
||||
v 0.353522 -0.613553 0.460000
|
||||
v 0.353553 0.056811 -0.121957
|
||||
v 0.353553 -0.224439 -0.609096
|
||||
v -0.353553 -0.555561 0.231596
|
||||
v -0.353553 -0.836811 -0.255543
|
||||
v -0.353553 0.056811 -0.121957
|
||||
v -0.353553 -0.224439 -0.609096
|
||||
v 0.353553 -0.555561 0.231596
|
||||
v 0.353553 -0.836811 -0.255543
|
||||
vt 0.562500 0.500000
|
||||
vt 0.562500 0.625000
|
||||
vt 0.437500 0.625000
|
||||
vt 0.437500 0.500000
|
||||
vt 0.437500 0.000000
|
||||
vt 0.562500 0.000000
|
||||
vt 0.562500 0.125000
|
||||
vt 0.437500 0.125000
|
||||
vt 0.000000 0.562500
|
||||
vt 0.000000 -0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 0.562500
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vn -0.000000 0.500000 0.866000
|
||||
vn -0.000000 0.866000 -0.500000
|
||||
vn 1.000000 0.000000 0.000000
|
||||
vn -0.707100 0.612400 -0.353600
|
||||
vn -0.707100 -0.612400 0.353600
|
||||
vn -0.707100 0.707100 -0.000000
|
||||
vn -0.707100 -0.707100 -0.000000
|
||||
g Cube_Cube.001_Cube_Cube.001_Material.001
|
||||
usemtl Material.001
|
||||
s off
|
||||
f 3/1/1 1/2/1 5/3/1 7/4/1
|
||||
f 8/5/1 4/6/1 2/7/1 6/8/1
|
||||
f 3/2/2 4/6/2 8/5/2 7/3/2
|
||||
f 1/3/3 3/2/3 4/6/3 2/5/3
|
||||
f 5/2/2 1/3/2 2/5/2 6/6/2
|
||||
f 7/3/3 8/5/3 6/6/3 5/2/3
|
||||
f 17/9/4 18/10/4 20/11/4 19/12/4
|
||||
f 21/9/5 22/10/5 24/11/5 23/12/5
|
||||
g Cube_Cube.001_Cube_Cube.001_Material.002
|
||||
usemtl Material.002
|
||||
f 9/12/6 10/13/6 12/14/6 11/9/6
|
||||
f 13/9/7 14/12/7 16/13/7 15/14/7
|
BIN
mods/torches/textures/default_torch_on_floor.png
Normal file
After Width: | Height: | Size: 214 B |
BIN
mods/torches/textures/default_torch_on_floor_animated.png
Normal file
After Width: | Height: | Size: 830 B |
199
readme.md
Normal file
@ -0,0 +1,199 @@
|
||||
|
||||
Inside The Box
|
||||
==============
|
||||
|
||||
A multi-player puzzle solving and creation game for minetest.
|
||||
|
||||
The game is meant to be run as a multiplayer puzzle-creating server.
|
||||
Players can connect and either play boxes, or create new ones.
|
||||
|
||||
The basic concept of the game is boxes. This is an area in which the
|
||||
player needs to find one or more objectives (keys). The player then
|
||||
needs to bring these objectives to a slot (keyhole). Once all the
|
||||
secrets have been found and returned, an exit opens that allows the
|
||||
player out, completing the puzzle box.
|
||||
|
||||
This minetest game is strongly inspired by the "parcels" MC player
|
||||
map. I did not want to replicate the map itself, even though the
|
||||
conversion tools exist to mostly do this, but more because giving
|
||||
it a multiplayer spin sounds much more appealing, and a far better
|
||||
tribute to the map itself. The possibility of having hundreds of
|
||||
puzzle boxes created also sounds much more appealing.
|
||||
|
||||
|
||||
## Playing
|
||||
|
||||
A player can choose to play available boxes. Selecting an available
|
||||
level to play will create a private copy of the level box and teleport
|
||||
the player to the starting point of the level. The starting point is
|
||||
in a hallway or entry room. There can be some clues left, and there
|
||||
should be some information of the builder, and perhaps difficulty,
|
||||
time spent by players in the level, popularity, rating information.
|
||||
|
||||
From the hallway the player should have some visual on the inside of
|
||||
the box. This will help players recognize boxes easier so they can
|
||||
skip ones they have played before, or gauge difficulty, etc..
|
||||
|
||||
The player moves through a door to the level. This may trigger a
|
||||
teleport to a starting location, or not. On the side of the wall
|
||||
somewhere is displayed a large number corresponding with the box ID.
|
||||
|
||||
In the box there is a collection area. In the collection area there
|
||||
are 1 or more collection slots. The slots all require to be filled
|
||||
with a "key" item. These items are found anywhere in the level. The
|
||||
player picks up the item and brings them to the collection slots.
|
||||
|
||||
The box largely contains unbreakable nodes. The box may contain certain
|
||||
digging tools to break nodes in the box (e.g. an axe to break certain
|
||||
wood blocks, a pickaxe to break stone blocks, or a shovel to dig
|
||||
sand blocks). The player may be forced to use these tools to reach
|
||||
new areas in the box, or to create bridges or ladders to climb up.
|
||||
|
||||
The player can not physically exit the box. The box is surrounded by
|
||||
unbreakable blocks uncluding invisible ceilings where needed. The
|
||||
player has an "escape" button that, when used, removes the player
|
||||
from the game and returns the player to the general lobby.
|
||||
|
||||
The player may take damage in the box through falling or lava
|
||||
or cacti, or other methods. The player recovers lost health somewhat
|
||||
quickly, but some errors may be deadly.
|
||||
|
||||
Once the player collects all the needed items, an exit doorway opens
|
||||
or becomes reachable. The player moves through the exit doorway and
|
||||
ends in an exit lobby/hallway.
|
||||
|
||||
In the exit lobby/hallway, the player can leave feedback or ranking
|
||||
votes for the level. Last, there is a method for the player to return
|
||||
to the general lobby. The player also receives a ranking/score
|
||||
about their performance in the box itself, but only on the first
|
||||
attempt. The performance includes time spent in the box, times died,
|
||||
and damage taken.
|
||||
|
||||
## Constructing
|
||||
|
||||
Players can construct new boxes. They do this by entering a pristine
|
||||
box that is created on the fly for them. In this box, the player
|
||||
receives full editing privileges. The player can construct and modify
|
||||
the collection point, place the secrets, place any node or liquid,
|
||||
fire, TNT or other element provided to them.
|
||||
|
||||
The entry hallway has a spot for a sign hint that the constructor can
|
||||
modify. It also has an interface for modifying the box parameters,
|
||||
such as name and size, and variations such as entry/exit gate locations
|
||||
and collection point stations.
|
||||
|
||||
|
||||
## Points
|
||||
|
||||
Points act as a measure of commitment. The more actions a player does
|
||||
that are in the interest of the community, the more points a player
|
||||
gains. These points can be exchanged for privileges.
|
||||
|
||||
For each level played and rated the player earns points.
|
||||
|
||||
A player may lose points for dying a lot in boxes, or dying a lot
|
||||
in boxes in general. A player may also lose points for other actions,
|
||||
such as going idle in a box, never rating boxes or always rating
|
||||
boxes the same level of hearts. This lowers the input their
|
||||
actions they have into the system. E.g. if a player continuously
|
||||
dies many times in a few boxes, their scoring values are reduced
|
||||
in the averages by a factor, reducing their impact on ratings.
|
||||
|
||||
Privileges that can be reached through gaining points are:
|
||||
- ability to create new boxes
|
||||
- ability to submit more boxes for trials
|
||||
- ability to choose larger level boxes
|
||||
- moderation of boxes that are eligible for moderation
|
||||
- moderation of other players with a lower point level
|
||||
|
||||
|
||||
## Ranking/Rating
|
||||
|
||||
Boxes are rated/ranked per players. Good boxes are promoted to box
|
||||
series that can be accessed from the main lobby easily ("play this
|
||||
months' top boxes") and ultimately make it in to a list of ultimate
|
||||
box boxes. This level series of boxes will only ever grow, and the
|
||||
player can track his progress through these series and continue at
|
||||
any point left.
|
||||
|
||||
A Random box can be chosen from the lobby.
|
||||
|
||||
A player can test trial boxes. Trial boxes are not yet finished
|
||||
but submitted by the creator for review. The player can rate and
|
||||
provide comments ("can't continue", "fell and stuck in a hole",
|
||||
"too easy") to the creator so they may modify the box.
|
||||
|
||||
Points are scored for time spent. More time equals more points, except
|
||||
when players are leaving before finishing, which subtracts points.
|
||||
|
||||
Points are scored for player rating. 0-5 hearts can be given.
|
||||
|
||||
Points are scored for damage taken by players, but subtracted for
|
||||
multiple deaths of the same player. In general, a player dying once
|
||||
in a level is OK, as long as it is instructional to the player and
|
||||
they understand afterwards how to overcome an obstacle. Subsequent
|
||||
deaths of a player may subtract points (note: need to account for
|
||||
trolling here).
|
||||
|
||||
|
||||
## Series
|
||||
|
||||
Series are curated boxes that can be played in succession. A
|
||||
series of boxes grows one box at a time (interval to be
|
||||
determined) and the newest box is always the top ranked box that is
|
||||
not yet in that series. It may be that a fixed amount of scoring points
|
||||
needs to be gained before a box can be promoted to a series.
|
||||
|
||||
- Master Series: A series of best rated boxes over time. These are
|
||||
boxes that have exceeded a certain amount of points. They are
|
||||
permanently added to the master series forever.
|
||||
|
||||
- The trial Series: Unranked and unfinished boxes. These are marked
|
||||
"can be played" but "review requested". Players can recieve extra
|
||||
points when they play and rank these.
|
||||
|
||||
- The Newest Series: Best ranked boxes in a certain time frame. These
|
||||
are up and coming boxes that are relatively new, but have been past
|
||||
review already (no longer "review requested"). Players are encouraged
|
||||
to play these boxes every week and rate.
|
||||
|
||||
|
||||
## Other box choices
|
||||
|
||||
These are suggested game play modes to vary game play a bit.
|
||||
|
||||
- Random rated or Random unrated box: Play a random box.
|
||||
- Box Race: Several players each attempt the same box separately.
|
||||
- Coop: Try boxes together with another player.
|
||||
|
||||
|
||||
## Roles
|
||||
|
||||
- Admin: reserved role for a player that can always moderate players
|
||||
and/or boxes, ban/kick players, edit all boxes, remove boxes.
|
||||
- Moderator: may suspend players, may suspend boxes.
|
||||
- Player: no privileges.
|
||||
|
||||
|
||||
## Technology
|
||||
|
||||
Inside The Box uses lsqlite3 to store player, box, series and score
|
||||
data. This assures that large amounts of data can be stored easily
|
||||
with reasonably good performance and reliability.
|
||||
|
||||
For creation and playing of maps, a virtual `plot` is reserved per
|
||||
player in a random location on the map away from the static lobby. This
|
||||
reservation is destroyed when the box is no longer needed.
|
||||
|
||||
The box contents are stored in the sqlite database and restored for
|
||||
each player that attempts to play the box. This assures that multiple
|
||||
players can separately try the same box without conflicts.
|
||||
|
||||
The sqlite backend also allows efficient storing and retrieval of
|
||||
scores for players or boxes and creating ranks, modifying or inspecting
|
||||
state of boxes or players.
|
||||
|
||||
Placement of boxes will use VoxelManips as well as additional metadata
|
||||
where needed to connect dynamic elements inside the box. These are
|
||||
subsequently connected to assure proper functioning of the box.
|
||||
|