diff --git a/antisplice.cabal b/antisplice.cabal
--- a/antisplice.cabal
+++ b/antisplice.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             0.13.0.1
+version:             0.13.1.0
 
 -- A short (one-line) description of the package.
 synopsis:            An engine for text-based dungeons.
diff --git a/src/Game/Antisplice/Prototypes.hs b/src/Game/Antisplice/Prototypes.hs
--- a/src/Game/Antisplice/Prototypes.hs
+++ b/src/Game/Antisplice/Prototypes.hs
@@ -83,7 +83,7 @@
   onLook $ mprintLn d
   onRoomEnter $ mnomaskLn =<< expand (printf "%s has entered the room." t)
   onRoomLeave $ mnomaskLn =<< expand (printf "%s has left the room." t)
-  onAnnounce $ enomaskLn (Dull Cyan) =<< expand (printf "  %s is here." t)
+  onAnnounce $ mnomaskLn =<< expand (printf "  %%{D6;%s is here.}" t)
   onDie $ do
     mnomaskLn =<< expand (printf "%s dies." t)
     void $ addRoomObject $ do
diff --git a/src/Game/Antisplice/Rooms.hs b/src/Game/Antisplice/Rooms.hs
--- a/src/Game/Antisplice/Rooms.hs
+++ b/src/Game/Antisplice/Rooms.hs
@@ -87,7 +87,10 @@
     withRoom,
     withPlayer,
     withObject,
-    guardVisible
+    -- * Guardians
+    guardRoom,
+    guardObject,
+    guardObjectInRoom
   ) where
 
 import Text.Chatty.Printer
@@ -182,7 +185,9 @@
   r <- enterRoom n
   rs <- getRoomState
   roomTriggerOnAnnounceOf rs
-  when r $ roomTriggerOnLookOf rs
+  --when r $
+  id $
+    roomTriggerOnLookOf rs
 
 -- | Construct a new room using the room monad.
 constructRoom :: (MonadDungeon m) => RoomT m a -> m NodeId
@@ -373,18 +378,34 @@
   case rs of
     [r] -> do
       o <- withRoom r $ removeRoomObject i
-      guardVisible r $ objectTriggerOnRoomLeaveOf o
+      guardRoom r $ objectTriggerOnRoomLeaveOf o
       let (n:rs) = objectRouteOf o
       withRoom n $ insertRoomObject o{objectRouteOf=rs++[n]}
-      guardVisible n $ objectTriggerOnRoomEnterOf o
+      guardRoom n $ objectTriggerOnRoomEnterOf o
       modifyPlayerState $ \s -> if playerOpponentOf s == i then s{playerOpponentOf=FalseObject} else s
       return ()
 
 -- | Only run the given function if the player is inside the also given room.
-guardVisible :: MonadDungeon m => NodeId -> m () -> m ()
-guardVisible n m = do
+guardRoom :: MonadDungeon m => NodeId -> m () -> m ()
+guardRoom n m = do
   s <- getDungeonState
   when (currentRoomOf s == Just n) m
+
+-- | Only run the given function if the given object exists
+guardObject :: MonadDungeon m => ObjectId -> m () -> m ()
+guardObject o m = do
+  rs <- roomOfObject o
+  case rs of
+    [] -> return ()
+    _ -> m
+
+-- | Only run the given function if the given object is in the also given room
+guardObjectInRoom :: MonadDungeon m => ObjectId -> NodeId -> m () -> m ()
+guardObjectInRoom o r m = do
+  rs <- roomOfObject o
+  case rs of
+    [r1] | r1 == r -> m
+    _ -> return ()
 
 -- | Determine which rooms contain the given object (won't be more than one, but we're careful)
 roomOfObject :: MonadDungeon m => ObjectId -> m [NodeId]
