diff --git a/data/scripts/default.lua b/data/scripts/default.lua
index b6c6b0d89c041ed7a70723a7179d54acef1d5493..ebd4e5ab673478f022c327bff766df20d518a771 100644
--- a/data/scripts/default.lua
+++ b/data/scripts/default.lua
@@ -140,7 +140,7 @@ local TNT = {
 	physical = true,
 	weight = 5,
 	boundingbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
-	visual = "box",
+	visual = "cube",
 	textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"},
 	-- Initial value for our timer
 	timer = 0,
@@ -148,11 +148,6 @@ local TNT = {
 	state_variables = {"timer"},
 }
 
--- Called after object is created
-function TNT:on_create()
-	print("TNT:on_create()")
-end
-
 -- Called periodically
 function TNT:on_step(dtime)
 	--print("TNT:on_step()")
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 567b489d917d31083ce249433d8f577f4944e456..8a0e67a2128c3fdb0bdb088e4cd9f08d9d873b62 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -1504,8 +1504,10 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
 	ServerActiveObject(env, pos),
 	m_init_name(name),
 	m_init_state(state),
-	m_registered(false)
+	m_registered(false),
+	m_prop(new LuaEntityProperties)
 {
+	// Only register type if no environment supplied
 	if(env == NULL){
 		ServerActiveObject::registerType(getType(), create);
 		return;
@@ -1518,6 +1520,7 @@ LuaEntitySAO::~LuaEntitySAO()
 		lua_State *L = m_env->getLua();
 		scriptapi_luaentity_rm(L, m_id);
 	}
+	delete m_prop;
 }
 
 void LuaEntitySAO::addedToEnvironment(u16 id)
@@ -1528,6 +1531,10 @@ void LuaEntitySAO::addedToEnvironment(u16 id)
 	m_registered = true;
 	lua_State *L = m_env->getLua();
 	scriptapi_luaentity_add(L, id, m_init_name.c_str(), m_init_state.c_str());
+	
+	// Get properties
+	*m_prop = scriptapi_luaentity_get_properties(L, m_id);
+	infostream<<"m_prop->visual="<<m_prop->visual<<std::endl;
 }
 
 ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos,
diff --git a/src/content_sao.h b/src/content_sao.h
index 115b9ead47f154eb35833636912eece282e94220..ef22f297499fc5779d8e917eae80ffa3ba93c856 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -195,7 +195,7 @@ class MobV2SAO : public ServerActiveObject
 	Settings *m_properties;
 };
 
-struct LuaState;
+struct LuaEntityProperties;
 
 class LuaEntitySAO : public ServerActiveObject
 {
@@ -219,6 +219,7 @@ class LuaEntitySAO : public ServerActiveObject
 	std::string m_init_name;
 	std::string m_init_state;
 	bool m_registered;
+	struct LuaEntityProperties *m_prop;
 };
 
 #endif
diff --git a/src/script.cpp b/src/script.cpp
index 0059683b7de17db2ceb06cc9809e1716d8452c5f..167f81c77805eaa9fea672173005a173b3152602 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -41,68 +41,6 @@ void script_error(lua_State *L, const char *fmt, ...)
 	exit(EXIT_FAILURE);
 }
 
-void script_call_va(lua_State *L, const char *func, const char *sig, ...)
-{
-	va_list vl;
-	int narg, nres; /* number of arguments and results */
-
-	va_start(vl, sig);
-	lua_getglobal(L, func); /* push function */
-
-	for (narg = 0; *sig; narg++) {
-		/* repeat for each argument */
-		/* check stack space */
-		luaL_checkstack(L, 1, "too many arguments");
-		switch (*sig++) {
-		case 'd': /* double argument */
-			lua_pushnumber(L, va_arg(vl, double));
-			break;
-		case 'i': /* int argument */
-			lua_pushinteger(L, va_arg(vl, int));
-			break;
-		case 's': /* string argument */
-			lua_pushstring(L, va_arg(vl, char *));
-			break;
-		case '>': /* end of arguments */
-			goto endargs;
-		default:
-			script_error(L, "invalid option (%c)", *(sig - 1));
-		}
-	}
-endargs:
-
-	nres = strlen(sig); /* number of expected results */
-
-	if (lua_pcall(L, narg, nres, 0) != 0) /* do the call */
-		script_error(L, "error calling '%s': %s", func, lua_tostring(L, -1));
-	
-	nres = -nres; /* stack index of first result */
-	while (*sig) { /* repeat for each result */
-		switch (*sig++) {
-		case 'd': /* double result */
-			if (!lua_isnumber(L, nres))
-			script_error(L, "wrong result type");
-			*va_arg(vl, double *) = lua_tonumber(L, nres);
-			break;
-		case 'i': /* int result */
-			if (!lua_isnumber(L, nres))
-			script_error(L, "wrong result type");
-			*va_arg(vl, int *) = lua_tointeger(L, nres);
-			break;
-		case 's': /* string result */
-			if (!lua_isstring(L, nres))
-			script_error(L, "wrong result type");
-			*va_arg(vl, const char **) = lua_tostring(L, nres);
-			break;
-		default:
-			script_error(L, "invalid option (%c)", *(sig - 1));
-		}
-		nres++;
-	}
-
-	va_end(vl);
-}
-
 bool script_load(lua_State *L, const char *path)
 {
 	infostream<<"Loading and running script from "<<path<<std::endl;
diff --git a/src/script.h b/src/script.h
index 82254744f76569bd4b9296681b55ab68403f572e..5f3b3912bf6a0f3c1d7141c822bb791ebb1c0b35 100644
--- a/src/script.h
+++ b/src/script.h
@@ -26,7 +26,6 @@ typedef struct lua_State lua_State;
 lua_State* script_init();
 lua_State* script_deinit(lua_State *L);
 void script_error(lua_State *L, const char *fmt, ...);
-void script_call_va(lua_State *L, const char *func, const char *sig, ...);
 bool script_load(lua_State *L, const char *path);
 
 #endif
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 2704f6c433f90c42b71c2676fbf4eb8bf171dcf8..3c39da6ad61b1ba3e8b2a87a051fc91264104cb4 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -606,16 +606,24 @@ void scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
 		luaL_typerror(L, -1, "ObjectRef");
 	lua_setfield(L, -2, "object");
 
-	// Get minetest.luaentities table
+	// minetest.luaentities[id] = object
 	lua_getglobal(L, "minetest");
 	lua_getfield(L, -1, "luaentities");
 	luaL_checktype(L, -1, LUA_TTABLE);
-	int luaentities = lua_gettop(L);
-	
-	// luaentities[id] = object
 	lua_pushnumber(L, id); // Push id
 	lua_pushvalue(L, object); // Copy object to top of stack
-	lua_settable(L, luaentities);
+	lua_settable(L, -3);
+	
+	// This callback doesn't really make sense
+	/*// Get on_activate function
+	lua_pushvalue(L, object);
+	lua_getfield(L, -1, "on_activate");
+	luaL_checktype(L, -1, LUA_TFUNCTION);
+	lua_pushvalue(L, object); // self
+	// Call with 1 arguments, 0 results
+	if(lua_pcall(L, 1, 0, 0))
+		script_error(L, "error running function %s:on_activate: %s\n",
+				name, lua_tostring(L, -1));*/
 }
 
 void scriptapi_luaentity_rm(lua_State *L, u16 id)
@@ -659,6 +667,76 @@ std::string scriptapi_luaentity_get_state(lua_State *L, u16 id)
 	return "";
 }
 
+LuaEntityProperties scriptapi_luaentity_get_properties(lua_State *L, u16 id)
+{
+	realitycheck(L);
+	assert(lua_checkstack(L, 20));
+	infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
+	StackUnroller stack_unroller(L);
+
+	LuaEntityProperties prop;
+
+	// Get minetest.luaentities[id]
+	luaentity_get(L, id);
+	//int object = lua_gettop(L);
+
+	lua_getfield(L, -1, "physical");
+	if(lua_isboolean(L, -1))
+		prop.physical = lua_toboolean(L, -1);
+	lua_pop(L, 1);
+	
+	lua_getfield(L, -1, "weight");
+	prop.weight = lua_tonumber(L, -1);
+	lua_pop(L, 1);
+
+	lua_getfield(L, -1, "boundingbox");
+	if(lua_istable(L, -1)){
+		lua_rawgeti(L, -1, 1);
+		prop.boundingbox.MinEdge.X = lua_tonumber(L, -1);
+		lua_pop(L, 1);
+		lua_rawgeti(L, -1, 2);
+		prop.boundingbox.MinEdge.Y = lua_tonumber(L, -1);
+		lua_pop(L, 1);
+		lua_rawgeti(L, -1, 3);
+		prop.boundingbox.MinEdge.Z = lua_tonumber(L, -1);
+		lua_pop(L, 1);
+		lua_rawgeti(L, -1, 4);
+		prop.boundingbox.MaxEdge.X = lua_tonumber(L, -1);
+		lua_pop(L, 1);
+		lua_rawgeti(L, -1, 5);
+		prop.boundingbox.MaxEdge.Y = lua_tonumber(L, -1);
+		lua_pop(L, 1);
+		lua_rawgeti(L, -1, 6);
+		prop.boundingbox.MaxEdge.Z = lua_tonumber(L, -1);
+		lua_pop(L, 1);
+	}
+	lua_pop(L, 1);
+
+	lua_getfield(L, -1, "visual");
+	if(lua_isstring(L, -1))
+		prop.visual = lua_tostring(L, -1);
+	lua_pop(L, 1);
+	
+	lua_getfield(L, -1, "textures");
+	if(lua_istable(L, -1)){
+		prop.textures.clear();
+		int table = lua_gettop(L);
+		lua_pushnil(L);
+		while(lua_next(L, table) != 0){
+			// key at index -2 and value at index -1
+			if(lua_isstring(L, -1))
+				prop.textures.push_back(lua_tostring(L, -1));
+			else
+				prop.textures.push_back("");
+			// removes value, keeps key for next iteration
+			lua_pop(L, 1);
+		}
+	}
+	lua_pop(L, 1);
+
+	return prop;
+}
+
 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
 {
 	realitycheck(L);
diff --git a/src/scriptapi.h b/src/scriptapi.h
index 9d10ec77e764e3af3ba4edb7344ea737d41588ab..891342fa33ef3ff206e645adb593fa85c845dc4a 100644
--- a/src/scriptapi.h
+++ b/src/scriptapi.h
@@ -34,10 +34,34 @@ void scriptapi_add_environment(lua_State *L, ServerEnvironment *env);
 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj);
 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj);
 
+struct LuaEntityProperties
+{
+	bool physical;
+	float weight;
+	core::aabbox3d<f32> boundingbox;
+	std::string visual;
+	core::list<std::string> textures;
+
+	LuaEntityProperties():
+		physical(true),
+		weight(5),
+		boundingbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5),
+		visual("cube")
+	{
+		textures.push_back("unknown_block.png");
+		textures.push_back("unknown_block.png");
+		textures.push_back("unknown_block.png");
+		textures.push_back("unknown_block.png");
+		textures.push_back("unknown_block.png");
+		textures.push_back("unknown_block.png");
+	}
+};
+
 void scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
 		const char *init_state);
 void scriptapi_luaentity_rm(lua_State *L, u16 id);
 std::string scriptapi_luaentity_get_state(lua_State *L, u16 id);
+LuaEntityProperties scriptapi_luaentity_get_properties(lua_State *L, u16 id);
 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime);
 void scriptapi_luaentity_rightclick_player(lua_State *L, u16 id,
 		const char *playername);