-# TODO: instead of sending tasks and thing types on request, send them on connection
+# TODO: instead of sending tasks, thing types etc. on request, send them on connection
 
 def cmd_TASKS(game, connection_id):
     tasks = []
 
 def cmd_THING_TYPES(game, connection_id):
     for t_t in game.thing_types.values():
-        game.io.send('THING_TYPE %s %s' % (t_t.get_type(), t_t.symbol_hint),
+        game.io.send('THING_TYPE %s %s' % (t_t.get_type(), quote(t_t.symbol_hint)),
                      connection_id)
 cmd_THING_TYPES.argtypes = ''
 
+def cmd_TERRAINS(game, connection_id):
+    for t in game.terrains.keys():
+        game.io.send('TERRAIN %s %s' % (quote(t), quote(game.terrains[t])),
+                     connection_id)
+cmd_TERRAINS.argtypes = ''
+
 def cmd_ALL(game, msg, connection_id):
 
     def lower_msg_by_volume(msg, volume):
 
         self.portals = {}
         self.player_chars = string.digits + string.ascii_letters
         self.player_char_i = -1
+        self.terrains = {
+            'X': 'wall',
+            'O': 'toilet'
+        }
         if os.path.exists(self.io.save_file):
             if not os.path.isfile(self.io.save_file):
                 raise GameError('save file path refers to non-file')
 
                                 cmd_ANNOTATE, cmd_PORTAL, cmd_GET_GAMESTATE,
                                 cmd_TASKS, cmd_MAP_CONTROL_LINE, cmd_MAP_CONTROL_PW,
                                 cmd_GOD_ANNOTATE, cmd_GOD_PORTAL, cmd_THING_TYPES,
-                                cmd_THING_NAME)
+                                cmd_THING_NAME, cmd_TERRAINS)
 from plomrogue.tasks import (Task_WAIT, Task_MOVE, Task_WRITE, Task_PICK_UP,
                              Task_DROP, Task_FLATTEN_SURROUNDINGS)
 from plomrogue.things import Thing_Player, Thing_Stone
 game.register_command(cmd_GET_GAMESTATE)
 game.register_command(cmd_TASKS)
 game.register_command(cmd_THING_TYPES)
+game.register_command(cmd_TERRAINS)
 game.register_command(cmd_THING)
 game.register_command(cmd_THING_NAME)
 game.register_task(Task_WAIT)
 
     game.thing_types[thing_type] = symbol_hint
 cmd_THING_TYPE.argtypes = 'string char'
 
+def cmd_TERRAIN(game, terrain_char, terrain_desc):
+    game.terrains[terrain_char] = terrain_desc
+cmd_TERRAIN.argtypes = 'char string'
+
 def cmd_PONG(game):
     pass
 cmd_PONG.argtypes = ''
         self.register_command(cmd_THING_TYPE)
         self.register_command(cmd_THING_NAME)
         self.register_command(cmd_THING_CHAR)
+        self.register_command(cmd_TERRAIN)
         self.register_command(cmd_MAP)
         self.register_command(cmd_MAP_CONTROL)
         self.register_command(cmd_PORTAL)
         self.player_id = -1
         self.info_db = {}
         self.portals = {}
+        self.terrains = {}
 
     def get_string_options(self, string_option_type):
         if string_option_type == 'map_geometry':
             self.socket_thread.start()
             self.disconnected = False
             self.game.thing_types = {}
+            self.game.terrains = {}
             self.socket.send('TASKS')
+            self.socket.send('TERRAINS')
             self.socket.send('THING_TYPES')
             self.switch_mode('login')
         except ConnectionRefusedError:
             pos_i = self.explorer.y * self.game.map_geometry.size.x + self.explorer.x
             info = 'outside field of view'
             if self.game.fov[pos_i] == '.':
-                info = 'TERRAIN: %s\n' % self.game.map_content[pos_i]
+                terrain_char = self.game.map_content[pos_i]
+                terrain_desc = '?'
+                if terrain_char in self.game.terrains:
+                    terrain_desc = self.game.terrains[terrain_char]
+                info = 'TERRAIN: "%s" / %s\n' % (terrain_char, terrain_desc)
                 for t in self.game.things:
                     if t.position == self.explorer:
                         info += 'THING: %s / %s' % (t.type_,
 
         this.websocket.onopen = function(event) {
             server.connected = true;
             game.thing_types = {};
+            game.terrains = {};
             server.send(['TASKS']);
+            server.send(['TERRAINS']);
             server.send(['THING_TYPES']);
             tui.log_msg("@ server connected! :)");
             tui.switch_mode(mode_login);
             game.tasks = tokens[1].split(',')
         } else if (tokens[0] === 'THING_TYPE') {
             game.thing_types[tokens[1]] = tokens[2]
+        } else if (tokens[0] === 'TERRAIN') {
+            game.terrains[tokens[1]] = tokens[2]
         } else if (tokens[0] === 'MAP') {
             game.map_geometry = tokens[1];
             tui.init_keys();
             return 'outside field of view';
         };
         let info = "";
-        info += "TERRAIN: " + game.map[position_i] + "\n";
+        let terrain_char = game.map[position_i]
+        let terrain_desc = '?'
+        if (game.terrains[terrain_char]) {
+            terrain_desc = game.terrains[terrain_char];
+        };
+        info += 'TERRAIN: "' + terrain_char + '" / ' + terrain_desc + "\n";
         for (let t_id in game.things) {
              let t = game.things[t_id];
              if (t.position[0] == this.position[0] && t.position[1] == this.position[1]) {