diff --git a/game/engine/Map.lua b/game/engine/Map.lua
index e54abfd326c7b1fb041d57ae5e145ddcc4b561cb..cbc26706fe63882a5494cb189b9c9e41e908dd53 100644
--- a/game/engine/Map.lua
+++ b/game/engine/Map.lua
@@ -211,6 +211,8 @@ end
 --- Serialization
 function _M:save()
 	return class.save(self, {
+		_check_entities = true,
+		_check_entities_store = true,
 		_map = true,
 		_fovcache = true,
 		surface = true,
@@ -309,6 +311,9 @@ function _M:loaded()
 	setmetatable(self.remembers, {__call = mapremember})
 	setmetatable(self.attrs, {__call = mapattrs})
 
+	self._check_entities = {}
+	self._check_entities_store = {}
+
 	self.surface = core.display.newSurface(self.viewport.width, self.viewport.height)
 	self.changed = true
 	self.finished = true
@@ -397,6 +402,18 @@ function _M:updateMap(x, y)
 		p:getMapObjects(self.tiles, mos, 13)
 	end
 
+	-- Update entities checker for this spot
+	-- This is to improve speed, we create a function for each spot that checks entities it knows are there
+	-- This avoid a costly for iteration over a pairs() and this allows luajit to compile only code that is needed
+	local ce = {}
+	local fstr = [[p = m[%s]:check(what, x, y, ...) if p then return p end ]]
+	ce[#ce+1] = [[return function(self, x, y, what, ...) local p local m = self.map[x + y * self.w] ]]
+	for idx, e in pairs(self.map[x + y * self.w]) do ce[#ce+1] = fstr:format(idx) end
+	ce[#ce+1] = [[end]]
+	local ce = table.concat(ce)
+	self._check_entities[x + y * self.w] = self._check_entities_store[ce] or loadstring(ce)()
+	self._check_entities_store[ce] = self._check_entities[x + y * self.w]
+
 	-- Cache the map objects in the C map
 	self._map:setGrid(x, y, mm, mos)
 
@@ -562,10 +579,7 @@ end
 function _M:checkAllEntities(x, y, what, ...)
 	if x < 0 or x >= self.w or y < 0 or y >= self.h then return end
 	if self.map[x + y * self.w] then
-		for _, e in pairs(self.map[x + y * self.w]) do
-			local p = e:check(what, x, y, ...)
-			if p then return p end
-		end
+		return self._check_entities[x + y * self.w](self, x, y, what, ...)
 	end
 end
 
diff --git a/game/engine/interface/ActorFOV.lua b/game/engine/interface/ActorFOV.lua
index 5ff5f7f1167ef8941c3369a4ac398535b349ac24..d26bf033b005402d083c60a5af9d588bcedca734 100644
--- a/game/engine/interface/ActorFOV.lua
+++ b/game/engine/interface/ActorFOV.lua
@@ -80,14 +80,16 @@ function _M:computeFOV(radius, block, apply, force, no_store, cache)
 				local t = {x=x,y=y, dx=dx, dy=dy, sqdist=sqdist}
 				fov.actors[a] = t
 				fov.actors_dist[#fov.actors_dist+1] = a
+				a.__sqdist = sqdist
 				a:check("seen_by", self)
 				a:updateFOV(self, t.sqdist)
 			end
 		end, cache and game.level.map._fovcache[block])
 
 		-- Sort actors by distance (squared but we do not care)
-		table.sort(fov.actors_dist, function(a, b) return fov.actors[a].sqdist < fov.actors[b].sqdist end)
-		for i = 1, #fov.actors_dist do fov.actors_dist[i].i = i end
+		table.sort(fov.actors_dist, "__sqdist")
+--		table.sort(fov.actors_dist, function(a, b) return a.__sqdist < b.__sqdist end)
+--		for i = 1, #fov.actors_dist do fov.actors_dist[i].i = i end
 --		print("Computed FOV for", self.uid, self.name, ":: seen ", #fov.actors_dist, "actors closeby")
 
 		self.fov = fov
diff --git a/game/modules/tome/class/NPC.lua b/game/modules/tome/class/NPC.lua
index c87b1c97f639c41d719802f4c4859f80f961a4af..71a4cdc4dfe1c5e7bd17f24a223c608293473ae7 100644
--- a/game/modules/tome/class/NPC.lua
+++ b/game/modules/tome/class/NPC.lua
@@ -39,7 +39,12 @@ function _M:act()
 --	print("lite", self.name, self.lite)
 --		self:computeFOV(self.lite, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true)
 --	end
-	self:computeFOV(self.sight or 20)
+	-- If the actor has no special vision we can use the default cache
+	if not self.special_vision then
+		self:computeFOV(self.sight or 20, "block_sight", nil, nil, nil, true)
+	else
+		self:computeFOV(self.sight or 20, "block_sight")
+	end
 
 	-- Let the AI think .... beware of Shub !
 	-- If AI did nothing, use energy anyway
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index 4b21b744d486d12741e1abab2302d43209c63276..90daf0455dbb1c4a158a08defd30b840c0c8b0c3 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -182,22 +182,28 @@ function _M:act()
 	end
 end
 
+-- Precompute FOV form
+local fovdist = {}
+for i = 0, 30 * 30 do
+	fovdist[i] = math.max((20 - math.sqrt(i)) / 14, 0.6)
+end
+
 function _M:playerFOV()
 	-- Clean FOV before computing it
 	game.level.map:cleanFOV()
 	-- Compute ESP FOV, using cache
-	if not game.zone.wilderness then self:computeFOV(self.esp.range or 10, "block_esp", function(x, y) game.level.map:applyESP(x, y) end, true, true) end
+	if not game.zone.wilderness then self:computeFOV(self.esp.range or 10, "block_esp", function(x, y) game.level.map:applyESP(x, y) end, true, true, true) end
 
 	if not self:attr("blind") then
 		-- Compute both the normal and the lite FOV, using cache
 		if game.zone.wilderness_see_radius then
 			self:computeFOV(self.sight or 20, "block_sight", function(x, y, dx, dy, sqdist)
-				game.level.map:apply(x, y, math.max((20 - math.sqrt(sqdist)) / 14, 0.6))
+					game.level.map:apply(x, y, fovdist[sqdist])
 			end, true, false, true)
 			self:computeFOV(game.zone.wilderness_see_radius, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true, true)
 		else
 			self:computeFOV(self.sight or 20, "block_sight", function(x, y, dx, dy, sqdist)
-				game.level.map:apply(x, y, math.max((20 - math.sqrt(sqdist)) / 14, 0.6))
+				game.level.map:apply(x, y, fovdist[sqdist])
 			end, true, false, true)
 			if self.lite <= 0 then game.level.map:applyLite(self.x, self.y)
 			else self:computeFOV(self.lite, "block_sight", function(x, y, dx, dy, sqdist) game.level.map:applyLite(x, y) end, true, true, true) end
diff --git a/src/core_lua.c b/src/core_lua.c
index 0fbc691dd1f59debbe103371b7082468200d9cfc..1920d62686d51bfcdc70d94532b5fa8312fe9074 100644
--- a/src/core_lua.c
+++ b/src/core_lua.c
@@ -170,14 +170,14 @@ static int lua_fov_calc_circle(lua_State *L)
 	}
 	fov.apply_ref = luaL_ref(L, LUA_REGISTRYINDEX);
 	fov.opaque_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-//	int i= SDL_GetTicks();
+
 	fov_settings_init(&(fov.fov_settings));
 	fov_settings_set_opacity_test_function(&(fov.fov_settings), map_opaque);
 	fov_settings_set_apply_lighting_function(&(fov.fov_settings), map_seen);
 	fov_circle(&(fov.fov_settings), &fov, NULL, x, y, radius+1);
 	map_seen(&fov, x, y, 0, 0, radius, NULL);
 	fov_settings_free(&(fov.fov_settings));
-//	printf("map display ticks %d\n",SDL_GetTicks()-i);
+
 	luaL_unref(L, LUA_REGISTRYINDEX, fov.apply_ref);
 	luaL_unref(L, LUA_REGISTRYINDEX, fov.opaque_ref);
 	if (fov.cache_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, fov.cache_ref);
diff --git a/src/lua/ltablib.c b/src/lua/ltablib.c
index b6d9cb4ac74d7ada27bfa1d429114a16758d257a..61e88922dd04e83d4ee2fc78a97683d5ade2a346 100644
--- a/src/lua/ltablib.c
+++ b/src/lua/ltablib.c
@@ -169,6 +169,27 @@ static int tconcat (lua_State *L) {
 **  Addison-Wesley, 1993.)
 */
 
+static void stackDump (lua_State *L) {
+	int i=lua_gettop(L);
+	printf(" ----------------  Stack Dump ----------------\n" );
+	while(  i   ) {
+		int t = lua_type(L, i);
+		switch (t) {
+		case LUA_TSTRING:
+			printf("%d:`%s'\n", i, lua_tostring(L, i));
+			break;
+		case LUA_TBOOLEAN:
+			printf("%d: %s\n",i,lua_toboolean(L, i) ? "true" : "false");
+			break;
+		case LUA_TNUMBER:
+			printf("%d: %g\n",  i, lua_tonumber(L, i));
+			break;
+		default: printf("%d: %s\n", i, lua_typename(L, t)); break;
+		}
+		i--;
+	}
+	printf("--------------- Stack Dump Finished ---------------\n" );
+}
 
 static void set2 (lua_State *L, int i, int j) {
   lua_rawseti(L, 1, i);
@@ -176,7 +197,7 @@ static void set2 (lua_State *L, int i, int j) {
 }
 
 static int sort_comp (lua_State *L, int a, int b) {
-  if (!lua_isnil(L, 2)) {  /* function? */
+  if (lua_isfunction(L, 2)) {  /* function? */
     int res;
     lua_pushvalue(L, 2);
     lua_pushvalue(L, a-1);  /* -1 to compensate function */
@@ -186,6 +207,17 @@ static int sort_comp (lua_State *L, int a, int b) {
     lua_pop(L, 1);
     return res;
   }
+  else if (!lua_isnil(L, 2)) {  /* index? */
+    int res;
+    lua_pushvalue(L, 2);
+    lua_gettable(L, a-1);
+
+    lua_pushvalue(L, 2);
+    lua_gettable(L, b-2);
+    res = lua_lessthan(L, -2, -1);
+    lua_pop(L, 2);
+    return res;
+  }
   else  /* a < b? */
     return lua_lessthan(L, a, b);
 }
@@ -257,7 +289,9 @@ static int sort (lua_State *L) {
   int n = aux_getn(L, 1);
   luaL_checkstack(L, 40, "");  /* assume array is smaller than 2^40 */
   if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */
-    luaL_checktype(L, 2, LUA_TFUNCTION);
+  {
+//    if (luaL_checktype(L, 2, LUA_TFUNCTION);
+  }
   lua_settop(L, 2);  /* make sure there is two arguments */
   auxsort(L, 1, n);
   return 0;
diff --git a/src/luajit/ltablib.c b/src/luajit/ltablib.c
index b6d9cb4ac74d7ada27bfa1d429114a16758d257a..e6bdb90fa17e5575a157732b0a1a4bd251d16c40 100644
--- a/src/luajit/ltablib.c
+++ b/src/luajit/ltablib.c
@@ -176,7 +176,7 @@ static void set2 (lua_State *L, int i, int j) {
 }
 
 static int sort_comp (lua_State *L, int a, int b) {
-  if (!lua_isnil(L, 2)) {  /* function? */
+  if (lua_isfunction(L, 2)) {  /* function? */
     int res;
     lua_pushvalue(L, 2);
     lua_pushvalue(L, a-1);  /* -1 to compensate function */
@@ -186,6 +186,17 @@ static int sort_comp (lua_State *L, int a, int b) {
     lua_pop(L, 1);
     return res;
   }
+  else if (!lua_isnil(L, 2)) {  /* index? */
+    int res;
+    lua_pushvalue(L, 2);
+    lua_gettable(L, a-1);
+
+    lua_pushvalue(L, 2);
+    lua_gettable(L, b-2);
+    res = lua_lessthan(L, -2, -1);
+    lua_pop(L, 2);
+    return res;
+  }
   else  /* a < b? */
     return lua_lessthan(L, a, b);
 }
@@ -257,7 +268,9 @@ static int sort (lua_State *L) {
   int n = aux_getn(L, 1);
   luaL_checkstack(L, 40, "");  /* assume array is smaller than 2^40 */
   if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */
-    luaL_checktype(L, 2, LUA_TFUNCTION);
+  {
+//    if (luaL_checktype(L, 2, LUA_TFUNCTION);
+  }
   lua_settop(L, 2);  /* make sure there is two arguments */
   auxsort(L, 1, n);
   return 0;
diff --git a/src/luaprofiler/core_profiler.c b/src/luaprofiler/core_profiler.c
index 0f70fba106e5ec8380b395fd29896752710e9ae4..0e15072040d58890e8024cc2ef4b70d2a146b631 100644
--- a/src/luaprofiler/core_profiler.c
+++ b/src/luaprofiler/core_profiler.c
@@ -79,7 +79,7 @@ static void formats(char *s) {
 
 
 /* computes new stack and new timer */
-void lprofP_callhookIN(lprofP_STATE* S, char *func_name, char *file, int linedefined, int currentline) {	
+void lprofP_callhookIN(lprofP_STATE* S, char *func_name, char *file, int linedefined, int currentline) {
   S->stack_level++;
   lprofM_enter_function(S, file, func_name, linedefined, currentline);
 }
@@ -103,8 +103,8 @@ int lprofP_callhookOUT(lprofP_STATE* S) {
   info->total_time += function_call_time;
   formats(info->file_defined);
   formats(info->function_name);
-  output("%d\t%s\t%s\t%d\t%d\t%f\t%f\n", S->stack_level, info->file_defined,
-	 info->function_name, 
+  output("%d\t%s\t%s:%d:%s\t%d\t%d\t%f\t%f\n", S->stack_level, info->file_defined,
+	 info->function_name, info->line_defined, info->file_defined,
 	 info->line_defined, info->current_line,
 	 info->local_time, info->total_time);
   /* ... now it's ok to resume the timer */
@@ -128,7 +128,7 @@ lprofP_STATE* lprofP_init_core_profiler(const char *_out_filename, int isto_prin
 
   function_call_time = _function_call_time;
   out_filename = (_out_filename) ? (_out_filename):(OUT_FILENAME);
-        
+
   /* the random string to build the logname is extracted */
   /* from 'tmpnam()' (the '/tmp/' part is deleted)     */
   randstr = tmpnam(NULL);
@@ -155,7 +155,7 @@ lprofP_STATE* lprofP_init_core_profiler(const char *_out_filename, int isto_prin
     fclose(outf);
     return 0;
   }
-    
+
   return S;
 }
 
@@ -174,7 +174,7 @@ lprofP_STATE* lprofP_create_profiler(float _function_call_time) {
   if(!S) {
     return 0;
   }
-    
+
   return S;
 }
 
diff --git a/src/luaprofiler/lua50_profiler.c b/src/luaprofiler/lua50_profiler.c
index 54533425c3beaf18ccdca27bb7c48f9d2fa42655..0a0a3dde17b33a23e0f8cf7fac54484df9b44df3 100644
--- a/src/luaprofiler/lua50_profiler.c
+++ b/src/luaprofiler/lua50_profiler.c
@@ -42,7 +42,7 @@ static void callhook(lua_State *L, lua_Debug *ar) {
     lua_getinfo(L, "l", &previous_ar);
     currentline = previous_ar.currentline;
   }
-      
+
   lua_getinfo(L, "nS", ar);
 
   if (!ar->event) {
@@ -90,7 +90,7 @@ static int coroutine_create(lua_State *L) {
   lua_pushlightuserdata(L, S);
   lua_settable(L, LUA_REGISTRYINDEX);
   lua_sethook(NL, (lua_Hook)callhook, LUA_MASKCALL | LUA_MASKRET, 0);
-  return 1;	
+  return 1;
 }
 #endif
 
@@ -134,7 +134,7 @@ static int profiler_init(lua_State *L) {
   lua_pushlightuserdata(L, &profstate_id);
   lua_pushlightuserdata(L, S);
   lua_settable(L, LUA_REGISTRYINDEX);
-	
+
   /* use our own exit function instead */
   lua_getglobal(L, "os");
   lua_pushlightuserdata(L, &exit_id);
@@ -158,7 +158,7 @@ static int profiler_init(lua_State *L) {
   /* as a library.                                                     */
 
   lprofP_callhookIN(S, "profiler_init", "(C)", -1, -1);
-	
+
   lua_pushboolean(L, 1);
   return 1;
 }