diff --git a/chat-cli/src/main.rs b/chat-cli/src/main.rs
index e58dca26fa..cb8b111de2 100644
--- a/chat-cli/src/main.rs
+++ b/chat-cli/src/main.rs
@@ -68,7 +68,7 @@ fn main() {
 
         for event in events {
             match event {
-                Event::Chat(msg) => println!("{}", msg),
+                Event::ChatMsg(msg) => println!("{}", msg),
                 Event::Disconnect => {} // TODO
             }
         }
diff --git a/client/src/lib.rs b/client/src/lib.rs
index be6f82bd67..1be02e2527 100644
--- a/client/src/lib.rs
+++ b/client/src/lib.rs
@@ -14,6 +14,7 @@ use common::{
     state::State,
     terrain::{block::Block, chonk::ChonkMetrics, TerrainChunk, TerrainChunkSize},
     vol::VolSize,
+    ChatType,
 };
 use log::{info, log_enabled, warn};
 use std::{
@@ -28,7 +29,10 @@ use vek::*;
 const SERVER_TIMEOUT: Duration = Duration::from_secs(20);
 
 pub enum Event {
-    Chat(String),
+    Chat {
+        chat_type: ChatType,
+        message: String,
+    },
     Disconnect,
 }
 
@@ -187,7 +191,7 @@ impl Client {
     /// Send a chat message to the server.
     #[allow(dead_code)]
     pub fn send_chat(&mut self, msg: String) {
-        self.postbox.send_message(ClientMsg::Chat(msg))
+        self.postbox.send_message(ClientMsg::chat(msg))
     }
 
     /// Remove all cached terrain
@@ -385,7 +389,16 @@ impl Client {
                             .duration_since(self.last_server_ping)
                             .as_secs_f64()
                     }
-                    ServerMsg::Chat(msg) => frontend_events.push(Event::Chat(msg)),
+                    ServerMsg::ChatMsg { chat_type, msg } => match chat_type {
+                        ChatType::Chat => frontend_events.push(Event::Chat {
+                            chat_type: ChatType::Chat,
+                            message: msg,
+                        }),
+                        ChatType::Tell => frontend_events.push(Event::Chat {
+                            chat_type: ChatType::Tell,
+                            message: msg,
+                        }),
+                    },
                     ServerMsg::SetPlayerEntity(uid) => {
                         self.entity = self.state.ecs().entity_from_uid(uid).unwrap()
                     } // TODO: Don't unwrap here!
diff --git a/common/src/lib.rs b/common/src/lib.rs
index a9706ef52e..67330defb8 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -50,3 +50,9 @@ pub mod volumes;
 /// assert_eq!("bar", scon.next_message().unwrap());
 /// ```
 pub mod net;
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub enum ChatType {
+    Chat,
+    Tell,
+}
diff --git a/common/src/msg/client.rs b/common/src/msg/client.rs
index 1da55e7857..c5ab98c029 100644
--- a/common/src/msg/client.rs
+++ b/common/src/msg/client.rs
@@ -1,6 +1,6 @@
 use super::ClientState;
-use crate::comp;
 use crate::terrain::block::Block;
+use crate::{comp, ChatType};
 use vek::*;
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -19,7 +19,10 @@ pub enum ClientMsg {
     PlaceBlock(Vec3<i32>, Block),
     Ping,
     Pong,
-    Chat(String),
+    ChatMsg {
+        chat_type: ChatType,
+        msg: String,
+    },
     PlayerPhysics {
         pos: comp::Pos,
         vel: comp::Vel,
@@ -30,3 +33,18 @@ pub enum ClientMsg {
     },
     Disconnect,
 }
+
+impl ClientMsg {
+    pub fn chat(message: String) -> crate::msg::client::ClientMsg {
+        crate::msg::client::ClientMsg::ChatMsg {
+            chat_type: ChatType::Chat,
+            msg: message,
+        }
+    }
+    pub fn tell(message: String) -> crate::msg::client::ClientMsg {
+        crate::msg::client::ClientMsg::ChatMsg {
+            chat_type: ChatType::Tell,
+            msg: message,
+        }
+    }
+}
diff --git a/common/src/msg/server.rs b/common/src/msg/server.rs
index 499df4f4e3..f71e065560 100644
--- a/common/src/msg/server.rs
+++ b/common/src/msg/server.rs
@@ -1,9 +1,5 @@
 use super::{ClientState, EcsCompPacket, EcsResPacket};
-use crate::{
-    comp,
-    terrain::{Block, TerrainChunk},
-};
-use fxhash::FxHashMap;
+use crate::{comp, terrain::TerrainChunk, ChatType};
 use vek::*;
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -32,7 +28,10 @@ pub enum ServerMsg {
     ForceState(ClientState),
     Ping,
     Pong,
-    Chat(String),
+    ChatMsg {
+        chat_type: ChatType,
+        msg: String,
+    },
     SetPlayerEntity(u64),
     EcsSync(sphynx::SyncPackage<EcsCompPacket, EcsResPacket>),
     EntityPhysics {
@@ -57,3 +56,18 @@ pub enum ServerError {
     TooManyPlayers,
     //TODO: InvalidAlias,
 }
+
+impl ServerMsg {
+    pub fn chat(message: String) -> crate::msg::server::ServerMsg {
+        crate::msg::server::ServerMsg::ChatMsg {
+            chat_type: ChatType::Chat,
+            msg: message,
+        }
+    }
+    pub fn tell(message: String) -> crate::msg::server::ServerMsg {
+        crate::msg::server::ServerMsg::ChatMsg {
+            chat_type: ChatType::Tell,
+            msg: message,
+        }
+    }
+}
diff --git a/server/src/cmd.rs b/server/src/cmd.rs
index b78319e8b1..abde945bc6 100644
--- a/server/src/cmd.rs
+++ b/server/src/cmd.rs
@@ -166,13 +166,13 @@ fn handle_jump(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
                 }
                 None => server.clients.notify(
                     entity,
-                    ServerMsg::Chat(String::from("You have no position!")),
+                    ServerMsg::chat(String::from("You have no position!")),
                 ),
             }
         }
         _ => server
             .clients
-            .notify(entity, ServerMsg::Chat(String::from(action.help_string))),
+            .notify(entity, ServerMsg::chat(String::from(action.help_string))),
     }
 }
 
@@ -188,12 +188,12 @@ fn handle_goto(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
             }
             _ => server
                 .clients
-                .notify(entity, ServerMsg::Chat(String::from(action.help_string))),
+                .notify(entity, ServerMsg::chat(String::from(action.help_string))),
         },
         None => {
             server.clients.notify(
                 entity,
-                ServerMsg::Chat(String::from("You don't have any position!")),
+                ServerMsg::chat(String::from("You don't have any position!")),
             );
         }
     }
@@ -221,14 +221,14 @@ fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
             Err(_) => {
                 server
                     .clients
-                    .notify(entity, ServerMsg::Chat(format!("'{}' is not a time!", n)));
+                    .notify(entity, ServerMsg::chat(format!("'{}' is not a time!", n)));
                 return;
             }
         },
         None => {
             server.clients.notify(
                 entity,
-                ServerMsg::Chat("You must specify a time!".to_string()),
+                ServerMsg::chat("You must specify a time!".to_string()),
             );
             return;
         }
@@ -249,13 +249,13 @@ fn handle_health(server: &mut Server, entity: EcsEntity, args: String, action: &
             None => {
                 server.clients.notify(
                     entity,
-                    ServerMsg::Chat(String::from("You must specify health amount!")),
+                    ServerMsg::chat(String::from("You must specify health amount!")),
                 );
             }
         },
         None => server.clients.notify(
             entity,
-            ServerMsg::Chat(String::from("You have no position.")),
+            ServerMsg::chat(String::from("You have no position.")),
         ),
     }
 }
@@ -273,7 +273,7 @@ fn handle_alias(server: &mut Server, entity: EcsEntity, args: String, action: &C
         }
         None => server
             .clients
-            .notify(entity, ServerMsg::Chat(String::from(action.help_string))),
+            .notify(entity, ServerMsg::chat(String::from(action.help_string))),
     }
 }
 
@@ -295,29 +295,29 @@ fn handle_tp(server: &mut Server, entity: EcsEntity, args: String, action: &Chat
                         }
                         None => server.clients.notify(
                             entity,
-                            ServerMsg::Chat(format!("Unable to teleport to player '{}'!", alias)),
+                            ServerMsg::chat(format!("Unable to teleport to player '{}'!", alias)),
                         ),
                     },
                     None => {
                         server.clients.notify(
                             entity,
-                            ServerMsg::Chat(format!("Player '{}' not found!", alias)),
+                            ServerMsg::chat(format!("Player '{}' not found!", alias)),
                         );
                         server
                             .clients
-                            .notify(entity, ServerMsg::Chat(String::from(action.help_string)));
+                            .notify(entity, ServerMsg::chat(String::from(action.help_string)));
                     }
                 },
                 None => {
                     server
                         .clients
-                        .notify(entity, ServerMsg::Chat(format!("You have no position!")));
+                        .notify(entity, ServerMsg::chat(format!("You have no position!")));
                 }
             }
         }
         None => server
             .clients
-            .notify(entity, ServerMsg::Chat(String::from(action.help_string))),
+            .notify(entity, ServerMsg::chat(String::from(action.help_string))),
     }
 }
 
@@ -351,17 +351,17 @@ fn handle_spawn(server: &mut Server, entity: EcsEntity, args: String, action: &C
                     }
                     server.clients.notify(
                         entity,
-                        ServerMsg::Chat(format!("Spawned {} entities", amount).to_owned()),
+                        ServerMsg::chat(format!("Spawned {} entities", amount).to_owned()),
                     );
                 }
                 None => server
                     .clients
-                    .notify(entity, ServerMsg::Chat("You have no position!".to_owned())),
+                    .notify(entity, ServerMsg::chat("You have no position!".to_owned())),
             }
         }
         _ => server
             .clients
-            .notify(entity, ServerMsg::Chat(String::from(action.help_string))),
+            .notify(entity, ServerMsg::chat(String::from(action.help_string))),
     }
 }
 
@@ -381,11 +381,11 @@ fn handle_players(server: &mut Server, entity: EcsEntity, _args: String, _action
 
         server
             .clients
-            .notify(entity, ServerMsg::Chat(header_message + &player_list));
+            .notify(entity, ServerMsg::chat(header_message + &player_list));
     } else {
         server
             .clients
-            .notify(entity, ServerMsg::Chat(header_message));
+            .notify(entity, ServerMsg::chat(header_message));
     }
 }
 
@@ -403,7 +403,7 @@ fn handle_build(server: &mut Server, entity: EcsEntity, _args: String, _action:
             .remove(entity);
         server.clients.notify(
             entity,
-            ServerMsg::Chat(String::from("Toggled off build mode!")),
+            ServerMsg::chat(String::from("Toggled off build mode!")),
         );
     } else {
         let _ = server
@@ -413,7 +413,7 @@ fn handle_build(server: &mut Server, entity: EcsEntity, _args: String, _action:
             .insert(entity, comp::CanBuild);
         server.clients.notify(
             entity,
-            ServerMsg::Chat(String::from("Toggled on build mode!")),
+            ServerMsg::chat(String::from("Toggled on build mode!")),
         );
     }
 }
@@ -422,7 +422,7 @@ fn handle_help(server: &mut Server, entity: EcsEntity, _args: String, _action: &
     for cmd in CHAT_COMMANDS.iter() {
         server
             .clients
-            .notify(entity, ServerMsg::Chat(String::from(cmd.help_string)));
+            .notify(entity, ServerMsg::chat(String::from(cmd.help_string)));
     }
 }
 
@@ -460,7 +460,7 @@ fn handle_killnpcs(server: &mut Server, entity: EcsEntity, _args: String, _actio
     } else {
         "No NPCs on server.".to_string()
     };
-    server.clients.notify(entity, ServerMsg::Chat(text));
+    server.clients.notify(entity, ServerMsg::chat(text));
 }
 
 fn handle_object(server: &mut Server, entity: EcsEntity, args: String, _action: &ChatCommand) {
@@ -613,29 +613,23 @@ fn handle_tell(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
             let msg = &args[alias.len()..args.len()];
             match opt_player {
                 Some(player) => {
-                    if player != entity {
-                        if msg.len() > 1 {
-                            let opt_name = ecs
-                                .read_storage::<comp::Player>()
-                                .get(entity)
-                                .map(|s| s.alias.clone());
-                            match opt_name {
-                                Some(name) => {
-                                    server.clients.notify(
-                                        player,
-                                        ServerMsg::Chat(format!("{} tells you:{}", name, msg)),
-                                    );
-                                    server.clients.notify(
-                                        entity,
-                                        ServerMsg::Chat(format!("You tell {}:{}", alias, msg)),
-                                    );
-                                }
-                                None => {
-                                    server.clients.notify(
-                                        entity,
-                                        ServerMsg::Chat(String::from("You do not exist!")),
-                                    );
-                                }
+                    if msg.len() > 1 {
+                        let opt_name = ecs
+                            .read_storage::<comp::Player>()
+                            .get(entity)
+                            .map(|s| s.alias.clone());
+                        match opt_name {
+                            Some(name) => {
+                                server.clients.notify(
+                                    player,
+                                    ServerMsg::tell(format!("{} tells you:{}", name, msg)),
+                                );
+                            }
+                            None => {
+                                server.clients.notify(
+                                    entity,
+                                    ServerMsg::chat(String::from("You do not exist!")),
+                                );
                             }
                         } else {
                             server.clients.notify(
@@ -647,21 +641,25 @@ fn handle_tell(server: &mut Server, entity: EcsEntity, args: String, action: &Ch
                             );
                         }
                     } else {
-                        server
-                            .clients
-                            .notify(entity, ServerMsg::Chat(format!("Don't be crazy!")));
+                        server.clients.notify(
+                            entity,
+                            ServerMsg::chat(format!(
+                                "You really should say something to {}!",
+                                alias
+                            )),
+                        );
                     }
                 }
                 None => {
                     server.clients.notify(
                         entity,
-                        ServerMsg::Chat(format!("Player '{}' not found!", alias)),
+                        ServerMsg::chat(format!("Player '{}' not found!", alias)),
                     );
                 }
             }
         }
         None => server
             .clients
-            .notify(entity, ServerMsg::Chat(String::from(action.help_string))),
+            .notify(entity, ServerMsg::chat(String::from(action.help_string))),
     }
 }
diff --git a/server/src/lib.rs b/server/src/lib.rs
index b73eea4284..65473961d1 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -526,14 +526,17 @@ impl Server {
                             }
                             ClientState::Pending => {}
                         },
-                        ClientMsg::Chat(msg) => match client.client_state {
+                        ClientMsg::ChatMsg {
+                            chat_type: _,
+                            msg: message,
+                        } => match client.client_state {
                             ClientState::Connected => {
                                 client.error_state(RequestStateError::Impossible)
                             }
                             ClientState::Registered
                             | ClientState::Spectator
                             | ClientState::Dead
-                            | ClientState::Character => new_chat_msgs.push((Some(entity), msg)),
+                            | ClientState::Character => new_chat_msgs.push((Some(entity), message)),
                             ClientState::Pending => {}
                         },
                         ClientMsg::PlayerPhysics { pos, vel, ori } => match client.client_state {
@@ -622,7 +625,7 @@ impl Server {
                     let argv = String::from(&msg[1..]);
                     self.process_chat_cmd(entity, argv);
                 } else {
-                    self.clients.notify_registered(ServerMsg::Chat(
+                    self.clients.notify_registered(ServerMsg::chat(
                         match self.state.ecs().read_storage::<comp::Player>().get(entity) {
                             Some(player) => format!("[{}] {}", &player.alias, msg),
                             None => format!("[<anon>] {}", msg),
@@ -630,7 +633,7 @@ impl Server {
                     ));
                 }
             } else {
-                self.clients.notify_registered(ServerMsg::Chat(msg.clone()));
+                self.clients.notify_registered(ServerMsg::chat(msg.clone()));
             }
             frontend_events.push(Event::Chat { entity, msg });
         }
@@ -719,7 +722,7 @@ impl Server {
                     }
                     .unwrap_or(format!("{} died", &player.alias));
 
-                    clients.notify_registered(ServerMsg::Chat(msg));
+                    clients.notify_registered(ServerMsg::chat(msg));
                 }
 
                 entity
@@ -849,7 +852,7 @@ impl Server {
             None => {
                 self.clients.notify(
                     entity,
-                    ServerMsg::Chat(format!(
+                    ServerMsg::chat(format!(
                         "Unrecognised command: '/{}'\ntype '/help' for a list of available commands",
                         kwd
                     )),
diff --git a/voxygen/src/hud/chat.rs b/voxygen/src/hud/chat.rs
index d6e29d8e72..f11a58a2a4 100644
--- a/voxygen/src/hud/chat.rs
+++ b/voxygen/src/hud/chat.rs
@@ -1,4 +1,6 @@
-use super::{img_ids::Imgs, Fonts, TEXT_COLOR};
+use super::{img_ids::Imgs, Fonts, TELL_COLOR, TEXT_COLOR};
+use client::Event as ClientEvent;
+use common::ChatType;
 use conrod_core::{
     input::Key,
     position::Dimension,
@@ -22,7 +24,7 @@ const MAX_MESSAGES: usize = 100;
 
 #[derive(WidgetCommon)]
 pub struct Chat<'a> {
-    new_messages: &'a mut VecDeque<String>,
+    new_messages: &'a mut VecDeque<ClientEvent>,
     force_input: Option<String>,
     force_cursor: Option<Index>,
 
@@ -34,7 +36,11 @@ pub struct Chat<'a> {
 }
 
 impl<'a> Chat<'a> {
-    pub fn new(new_messages: &'a mut VecDeque<String>, imgs: &'a Imgs, fonts: &'a Fonts) -> Self {
+    pub fn new(
+        new_messages: &'a mut VecDeque<ClientEvent>,
+        imgs: &'a Imgs,
+        fonts: &'a Fonts,
+    ) -> Self {
         Self {
             new_messages,
             force_input: None,
@@ -71,7 +77,7 @@ impl<'a> Chat<'a> {
 }
 
 pub struct State {
-    messages: VecDeque<String>,
+    messages: VecDeque<ClientEvent>,
     input: String,
 
     ids: Ids,
@@ -179,27 +185,44 @@ impl<'a> Widget for Chat<'a> {
         while let Some(item) = items.next(ui) {
             // This would be easier if conrod used the v-metrics from rusttype.
             let widget = if item.i < state.messages.len() {
-                let text = Text::new(&state.messages[item.i])
-                    .font_size(15)
-                    .font_id(self.fonts.opensans)
-                    .w(470.0)
-                    .color(TEXT_COLOR)
-                    .line_spacing(2.0);
-                // Add space between messages.
-                let y = match text.get_y_dimension(ui) {
-                    Dimension::Absolute(y) => y + 2.0,
-                    _ => 0.0,
-                };
-                text.h(y)
+                let msg = &state.messages[item.i];
+                match msg {
+                    ClientEvent::Chat { chat_type, message } => {
+                        let color = match chat_type {
+                            ChatType::Tell => TELL_COLOR,
+                            _ => TEXT_COLOR,
+                        };
+                        let text = Text::new(&message)
+                            .font_size(15)
+                            .font_id(self.fonts.opensans)
+                            .w(470.0)
+                            .color(color)
+                            .line_spacing(2.0);
+                        // Add space between messages.
+                        let y = match text.get_y_dimension(ui) {
+                            Dimension::Absolute(y) => y + 2.0,
+                            _ => 0.0,
+                        };
+                        Some(text.h(y))
+                    }
+                    _ => None,
+                }
             } else {
                 // Spacer at bottom of the last message so that it is not cut off.
                 // Needs to be larger than the space above.
-                Text::new("")
-                    .font_size(6)
-                    .font_id(self.fonts.opensans)
-                    .w(470.0)
+                Some(
+                    Text::new("")
+                        .font_size(6)
+                        .font_id(self.fonts.opensans)
+                        .w(470.0),
+                )
             };
-            item.set(widget, ui);
+            match widget {
+                Some(widget) => {
+                    item.set(widget, ui);
+                }
+                None => {}
+            }
         }
 
         // Chat Arrow
diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs
index c257a13bb5..3cbb4fa615 100644
--- a/voxygen/src/hud/mod.rs
+++ b/voxygen/src/hud/mod.rs
@@ -31,7 +31,7 @@ use crate::{
     window::{Event as WinEvent, GameInput, Window},
     GlobalState,
 };
-use client::Client;
+use client::{Client, Event as ClientEvent};
 use common::{comp, terrain::TerrainChunkSize, vol::VolSize};
 use conrod_core::{
     text::cursor::Index,
@@ -50,6 +50,7 @@ const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0);
 const TEXT_COLOR_2: Color = Color::Rgba(0.0, 0.0, 0.0, 1.0);
 const HP_COLOR: Color = Color::Rgba(0.33, 0.63, 0.0, 1.0);
 const MANA_COLOR: Color = Color::Rgba(0.42, 0.41, 0.66, 1.0);
+const TELL_COLOR: Color = Color::Rgba(1.0, 1.0, 0.0, 1.0);
 
 widget_ids! {
     struct Ids {
@@ -269,7 +270,7 @@ pub struct Hud {
     ids: Ids,
     imgs: Imgs,
     fonts: Fonts,
-    new_messages: VecDeque<String>,
+    new_messages: VecDeque<ClientEvent>,
     inventory_space: usize,
     show: Show,
     to_focus: Option<Option<widget::Id>>,
@@ -743,7 +744,7 @@ impl Hud {
         events
     }
 
-    pub fn new_message(&mut self, msg: String) {
+    pub fn new_message(&mut self, msg: ClientEvent) {
         self.new_messages.push_back(msg);
     }
 
diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs
index 882d78cb2b..1bfb22d706 100644
--- a/voxygen/src/session.rs
+++ b/voxygen/src/session.rs
@@ -44,8 +44,11 @@ impl SessionState {
     fn tick(&mut self, dt: Duration) -> Result<(), Error> {
         for event in self.client.borrow_mut().tick(self.controller.clone(), dt)? {
             match event {
-                client::Event::Chat(msg) => {
-                    self.hud.new_message(msg);
+                client::Event::Chat {
+                    chat_type: _,
+                    message: _,
+                } => {
+                    self.hud.new_message(event);
                 }
                 client::Event::Disconnect => {} // TODO
             }