diff --git a/chat/command.go b/chat/command.go
index 536de69..7a41148 100644
--- a/chat/command.go
+++ b/chat/command.go
@@ -6,6 +6,7 @@ import (
 	"errors"
 	"fmt"
 	"sort"
+	"strconv"
 	"strings"
 	"time"
 
@@ -191,13 +192,27 @@ func InitCommands(c *Commands) {
 
 			names := room.Members.ListPrefix("")
 			sort.Slice(names, func(i, j int) bool { return names[i].Key() < names[j].Key() })
-			colNames := make([]string, len(names))
-			for i, uname := range names {
-				colNames[i] = colorize(uname.Value().(*Member).User)
+			activeColNames := []string{}
+			awayColNames := []string{}
+			for _, uname := range names {
+				user := uname.Value().(*Member).User
+				colUser := colorize(user)
+				if isAway, _, _ := user.GetAway(); isAway {
+					awayColNames = append(awayColNames, colUser)
+				} else {
+					activeColNames = append(activeColNames, colUser)
+				}
+			}
+			numPeople := strconv.Itoa(len(names))
+			activePeople := strings.Join(activeColNames, ", ")
+
+			if len(awayColNames) > 0 {
+				awayPeople := strings.Join(awayColNames, ",")
+				room.Send(message.NewSystemMsgP(msg.From(), numPeople, " connected: ", activePeople, "; away: ", awayPeople))
+			} else {
+				room.Send(message.NewSystemMsgP(msg.From(), numPeople, " connected: ", activePeople))
 			}
 
-			body := fmt.Sprintf("%d connected: %s", len(colNames), strings.Join(colNames, ", "))
-			room.Send(message.NewSystemMsg(body, msg.From()))
 			return nil
 		},
 	})
diff --git a/chat/message/message.go b/chat/message/message.go
index 79244eb..b251f19 100644
--- a/chat/message/message.go
+++ b/chat/message/message.go
@@ -202,38 +202,70 @@ func (m PrivateMsg) String() string {
 	return m.Render(nil)
 }
 
+var _ Message = &SystemMsg{}
+
 // SystemMsg is a response sent from the server directly to a user, not shown
 // to anyone else. Usually in response to something, like /help.
 type SystemMsg struct {
-	Msg
-	to *User
+	parts     []string
+	timestamp time.Time
+	to        *User
 }
 
+var systemMessagePrefix = []string{"-> "}
+
 func NewSystemMsg(body string, to *User) *SystemMsg {
 	return &SystemMsg{
-		Msg: Msg{
-			body:      body,
-			timestamp: time.Now(),
-		},
-		to: to,
+		parts:     append(systemMessagePrefix, body),
+		timestamp: time.Now(),
+		to:        to,
 	}
 }
 
+func NewSystemMsgP(to *User, parts ...string) *SystemMsg {
+	return &SystemMsg{
+		to:        to,
+		parts:     append(systemMessagePrefix, parts...),
+		timestamp: time.Now(),
+	}
+}
+
+func (m *SystemMsg) renderPlain() string {
+	spArgs := make([]interface{}, len(m.parts))
+	for i, arg := range m.parts {
+		spArgs[i] = arg
+	}
+	return fmt.Sprint(spArgs...)
+}
+
 func (m *SystemMsg) Render(t *Theme) string {
 	if t == nil {
 		return m.String()
 	}
-	return t.ColorSys(m.String())
+
+	colPart := make([]interface{}, len(m.parts))
+	for i, part := range m.parts {
+		colPart[i] = t.ColorSys(part)
+	}
+	return fmt.Sprint(colPart...)
 }
 
 func (m *SystemMsg) String() string {
-	return fmt.Sprintf("-> %s", m.body)
+	return fmt.Sprintf("-> %s", m.renderPlain())
 }
 
 func (m *SystemMsg) To() *User {
 	return m.to
 }
 
+func (m *SystemMsg) Command() string {
+	return ""
+}
+
+func (m *SystemMsg) Timestamp() time.Time {
+	return m.timestamp
+}
+
 // AnnounceMsg is a message sent from the server to everyone, like a join or
 // leave event.
 type AnnounceMsg struct {