diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk
index f78b78b9bb3e79145580c85c9e19398a56587aba..2c574bc4167fe9d6a9e34cf6f8eae47348def12b 100644
--- a/build/android/jni/Android.mk
+++ b/build/android/jni/Android.mk
@@ -182,6 +182,7 @@ LOCAL_SRC_FILES :=                                \
 		jni/src/nodemetadata.cpp                  \
 		jni/src/nodetimer.cpp                     \
 		jni/src/noise.cpp                         \
+		jni/src/objdef.cpp                        \
 		jni/src/object_properties.cpp             \
 		jni/src/particles.cpp                     \
 		jni/src/pathfinder.cpp                    \
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 89be914131bcd76f00a96a7142b22e4192f6e1a7..190f4e9bd9d079056093975522d387e3ff3a7a0c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -330,6 +330,7 @@ set(common_SRCS
 	nodemetadata.cpp
 	nodetimer.cpp
 	noise.cpp
+	objdef.cpp
 	object_properties.cpp
 	pathfinder.cpp
 	player.cpp
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 1de7fca817859d48e3a4ab8753aad1b922193ec5..7965730e48cc4efbed72d3772bef66e439eb397f 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -1,6 +1,7 @@
 /*
 Minetest
-Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2010-2015 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
+Copyright (C) 2010-2015 celeron55, Perttu Ahola <celeron55@gmail.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
@@ -427,175 +428,8 @@ void GenerateNotifier::getEvents(
 		m_notify_events.clear();
 }
 
-
 ///////////////////////////////////////////////////////////////////////////////
 
-
-ObjDefManager::ObjDefManager(IGameDef *gamedef, ObjDefType type)
-{
-	m_objtype = type;
-	m_ndef = gamedef ? gamedef->getNodeDefManager() : NULL;
-}
-
-
-ObjDefManager::~ObjDefManager()
-{
-	for (size_t i = 0; i != m_objects.size(); i++)
-		delete m_objects[i];
-}
-
-
-ObjDefHandle ObjDefManager::add(ObjDef *obj)
-{
-	assert(obj);
-
-	if (obj->name.length() && getByName(obj->name))
-		return OBJDEF_INVALID_HANDLE;
-
-	u32 index = addRaw(obj);
-	if (index == OBJDEF_INVALID_INDEX)
-		return OBJDEF_INVALID_HANDLE;
-
-	obj->handle = createHandle(index, m_objtype, obj->uid);
-	return obj->handle;
-}
-
-
-ObjDef *ObjDefManager::get(ObjDefHandle handle) const
-{
-	u32 index = validateHandle(handle);
-	return (index != OBJDEF_INVALID_INDEX) ? getRaw(index) : NULL;
-}
-
-
-ObjDef *ObjDefManager::set(ObjDefHandle handle, ObjDef *obj)
-{
-	u32 index = validateHandle(handle);
-	if (index == OBJDEF_INVALID_INDEX)
-		return NULL;
-
-	ObjDef *oldobj = setRaw(index, obj);
-
-	obj->uid    = oldobj->uid;
-	obj->index  = oldobj->index;
-	obj->handle = oldobj->handle;
-
-	return oldobj;
-}
-
-
-u32 ObjDefManager::addRaw(ObjDef *obj)
-{
-	size_t nobjects = m_objects.size();
-	if (nobjects >= OBJDEF_MAX_ITEMS)
-		return -1;
-
-	obj->index = nobjects;
-
-	// Ensure UID is nonzero so that a valid handle == OBJDEF_INVALID_HANDLE
-	// is not possible.  The slight randomness bias isn't very significant.
-	obj->uid = myrand() & OBJDEF_UID_MASK;
-	if (obj->uid == 0)
-		obj->uid = 1;
-
-	m_objects.push_back(obj);
-
-	infostream << "ObjDefManager: added " << getObjectTitle()
-		<< ": name=\"" << obj->name
-		<< "\" index=" << obj->index
-		<< " uid="     << obj->uid
-		<< std::endl;
-
-	return nobjects;
-}
-
-
-ObjDef *ObjDefManager::getRaw(u32 index) const
-{
-	return m_objects[index];
-}
-
-
-ObjDef *ObjDefManager::setRaw(u32 index, ObjDef *obj)
-{
-	ObjDef *old_obj = m_objects[index];
-	m_objects[index] = obj;
-	return old_obj;
-}
-
-
-ObjDef *ObjDefManager::getByName(const std::string &name) const
-{
-	for (size_t i = 0; i != m_objects.size(); i++) {
-		ObjDef *obj = m_objects[i];
-		if (obj && !strcasecmp(name.c_str(), obj->name.c_str()))
-			return obj;
-	}
-
-	return NULL;
-}
-
-
-void ObjDefManager::clear()
-{
-	for (size_t i = 0; i != m_objects.size(); i++)
-		delete m_objects[i];
-
-	m_objects.clear();
-}
-
-
-u32 ObjDefManager::validateHandle(ObjDefHandle handle) const
-{
-	ObjDefType type;
-	u32 index;
-	u32 uid;
-
-	bool is_valid =
-		(handle != OBJDEF_INVALID_HANDLE)         &&
-		decodeHandle(handle, &index, &type, &uid) &&
-		(type == m_objtype)                       &&
-		(index < m_objects.size())                &&
-		(m_objects[index]->uid == uid);
-
-	return is_valid ? index : -1;
-}
-
-
-ObjDefHandle ObjDefManager::createHandle(u32 index, ObjDefType type, u32 uid)
-{
-	ObjDefHandle handle = 0;
-	set_bits(&handle, 0, 18, index);
-	set_bits(&handle, 18, 6, type);
-	set_bits(&handle, 24, 7, uid);
-
-	u32 parity = calc_parity(handle);
-	set_bits(&handle, 31, 1, parity);
-
-	return handle ^ OBJDEF_HANDLE_SALT;
-}
-
-
-bool ObjDefManager::decodeHandle(ObjDefHandle handle, u32 *index,
-	ObjDefType *type, u32 *uid)
-{
-	handle ^= OBJDEF_HANDLE_SALT;
-
-	u32 parity = get_bits(handle, 31, 1);
-	set_bits(&handle, 31, 1, 0);
-	if (parity != calc_parity(handle))
-		return false;
-
-	*index = get_bits(handle, 0, 18);
-	*type  = (ObjDefType)get_bits(handle, 18, 6);
-	*uid   = get_bits(handle, 24, 7);
-	return true;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-
 void MapgenParams::load(const Settings &settings)
 {
 	std::string seed_str;
diff --git a/src/mapgen.h b/src/mapgen.h
index b7fecb7a45c04139d0763397d897f689799088f1..351a09bb26baf302b27c05f631db8c1a6c2accec 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -186,72 +186,4 @@ struct MapgenFactory {
 	virtual ~MapgenFactory() {}
 };
 
-typedef std::map<std::string, std::string> StringMap;
-typedef u32 ObjDefHandle;
-
-#define OBJDEF_INVALID_INDEX ((u32)(-1))
-#define OBJDEF_INVALID_HANDLE 0
-#define OBJDEF_HANDLE_SALT 0x00585e6fu
-#define OBJDEF_MAX_ITEMS (1 << 18)
-#define OBJDEF_UID_MASK ((1 << 7) - 1)
-
-enum ObjDefType {
-	OBJDEF_GENERIC,
-	OBJDEF_BIOME,
-	OBJDEF_ORE,
-	OBJDEF_DECORATION,
-	OBJDEF_SCHEMATIC,
-};
-
-class ObjDef {
-public:
-	virtual ~ObjDef() {}
-
-	u32 index;
-	u32 uid;
-	ObjDefHandle handle;
-	std::string name;
-};
-
-// WARNING: Ownership of ObjDefs is transferred to the ObjDefManager it is
-// added/set to.  Note that ObjDefs managed by ObjDefManager are NOT refcounted,
-// so the same ObjDef instance must not be referenced multiple
-class ObjDefManager {
-public:
-	ObjDefManager(IGameDef *gamedef, ObjDefType type);
-	virtual ~ObjDefManager();
-
-	virtual const char *getObjectTitle() const { return "ObjDef"; }
-
-	virtual void clear();
-	virtual ObjDef *getByName(const std::string &name) const;
-
-	//// Add new/get/set object definitions by handle
-	virtual ObjDefHandle add(ObjDef *obj);
-	virtual ObjDef *get(ObjDefHandle handle) const;
-	virtual ObjDef *set(ObjDefHandle handle, ObjDef *obj);
-
-	//// Raw variants that work on indexes
-	virtual u32 addRaw(ObjDef *obj);
-
-	// It is generally assumed that getRaw() will always return a valid object
-	// This won't be true if people do odd things such as call setRaw() with NULL
-	virtual ObjDef *getRaw(u32 index) const;
-	virtual ObjDef *setRaw(u32 index, ObjDef *obj);
-
-	size_t getNumObjects() const { return m_objects.size(); }
-	ObjDefType getType() const { return m_objtype; }
-	INodeDefManager *getNodeDef() const { return m_ndef; }
-
-	u32 validateHandle(ObjDefHandle handle) const;
-	static ObjDefHandle createHandle(u32 index, ObjDefType type, u32 uid);
-	static bool decodeHandle(ObjDefHandle handle, u32 *index,
-		ObjDefType *type, u32 *uid);
-
-protected:
-	INodeDefManager *m_ndef;
-	std::vector<ObjDef *> m_objects;
-	ObjDefType m_objtype;
-};
-
 #endif
diff --git a/src/mg_biome.h b/src/mg_biome.h
index e289fb16dd71657b928f902df25c532c4d256c39..8d519f808cc175de92254c1c2dea33a72315e397 100644
--- a/src/mg_biome.h
+++ b/src/mg_biome.h
@@ -20,9 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef MG_BIOME_HEADER
 #define MG_BIOME_HEADER
 
-#include "mapgen.h"
-
-struct NoiseParams;
+#include "objdef.h"
+#include "nodedef.h"
 
 enum BiomeType
 {
diff --git a/src/mg_decoration.h b/src/mg_decoration.h
index 8ece5d684e3174a608ed4fe7684abed1a6b07f4c..056748918c2dc0d24b73551b08e880154a0d9325 100644
--- a/src/mg_decoration.h
+++ b/src/mg_decoration.h
@@ -21,9 +21,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define MG_DECORATION_HEADER
 
 #include <set>
-#include "mapgen.h"
+#include "objdef.h"
+#include "noise.h"
+#include "nodedef.h"
 
-struct NoiseParams;
 class Mapgen;
 class MMVManip;
 class PseudoRandom;
diff --git a/src/mg_ore.h b/src/mg_ore.h
index cff1622fbc57a8ce88ff4a0e5182b2ecf0a68244..ffe8cfe5081e7f19d7e1b80f5dd3fb5c7da6c5c7 100644
--- a/src/mg_ore.h
+++ b/src/mg_ore.h
@@ -20,10 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef MG_ORE_HEADER
 #define MG_ORE_HEADER
 
-#include "util/string.h"
-#include "mapgen.h"
+#include "objdef.h"
+#include "noise.h"
+#include "nodedef.h"
 
-struct NoiseParams;
 class Noise;
 class Mapgen;
 class MMVManip;
diff --git a/src/objdef.cpp b/src/objdef.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bdf9c4dfc7bd9b7b38d8e2ab160728e510401c4b
--- /dev/null
+++ b/src/objdef.cpp
@@ -0,0 +1,185 @@
+/*
+Minetest
+Copyright (C) 2010-2015 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
+
+This program is free software; 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; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "objdef.h"
+#include "util/numeric.h"
+#include "debug.h"
+#include "log.h"
+#include "gamedef.h"
+
+ObjDefManager::ObjDefManager(IGameDef *gamedef, ObjDefType type)
+{
+	m_objtype = type;
+	m_ndef = gamedef ? gamedef->getNodeDefManager() : NULL;
+}
+
+
+ObjDefManager::~ObjDefManager()
+{
+	for (size_t i = 0; i != m_objects.size(); i++)
+		delete m_objects[i];
+}
+
+
+ObjDefHandle ObjDefManager::add(ObjDef *obj)
+{
+	assert(obj);
+
+	if (obj->name.length() && getByName(obj->name))
+		return OBJDEF_INVALID_HANDLE;
+
+	u32 index = addRaw(obj);
+	if (index == OBJDEF_INVALID_INDEX)
+		return OBJDEF_INVALID_HANDLE;
+
+	obj->handle = createHandle(index, m_objtype, obj->uid);
+	return obj->handle;
+}
+
+
+ObjDef *ObjDefManager::get(ObjDefHandle handle) const
+{
+	u32 index = validateHandle(handle);
+	return (index != OBJDEF_INVALID_INDEX) ? getRaw(index) : NULL;
+}
+
+
+ObjDef *ObjDefManager::set(ObjDefHandle handle, ObjDef *obj)
+{
+	u32 index = validateHandle(handle);
+	if (index == OBJDEF_INVALID_INDEX)
+		return NULL;
+
+	ObjDef *oldobj = setRaw(index, obj);
+
+	obj->uid    = oldobj->uid;
+	obj->index  = oldobj->index;
+	obj->handle = oldobj->handle;
+
+	return oldobj;
+}
+
+
+u32 ObjDefManager::addRaw(ObjDef *obj)
+{
+	size_t nobjects = m_objects.size();
+	if (nobjects >= OBJDEF_MAX_ITEMS)
+		return -1;
+
+	obj->index = nobjects;
+
+	// Ensure UID is nonzero so that a valid handle == OBJDEF_INVALID_HANDLE
+	// is not possible.  The slight randomness bias isn't very significant.
+	obj->uid = myrand() & OBJDEF_UID_MASK;
+	if (obj->uid == 0)
+		obj->uid = 1;
+
+	m_objects.push_back(obj);
+
+	infostream << "ObjDefManager: added " << getObjectTitle()
+		<< ": name=\"" << obj->name
+		<< "\" index=" << obj->index
+		<< " uid="     << obj->uid
+		<< std::endl;
+
+	return nobjects;
+}
+
+
+ObjDef *ObjDefManager::getRaw(u32 index) const
+{
+	return m_objects[index];
+}
+
+
+ObjDef *ObjDefManager::setRaw(u32 index, ObjDef *obj)
+{
+	ObjDef *old_obj = m_objects[index];
+	m_objects[index] = obj;
+	return old_obj;
+}
+
+
+ObjDef *ObjDefManager::getByName(const std::string &name) const
+{
+	for (size_t i = 0; i != m_objects.size(); i++) {
+		ObjDef *obj = m_objects[i];
+		if (obj && !strcasecmp(name.c_str(), obj->name.c_str()))
+			return obj;
+	}
+
+	return NULL;
+}
+
+
+void ObjDefManager::clear()
+{
+	for (size_t i = 0; i != m_objects.size(); i++)
+		delete m_objects[i];
+
+	m_objects.clear();
+}
+
+
+u32 ObjDefManager::validateHandle(ObjDefHandle handle) const
+{
+	ObjDefType type;
+	u32 index;
+	u32 uid;
+
+	bool is_valid =
+		(handle != OBJDEF_INVALID_HANDLE)         &&
+		decodeHandle(handle, &index, &type, &uid) &&
+		(type == m_objtype)                       &&
+		(index < m_objects.size())                &&
+		(m_objects[index]->uid == uid);
+
+	return is_valid ? index : -1;
+}
+
+
+ObjDefHandle ObjDefManager::createHandle(u32 index, ObjDefType type, u32 uid)
+{
+	ObjDefHandle handle = 0;
+	set_bits(&handle, 0, 18, index);
+	set_bits(&handle, 18, 6, type);
+	set_bits(&handle, 24, 7, uid);
+
+	u32 parity = calc_parity(handle);
+	set_bits(&handle, 31, 1, parity);
+
+	return handle ^ OBJDEF_HANDLE_SALT;
+}
+
+
+bool ObjDefManager::decodeHandle(ObjDefHandle handle, u32 *index,
+	ObjDefType *type, u32 *uid)
+{
+	handle ^= OBJDEF_HANDLE_SALT;
+
+	u32 parity = get_bits(handle, 31, 1);
+	set_bits(&handle, 31, 1, 0);
+	if (parity != calc_parity(handle))
+		return false;
+
+	*index = get_bits(handle, 0, 18);
+	*type  = (ObjDefType)get_bits(handle, 18, 6);
+	*uid   = get_bits(handle, 24, 7);
+	return true;
+}
diff --git a/src/objdef.h b/src/objdef.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e0c0b001786e3d4d49172f641f0e1bec8a96c24
--- /dev/null
+++ b/src/objdef.h
@@ -0,0 +1,97 @@
+/*
+Minetest
+Copyright (C) 2010-2015 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
+
+This program is free software; 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; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef OBJDEF_HEADER
+#define OBJDEF_HEADER
+
+#include <string>
+#include <vector>
+#include "irrlichttypes.h"
+
+class IGameDef;
+class INodeDefManager;
+
+#define OBJDEF_INVALID_INDEX ((u32)(-1))
+#define OBJDEF_INVALID_HANDLE 0
+#define OBJDEF_HANDLE_SALT 0x00585e6fu
+#define OBJDEF_MAX_ITEMS (1 << 18)
+#define OBJDEF_UID_MASK ((1 << 7) - 1)
+
+typedef u32 ObjDefHandle;
+
+enum ObjDefType {
+	OBJDEF_GENERIC,
+	OBJDEF_BIOME,
+	OBJDEF_ORE,
+	OBJDEF_DECORATION,
+	OBJDEF_SCHEMATIC,
+};
+
+class ObjDef {
+public:
+	virtual ~ObjDef() {}
+
+	u32 index;
+	u32 uid;
+	ObjDefHandle handle;
+	std::string name;
+};
+
+// WARNING: Ownership of ObjDefs is transferred to the ObjDefManager it is
+// added/set to.  Note that ObjDefs managed by ObjDefManager are NOT refcounted,
+// so the same ObjDef instance must not be referenced multiple
+class ObjDefManager {
+public:
+	ObjDefManager(IGameDef *gamedef, ObjDefType type);
+	virtual ~ObjDefManager();
+
+	virtual const char *getObjectTitle() const { return "ObjDef"; }
+
+	virtual void clear();
+	virtual ObjDef *getByName(const std::string &name) const;
+
+	//// Add new/get/set object definitions by handle
+	virtual ObjDefHandle add(ObjDef *obj);
+	virtual ObjDef *get(ObjDefHandle handle) const;
+	virtual ObjDef *set(ObjDefHandle handle, ObjDef *obj);
+
+	//// Raw variants that work on indexes
+	virtual u32 addRaw(ObjDef *obj);
+
+	// It is generally assumed that getRaw() will always return a valid object
+	// This won't be true if people do odd things such as call setRaw() with NULL
+	virtual ObjDef *getRaw(u32 index) const;
+	virtual ObjDef *setRaw(u32 index, ObjDef *obj);
+
+	size_t getNumObjects() const { return m_objects.size(); }
+	ObjDefType getType() const { return m_objtype; }
+	INodeDefManager *getNodeDef() const { return m_ndef; }
+
+	u32 validateHandle(ObjDefHandle handle) const;
+	static ObjDefHandle createHandle(u32 index, ObjDefType type, u32 uid);
+	static bool decodeHandle(ObjDefHandle handle, u32 *index,
+		ObjDefType *type, u32 *uid);
+
+protected:
+	INodeDefManager *m_ndef;
+	std::vector<ObjDef *> m_objects;
+	ObjDefType m_objtype;
+};
+
+#endif
diff --git a/src/unittest/test_objdef.cpp b/src/unittest/test_objdef.cpp
index ddb3bc60dba869739f1fc6d06087c890b5633a40..df2633b38f850e08e99eebda85dc9b70bf1f497e 100644
--- a/src/unittest/test_objdef.cpp
+++ b/src/unittest/test_objdef.cpp
@@ -20,8 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "test.h"
 
 #include "exceptions.h"
-#include "mapgen.h"
-
+#include "objdef.h"
 
 class TestObjDef : public TestBase {
 public:
diff --git a/src/util/string.h b/src/util/string.h
index 4ab5cf3f7b747f800e23a67ae106b4bdcf7a9e42..b80e3c9a82b01ca179f7c6fa405dd2fdda2918fc 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -25,18 +25,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <string>
 #include <cstring>
 #include <vector>
+#include <map>
 #include <sstream>
 #include <cctype>
 
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
 
+typedef std::map<std::string, std::string> StringMap;
+
 struct FlagDesc {
 	const char *name;
 	u32 flag;
 };
 
-
 // You must free the returned string!
 // The returned string is allocated using new
 wchar_t *narrow_to_wide_c(const char *str);