diff --git a/game/engine/Map.lua b/game/engine/Map.lua
index 656af802a555e73132259b0c6143f23ca7b8b095..5469568d4f1ca5b18d713c8298108aab17b17ea6 100644
--- a/game/engine/Map.lua
+++ b/game/engine/Map.lua
@@ -17,7 +17,7 @@ OBJECT = 1000
 --- The order of display for grid seen
 displayOrder = { ACTOR, OBJECT, TERRAIN }
 --- The order of display for grids remembered
-rememberDisplayOrder = { ACTOR, TERRAIN }
+rememberDisplayOrder = { TERRAIN }
 
 --- Sets the viewport size
 -- Static
@@ -33,6 +33,7 @@ function _M:setViewPort(x, y, w, h, tile_w, tile_h, fontname, fontsize)
 	self.display_x, self.display_y = x, y
 	self.viewport = {width=w, height=h, mwidth=math.floor(w/tile_w), mheight=math.floor(h/tile_h)}
 	self.tiles = Tiles.new(tile_w, tile_h, fontname, fontsize, true)
+	self.tilesSurface = Tiles.new(tile_w, tile_h, fontname, fontsize, false)
 	self.tile_w, self.tile_h = tile_w, tile_h
 end
 
@@ -57,7 +58,6 @@ function _M:init(w, h)
 	self.seens = {}
 	self.remembers = {}
 	self.effects = {}
-	self._map = core.map.newMap(w, h, self.mx, self.my, self.viewport.mwidth, self.viewport.mheight)
 	for i = 0, w * h - 1 do self.map[i] = {} end
 
 	self:loaded()
@@ -73,26 +73,43 @@ function _M:save()
 	})
 end
 function _M:loaded()
-	local mapbool = function(t, x, y, v)
+	self._map = core.map.newMap(self.w, self.h, self.mx, self.my, self.viewport.mwidth, self.viewport.mheight)
+
+	local mapseen = function(t, x, y, v)
 		if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
 		if v ~= nil then
 			t[x + y * self.w] = v
-			self:updateMap(x, y)
+			self._map:setSeen(x, y, v)
+		end
+		return t[x + y * self.w]
+	end
+	local mapremember = function(t, x, y, v)
+		if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
+		if v ~= nil then
+			t[x + y * self.w] = v
+			self._map:setRemember(x, y, v)
+		end
+		return t[x + y * self.w]
+	end
+	local maplite = function(t, x, y, v)
+		if x < 0 or y < 0 or x >= self.w or y >= self.h then return end
+		if v ~= nil then
+			t[x + y * self.w] = v
+			self._map:setLite(x, y, v)
 		end
 		return t[x + y * self.w]
 	end
 
 	getmetatable(self).__call = _M.call
-	setmetatable(self.lites, {__call = mapbool})
-	setmetatable(self.seens, {__call = mapbool})
-	setmetatable(self.remembers, {__call = mapbool})
+	setmetatable(self.lites, {__call = maplite})
+	setmetatable(self.seens, {__call = mapseen})
+	setmetatable(self.remembers, {__call = mapremember})
 
 	self.surface = core.display.newSurface(self.viewport.width, self.viewport.height)
 	self._fov = core.fov.new(_M.opaque, _M.apply, self)
 	self._fov_lite = core.fov.new(_M.opaque, _M.applyLite, self)
 	self.changed = true
 
-	self._map = core.map.newMap(self.w, self.h, self.mx, self.my, self.viewport.mwidth, self.viewport.mheight)
 	for i = 0, self.w - 1 do for j = 0, self.h - 1 do
 		self:updateMap(i, j)
 	end end
@@ -115,12 +132,8 @@ function _M:fov(x, y, d)
 	-- Reset seen grids
 	if self.clean_fov then
 		self.clean_fov = false
-		for i = 0, self.w - 1 do for j = 0, self.h - 1 do
-			t[i + j * self.w] = nil
-			self:updateMap(i, j)
---			self.seens(i, j, false)
-		end end
---		for i = 0, self.w * self.h - 1 do self.seens[i] = nil end
+		for i = 0, self.w * self.h - 1 do self.seens[i] = nil end
+		self._map:cleanSeen();
 	end
 	self._fov(x, y, d)
 end
@@ -133,32 +146,22 @@ function _M:fovLite(x, y, d)
 	-- Reset seen grids
 	if self.clean_fov then
 		self.clean_fov = false
-		for i = 0, self.w - 1 do for j = 0, self.h - 1 do
-			t[i + j * self.w] = nil
-			self:updateMap(i, j)
---			self.seens(i, j, false)
-		end end
---		for i = 0, self.w * self.h - 1 do self.seens[i] = nil end
-		self._fov_lite(x, y, d)
+		for i = 0, self.w * self.h - 1 do self.seens[i] = nil end
+		self._map:cleanSeen();
 	end
+	self._fov_lite(x, y, d)
 end
 
 function _M:updateMap(x, y)
-	local order = displayOrder
-	local e, si = nil, 1
-	local z = x + y * self.w
-
-	if self.seens[z] or self.remembers[z] then
-		if not self.seens[z] then order = rememberDisplayOrder end
-		while not e and si <= #order do e = self(x, y, order[si]) si = si + 1 end
-		if e then
-			if self.seens[z] then
-				self._map:setGrid(x, y, self.tiles:get(e.display, e.color_r, e.color_g, e.color_b, e.color_br, e.color_bg, e.color_bb, e.image), 255)
-			elseif self.remembers[z] then
-				self._map:setGrid(x, y, self.tiles:get(e.display, e.color_r, e.color_g, e.color_b, e.color_br, e.color_bg, e.color_bb, e.image), 85)
-			end
-		end
-	end
+	local g = self(x, y, TERRAIN)
+	local o = self(x, y, OBJECT)
+	local a = self(x, y, ACTOR)
+
+	if g then g = self.tiles:get(g.display, g.color_r, g.color_g, g.color_b, g.color_br, g.color_bg, g.color_bb, g.image) end
+	if o then o = self.tiles:get(o.display, o.color_r, o.color_g, o.color_b, o.color_br, o.color_bg, o.color_bb, o.image) end
+	if a then a = self.tiles:get(a.display, a.color_r, a.color_g, a.color_b, a.color_br, a.color_bg, a.color_bb, a.image) end
+
+	self._map:setGrid(x, y, g, o, a)
 end
 
 --- Sets/gets a value from the map
@@ -200,80 +203,41 @@ end
 --- Displays the map on a surface
 -- @return a surface containing the drawn map
 function _M:display()
-	do
 	self._map:toScreen(self.display_x, self.display_y)
-	self.changed = false
-	return
-	end
 
-	-- If nothing changed, return the same surface as before
---	if not self.changed then return self.surface end
-	self.changed = false
-	self.clean_fov = true
-
-	-- Erase and the display the map
---	self.surface:erase()
-	if not self.multi_display then
-		-- Version without multi display
-		local e, si
+	-- Tactical display
+	if self.view_faction then
+		local e
 		local z
-		local order
 		local friend
 		for i = self.mx, self.mx + self.viewport.mwidth - 1 do
 		for j = self.my, self.my + self.viewport.mheight - 1 do
-			e, si = nil, 1
-			z = i + j * self.w
-			order = displayOrder
-			if self.seens[z] or self.remembers[z] then
-				if not self.seens[z] then order = rememberDisplayOrder end
-				while not e and si <= #order do e = self(i, j, order[si]) si = si + 1 end
+			local z = i + j * self.w
+			if self.seens[z] then
+				e = self(i, j, ACTOR)
 				if e then
-					if self.seens[z] then
-						self.tiles:get(e.display, e.color_r, e.color_g, e.color_b, e.color_br, e.color_bg, e.color_bb, e.image):toScreen((i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
-					elseif self.remembers[z] then
-						self.tiles:get(e.display, e.color_r/3, e.color_g/3, e.color_b/3, e.color_br/3, e.color_bg/3, e.color_bb/3, e.image):toScreen((i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
-					end
 					-- Tactical overlay ?
-					if self.view_faction and e.faction then
+					if e.faction then
 						friend = Faction:factionReaction(self.view_faction, e.faction)
 						if friend > 0 then
-							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_friend), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
+							self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_friend):toScreen(self.display_x + (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
 						elseif friend < 0 then
-							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_enemy), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
+							self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_enemy):toScreen(self.display_x + (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
 						else
-							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_neutral), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
+							self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_neutral):toScreen(self.display_x + (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
 						end
 					end
 				end
 			end
 		end end
-	else
-		-- Version with multi display
---[[
-		local z, e, si = nil, nil, 1
-		for i = 0, self.w - 1 do for j = 0, self.h - 1 do
-			z = i + j * self.w
-			z, e, si = 0, nil, #displayOrder
-			while si >= 1 do
-				e = self(i, j, displayOrder[si])
-				if e then
-					if self.seens[z] then
-					self.surface:merge(self.tiles:get(e.display, e.color_r, e.color_g, e.color_b, e.color_br, e.color_bg, e.color_bb), i * 16, j * 16)
-				elseif self.remembers[z] then
-					self.surface:merge(self.tiles:get(e.display, e.color_r/3, e.color_g/3, e.color_b/3, e.color_br/3, e.color_bg/3, e.color_bb/3), i * 16, j * 16)
-					end
-				end
-
-				si = si - 1
-			end
-			self.seens[z] = nil
-		end end
-]]
 	end
 
 	self:displayEffects()
 
-	return self.surface
+	-- If nothing changed, return the same surface as before
+	if not self.changed then return end
+	self.changed = false
+	self.clean_fov = true
 end
 
 --- Sets checks if a grid lets sigth pass through
@@ -291,7 +255,8 @@ function _M:apply(x, y)
 	if self.lites[x + y * self.w] then
 		self.seens[x + y * self.w] = true
 		self.remembers[x + y * self.w] = true
-		self:updateMap(x, y)
+		self._map:setSeen(x, y, true)
+		self._map:setRemember(x, y, true)
 	end
 end
 
@@ -302,7 +267,9 @@ function _M:applyLite(x, y)
 	self.lites[x + y * self.w] = true
 	self.seens[x + y * self.w] = true
 	self.remembers[x + y * self.w] = true
-	self:updateMap(x, y)
+	self._map:setSeen(x, y, true)
+	self._map:setRemember(x, y, true)
+	self._map:setLite(x, y, true)
 end
 
 --- Check all entities of the grid for a property
@@ -423,8 +390,7 @@ function _M:displayEffects()
 		-- Dont bother with obviously out of screen stuff
 		if e.x + e.radius >= self.mx and e.x - e.radius < self.mx + self.viewport.mwidth and e.y + e.radius >= self.my and e.y - e.radius < self.my + self.viewport.mheight then
 			local grids
-			local s = self.tiles:get(e.overlay.display, e.overlay.color_r, e.overlay.color_g, e.overlay.color_b, e.overlay.color_br, e.overlay.color_bg, e.overlay.color_bb, e.overlay.image)
-			s:alpha(e.alpha or 150)
+			local s = self.tilesSurface:get(e.overlay.display, e.overlay.color_r, e.overlay.color_g, e.overlay.color_b, e.overlay.color_br, e.overlay.color_bg, e.overlay.color_bb, e.overlay.image, 120)
 
 			-- Handle balls
 			if e.dir == 5 then
@@ -438,7 +404,7 @@ function _M:displayEffects()
 			for lx, ys in pairs(grids) do
 				for ly, _ in pairs(ys) do
 					if self.seens(lx, ly) then
-						self.surface:merge(s, (lx - self.mx) * self.tile_w, (ly - self.my) * self.tile_h)
+						s:toScreen(self.display_x + (lx - self.mx) * self.tile_w, self.display_y + (ly - self.my) * self.tile_h)
 					end
 				end
 			end
diff --git a/game/engine/Target.lua b/game/engine/Target.lua
index e44e49c6a738b513009316037a94f23b3a24b5d2..c57fc87cd98c1d63c6f683fed833988411d55e0f 100644
--- a/game/engine/Target.lua
+++ b/game/engine/Target.lua
@@ -14,14 +14,11 @@ function _M:init(map, source_actor)
 	self.cursor = core.display.loadImage(engine.Tiles.prefix.."target_cursor.png")
 
 	self.sr = core.display.newSurface(map.tile_w, map.tile_h)
-	self.sr:alpha(90)
-	self.sr:erase(255, 0, 0)
+	self.sr:erase(255, 0, 0, 90)
 	self.sb = core.display.newSurface(map.tile_w, map.tile_h)
-	self.sb:alpha(90)
-	self.sb:erase(0, 0, 255)
+	self.sb:erase(0, 0, 255, 90)
 	self.sg = core.display.newSurface(map.tile_w, map.tile_h)
-	self.sg:alpha(90)
-	self.sg:erase(0, 255, 0)
+	self.sg:erase(0, 255, 0, 90)
 
 	self.source_actor = source_actor
 
diff --git a/game/engine/Tiles.lua b/game/engine/Tiles.lua
index 68bff87f9fa729293267f987735148cd3e56c520..8cab4c7897eef2ef3f0cde07d2e7e97ca6e54f46 100644
--- a/game/engine/Tiles.lua
+++ b/game/engine/Tiles.lua
@@ -14,7 +14,8 @@ function _M:init(w, h, fontname, fontsize, texture)
 	self.repo = {}
 end
 
-function _M:get(char, fr, fg, fb, br, bg, bb, image)
+function _M:get(char, fr, fg, fb, br, bg, bb, image, alpha)
+	alpha = alpha or 255
 	local fgidx = 65536 * fr + 256 * fg + fb
 	local bgidx
 	if br >= 0 and bg >= 0 and bb >= 0 then
@@ -35,7 +36,9 @@ function _M:get(char, fr, fg, fb, br, bg, bb, image)
 			s = core.display.newSurface(self.w, self.h)
 
 			if br >= 0 then
-				s:erase(br, bg, bb)
+				s:erase(br, bg, bb, alpha)
+			else
+				s:erase(0, 0, 0, alpha)
 			end
 
 			local w, h = self.font:size(char)
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 419e71094e1ff4d6d223ff5ddc7ad2fc2aee3ad0..00a7049e60da3cdccdb96dbb02cdf0d6cff78bca 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -144,18 +144,6 @@ function _M:onTurn()
 end
 
 function _M:display()
---[[
-	if self.level and self.level.map then
-		-- Display the map and compute FOV for the player if needed
---		if self.level.map.changed then
---			self.level.map:fov(self.player.x, self.player.y, 20)
---			self.level.map:fovLite(self.player.x, self.player.y, 4)
---		end
-		self.level.map:display()
-		--:toScreen(self.level.map.display_x, self.level.map.display_y)
-	end
--- ]]
--- [[
 	self.log:display():toScreen(self.log.display_x, self.log.display_y)
 	self.player_display:display():toScreen(self.player_display.display_x, self.player_display.display_y)
 	self.talents_display:display():toScreen(self.talents_display.display_x, self.talents_display.display_y)
@@ -167,7 +155,6 @@ function _M:display()
 			self.level.map:fovLite(self.player.x, self.player.y, 4)
 		end
 		self.level.map:display()
---		:toScreen(self.level.map.display_x, self.level.map.display_y)
 
 		-- Display the targetting system if active
 		self.target:display()
@@ -176,7 +163,7 @@ function _M:display()
 		local mx, my = core.mouse.get()
 		local tmx, tmy = self.level.map:getMouseTile(mx, my)
 		local tt = self.level.map:checkAllEntities(tmx, tmy, "tooltip")
-		if tt and self.level.map.seens(tmx, tmy) then
+		if tt then
 			self.tooltip:set(tt)
 			local t = self.tooltip:display()
 			mx = mx - self.tooltip.w
diff --git a/game/modules/tome/class/Grid.lua b/game/modules/tome/class/Grid.lua
index cc516c639401280018453647860b2b279769ebb5..8c9a2029e091b230bdefaf45df4dc66ee9394811 100644
--- a/game/modules/tome/class/Grid.lua
+++ b/game/modules/tome/class/Grid.lua
@@ -15,9 +15,3 @@ function _M:block_move(x, y, e)
 	end
 	return false
 end
-
-function _M:tooltip()
-	local mx, my = core.mouse.get()
-	local tmx, tmy = game.level.map:getMouseTile(mx, my)
-	return ("%d:%d\nSeen %s\nRemember %s\nLite %s"):format(tmx,tmy,tostring(game.level.map.seens(tmx, tmy)), tostring(game.level.map.remembers(tmx, tmy)), tostring(game.level.map.lites(tmx, tmy)))
-end
diff --git a/game/modules/tome/data/zones/ancient_ruins/grids.lua b/game/modules/tome/data/zones/ancient_ruins/grids.lua
index e553fbe6062e771a627cb877edacde083d0aefe8..27e1303b2a96004b8f510e020ac7fae34d8722f0 100644
--- a/game/modules/tome/data/zones/ancient_ruins/grids.lua
+++ b/game/modules/tome/data/zones/ancient_ruins/grids.lua
@@ -16,6 +16,7 @@ newEntity{
 	define_as = "FLOOR",
 	name = "floor",
 	display = '.', color_r=255, color_g=255, color_b=255,
+--	color_br=55, color_bg=125, color_bb=5,
 }
 
 newEntity{
diff --git a/src/core_lua.c b/src/core_lua.c
index 9fc5b47ee67eb879a3cf8aa7fdbdb4e1d05784a6..90166aaebc9a02f96d15d4ea2592b880306b2389 100644
--- a/src/core_lua.c
+++ b/src/core_lua.c
@@ -573,7 +573,7 @@ static int sdl_surface_alpha(lua_State *L)
 {
 	SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1);
 	int a = luaL_checknumber(L, 2);
-//	SDL_SetAlpha(*s, SDL_SRCALPHA | SDL_RLEACCEL, (a < 0) ? 0 : (a > 255) ? 255 : a);
+	SDL_SetAlpha(*s, SDL_SRCALPHA | SDL_RLEACCEL, (a < 0) ? 0 : (a > 255) ? 255 : a);
 	return 0;
 }
 
diff --git a/src/map.c b/src/map.c
index 93c2bb98714fd0de3200e9a38ea28f5aa08eab3e..a8e6289ac7b6048a91cad56ee0968384ec796287 100644
--- a/src/map.c
+++ b/src/map.c
@@ -20,24 +20,36 @@ static int map_new(lua_State *L)
 	map_type *map = (map_type*)lua_newuserdata(L, sizeof(map_type));
 	auxiliar_setclass(L, "core{map}", -1);
 
+	map->multidisplay = FALSE;
 	map->w = w;
 	map->h = h;
 	map->mx = mx;
 	map->my = my;
 	map->mwidth = mwidth;
 	map->mheight = mheight;
-	map->grids = calloc(w, sizeof(GLuint*));
+	map->grids_terrain = calloc(w, sizeof(GLuint*));
+	map->grids_actor = calloc(w, sizeof(GLuint*));
+	map->grids_object = calloc(w, sizeof(GLuint*));
+	map->grids_seens = calloc(w, sizeof(bool*));
+	map->grids_remembers = calloc(w, sizeof(bool*));
+	map->grids_lites = calloc(w, sizeof(bool*));
 	printf("size %d:%d :: %d\n", mwidth, mheight,mwidth * mheight);
 
 	int i;
 	for (i = 0; i < w; i++)
 	{
-		map->grids[i] = calloc(h, sizeof(GLuint));
+		map->grids_terrain[i] = calloc(h, sizeof(GLuint));
+		map->grids_actor[i] = calloc(h, sizeof(GLuint));
+		map->grids_object[i] = calloc(h, sizeof(GLuint));
+		map->grids_seens[i] = calloc(h, sizeof(bool));
+		map->grids_remembers[i] = calloc(h, sizeof(bool));
+		map->grids_lites[i] = calloc(h, sizeof(bool));
 	}
 
-	map->dlist = glGenLists(1);
 
 	/* New compiled box display list */
+	/*
+	map->dlist = glGenLists(1);
 	glNewList(map->dlist, GL_COMPILE);
 		glBegin(GL_QUADS);
 		glTexCoord2f(0,0); glVertex2f(0  , 0  );
@@ -45,7 +57,8 @@ static int map_new(lua_State *L)
 		glTexCoord2f(1,1); glVertex2f(16 , 16 );
 		glTexCoord2f(1,0); glVertex2f(16 , 0  );
 		glEnd();
-	glEndList( );
+	glEndList();
+	*/
 
 	return 1;
 }
@@ -57,9 +70,19 @@ static int map_free(lua_State *L)
 
 	for (i = 0; i < map->w; i++)
 	{
-		free(map->grids[i]);
+		free(map->grids_terrain[i]);
+		free(map->grids_actor[i]);
+		free(map->grids_object[i]);
+		free(map->grids_seens[i]);
+		free(map->grids_remembers[i]);
+		free(map->grids_lites[i]);
 	}
-	free(map->grids);
+	free(map->grids_terrain);
+	free(map->grids_actor);
+	free(map->grids_object);
+	free(map->grids_seens);
+	free(map->grids_remembers);
+	free(map->grids_lites);
 
 	lua_pushnumber(L, 1);
 	return 1;
@@ -70,9 +93,79 @@ static int map_set_grid(lua_State *L)
 	map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
 	int x = luaL_checknumber(L, 2);
 	int y = luaL_checknumber(L, 3);
-	GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 4);
+	GLuint *t = lua_isnil(L, 4) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 4);
+	GLuint *a = lua_isnil(L, 5) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 5);
+	GLuint *o = lua_isnil(L, 6) ? NULL : (GLuint*)auxiliar_checkclass(L, "gl{texture}", 6);
+
+	map->grids_terrain[x][y] = t ? *t : 0;
+	map->grids_actor[x][y] = a ? *a : 0;
+	map->grids_object[x][y] = o ? *o : 0;
+}
+
+static int map_set_seen(lua_State *L)
+{
+	map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
+	int x = luaL_checknumber(L, 2);
+	int y = luaL_checknumber(L, 3);
+	bool v = lua_toboolean(L, 4);
+
+	map->grids_seens[x][y] = v;
+	return 0;
+}
+
+static int map_set_remember(lua_State *L)
+{
+	map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
+	int x = luaL_checknumber(L, 2);
+	int y = luaL_checknumber(L, 3);
+	bool v = lua_toboolean(L, 4);
 
-	map->grids[x][y] = *t;
+	map->grids_remembers[x][y] = v;
+	return 0;
+}
+
+static int map_set_lite(lua_State *L)
+{
+	map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
+	int x = luaL_checknumber(L, 2);
+	int y = luaL_checknumber(L, 3);
+	bool v = lua_toboolean(L, 4);
+
+	map->grids_lites[x][y] = v;
+	return 0;
+}
+
+static int map_clean_seen(lua_State *L)
+{
+	map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
+	int i, j;
+
+	for (i = 0; i < map->w; i++)
+		for (j = 0; j < map->h; j++)
+			map->grids_seens[i][j] = FALSE;
+	return 0;
+}
+
+static int map_clean_remember(lua_State *L)
+{
+	map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
+	int i, j;
+
+	for (i = 0; i < map->w; i++)
+		for (j = 0; j < map->h; j++)
+			map->grids_remembers[i][j] = FALSE;
+	return 0;
+}
+
+static int map_clean_lite(lua_State *L)
+{
+	map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
+	int i, j;
+
+	for (i = 0; i < map->w; i++)
+		for (j = 0; j < map->h; j++)
+			map->grids_lites[i][j] = FALSE;
+	return 0;
 }
 
 static int map_set_scroll(lua_State *L)
@@ -83,6 +176,7 @@ static int map_set_scroll(lua_State *L)
 
 	map->mx = x;
 	map->my = y;
+	return 0;
 }
 
 static int map_to_screen(lua_State *L)
@@ -96,20 +190,105 @@ static int map_to_screen(lua_State *L)
 	{
 		for (j = map->my; j < map->my + map->mheight; j++)
 		{
-			if ((i >= map->w) || (j >= map->h) || (!map->grids[i][j])) continue;
+			if ((i >= map->w) || (j >= map->h)) continue;
 
 			int dx = x + (i - map->mx) * 16;
 			int dy = y + (j - map->my) * 16;
 
-			glBindTexture(GL_TEXTURE_2D, map->grids[i][j]);
-			glBegin(GL_QUADS);
-			glTexCoord2f(0,0); glVertex3f(0  +dx, 0  +dy,-99);
-			glTexCoord2f(1,0); glVertex3f(16 +dx, 0  +dy,-99);
-			glTexCoord2f(1,1); glVertex3f(16 +dx, 16 +dy,-99);
-			glTexCoord2f(0,1); glVertex3f(0  +dx, 16 +dy,-99);
-			glEnd();
+			if (map->grids_seens[i][j] || map->grids_remembers[i][j])
+			{
+				if (map->grids_seens[i][j])
+				{
+					glColor4f(1, 1, 1, 1);
+
+					if (map->multidisplay)
+					{
+						if (map->grids_terrain[i][j])
+						{
+							glBindTexture(GL_TEXTURE_2D, map->grids_terrain[i][j]);
+							glBegin(GL_QUADS);
+							glTexCoord2f(0,0); glVertex3f(0  +dx, 0  +dy,-99);
+							glTexCoord2f(1,0); glVertex3f(16 +dx, 0  +dy,-99);
+							glTexCoord2f(1,1); glVertex3f(16 +dx, 16 +dy,-99);
+							glTexCoord2f(0,1); glVertex3f(0  +dx, 16 +dy,-99);
+							glEnd();
+						}
+						if (map->grids_object[i][j])
+						{
+							glBindTexture(GL_TEXTURE_2D, map->grids_object[i][j]);
+							glBegin(GL_QUADS);
+							glTexCoord2f(0,0); glVertex3f(0  +dx, 0  +dy,-99);
+							glTexCoord2f(1,0); glVertex3f(16 +dx, 0  +dy,-99);
+							glTexCoord2f(1,1); glVertex3f(16 +dx, 16 +dy,-99);
+							glTexCoord2f(0,1); glVertex3f(0  +dx, 16 +dy,-99);
+							glEnd();
+						}
+						if (map->grids_actor[i][j])
+						{
+							glBindTexture(GL_TEXTURE_2D, map->grids_actor[i][j]);
+							glBegin(GL_QUADS);
+							glTexCoord2f(0,0); glVertex3f(0  +dx, 0  +dy,-99);
+							glTexCoord2f(1,0); glVertex3f(16 +dx, 0  +dy,-99);
+							glTexCoord2f(1,1); glVertex3f(16 +dx, 16 +dy,-99);
+							glTexCoord2f(0,1); glVertex3f(0  +dx, 16 +dy,-99);
+							glEnd();
+						}
+					}
+					else
+					{
+						if (map->grids_actor[i][j])
+						{
+							glBindTexture(GL_TEXTURE_2D, map->grids_actor[i][j]);
+							glBegin(GL_QUADS);
+							glTexCoord2f(0,0); glVertex3f(0  +dx, 0  +dy,-99);
+							glTexCoord2f(1,0); glVertex3f(16 +dx, 0  +dy,-99);
+							glTexCoord2f(1,1); glVertex3f(16 +dx, 16 +dy,-99);
+							glTexCoord2f(0,1); glVertex3f(0  +dx, 16 +dy,-99);
+							glEnd();
+						}
+						else if (map->grids_object[i][j])
+						{
+							glBindTexture(GL_TEXTURE_2D, map->grids_object[i][j]);
+							glBegin(GL_QUADS);
+							glTexCoord2f(0,0); glVertex3f(0  +dx, 0  +dy,-99);
+							glTexCoord2f(1,0); glVertex3f(16 +dx, 0  +dy,-99);
+							glTexCoord2f(1,1); glVertex3f(16 +dx, 16 +dy,-99);
+							glTexCoord2f(0,1); glVertex3f(0  +dx, 16 +dy,-99);
+							glEnd();
+						}
+						else if (map->grids_terrain[i][j])
+						{
+							glBindTexture(GL_TEXTURE_2D, map->grids_terrain[i][j]);
+							glBegin(GL_QUADS);
+							glTexCoord2f(0,0); glVertex3f(0  +dx, 0  +dy,-99);
+							glTexCoord2f(1,0); glVertex3f(16 +dx, 0  +dy,-99);
+							glTexCoord2f(1,1); glVertex3f(16 +dx, 16 +dy,-99);
+							glTexCoord2f(0,1); glVertex3f(0  +dx, 16 +dy,-99);
+							glEnd();
+						}
+					}
+				}
+				else
+				{
+					glColor4f(1, 1, 1, 0.3f);
+					if (map->grids_terrain[i][j])
+					{
+						glBindTexture(GL_TEXTURE_2D, map->grids_terrain[i][j]);
+						glBegin(GL_QUADS);
+						glTexCoord2f(0,0); glVertex3f(0  +dx, 0  +dy,-99);
+						glTexCoord2f(1,0); glVertex3f(16 +dx, 0  +dy,-99);
+						glTexCoord2f(1,1); glVertex3f(16 +dx, 16 +dy,-99);
+						glTexCoord2f(0,1); glVertex3f(0  +dx, 16 +dy,-99);
+						glEnd();
+					}
+				}
+			}
 		}
 	}
+
+	// Restore normal display
+	glColor4f(1, 1, 1, 1);
+	return 0;
 }
 
 static const struct luaL_reg maplib[] =
@@ -123,6 +302,12 @@ static const struct luaL_reg map_reg[] =
 	{"__gc", map_free},
 	{"close", map_free},
 	{"setGrid", map_set_grid},
+	{"cleanSeen", map_clean_seen},
+	{"cleanRemember", map_clean_remember},
+	{"cleanLite", map_clean_lite},
+	{"setSeen", map_set_seen},
+	{"setRemember", map_set_remember},
+	{"setLite", map_set_lite},
 	{"setScroll", map_set_scroll},
 	{"toScreen", map_to_screen},
 	{NULL, NULL},
diff --git a/src/map.h b/src/map.h
index 6f319d08f98b08630af01a3d614ff285c28e83f1..c056ea951aac0383e6bd7145331ebe909a51ecb5 100644
--- a/src/map.h
+++ b/src/map.h
@@ -4,9 +4,14 @@
 #include <GL/gl.h>
 
 typedef struct {
-	GLuint **grids;
+	GLuint **grids_terrain;
+	GLuint **grids_actor;
+	GLuint **grids_object;
+	bool **grids_seens;
+	bool **grids_remembers;
+	bool **grids_lites;
 
-	GLuint dlist;
+	bool multidisplay;
 
 	// Map size
 	int w;